“ID串行化”是如何保证消息顺序性的?

开发 开发工具 前端
在《消息顺序性为何这么难?》中,介绍了一种为了保证“所有群友展示的群消息时序都是一致的”所使用的“ID串行化”的方法:让同一个群gid的所有消息落在同一台服务器上处理。

在《消息顺序性为何这么难?》中,介绍了一种为了保证“所有群友展示的群消息时序都是一致的”所使用的“ID串行化”的方法:让同一个群gid的所有消息落在同一台服务器上处理。

[[260316]]

ID串行化是如何实现的呢?

1. 互联网高可用常见分层架构

客户端,反向代理层,接入层,服务层,存储层,这是互联网常见的高可用分层架构。

画外音:这个图用过好多次。

这里的“服务层”至关重要,ID串行化保证的是,同一个群gid的消息落在同一个服务上。

画外音:服务集群有很多节点,如果能落在同一个服务节点上,就可以利用这个服务节点做消息串行化。

2. 服务层上下游细节

服务一般由RPC框架实现,上游调用方是多线程程序,通过RPC-client访问服务,而RPC-client内部又通过连接池connection-pool来访问的。

画外音:为了保证高可用,连接池会对集群中的每个服务都建立连接。

如上图:

(1)上游是业务应用;

(2)下游是服务集群;

(3)业务应用,它又分为了这么几个部分:

  • 上层是任务队列(粉色);
  • 中间是工作线程(蓝色),每个工作线程完成实际的业务任务,典型的工作任务是通过服务连接池进行RPC调用;
  • 下层是服务连接池(绿色),所有的RPC调用都是通过服务连接池往下游服务发请求执行;

画外音:橙色是连接池中的一条连接。

工作线程的典型工作流是这样的:

  1. void work_thread_routine(){ 
  2. // 获取任务 
  3. Task t = TaskQueue.pop();  
  4. // 任务逻辑处理,组成一个网络包packet 
  5. Packet p = MakePacket(t); 
  6.  
  7. // 从Service连接池获取一个Service连接 
  8. ServiceConnection c = CPool.GetConnection(); 
  9. // 通过Service连接发送报文执行RPC请求 
  10. c.Send(p);  
  11. // 将Service连接放回Service连接池 
  12. CPool.PutConnection(c);  

如何保证同一个群gid的消息落在同一个服务上呢?

对连接池进行少量改动,获取连接时:

  1. CPool.GetConnection() 

画外音:返回任何一个可用服务连接。

升级为

  1. CPool.GetConnection(long id) 

画外音:返回id取模相关联的服务连接。

只要传入群gid,就能够保证同一个群的请求获取到同一个连接,从而使请求落到同一个服务上。

需要注意的是,连接池不关心传入的long id是什么业务含义:

  • 传入群gid,同gid的请求落在同一个服务上;
  • 传入用户uid,同uid的请求落在同一个服务上;
  • 传入任何业务xid,同业务xid的请求落在同一个服务上;

ID串行化访问服务,同一个id访问同一个服务,当服务挂掉时,会不会受影响服务可用性?

不会,当有下游服务挂掉的时候,连接池能够检测到连接的可用性,取模时要把不可用的服务连接排除掉。

取模访问服务,是否会影响各连接上请求的负载均衡?

不会,只要数据访问id是均衡的,从全局来看,由id取模获取各连接的概率也是均等的,即负载是均衡的。

【本文为51CTO专栏作者“58沈剑”原创稿件,转载请联系原作者】

戳这里,看该作者更多好文

责任编辑:赵宁宁 来源: 51CTO专栏
相关推荐

2016-11-17 22:18:31

id串行化服务器

2023-12-04 09:23:49

分布式消息

2023-11-27 17:29:43

Kafka全局顺序性

2024-06-27 08:00:17

2009-07-10 09:38:06

Java swing组

2009-11-18 11:05:27

PHP串行化

2009-06-09 16:14:47

Java swing组件串行化

2021-02-02 11:01:31

RocketMQ消息分布式

2009-09-11 12:17:59

C#控件属性

2009-11-02 16:41:55

VB.NET串行化对象

2024-05-09 08:04:23

RabbitMQ消息可靠性

2023-09-21 09:02:03

RocketMQ全局有序局部有序

2021-04-27 07:52:18

RocketMQ消息投递

2010-01-12 10:29:51

VB.NET对象串行化

2021-04-14 15:01:44

串行化方式缓存

2010-01-06 10:49:54

PHP串行化JSON

2023-12-15 13:08:00

RocketMQ中间件消费顺序

2010-01-14 18:00:07

VB.NET串行化对象

2009-11-17 16:24:27

PHP变量串行化

2021-03-04 06:49:53

RocketMQ事务
点赞
收藏

51CTO技术栈公众号