Nginx-websocket反向代理问题处理过程

一、环境介绍
Nginx版本1.14,服务端为两台windows server2016服务器,appserver1:192.168.1.27,appserver2:192.168.1.28。

​ web服务端口80,API服务端口8080,WebSocket服务端口9090。

​ 两台Nginx服务器,NginxA:192.168.1.31,NginxB:192.168.1.32,虚拟IP地址为:192.168.1.26。

​ 客户端通过http://192.168.1.26访问服务。
二、反向代理设置

​ 以上配置分别配置在两个.conf文件下,web和webapi配置在apknginx.conf中,websocket配置在apk-wsnginx.conf中,访问正常,无报错。

​ 现需要将websocket监听端口改成80,所有的服务均通过80端口访问。
三、问题处理过程步骤:

  1. 按照官网官网信息,1.13版本之后支持websocket代理,现有1.14.0版本已经支持。

  2. 新建apknginx-new.conf,合并配置,为了满足websocket协议转换要求,按照官网配置,在nginx.conf下新增配置如下:

    map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
    }
    

    在apknginx-new中新增配置

    #websocket配置
        location /apk-ws/ {
            proxy_pass http://websocket/;
         	proxy_pass_request_headers on;
    		proxy_set_header Host $http_host
            proxy_http_version 1.1;
         	proxy_set_header Host $upstream_addr;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_redirect off;
            proxy_set_header X-Forwarded-Host $host;
            proxy_set_header X-Forwarded-Server $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header  X-Real-IP  $remote_addr;
      		proxy_read_timeout 120s;
        	proxy_send_timeout 120s;
        	proxy_connect_timeout 120s;
            client_max_body_size 10240m;
            client_body_buffer_size 25600k;
            proxy_connect_timeout 5;
            proxy_buffer_size 4k;
            proxy_buffers 4 32k;
            proxy_busy_buffers_size 64k;
            proxy_temp_file_write_size 128k;
                }
    
  3. 访问测试发现返回400错误;

  4. 判断是proxy_set_header发送的请求包头有问题,添加proxy_set_header Hsot $http_host,重启nginx后访问,发现还是返回400错误。删除添加内容。

  5. 将proxy_pass http://websocket/改成proxy_pass http://192.168.1.27:9090/,访问返回101,可正常访问。

  6. 初步判断为$proxy_host Host配置问题导致发送给前端的包头问题导致。

  7. 在nginx.conf配置中的log-format main新增"$proxy_host" "$http_host" "$host" "$server_port" "$proxy_port"字段。

  8. 重复步骤1和步骤4以及最初配置,分别查看输出结果,如下:

  9. 由由输出日志可得知在监听9090端口负载均衡模式下,前端获取的包头请求信息为‘’192.168.20.9090‘’,在监听80端口无负载均衡模式下,前端获取的包头请求信息为‘’192.168.246.100:9090‘’,在监听80端口负载均衡模式下,前端获取到的包头请求信息为“websocket”,但是,前端无法获取websocket信息,这个信息是Nginx本地的,故判断是因为在第三种模式下访问发送给前端的请求信息不准确才导致访问返回400错误。

  10. 在查阅资料后,发现Nginx支持在location下自定义变量,在location下设置变量“set $in_port 9090”,proxy_set_header Host $proxy_host:$in_port,访问返回101,访问成功。
    四、总结
    在负载均衡模式下,如果Nginx监听端口如果和前端端口不一致,反向代理location下需自定义端口变量重定向header信息。
    五、完整配置:

    应该还有其他的解决方案,本人愚钝,各位大佬如有其它解决方案请不吝赐教!!

    upstream websocket{
       server 192.168.246.2:9090 weight=1;
       server 192.168.246.100:9090 weight=1;
       }
    server {
       listen 80;
       server_name 192.168.246.20;
       #charset koi8-r;
       access_log  /root/logs/nginx/meswstest.log main;
       error_log  /root/logs/nginx/meswstest_error.log;
    
       location /apkws/ {
               set $in_port 9090;
               #root   html;
               #index  index.html index.htm;
               proxy_pass http://websocket/;
               proxy_set_header Host $host:$in_port;
               proxy_http_version 1.1;
               proxy_set_header Upgrade $http_upgrade;
               proxy_set_header Connection "upgrade";
               proxy_redirect off;
               proxy_set_header X-Forwarded-Host $host;
               proxy_set_header X-Forwarded-Server $host;
               proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
               proxy_set_header  X-Real-IP  $remote_addr;
               client_max_body_size 10240m;
               client_body_buffer_size 25600k;
               proxy_connect_timeout 5;
               proxy_buffer_size 4k;
               proxy_buffers 4 32k;
               proxy_busy_buffers_size 64k;
               proxy_temp_file_write_size 128k;
               }
    

    应该还有其他的解决方案,本人愚钝,各位大佬如有其它解决方案请不吝赐教!!

posted @ 2021-03-16 18:22  gody2019  阅读(590)  评论(0)    收藏  举报