• Feeds

  • 陈杰谈网游服务器的后端技术

    在12/20的Erlang开发者大会上,西山居的陈杰(bitcowboy)的演讲《网游服务端寻路》给我的印象非常深刻。他通过一个网游服务器寻路的案例,给大家讲述了在算法,架构,cache,并发编程及借鉴了Erlang的一些先进思路的各种经验及体会。

    • 算法,运营对寻路的要求比普通算法性能要高100倍。2D/3D中分别如何设计算法达到性能要求。
    • 稳定性
    1. 将独立的模块封装成单独的进程。
    2. 进程间通讯(IPC)使用TCP,为什么使用TCP而不是其他更高效的本地IPC方式?一方面因为大部分项目都有现成稳定的TCP模块,另外一方面更容易将一台服务器拆分到多个服务器,程序完全不用修改。
    3. 进程死掉怎么办?进程调用长时间不返回怎么办?
    4. 面对3的问题,旁边有另外一游戏架构设计师更是提到他们采取更激进的做法,将所有的进程做成单任务式的,完成任务就结束。分配任务线程为每个任务开新进程。有点象用Erlang中的process或Java中线程池的做法。
    • 一种多进程访问共享内存不需要加锁的设计模式,如图所示。

    调度进程

    (Figure: 来源陈杰PPT, 作者为陈杰)

    1. 调度进程给寻路进程分配任务,每次一个任务。
    2. 寻路进程更新cache为了避免并发访问,先只写入到 local cache
    3. 如果所有寻路进程空闲,调度进程会通知其中1个寻路进程将local cache同步到全局cache
    4. 如果一个寻路进程指定的时间没有返回,可简单kill之
    5. 此模式适合更多使用场合
    • 一种热升级模块的设计模式,简述:新进程使用新端口启用->通知调度启用新端口->调度程序将请求转向新端口->老模块完成手头工作后,被调度告知自动结束。

    总的说来,陈杰的演讲反应非常热烈,旁听参与的听众讨论也非常热烈,因为本人不是演讲者,很多细节没法在这里深入表达,PPT中也只是表达了现场的部分观点。

    另外这个演讲是以一个小组讨论的形式进行的,这样演讲者和听众的思路非常自由,比单独站台上讲相比可以进行更深入的交流。所以陈杰总是提醒大家,我们还是把这个演讲稿先讲完吧。

    对,我们也先把演讲稿看完把,Google Docs 在线预览版:网游服务端寻路

    disco#info, service discovery 发现服务 XEP-0030

    总结一下,XEP-0030 (前JEP-0030) disco#info 3个主要用途:

    1. 查询服务器
    <iq from=’tim@timpc/home’ to=’timpc’>
    <query xmlns=’http://jabber.org/disco#info’/>
    </iq>

    目标主机必须返回一个IQ结果或错误。
    返回结果的 <query/> 必须标明 ‘http://jabber.org/protocol/disco#info’ namespace,含有一到多个 <identity/> 一到多个 <feature/> elements.

    Note: Every entity MUST have at least one identity, and every entity MUST support at least the ‘http://jabber.org/protocol/disco#info’ feature; however, an entity is not required to return a result and MAY return an error, most likely <feature-not-implemented/> or <service-unavailable/>, although other error conditions may be appropriate.

    每个 <identity/> 里面必须包含 ‘category’ and ‘type’, 并可以加上一个友好的名称 ‘name’
    每个 <feature/> 必须包含 ‘var’ protocol namespace or other feature offered by the entity.category/type 最好是存在一个注册表里面

    2. 查询某个JID
    当一个 disco#info 发送到一个普通用户JID时候,JID的服务器必须直接返回结果,不过我看不出这个请求有多大的实际用途。JEP的例子说应答服务器在确认请求方是可以信任的前提下可以返回这个用户是否注册。

    向服务器查询 [email protected] 的 disco#info
    &lt;iq type='get'
    from='shakespeare.lit'
    to='[email protected]'
    id='info2'&gt;
    &lt;query xmlns='http://jabber.org/protocol/disco#info'/&gt;
    &lt;/iq&gt;

    服务器应答 registered account
    &lt;iq type='result'
    from='[email protected]'
    to='shakespeare.lit'
    id='info2'&gt;
    &lt;query xmlns='http://jabber.org/protocol/disco#info'&gt;
    &lt;identity category='account' type='registered'/&gt;
    &lt;/query&gt;
    &lt;/iq&gt;

    也可以应答当前用户连接的 resource 的信息
    &lt;iq type='get'
    from='[email protected]/balcony'
    to='[email protected]/orchard'
    id='info4'&gt;
    &lt;query xmlns='http://jabber.org/protocol/disco#info'/&gt;
    &lt;/iq&gt;

    <iq type=’result’
    from=’[email protected]/orchard’
    to=’[email protected]/balcony’
    id=’info4′>
    <query xmlns=’http://jabber.org/protocol/disco#info’>
    <identity
    category=’client’
    type=’pc’
    name=’Gabber’/>
    <feature var=’jabber:iq:time’/>
    <feature var=’jabber:iq:version’/>
    </query>
    </iq>

    3. 查询 conference room (muc)
    <iq type=’get’
    from=’[email protected]/balcony’
    to=’[email protected]
    id=’info3′>
    <query xmlns=’http://jabber.org/protocol/disco#info’/>
    </iq>

    <iq type=’result’
    from=’[email protected]
    to=’[email protected]/balcony’
    id=’info3′>
    <query xmlns=’http://jabber.org/protocol/disco#info’>
    <identity
    category=’conference’
    type=’text’
    name=’Romeo and Juliet, Act II, Scene II’/>
    <feature var=’http://jabber.org/protocol/disco#info’/>
    <feature var=’http://jabber.org/protocol/muc’/>
    <feature var=’http://jabber.org/protocol/feature-neg’/>
    <feature var=’muc-password’/>
    <feature var=’muc-hidden’/>
    <feature var=’muc-temporary’/>
    <feature var=’muc-open’/>
    <feature var=’muc-unmoderated’/>
    <feature var=’muc-nonanonymous’/>
    </query>
    </iq>

    JID欺骗 (JEP-0165) JID Spoofing

    JEP-0165 JID Spoofing,最新版本叫XEP-0165: Best Practices to Discourage JID Mimicking

    JID 欺骗其实不只是在Jabber的领域发生,在MSN, Email中同样也存在,如你是 Microsoft 的员工,有个
    的MSN账号添加你(注意是BI11),这就是一个账号欺骗,他希望你认为他是。

    因此在 jabber 的世界里面 (注意是PAYPA1)会冒充 来欺骗你。这个方法在一些术语里面也称为“typejacking”,因此这个JEP提供了几个 best practice 来防止 JID 欺骗。

    1. 使用 petname system
    2. 使用证书
    3. 添加好友需要一个双方都认识的中间人(相当于只有邀请only的圈子)

    其他还有些不是十分实用的方法

    Every human user of Jabber/XMPP technologies presumably has a preferred language (or, in some cases, a small set of preferred languages), which an XMPP application SHOULD gather either explicitly from the user or implicitly via the user’s operating system. Furthermore, every language has a range of characters normally used to represent that language in textual form. Therefore, an XMPP application SHOULD warn the user when presenting a JID that uses characters outside the normal range of the user’s preferred language(s).