搬服务端的体会--接着来。

搬服务端的体会--接着来。
上一篇 说了问题。现在说说重构后的构架。
基于freebsd6.3 boost-1.35.0(多处升级,最重要是包含了asio,升级了thread) STLport-5.1.5 消息队列(msgget,msgsnd,msgrcv)

构架方便借鉴了部分 云风的思路。
loginserver,gate,gamedb,postoffice,mapserver
accountdb去掉了,整合进loginserver里,loginserver直接连oracle,取列表信息后去连gate,gate连gamedb负责发人物列表
搬服务端的体会--接着来。_第1张图片
家里机器只有画图。。。忍着看吧。。。
下面开始都是一个服为一个单位。
一个服的gate是可以随时开关的,gate起来的时候会给loginserver和postoffice注册
 1  struct  GateInfo
 2  {
 3       char  name[ 25 ];
 4       char  ip[ 16 ];
 5       short  port;
 6       uint  online;
 7  };
 8 
 9  typedef vector < GateInfo *>  VecGateInfo;
10  VecGateInfo _gateinfo;
11 
12  //  当有用户连上或者断开gate时
13  sort(_gateinfo.begin(), _gateinfo.end(), GateSort)
14 
15  //  这样client取gate信息的时候只需要发给每个gate_group的第一个就行。

gamedb是所有userinfo的集结地,有缓存,只在第一次请求的时候把userinfo读进缓存,其余时刻都是写,一个慢线程,5分钟轮询写一遍,某个user更新发给gamedb,由gamedb负责通知其他拷贝同步更新。

mapserver实际上是一堆服务端的组合总称,这块来自云风的构架,分为chatserver(聊天服务端),mapserver(地图服务端,还可以区分为只带功能性npc地图,或者称为非pk地图,和其他地图),guildserver,dropserver。。。每个server都和postoffice连接,并且按功能和gamedb和其他服务端连接,按功能划分具体的服务端可以很好的把逻辑分散,不会导致某个模块的bug整个服务端的崩溃,在程序员整体调试水平不高的情况下,大大降低出错后分析的难度。

相比较以前来说就是gamedb后移,数据重心放在gamedb上,只读一次的做法要严格保证gamedb的效率和稳定,否则会死的很抽象。

一些细节mark下来,boost+asio在freebsd上居然不用kqueue用的是select。。。Orz,这是我在一次单步跟一个内存错误发现的
 1  //
 2  //  kqueue_reactor_fwd.hpp
 3  //  ~~~~~~~~~~~~~~~~~~~~~~
 4  //
 5  //  Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 6  //  Copyright (c) 2005 Stefan Arentz (stefan at soze dot com)
 7  //
 8  //  Distributed under the Boost Software License, Version 1.0. (See accompanying
 9  //  file LICENSE_1_0.txt or copy at  http://www.boost.org/LICENSE_1_0.txt )
10  //
11 
12  #ifndef BOOST_ASIO_DETAIL_KQUEUE_REACTOR_FWD_HPP
13  #define  BOOST_ASIO_DETAIL_KQUEUE_REACTOR_FWD_HPP
14 
15  #if  defined(_MSC_VER) && (_MSC_VER >= 1200)
16  # pragma once
17  #endif   //  defined(_MSC_VER) && (_MSC_VER >= 1200)
18 
19  #include  < boost / asio / detail / push_options.hpp >
20 
21  #if  !defined(BOOST_ASIO_DISABLE_KQUEUE)
22  #if  defined(__MACH__) && defined(__APPLE__)
23 
24  //  Define this to indicate that epoll is supported on the target platform.
25  #define  BOOST_ASIO_HAS_KQUEUE 1
26 
27  namespace  boost {
28  namespace  asio {
29  namespace  detail {
30 
31  template  < bool  Own_Thread >
32  class  kqueue_reactor;
33 
34  //  namespace detail
35  //  namespace asio
36  //  namespace boost
37 
38  #endif   //  defined(__MACH__) && defined(__APPLE__)
39  #endif   //  !defined(BOOST_ASIO_DISABLE_KQUEUE)
40 
41  #include  < boost / asio / detail / pop_options.hpp >
42 
43  #endif   //  BOOST_ASIO_DETAIL_KQUEUE_REACTOR_FWD_HPP
反正我只是不负责任的把22和38行屏蔽掉而已。

消息队列只传递指针,意思就是某个消息由接收方alloc,然后msgsnd这块内存的指针,msgrcv收到这个指针,处理完了free掉,而不是整个消息放进去。
1  struct  mymsg {
2       long   int     mtype;        /*  message type  */
3       char         mtext[ 4 ];     /*  message text  */
4  }
5 
说实话当初在msgsnd msgrcv上调试了很久
1  char *  packet; //  假设这个packet包括了传进来的包
2  mymsg *  msg  =  (mymsg * )mem_alloc( sizeof (mymsg));
3  memcpy(msg -> mtext,  & packet,  sizeof ( char * ));
4  msgsnd(msgid, msg,  sizeof ( char * ), 0 )
然后死活提示参数不正确。。。

逐字逐句读了man msgsnd数十遍之后发现。。。问题在msg->mtype不能等于0

ok,公司物理断网,usb口物理破坏。。。囧。。。当然,我要起带头作用,忍。。。

你可能感兴趣的:(搬服务端的体会--接着来。)