• WebSocket :Nginx+WebSocket内部路由策略推送服务器的实现(附可生产环境应用代码)


    1.项目背景

    前几天写了一篇WebSocket推送的博客:WebSocket :用WebSocket实现推送你必须考虑的几个问题 支持的连接数大概几千个,具体数量依赖于tomcat能并发的线程数,但很多时候生产环境应用的话几千个肯定是不行的,所以本问介绍Nginx+WebSocket的实现思路及代码.

    2.实现思路

    依照设计模式中的 迪米特法则 外部调用模块来讲要尽量少的参与推送模块的逻辑,以达到解耦的目的,所以我们虽然通过Nginx+WebSocket做了集群策略,但是不应该让外部感知.对于外部调用模块来讲你是否应用集群与我调用你无关.

    大概实现思路是这样的,推送服务要把不是本机的请求内部路由到相应兄弟服务器.很多同学有疑问了为什么要路由呢,Nginx到任意一个节点处理不是就可以了. 大家注意哈,http实现了无状态请求,但是对于ws来讲tcp长连接显然是一个有状态请求,举个例子:server A连接client a,你想通过server B给client a发消息是做不到的,因为tcp连接在server A上.

    设计图: 

    连接过程: 所有client连接地址均为Nginx地址,但是实际tcp连接是建立在具体服务器上的.连接完成后redis中要存储对应用户的serverId和SessionId(WsSession 是ws用来标识具体连接的).

    发送消息过程:外部调用模块将消息发送到Nginx,假设发送消息的请求发送到了Server B上,那么Server B需要查出具体用户当前所连接的服务器,将请求路由转发到兄弟服务器上去.

    3.源码地址

    下载地址 
    http://download.csdn.net/download/shangmingtao/9920532

    4.可优化的点

    1.路由转发方式: 现在实现是用http转发的,效率很低,可以采用redis PUB/SUB方式 或者 rabbitMQ等. 
    2.路由转发内容: 我先再路由转发的是Client的userId+platform ,为的是能复用外部调用模块访问的接口.其实这里转发sessionId就可以了. 
    3.redis存储用户信息当前是序列化进去的.最好用hash这种数据类型.

    5.Nginx配置及说明

    user  nobody;
    worker_processes 1;
    
    events {
        worker_connections  8192; #这个要大一些
    }
    
    
    http {
    
        upstream ws{
            server 127.0.0.1:18080;
            server 127.0.0.1:28080;
        }
    
            server {
    
                 listen 81;
                 server_name localhost;
    
     #           动静分离处理
     #           location ~ .*.(gif|jpg|jpeg|png|bmp|swf|js|css)$ {
     #                   root html;
     #          }
    
    
                 location ~/WSPush {
                    proxy_pass http://ws;
                    proxy_http_version 1.1;
                    proxy_set_header Upgrade $http_upgrade;
                    proxy_set_header Connection "upgrade";
                    proxy_set_header Host $host:$server_port; #这个用来透传用户http请求头的,因为我代码里调用了request.getServerName()方法,如果不加个配置,取出来是http://ws
                    proxy_read_timeout 30m;#这里一定不要忘了改,默认1分钟后nginx会断开ws
                }
            }
    }

    转自:http://m.blog.csdn.net/shangmingtao/article/details/76639821
  • 相关阅读:
    cassandra复制到一个新机器编译失败的问题
    cassandra在服务端像leveldb一样进行插入初试成功
    git push不成功 insufficient permission for adding an object to repository database
    fuse进级
    fuse入门
    cassandra的写过程
    cassandra-执行请求入口函数
    cassandra-replication_factor 和 consistency level
    根据金额大小升序排序
    PL/SQL Developer连接本地Oracle 11g 64位数据库(转)
  • 原文地址:https://www.cnblogs.com/duanxz/p/5149403.html
Copyright © 2020-2023  润新知