任务背景
我们有n台ws服务,但是某些客户他们客户端都是用https,所以就不能用ws协议了,得换成wss。而每台ws服务升级成wss成本太高太麻烦,所以想使用nginx来做这些ws服务的反向代理服务器,并给访问域名部署https以支持wss
解决
解决的方法也是在nginx配置一个upstream,里面可以若干个节点信息,也可以是引入一个文件,这个文件包含的节点信息,这样可能更方便维护节点信息。 然后就是server进行请求转发到upstream。
现在本地开2个soket服务,php需要开启sokets扩展,代码在最下面的 ws.php。
cd D:/www/test
php ws.php #soket服务1 127.0.0.1:8001
php ws2.php #soket服务2 127.0.0.1:8002
访问2个聊天室,这些都是网上找的demo,方便测试用。 对应打开2个chat.html和chat2.html,分别websoket上面2个soket服务地址。
demo地址:浅谈php中使用websocket
本地配置一个虚拟域名www.wss.com,然后修改nginx配置,想要wss的话,就给域名配置证书就行了,其他不变。
upstream websocket {
#ip_hash;
server 127.0.0.1:8001;
server 127.0.0.1:8002;
}
server {
listen 80;
server_name www.wss.com;
location / {
#反向代理
proxy_pass http://websocket;
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; # 升级协议头
proxy_set_header Connection upgrade;
proxy_read_timeout 6000s; #超时时间 10分钟
}
}
重启nginx,新建一个test.html测试:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>websoket代理测试</h1>
<script>
var websocket = null;
//判断当前浏览器是否支持WebSocket
if ('WebSocket' in window) {
websocket = new WebSocket("ws://www.wss.com");
}
else {
alert('当前浏览器 Not support websocket')
}
//连接发生错误的回调方法
websocket.onerror = function () {
console.log("WebSocket连接发生错误");
};
//连接成功建立的回调方法
websocket.onopen = function () {
console.log("WebSocket连接成功");
}
//接收到消息的回调方法
websocket.onmessage = function (event) {
console.log(event.data);
}
//连接关闭的回调方法
websocket.onclose = function () {
console.log("WebSocket连接关闭");
}
</script>
</body>
</html>
接下来就可以测试效果了,分别在两个聊天室输入内容,看看test.html控制台输出的是哪个聊天室的内容吧。刷新后,再试试。
我这边是把ip_hash给注释了,就是轮训的策略,具体还是可以参考nginx负载均衡的策略配置。
问题:其实我开始不是用原生的websoket测试,而且部署了wokerman的soketio来测试,必须配置ip_hash,不然连接就会自动关闭等,这个我也纳闷啊。
补充
比如我们需要维护负载的配置,增删改节点,可以这么操作。
1. 将节点信息放入外部文件中,upstream websocket 中引入;
2. 部署一个php脚本,作为api接口,当节点方式变化时带上信息请求该接口。
3. 接口脚本根据请求参数,更新节点文件,并exec调用nginx重载配置的命令,nginx -s reload
4. websocket连接期间可以进行ping的操作,就发消息给服务器,避免连接超时
5. websocket做负载均衡的话,得处理好多个节点间的交互,比如数据到了W1节点,那么连接到其他节点的客户端必须也能收到消息。
继续
关于生产环境的部署测试等,还在摸索中,后续还会更新进行对websocket的压测内容。。