go语言服务器负载均衡 golang服务器用什么框架( 三 )


会话保持的作用是什么?
开启SLB会话保持功能后 , SLB会记录客户端的IP地址 , 在一定时间内,自动将同一个IP的连接转发到上次连接的网关 。
在网络不稳定的情况下,游戏容易心跳或者发包超时,开启会话保持 , 能解决大部分情况下的重连问题 。
但是在切换网络的时候 , 手机网络从Wifi切换成4G,自身IP会变,这时候连接必定和服务器断开 , 需要重新建立连接 。由于IP已经变化,SLB不能识别到是同一个客户端发出的请求,会将连接转发到其他网关节点 。所以使用TCP连接的情况下,SLB开启会话保持并不能解决所有的重连问题 。
另外某些时刻,手机频繁开启和断开WI-FI,有时候可能不会断开网络,这并不是因为4G切换WI-FI时网络没断开,从4G切换到Wi-Fi网络,因为IP变了 , 服务器不能识别到新的IP , 连接肯定是断开的 。这时候网络没断开,主要是因为现在智能手机会对4G和Wi-Fi网络做个权重判断 , 当Wi-Fi网络频繁打开关闭时,手机会判断Wi-Fi网络不稳定,所有流量都走4G 。所以网络没断开是因为一直使用4G连接,才没有断开 。想要验证,只需要切换Wi-Fi时,把4G网络关闭,这样流量就必定走Wi-Fi 。
上面说过 , 四层的TCP协议主要是基于IP来实现会话保持 。但是切换网络的时候客户端的IP会变 。所以要解决切换网络时的重连问题,只有两个方法:1. 当客户端成功连接网关节点后 , 记录下网关节点的IP,下次重连后不经过SLB,直接向网关节点发送连接请求 。2.使用 SLB的七层(HTTP)转发服务 。
当客户端经过SLB将连接转发到网关时,二次握手验证成功后向客户端发送自己节点的IP , 这样客户端下次连接的时候就能直接连接网关节点 。但是这样会暴露网关的IP地址,为安全留下隐患 。
如果不希望暴露网关的IP地址,就需要增加一层代理层,SLB将客户端请求转发到代理层,代理层再根据客户端带有的key,转发到正确的网关节点上 。增加一层代理层,不仅会增加请求的响应时间,还会增加整体框架的复杂度 。
阿里云的七层SLB会话保持服务,主要是基于cookie的会话保持 。客户端在往服务器发送HTTP请求后,服务器会返回客户端一个Response,SLB会在这时候 , 将经过的Response插入或者重写cookie 。客户端获取到这个cookie,下次请求时会带上cookie,SLB判断Request的Headers里面有cookie,就将连接转发到之前的网关节点 。
HTTP是短链接,我们游戏是长连接,所以用HTTP肯定不合适 。但是可以考虑基于HTTP的WebSocket 。
什么是WebSocket?
WSS(Web Socket Secure)是WebSocket的加密版本 。
SLB对WebSocket的支持
查看阿里云SLB文档对WS的支持,说明SLB是支持WS协议的,并且SLB对于WS无需配置,只需要选用HTTP监听时,就能够转发WS协议 。说明WS协议在SLB这边看来就是一个HTTP,这样WS走的也是七层的转发服务 。只要SLB能够正常识别WS握手协议里Request的cookie和正常识别服务器返回的Response并且往里面插入cookie,就可以利用会话保持解决重连问题 。
Go语言实现WS服务器有两种方法,一种是利用golang.org/x/net下的websocket包,另外一种方法就是自己解读Websocket协议来实现,由于WS协议一样是基于TCP协议之上,完全可以通过监听TCP端口来实现 。
客户端发送Request消息
服务器返回Response消息
其中服务器返回的Sec-WebSocket-Accept字段,主要是用于客户端需要验证服务器是否支持WS 。RFC6455文档中规定,在WebSocket通信协议中服务端为了证实已经接收了握手,它需要把两部分的数据合并成一个响应 。一部分信息来自客户端握手的Sec-WebSocket-Keyt头字段:Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== 。对于这个字段,服务端必须得到这个值(头字段中经过base64编码的值减去前后的空格)并与GUID"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"组合成一个字符串 , 这个字符串对于不懂WebSocket协议的网络终端来说是不能使用的 。这个组合经过SHA-1掩码,base64编码后在服务端的握手中返回 。如果这个Sec-WebSocket-Accept计算错误浏览器会提示:Sec-WebSocket-Accept dismatch

推荐阅读