• 采坑websocket总结(二)


    集群环境遇到的坑

    测试通过一切准备就绪,放到QA的集群环境上面就发现,很多报错的请求。大概长这样子:

    前端 

     后端

     “Unauthorized client with sessionId”两次xhr请求发送到了两个服务器导致其中一台在尝试用过sessionId获取client信息时获取不到,从而主动断开了连接。

    原因

     什么原因呢?这就要从socket.io的原理说起。

    刚开始并没有websocket,只有http,我们要实现数据的实时展示该怎么办呢?那就不断的发http请求,模拟一个“实时”的数据传输,就是polling(轮询)模式

    是可以勉强达到目的,但是,很显然http是无状态的,而且每次轮询的时间间隔的长短决定了数据的“实时”度,毕竟啥时候服务器有数据产生,客户端是不知道的,为了标记同一类交互,还加了个sessionId,直到有了websocket也一样用了sessionId。

    后来有了websocket模式代替了模拟长连接,做到了真正的实时推送数据。客户端发送连接请求,服务器恢复连接成功,握手成功。直到没有数据推送到超时。

    nginx默认的负载均衡策略是轮询,所以有可能同一个sessionId的请求会被转发到不同的机器上去,这个时候会收到错误的response也就不奇怪了。当天如果运气好,请求都转到同一台机器,当请求升级为websocket后连接就成功了。

    当然我们不可能碰运气。

    解决策略

    1.Nginx转发时策略改为ip_hash

    1. server {
    2. listen 80;
    3. listen 443 ssl;
    4. server_name example.domain;
    5. root "/project/path";
    6. index index.html index.htm index.php; // 配置负载的后端
    7. upstream socket_nodes {
    8. ip_hash;
    9. server server1.app:5000 weight=5;
    10. server server2.app:5000;
    11. server server3.app:5000;
    12. server server4.app:5000;
    13. }
    14. location /socket.io/ {
    15. proxy_pass http://socket_nodes;
    16. proxy_set_header Upgrade $http_upgrade;
    17. proxy_set_header Connection "upgrade";
    18. proxy_http_version 1.1;
    19. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    20. proxy_set_header Host $host;
    21. }
    22. // 其他配置项
    23. // ...
    24. }

    2.只用websocket模式

    客户端和服务端都指定使用websocket模式一次性握手成功,不存在轮询,问题不就解决了

    客户端:

     socket = io.connect('192.168.x.x:10086/remoteWeb?token=stj2htu5qznutlngk48n9j98kz8r2m6d&lang=en',{path:'/localPath/socket.io',transports:['websocket']});

     服务端:

    在创建配置的时候加上

    config.setTransports(Transport.WEBSOCKET);

     

     总结

    我们在开发过程中要时刻注意产品化,在开发环境上单机开发可能没问题,但一上集群环境就各种问题。很尴尬,当然,这也是因为开发环境和生产环境不对等导致的。

    在有websocket之前,实时数据的请求是http请求使用polling模式模拟的,握手的过程可能要好几个polling请求升级到websocket模式

    • Nginx转发策略使用ip_hash,可以解决问题,但在系统扩容时会报错
    • 前端后端指定transports=websocket,不需要轮询,但缺点是有些老版本的浏览器不支持。
  • 相关阅读:
    使用autoIt 上传文件
    京准,NTP网络时间服务器在大型工厂应用方案
    SwiftUI 导航设置
    asp.net阅查卷管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio
    elasticsearch 官方优化建议
    acwing算法基础之基础算法--差分算法
    2020华数杯全国大学生数学建模竞赛C题-基于大数据对脱贫帮扶绩效的评价(一)(附带赛题解析&获奖论文及MATLAB代码)
    Spring之IOC 为什么能解耦
    你真的面向对象了吗?
    万应案例精选|抓紧抓实抓细,万应为安全生产全域监管护航
  • 原文地址:https://blog.csdn.net/merryxuan/article/details/126307376