如果在开启多个worker,由fpm通过socket来触发推送消息,如何保证消息在一定被用户归属connect的worker处理?

liuzeming

因为多个worker是竞争消费的,没有办法保证一一对应。我看现在的解决方案只有使用channel注册订阅的方式,还有其它方案可以解决吗

1678 3 0
3个回答

phpcreeper

对于纯workerman环境:
一个socket连接一旦连接到哪个worker进程,那么后续这个连接上的消息依然还是由相应的这个worker进程来处理的;【worker节点依赖内核调度实现】
再比如gatewayworker环境:
也有类似的实现机制,gateway转发连接连接到businessworker时,一开始随机路由选择一个worker进程,在此之后同一连接继续转发来的消息就会自动交由给先前路由好的那个进程。【worker节点依赖内核调度实现,转发节点之间则依赖应用实现】

  • liuzeming 2020-07-18

    对于纯workerman环境:有没有内核版本限制呢,我看3.9以上使用了端口复用SO_REUSEPORT可以实现同一个连接一直由同一个worker处理(内核根据tcp四元组hash负载均衡)。

  • phpcreeper 2020-07-18

    进程的负载均衡是需要开启端口复用机制、workerman已经支持、另linux内核好像是需要2.6以上即可。

  • liuzeming 2020-07-18

    @614:我在网上查,内核要3.9以上。如果没有3.9以上,感觉就只能够单进程或者使用channel了

小阳光

每个worker 维持部分连接。所以单进程或者使用channel可以。换个角度想,可不可以每个进程开启一个udp内部端口,接收广播,有这个id就做事,没就不管。广播如果有广播风暴,用redis队列呢?或者消息队列,同理在我这,我就处理,没有我就不管。

  • liuzeming 2020-07-20

    开启一个udp内部端口,接收广播,有这个id就做事,没就不管,channel就是这个原理。redis或者消息队列用不了,会阻塞

喵了个咪

每个worker进程开一个内部端口,每个进程内部端口不一样,这样就可以用socket连对应的进程内部端口,就能保证消息在一定被用户归属connect的worker处理。不过前提是你知道用户归属connect的worker是哪个进程。

  • liuzeming 2020-07-20

    这种处理方式是不优雅的,相当于你需要起很多不同的端口才行,而且都只能够单进程

年代过于久远,无法发表回答
×
🔝