在《消息顺序性为何这么难?》中,介绍了一种为了保证“所有群友展示的群消息时序都是一致的”所使用的“id串行化”的方法:让同一个群gid的所有消息落在同一台服务器上处理。
id串行化是如何实现的呢?
客户端,反向代理层,接入层,服务层,存储层,这是互联网常见的高可用分层架构。
画外音:这个图用过好多次。
这里的“服务层”至关重要,id串行化保证的是,同一个群gid的消息落在同一个服务上。
画外音:服务集群有很多节点,如果能落在同一个服务节点上,就可以利用这个服务节点做消息串行化。
服务一般由rpc框架实现,上游调用方是多线程程序,通过rpc-client访问服务,而rpc-client内部又通过连接池connection-pool来访问的。
画外音:为了保证高可用,连接池会对集群中的每个服务都建立连接。
如上图:
(1)上游是业务应用;
(2)下游是服务集群;
(3)业务应用,它又分为了这么几个部分:
上层是任务队列(粉色);
中间是工作线程(蓝色),每个工作线程完成实际的业务任务,典型的工作任务是通过服务连接池进行rpc调用;
下层是服务连接池(绿色),所有的rpc调用都是通过服务连接池往下游服务发请求执行;
画外音:橙色是连接池中的一条连接。
工作线程的典型工作流是这样的:
对连接池进行少量改动,获取连接时:
cpool.getconnection()
画外音:返回任何一个可用服务连接。
升级为
cpool.getconnection(long id)
画外音:返回id取模相关联的服务连接。
只要传入群gid,就能够保证同一个群的请求获取到同一个连接,从而使请求落到同一个服务上。
需要注意的是,连接池不关心传入的long id是什么业务含义:
(1)传入群gid,同gid的请求落在同一个服务上;
(2)传入用户uid,同uid的请求落在同一个服务上;
(3)传入任何业务xid,同业务xid的请求落在同一个服务上;
不会,当有下游服务挂掉的时候,连接池能够检测到连接的可用性,取模时要把不可用的服务连接排除掉。
不会,只要数据访问id是均衡的,从全局来看,由id取模获取各连接的概率也是均等的,即负载是均衡的。
获取连接,id取模,希望大家有收获。
架构师之路-分享可落地的技术文章
相关推荐:
《离不开的微服务架构,脱不开的rpc细节(值得收藏)》
《究竟啥才是互联网架构“高可用”》