.Net 还是 Java? :)
最近园子里又出现了.Net 和 Java 的口水贴,如果你觉得本文的内容根本就是 a piece of cake,不值一提,轻轻松松就能码出可靠健壮的实现,或许还可以讨论下.Net 和 Java 的问题,否则我想你还是歇歇吧,对你来说都是一样的,用好一样就行了,否则 .Net 1.1 都能完爆你。
.Net的应用领域没有有些人想的那么窄,只能说你眼界实在是太浅了。.Net在国外是否受待见?自己去国外招聘网站看一看就是了,又没被墙的,呵呵。
技术不过关不要赖平台和编译器,那是编程爱好者。(这话不是我说的,老外的书上看来的,深以为然)
-------------------------
园子中的文章现在主要以代码片段,特定功能的实现,和Hello World类的文章为主,本系列文章将着重围绕产品设计的理念、技术架构/部署架构的方案、以及代码的设计模式为主线来讨论。
升讯威微信营销系统开发实践系列,将以一个实际的微信平台项目为案例,深入浅出的讲解微信开发、应用各环节的实现方案和技术细节。
本系列文章的最终目标是完成一个功能完善并达到高可用性能指标的微信管理软件,所以除了与微信本身紧密相关的对接和应用技术,还会讲到其它相关的所有知识点,从技术选型,架构设计,数据层的设计,API的设计,数据传输协议的设计,再到细节的前端的设计及技术应用,后台开发中的各方面技术,都会涉及。同时,在架构设计中,会考虑到运维领域的诸多问题,会涉及到部署环节中负载均衡及CDN分发,服务器流量及带宽控制等因素。有许多开发人员对运维领域的工作不熟悉造成项目运维阶段成本高,难度大,希望本文能够帮助到你。
本系列文章文会公开部分代码,开源部分模块,但是不会全部开源,请见谅,毕竟:Who can afford to do professional work for nothing? :) 不过我相信本系列文章会使你在开展相关工作时,轻车熟路,找到捷径。
这个项目是一个实际上已完成并应用的项目,所以本系列文章中可能出现项目的相关信息,但是个别技术细节会隐去或简化,请见谅,我会尽量保持每周一篇的速度更新,希望你有所收获。
写一篇文章,加上排版校对大约要用掉六小时左右的时间,你的支持是我最大的动力,对你有帮助的话请点击右下角“推荐”,谢谢。 :)
原创内容,转载请注明出处。
------------------------
在上一篇文章中,简要介绍了升讯威微信营销系统的功能设计和架构设计,限于篇幅只能抛砖引玉,从本章节开始将围绕功能的设计和架构的设计进行详细的论述。
中控服务器的设计
在上文中,我们谈到需要一个中控服务器,用来维护公众号的AccessToken等。本节首先围绕这个内容讨论。
背景
微信接口调用需要首先获取一个AccessToken进行鉴权,目前每次获取的AccessToken有效期为2个小时,每天获取次数限制在2000次以下。当然我们不需要如此频繁的请求新的AccessToken,我们只需要把它存储起来,在过期前刷新即可。
对于只为单个公众号服务的系统,中控服务器的设计实现可以从简,只需定时刷新AccessToken,并为应用服务器提供获取AccessToken的接口即可。
对于直接将AccessToken写入Redis,在我实践过程中发现不能100%保证写入成功,存在写入失败,数据没有更新的情况,这个问题是致命的,因为一旦获取了新的AccessToken,旧的就会很快失效,如果不能写入成功,应用服务器继续使用旧的AccessToken,将导致微信API调用全部失败。
我没有找到相关资料说明是否Redis写入机制不保证一定成功?如果有熟悉Redis的大神请指教,谢谢。
对于需要同时服务于多个公众号的系统,中控服务器的设计要稍微复杂一些。
我们现在将问题放大一些,在升讯威微信营销系统中,所需要维护和管理的数据很多,其中有一些数据,如公众号的基本信息数据、个性化设置数据、授权数据、以及各种AccessToken、Ticket等,我将之打包称之为“公众号上下文”。中控服务器除了维护AccessToken,更重要的作用是维护起整个公众号上下文。
设计目标
概括来说中控服务器有以下几个职责:
1) 维护鉴权所需的各种AccessToken、Ticket。
2) 维护基本信息、授权信息等基础数据。
3) 提供一套供应用服务器使用的API,用于同步用户的个性化设置及其它需要动态更新的数据。
4) 提供基于 TCP/IP 的接口以提高通信能力。
5) 可通过增加服务器横向扩展以提高承载能力。
架构设计
这里的架构设计是针对上一篇《功能设计及架构设计》中“架构设计”环节里中控服务器部分的展开。
中控服务器的具体实现方法我想放到后面的章节中介绍,本篇专注于架构的设计。
中控服务器最重要的核心即“域容器”。
对于我们的系统来说,要提供承载多个公众号(100000+)的能力,所以需要将不同公众号的上下文数据组织好之后,放到一个域容器中进行维护。为什么这里叫做“域容器”而不叫做“公众号容器”?这里为了方便论述,我对相关的设计做了简化,实际上单个公众号上下文是被包含在一个“域”中的,“域”除了承载公众号上下文数据之外,还需要承载并维护其它一些数据。
中控服务器在维护公众号上下文时,有多种架构设计方案,根据项目的技术指标,由易到难。
入门级
入门级只需要单台中控服务器即可,维护所有的公众号上下文,通过Http Web API 接口向应用服务器提供服务。
可以适用于一般小规模服务,如果中控服务器Out of Service,需要运维团队及时响应,重启服务或服务器,数据可以在启动时从缓存中恢复,但是会造成短时间的服务中断。
门厅级
鉴于中控服务器的重要性,我们不能接受它出现问题,我们的目标是达到服务99.999% 以上的可用时间。
进一步的方案是对中控服务器进行冗余,使用多台服务器维护公众号上下文并提供服务。
在此方案中,每台中控服务器所维护的数据是一致的,都是彼此的副本。
规模不大时已经适用了,可以将部分接口基于TCP/IP来实现,主要是为应用服务器提供AccessToken的接口,请求频率会非常高。
如果系统所需要服务的公众号数量非常多,达到数万甚至数十万,单台中控服务器的承载能力将受到很大影响,甚至根本不能承受,我们需要对公众号上下文数据的维护进行拆分。
客厅级
在客厅级方案中,最重要的目的是拆分中控服务器对公众号上下文的维护,使系统的整体承载能力得到提高,并使之具有横向扩展的能力。
举例来说中控服务器1维护第1~3000个公众号上下文,中控服务器2维护第3001~6000个公众号上下文。具体维护数量根据服务器配置和网络情况,以及你的中控服务器实现质量决定。
中控服务器对公众号上下文的维护的拆分,带来的问题当然是应用层怎么样才能找到指定公众号所需的上下文数据在哪台服务器上呢?偷懒的方案是在公众号对接时直接定死,但是这个方案很容易造成运维阶段的成本浪费,因为公众号的活跃度是不同的,有很多公众号在对接后可能长时间处于不活动状态。而且定死的话你虽然能通过横向扩展增加服务的承载能力,但是没有办法通过增加单台服务器的配置提高既有服务器的承载能力。所以在我们的具体实现中,中控服务器对于公众号上下文的加载和维护都是懒加载的,单台可加载数量可以根据运维期的服务器配置进行调整。
如何使应用层的服务器找到指定公众号上下文在哪台服务器上?其实很简单,增加一个中控服务器路由即可,这个路由服务器必须知道公众号上下文和中控服务器的对应关系,知道它在哪里。是不是每次请求中控服务器都需要经过路由服务器去定位哪?并不需要这样做,只需要在应用层服务器初次定位时到路由服务器上查询即可,后续的通信直接与中控服务器进行。
卧室级
客厅级的加强版,对所有中控服务器进行一对一的冗余,以防单台故障Out Of Service。
其实这里有一个技术点是要注意的,AccessToken的同步问题,这个问题在上文的门厅级方案中也是一样存在的,冗余的服务器之间如何确保AccessToken是同步的,当然不能各自去调用微信API刷新,后刷新的就把先刷新的冲掉了,所以需要把刷新AccessToken的工作放到中控服务器对外代理中,在其中实现一个队列来处理这件事,并在得到新的AccessToken后,分发到中控服务器。
阳台级
生活不只是眼前的苟且,还有远方的苟且等着你,慢慢来……
中控服务器的设计实现可以采取不断演进的方式进行,可以随着运维规模的扩大适时迭代,但是必须在前期规划设计时考虑到这些问题,特别是横向扩展的能力。
====
本章节结束。
写一篇文章,加上排版校对大约要用掉六小时左右的时间,你的支持是我最大的动力,对你有帮助的话请点击右下角“推荐”,谢谢。 :)
欢迎加我QQ交流探讨,共同学习:279060597,另外我在南京,有南京的朋友吗?