在 2013年10月28日上午11:19,YuLei Liao <dual...@
gmail.com>写道:
raw socket要自己处理粘包,拆包等问题。websockets库相当小,所以用起来很省事儿。
这个倒是,不过我不清楚在同样的平台上,用 websocket 和 tcp socket 效率上的差距有多大,我知道这样问很不专业,应为这两个差的很多而且各种具体实现也不一样。
这个架构就是运维麻烦。现在有一种SLG游戏的方案就是用Java做服务端,实现一个all in one的server。
嗯,我和一些做页游后端交流过,因为他们现在的模式都是分逻辑游戏服务器的,所以在线人数规模都是设计好的,所以他们尽量做成单进程的,运维、开服、关服都是很方便的。
当然,还是和具体项目有关,如果要做大型 MMORPG 这样肯定不行。
Nanomsg 貌似没有现成的 lua 库吧?
有是有,不过 nanomsg 本身还处在 alpha 阶段,虽然有 zmq 的光环,但是估计有坑。
廖大可以做第一个吃螃蟹的人。
YuLei Liao (dualface)
在 2013年10月28日,10:12,G_will <gwill...@
gmail.com> 写道:
赞!!!
提点建议。
1. 消息部分可以使用 nanomsg 作为支撑, nanomsg 里的 pub/sub 模式天生就可以用来消息广播,而且 nanomsg 还有很多其他消息模式,很多都可以直接在游戏场景中使用。
2. 运维复杂度的问题,这个架构里涉及到好几个 deamon 程序,这些进程的维护、启动顺序、失败管理都是坑点,这里估计要仔细想想,这也是 nanomsg 的优势。
3. 还有一点就是,其实我一直很纠结,我们有客户端,我们都有 websocket 了,为啥不直接 raw tcp socket 呢?很多游戏其实用 websocket 都重,起码要打包个 websocket 客户端库。现在情况是可以永 ngx-tcp-lua-module,但是和 openresty 兼容不够好,如果春哥能搞个 tcp_by_lua 或者 pre_http_check_by_lua 就好了。
在 2013年10月28日上午12:05,dualface <dual...@
gmail.com>写道:
我们是做手游的团队,最近一款游戏有不少实时性,正好看到 OpenResty 已经支持了 WebSockets,所以基于 OpenResty 设计了一个 game server 架构。
PS: 选择 OpenResty 的原因是我们前一款游戏也是用的 OpenResty,感觉很不错(虽然最后游戏没有挣到钱)。
整体架构图:
<Snip20131027_17.png>
几点说明:
2. redis 是主数据库,日志类数据则存入 mysql,图里没有画出来
----
整个架构的重点有三部分:请求/响应模型,使用 redis 做消息转发,使用 job server 执行延时任务
1. 请求/响应模型
客户端通过 websockets 发送消息给服务端。每个消息都是 JSON 格式。其中包含 action 和 msgid 两个必须的参数。
- action 用于指示要调用服务端哪一个消息处理函数。例如 action = "" 就表示要调用服务端 UsersAction 模块的 authAction 方法。
- msgid 用于跟踪消息的执行结果,每一个从客户端发往服务端的消息都会带有一个 msgid(累加值)。当服务端的消息处理函数执行后,通过 websockets 发送消息到客户端,其中会包含请求消息中的 msgid。这样客户端就可以知道从服务端发来的消息是属于先前哪一个请求的反馈。这样模拟了 HTTP 的请求/响应模型,简化了客户端的代码实现。
2. 使用 redis 做消息转发
因为现在没有办法从外部取得一个线程的 cosocket 对象,所以也就无法直接向任意客户端发送消息。为了解决这个问题,我利用 redis 的 pub/sub 特性,实现了一个简单的消息中转机制。
每一个客户端连接到 OpenResty 后,就会创建一个子线程(ngx.thread.spawn)。这个子线程会创建一个 redis 连接,并 subscribe channel.id(连接成功的客户端都有一个自己的频道)。当有任何消息进入频道,这个子线程就通过主线程的 cosocket 对象将消息发往客户端(这里就需要前面提到的 cosocket 补丁)。
3. 使用 job server 执行延时任务
选择 beanstalkd 是因为有现成的 lua-resty-beanstalkd 模块,用起来省事儿。而且 beanstalkd 也支持延时消息,非常适合我们游戏中的需求。比如升级一个建筑物需要 10 分钟,那么我添加一个延时 10 分钟的消息到 beanstalkd 里就行了。
当一个消息倒计时结束时,就会由 worker 负责处理消息。worker 取得消息后,进行处理。如果处理后需要将更新后的数据发送到客户端,就通过 redis publish 命令来进行了。
----
整体架构还在开发,目前 1/2 都已经实现,初步测试效果还不错。下一步就是整合 beanstalkd。
由于第一次这样运用 OpenResty,所以还请各位多多提意见,看看有没有什么问题。
谢谢大家 :)
--
--
--
--
--
--