Websockets和负载平衡

Evg*_*rov 9 javascript java html5 spring websocket

Spring和Java EE对websockets提供了很好的支持.例如在Spring中,您可以:

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new MyHandler(), "/myHandler")
            .addInterceptors(new HttpSessionHandshakeInterceptor());
    }

}
Run Code Online (Sandbox Code Playgroud)

通过MyHandler类,您可以发送和侦听HTML5 websocket的消息.

var webSocket = 
      new WebSocket('ws://localhost:8080/myHandler');
 webSocket.onmessage = function(event) {
      onMessage(event)
    };
Run Code Online (Sandbox Code Playgroud)

问题是如果您在负载均衡器后面运行多个服务器.服务器A的客户端不会收到服务器B上的事件通知.

Spring中使用带有Stomp协议的消息代理解决了这个问题(http://assets.spring.io/wp/WebSocketBlogPost.html)

由于使用处理程序和"本机"html5 websockets对我来说更容易,然后是Stomp方式,我的问题是:

  1. 没有Stomp协议使用消息代理是否可行?
  2. 还有其他选择可以克服负载平衡问题吗?

Ang*_*ity 3

消息代理可以在没有 STOMP 的情况下使用,例如RabbitMQ 代理,它可以与其他几种协议一起使用;HTTP、AMQP、MQTT、AMQP。您可以将它们用作 JMS 实现。

由于应用程序有多个实例,因此最好的替代方案实际上是拥有一个中央消息传递代理来处理需要发布到所有应用程序客户端的消息。

任何替代方案都意味着手动执行类似的操作,后端的服务器需要以某种方式进行通信并相互通知这些事件。另一种方法是将某些事件写入数据库并让每个服务器轮询某些表,但这是我们尽量避免的设计类型。

另外,关于负载平衡和 Web 套接字,负载平衡器需要配置为允许转发 HTTP 升级标头,默认情况下通常是关闭的。例如,nginx 需要一些配置来允许转发这些标头,否则 Websockets 将无法工作。

在这种情况下,SockJS 将自动使用一些在 Web 套接字不可用时启动的后备选项。