• 采坑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,不需要轮询,但缺点是有些老版本的浏览器不支持。
  • 相关阅读:
    python 实现MAC泛洪与ARP欺骗
    Ubuntu20.04安装graph-tool
    HTTP中的GET方法与POST方法
    Apollo 应用与源码分析:Monitor监控-硬件监控-CPU、磁盘、内存资源监控逻辑源码分析
    js案例:选字游戏
    InputMethodManagerService启动-Android12
    3.7 学会这2招,让你的笔记分分钟上热门 【玩赚小红书】
    前端架构思考,Vue or React?领域设计、文件结构、数据管理、主题替换
    C++多线程学习10 promise和future多线程异步传值
    codeforces (C++ Simple Design)
  • 原文地址:https://blog.csdn.net/merryxuan/article/details/126307376