一聚教程网:一个值得你收藏的教程网站

热门教程

分享Websocket进行负载均衡方案及应用

时间:2022-06-29 11:13:17 编辑:袖梨 来源:一聚教程网

对Websocket进行负载均衡

http {
    // ...省略

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

    upstream websocketCluster {
        ip_hash;
        server 127.0.0.1:6181;
        server 127.0.0.1:6182;
    }

    server {
        listen       80;
        proxy_pass   httpCluster;
        #域名可以有多个,用空格隔开
        server_name  localhost 127.0.0.1;

        location /chat {
        # proxy_pass 127.0.0.1:6181
        proxy_pass websocketCluster

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        }
    }

    // ...省略
}


WebSocket负载均衡方案

目标

根据指定的key对websocket连接进行负载均衡,达到一致性哈希的效果。

调度模式

Haproxy,负载均衡调度模式有如下几种:

    roundrobin,表示简单的轮询,这个不多说,这个是负载均衡基本都具备的;
    static-rr,表示根据权重;
    leastconn,表示最少连接者先处理;
    source,表示根据请求源IP;
    uri,表示根据请求的URI;
    url_param,表示根据请求的URl参数'balance url_param' requires an URL parameter name
    hdr(name),表示根据HTTP请求头来锁定每一次HTTP请求;
    rdp-cookie(name),表示根据据cookie(name)来锁定并哈希每一次TCP请求。

方案及实现
模式:url_param
前端:通过带参的uri,来向server端(Haproxy/Socketserver)发起请求,如:

    ws://localhost/ws?userid=111,来向server端发起请求。

Haproxy:通过acl来配置规则,如:

    acl is_websocket hdr(Upgrade) -i WebSocket
    acl is_websocket hdr_beg(Host) -i ws

反向代理负载均衡配置,如:

    backend socket_backend_url_param
    balance url_param userid
    option forwardfor
    timeout queue 5000
    timeout server 5000
    timeout connect 5000
    server server1 test:8081
    server server2 test:8082

整体配置

globalmaxconn     4096 # Total Max Connections. This is dependent on ulimitnbproc


为websocket应用实现负载均衡

前言:

websocket相信经常逛cnode社区的孩纸们都知道…具体API使用方式也再熟悉不过了…使用nodejs开发的websocket服务端也是品种繁多…github上总有你喜欢的…平时耍耍当然没问题…如果真要是承载一个生产环境服务的核心…总会有些问题需要你去解决.

不可避免的问题:

按照一个web请求占用线程数为参照…我们可以把nodejs称之为单线程语言…而java的servlet这种应该就是多线程语言了…我们可以想象在高并发情况下…单线程语言的运行风险还是蛮高的…毕竟如果一个请求出事那么整个线程(进程)就退出了…于是乎停止服务了…为了规避风险…我们常常会使用负载均衡技术…保证整个系统的对外正常服务…

解决方案:

负载均衡方案目前来讲…用apache的也不多了吧…普遍的解决方案是使用nginx配置多个upstream.实现负载均衡…例子如下:

http{

upstream http_sr {

    server 192.168.0.2:8080;

    server 192.168.0.3:8080;

}

server {

     listen 80 ;

     proxy_pass http_sr;

}

}


这样对于部署在192.168.0.2和3这两台机器上http服务…就通过这台nginx服务器实现了负载均衡…但是websocket的服务端nginx的http反向代理是不能支持的.从websocket的specs我们可以很明确的其实基于tcp协议的…http协议虽然也是基于tcp…它们都使用了tcp的握手方式…但是nginx的http_proxy_pass是不能支持websocket的…

于是我们可以寻根问主…让nginx支持tcp_proxy_pass…那websocket负载均衡的问题不就迎刃而解了…nginx有丰富的第三方扩展…一顿搜索在github上找到了yaoweibin老师的nginx_tcp_proxy_module

二话不说下载此模块…重新编译nginx(此过程略吧大家应该都懂) …修改nginx配置文件加入下面conf:

tcp {

      upstream websocket {

          server 192.168.0.2:8080;

          server 192.168.0.3:8080;

          check interval=3000 rise=2 fall=5 timeout=1000;

      }

      server {

           listen 80;

           proxy_pass websocket;

      }

}


这个module的作者在description写到:

 The motivation of writing these modules is Nginx’s high performance and

    robustness. At first, I developed this module just for general TCP

    proxy. And now, this module is frequently used in websocket reverse

    proxying.


目前基本就是用来做websocket反向代理的…测试后确实是支持的…非常感谢module的开发者另外值得注意的是你要在nginx里同时配置tcp和http…那么它们是不能listen同一端口的…

热门栏目