背景介绍
游戏经过一段时间的运营,发现了原来的设计缺陷太多,所以决定重新设计架构。使用到nginx作为核心并通过lua+redis设计实现自己的负载分配方案。先看看下面这张简单的架构图吧~
从图上看,结构是非常简单的。主要通过编写lua分配策略使游戏房间内的人数尽量坐满。
技术实现思路
要编写lua插件通常需求编译nginx使其支持,如果嫌麻烦可以直接上手openresty就可以了。我刚开始编译nginx插件模块也费了不少时间,现在使用openresty方便多了。
我们的游戏房间是9个人,产品需要优先坐满一个房间才分配下一个房间;玩家通过websocket连接到咱们的服务器上,为了使nginx记住我们的节点负载情况,我使用redis记录每一个节点的连接数量,并设计一套权重策略依据节点连接数量求9的余数进行排序。当然具体看代码更加容易理解~~准备工作
假设已经安装好了openresty,可以直接在/usr/local/openresty/nginx/conf下面找到nginx.conf文件,增加下面一行(注意如果已经安装了nginx的其他版本,需要将openresty安装的nginx进行端口重新配置)
... 30 #keepalive_timeout 0; 31 keepalive_timeout 65; 32 include /usr/local/openresty/nginx/conf.d/*.conf; 33 #gzip on;....
为了方便加载个人的配置,我在nginx下面自己建立了一个conf.d文件目录,存放自己的配置。下面查看nginx具体配置。
server { listen 9009; location / { set $websocket_addr ""; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header X-Real-Ip $remote_addr; proxy_set_header X-Scheme $scheme; rewrite_by_lua_file /usr/local/lua/dispatcher.lua; proxy_pass http://$websocket_addr; } }
注意这里刚开始,我使用的是set_by_lua_file
来返回一个websocket_add。那样容易理解但是不支持redis,与数据库的访问。所以这里使用了rewrite_by_lua_file方式。在开始出声明了websocket_add全局变量,主要是为了在lua插件里面进行修改。下面看lua插件简单版本为了方便管理,我建立了lua代码目录在/usr/local/lua。文件名取名为dispatcher.lua
local var = ngx.varhosts = { "127.0.0.1:8109", "127.0.0.1:8108",}host = hosts[math.random(#hosts)]ngx.var.websocket_addr = host
这个时候再打开一个websocket服务器,例如我跑了两个tornado的websocket服务器分别运行了8109/8108端口,(websocket服务器简单版在https://github.com/land-pack/tornado-websocket-example/blob/master/app/simple.py)
这时候你最好启动两个,分别监听这两个端口。下面就可以重新启动你的openresty版本的nginx了。 通过chrome的websocket客户端你可以访问到下面这个地址。可以看到,我们的请求得到了回复。那么这次我只是通过lua的随机数进行的负载分配的,这就是我们的第一步,下一篇我将会介绍如何通过redis来管理分配我们的客户端连接~~
总结
好久没写blog了,最近又学了那么多新玩意,想记录一下~~