timzaak / blog

8 stars 1 forks source link

websocket 高负载搭建 #19

Closed timzaak closed 3 years ago

timzaak commented 6 years ago

https://github.com/smallnest/C1000K-Servers

涵盖了大部分流行的 java ws 框架测试,也包含机器参数调优。

但 ws ssl 反向代理的 benchmark 太少。

另外,如何做 nginx 集群呢?

nginx 官网给出的一个答案是 public vip!

timzaak commented 6 years ago

Akka as WS connection holder

Actor 的 ActorPath 是用来描述 Actor 的树状结构的,目前不支持正则匹配(支持通过 * 拿到所有其子类 )这种设计就无法依照 Actor Path 去处理多机登录的情况。需要找个地方存储 Actor 对 Client 端的映射了。单机情况,这样就挺好。但分布式的时候,其负载如何 load balancing, 就不知道了。

另一种就是 通过 akka cluster group router 去挂载 connection。 每一个WS 都是一个 routee。 但需要自己保证 Actor 内部状态机, WS 挂载 到哪里就是哪里了。

还有一种是 akka sharding + akka persistence。 通过userId + deviceId 定位 WS 在哪个 akka 里面。但我始终搞不定: WS 链接如何在 scale 的时候保持住。

目前需要在其它的项目中捕获灵感。

timzaak commented 6 years ago

关于链接通信的抽象

我始终认为链接应该以标识用户为基本单位,但从目前看来,它无法覆盖用户未登录时的请求状况,还是应该需要 sessionId,在 sessionId 上封出 userId + deviceId 目前看的各种框架也是以 session 为基本单位

timzaak commented 6 years ago

基于 SessionId 的链接抽象

当以 SessionId 作为抽象基本单位,作为 ConnectionActor 标识时, 便自然地获得了scale 能力! 在请求从 ConnectionActor 往外分发时,会自然而然的带上 我是谁 的信息, 那么后面的逻辑处理,就可以做到无状态了! 当把 ConnectionActor 放入 sharding, 然后sharding rebalancing 时, 需要被移动的Actor,会被 kill 掉。这时候,ConnectionActor 主动释放掉链接, 等客户端重新连接时,可以根据客户端的 sessionId 再次找到其 ConnectionActor。

ConnectionActor 里面可以存放一个持久化 Queue,里面记录要向用户发送的信息。防止 rebalancing 时,消息丢失。

至于 sessionId 过期一说,可以通过 cache 解耦,将 Actor 寻址 SessionId 和用户认证 session 做特定映射。

timzaak commented 6 years ago

参考资料: spray-socketio akka-cluster-2-4 scalability-using-sharding-from-akka-cluster realtime-message-system

timzaak commented 6 years ago

目前已基本实现。剩下的需要根据具体业务需求再做实现。

这里列举下以后可能需要实现的(除非真用到了,否则不予以实现):