【问题标题】:How to handle long polling in a spring boot app, load balanced by nginx?如何在 Spring Boot 应用程序中处理长轮询,由 Nginx 负载平衡?
【发布时间】:2017-08-24 12:11:12
【问题描述】:

让我先描述一下给定的情况。

我有一个有角度的 JavaScript 前端。我需要使用 websockets,因此我使用“sockjs”和“stomp-websocket”。

var socket,
    client;
socket = new SockJS('http://localhost:8080/stomp');
client = Stomp.over(socket);
client.connect({}, function () {
  client.subscribe('/dummy/message', function (message) {
    console.log('subscribed');
  }
});

我的后端是一个 Spring Boot 应用程序:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/dummy");
        registry.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
        stompEndpointRegistry
            .addEndpoint("/stomp")
            .setAllowedOrigins("*")
            .withSockJS()
            .setSessionCookieNeeded(false);
    }
}

此设置可以正常工作。即使我在 Firefox 中禁用了 websocket,它仍然可以正常工作(在这种情况下可以使用回退)。

当我启动更多后端实例并使用 nginx 时,我的问题就开始了。

我的 nginx 配置是:

upstream ws_be {
    server localhost:8081;
    server localhost:8082;
}

server {
    listen 8080;

    location / {
        proxy_pass http://ws_be;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

当我将此设置与多个后端一起使用时,websockets 仍然可以按预期工作但是如果我在浏览器中禁用 websockets,则后备将不再起作用。它只是保持连接并立即断开连接。

浏览器控制台出错:

Opening Web Socket...  stomp.min.js:8:1893
Web Socket Opened...  stomp.min.js:8:1893
>>> CONNECT
accept-version:1.1,1.0
heart-beat:10000,10000

<<< CONNECTED
version:1.1
heart-beat:0,0

connected to server undefined  stomp.min.js:8:1893
>>> SUBSCRIBE
id:sub-0
destination:/dummy/message

Whoops! Lost connection to undefined

在后端我收到一个 IO 损坏的管道错误:

org.apache.catalina.connector.ClientAbortException: java.io.IOException: Datenübergabe unterbrochen (broken pipe)

此时我不知道如何配置 nginx 或我的后端才能在给定的设置下正常工作。 现在我希望有人对这个问题有想法或提示。

【问题讨论】:

标签: javascript nginx spring-boot stomp spring-websocket


【解决方案1】:

我找到了一种可能适用于其他人的解决方案。它适用于粘性会话 (http://nginx.org/en/docs/http/ngx_http_upstream_module.html#ip_hash)

upstream ws_be {
    ip_hash;
    server localhost:8081;
    server localhost:8082;
}

很遗憾,我不允许使用粘性会话。因此我的搜索不断。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-13
    • 2016-10-16
    • 2016-09-28
    • 2020-09-11
    • 2019-08-10
    • 1970-01-01
    • 2011-01-13
    • 2011-02-28
    相关资源
    最近更新 更多