posts - 18,  comments - 21,  trackbacks - 0

终于从欢跃数码出来了。离开了成都。

这边很迅速的办好了各种手续,房子也租上了,白菜也搬过来了。东西还没有寄到,主要是车,可能老马都还没给寄。

有点流水账的感觉了。。。其实这段时间事情太多了。也算了经历了人生一大转折,正式转型到管理层了。有很多想法。慢慢来。

在装新的工作机。卡位暂时安排在程序这边。

装补丁要重启机器了。下次慢慢写。

posted @ 2009-10-12 13:00 大日如来 阅读(267) | 评论 (0)编辑 收藏

比如我开了2个终端,ttyp1空着,在ttyp2上gdb loginserver跑起来之后,who看有ttyp1和ttyp2,ttyp1上有bash,sshd,ttyp2上有bash,sshd,gdb,loginserver。

我关了ttyp2,再看who只有ttyp1了,ttyp2上的bash和sshd没了,但是gdb和loginserver还在,假如我kill掉loginserver,gdb也会跟着关掉,我现在想要gdb和loginserver重新回到ttyp1的控制里,感觉上就是从ttyp1的STDIN里读,往ttyp2的STDOUT里写,怎么做?

gettty貌似有这个功能,但是他不算是一个utility tools,watch可以,带-W参数还可以写,但是需要root权限,而且还是和接管这种感觉差了一点,因为我对服务器管理实在很差,哪位看到了知道怎么做可以留言给我,不甚感激。

posted @ 2008-05-12 01:26 大日如来 阅读(1394) | 评论 (1)编辑 收藏

又是一个月没写BLOG了,这一个月回家基本都不怎么碰电脑,更换平台也一段时间了,FreeBSD留给我的印象最大的是稳定,其次是反应很干脆,比如程序有什么BUG,直接SIGSEGV,比如:

int a = 5;

printf("%s", a);

这个在WIN32平台上只可能是未知结果,FreeBSD就报了错误。

还有就是FreeBSD和WIN32的内存管理完全是2个极端,WIN32在物理内存闲置的时候都占用了一半的虚拟内存,而FreeBSD仅仅是在物理内存被吃完,留下512K开始使用虚拟内存。

个人感觉,这样的区别是来自一个做桌面,一个做服务,做桌面的总有一些慢轮询需要处理,比如图标的cache啊,各种状态的保存啊,很占内存的东西,但是又不是实时的使用,留在物理内存里纯属浪费,而FreeBSD一开始设计的时候根本没有图形界面,纯纯一个terminal,需要的东西内核都帮你做了,你可以随意开关你认为必要不必要的东西,所以FreeBSD做服务端非常合适的。

 

终于还是把GC加到了服务端里面,mapserver内存从960M涨到了1560,效率上没怎么测试,稳定性感觉略微有点下降,好处可能要在实际应用中才能体会了。

posted @ 2008-05-12 01:23 大日如来 阅读(289) | 评论 (0)编辑 收藏

showimg(19) 

showimg(18)

showimg(17)

showimg(16)

showimg(15) 


快到都江堰叻

showimg(14)

showimg(13)

从都江堰包车到青城后山

showimg(1)

showimg

showimg(2)

早饭+男女配角

showimg(3)

农家乐后得小溪

 showimg(4)

早上准备爬山叻

showimg(5)

showimg(6)

showimg(7)

男女配角全面登场

showimg(8)

showimg(9)

showimg(10)

开始上山叻

showimg(11)

体力很充沛,还可以拍风景

showimg(12)

showimg(44)

某猛男中招,拉肚子叻

showimg(45)

刚开始走就吃!

showimg(46)

嘎嘎

showimg(47)

个性男

showimg(48)

上主题,哇哈哈哈哈

showimg(49)

实际上大部分路都在推和抗

showimg(50)

还有体力拍风景

showimg(51)

showimg(52)

showimg(53)

showimg(54)

背包跑到某男身上去叻。。汗一个。

showimg(55)

某男开始执掌相机

showimg(61)

真得很耗体力。。。

showimg(60)

showimg(59)

showimg(58)

showimg(57)

到叻山脚至半山得缆车

showimg(56)

又一村,我得车车止步于此。。。实在可惜。

showimg(25)

showimg(26)

showimg(27)

我得体力透支,艰难得在往上爬

showimg(28)

showimg(29)

showimg(30)

还好没抗车上来,万佛洞得栈道实在BT

showimg(31)

showimg(32)

天王殿门口,目标在望

showimg(33)

多谢2位帅哥一路陪我

showimg(34)

showimg(35)

showimg(36)

showimg(37)

showimg(38)

showimg(39)

showimg(40)

下又一村做得缆车,45,贵就一个字。。。

showimg(41)

showimg(42)

showimg(43)

showimg(20)

又一村取上车,因为还要骑回成都,本来打算继续做缆车,结果被告知要排至少2个小时队

showimg(21)

showimg(22)

showimg(23)

一咬牙一跺脚,推下山
相机被某男拿走,没得照片叻。

回到后山,居然轻松爬上回去得半山,然后放坡57到前山。

都江堰一顿30晚饭。

吃到天黑,摸黑30码拉回成都。

到家10:30不到。

最后总结。。抗车上山是个很拉风很自虐得行为。

准备上山得路上旁边卖黄瓜得都在说 小伙子,车子上不去得。

半路上不断有人嘀咕,自行车怎么上得山

上了山只想爽快得吼出来。

其实我也不太懂怎么会抗车上山,一开始只是退了农家乐得房子,寄存下来不放心,爬叻一截就只剩一个想法,一定要上去。

posted @ 2008-05-12 00:38 大日如来 阅读(269) | 评论 (0)编辑 收藏
上一篇 说了问题。现在说说重构后的构架。
基于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负责发人物列表

家里机器只有画图。。。忍着看吧。。。
下面开始都是一个服为一个单位。
一个服的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口物理破坏。。。囧。。。当然,我要起带头作用,忍。。。
posted @ 2008-04-09 22:42 大日如来 阅读(2329) | 评论 (2)编辑 收藏
以前的服务端是win32平台,STLport-5.1.4,boost-1.34.1,asio-0.3.8,apr的内存管理,消息池用的是MSMQ。
构架是loginserver,accountdb,gate,gamedb,gameserver,数据流向是:帐号密码->loginserver->accountdb->loginserver->client->选区->gate->gamedb->gate->client->选人->gate->gameserver

先说说现在的问题,win32平台就不说了^_^,也不谈stlport boost的效率问题,msmq也中规中矩,主要是apr的问题,使用的是这样的形式来做的内存管理
 1 struct cUser
 2 {
 3     apr_pool_t* pool;
 4     
 5     char name[25];
 6     ushort level;
 7     
 8 };
 9 
10 // 申请
11 apr_pool_t* pool = 0;
12 apr_pool_create(_mainpool, &pool);
13 cUser* user = (cUser*)apr_pcalloc(pool, sizeof(cUser));
14 user->pool = pool;
15 strcpy_s(user->name, "test");
16 user->level = 0;
17 
18 // 释放
19 if (user)
20 {
21     if (user->pool)
22         apr_pool_destory(user->pool);
23 }

服务端运行过程中很偶尔会出现user->pool为空,因为释放是程序结束时统一释放,所以没有理由怀疑释放错误,只能是内存越界,比如

1 apr_pool_t* pool = 0;
 
2 apr_pool_create(mainpool, &pool);
 
3 
 
4 cUser* user = (cUser*)apr_pcalloc(pool, sizeof(cUser) * 20);
 
5 
 
6 for (int i = 0; i < 20; i++)
 
7     user[i].pool = pool;
 
8 
 
9 // 这只是个示例,当然不会有人这么做
10 // 假设cUser最后一个变量是 char temp[100];
11 struct cUser
12 {
13     apr_pool_t* pool;
14 
15     char name[25];
16     ushort level;
17     char temp[100];
18 };
19 memcpy(user[0].temp, "test"104);
20 // 这个时候user[1]的pool就是空的了。

因为构架是我做的,具体逻辑不是我写的,在几十万行代码里一点一点跟哪里出错实在太渺茫,而且有点怀疑apr内部是否有bug,因为看错误的内存,明显整个user都是被apr_pool_destroy掉的。so。。这次不用apr了,那么大个库使用一个apr_pool是有点杀鸡牛刀的感觉。

这次简简单单定义
void* mem_alloc(size_t size);
void* mem_realloc(void* p, size_t size);
void mem_free(void* p);

// 实现
void* mem_alloc(size_t size)
{
    
void* p = 0;
    p 
= malloc(size);

#ifdef _DEBUG
   
if (p)
        memset(p, 
0, size);
#endif
    
return p;
}

void* mem_realloc(void* p, size_t size)
{
    
void* p = 0;
    p 
= realloc(p, size);

    
return p;
}

void mem_free(void* p)
{
    
if (p)
    {
        free(p);
        p 
= 0;
    }
}


当然后面打算带上gc,暂时直接申请内存方便valgrind挑错。


构架的问题就大了,一开始的设计是单loginserver多gate,单gate对单gameserver,后来发现一个gameserver带30几张地图,跑5000+npc简直就是自残,于是改,改单gate带多gameserver,问题来了,我们的构架是gamedb只和gate联系,一旦跨地图组队,user信息就要从一个gameserver带到gate再发给另一个gameserver,以前只考虑了由gate保存user信息,gameserver只是一份copy,更新数据方便,但是现在gate的负担超级重。

还有数据库问题,用的oracle,oci直接操作,accountdb没问题,gamedb是来了请求就去数据库拿或者写,没有做user的缓存,而且是整个user结构体带来带去,通信量特别大。结果是经常报告statement操作的游标过多,提高oracle的64个游标数量只是暂时解决方案。经常选了服就卡住,拿不到人物信息。

最主要就是msmq轮询取消息process的时候没有用阻塞模式(或者没有阻塞模式?)
1 if (0 == MSMQGetMessage())
2 {
3     Sleep(1);
4 }
5 else
6 {
7     Process_Packet();
8 }

问题出在这个sleep(1)上了,不sleep,4个msmq线程,npc的process被抢的什么都干不成,sleep的话cpu就死活利用不上去。懒得找msmq的阻塞模式了。

还有就是设计上的问题了,比如
1 struct User_Save_Info
2 {
3     char name[25];// 没问题,12个中文字的名字。
4     int gender;// 性别,大哥,你有42亿种性别么?
5     int facestyle;// 脸型,同上
6     int hairstyle;// 发型,同上
7     // 后面类似的不说了。
8 };

我就说策划大哥们,我为了省包头的2字节绞尽脑汁,你们可好。。。无语了。。。

Item_Info_Save是存装备的,我们的装备有随机属性,但是他们居然把装备的通用属性都由服务器来发,最郁闷的是设计npc死亡掉落物品数量达到50件。。。就是一个npc死亡,我需要发8(小队人数)*50(装备个数)*sizeof(Item_Info_Save)(这个sizeof至少100字节)。。。

ok问题暂时说到这里,下一贴说重构后的改动。
posted @ 2008-04-09 00:01 大日如来 阅读(2435) | 评论 (10)编辑 收藏
系 统 配 件 型 号 价 格 备 注
车身 车架 BIGCAT COMPLITE ¥450  
前叉 SUNTOUR XCR ¥640 油压线控锁
立管 UNO四钉 ¥40  
副把    
把横 X MISSION直把 ¥20  
把套 PRO TEN ¥25  
碗组    
坐管 ZOOM全铝 27.2 ¥30 无标
坐垫 WTB SPEED V COMP ¥230  
坐夹 铝合金快拆 ¥10  
车首垫环 SCOTT铝合金    
传动 牙盘 SHIMANO M440 9S ¥230  
中轴 清豪CH52轴承 ¥30  
脚踏 FPD NWL90 ¥45  
飞轮 SRAM PG950 ¥130  
链条 SHIMANO HG73 ¥60  
轮组 花鼓 QUANDO 昆腾滚珠碟刹 ¥150  
车圈 ALEX DP20碟刹专用 ¥150  
钢丝 电镀黑不锈钢 ¥35  
胎垫 XXF尼龙高压 ¥20  
内胎 KENDA建大 ¥20  
外胎 建大26*1.95 ¥60  
变速 指拨 SHIMANO DEORE M510 ¥230  
前拨 SHIMANO DEORE M510 ¥130  
后拨 SHIMANO XT M760 ¥320  
制动 刹把 AVID FR5 ¥85  
夹器 HAYES MX1 ¥350  
碟片      
其他 马表 SIGMA BC906          ¥100  
前灯    
尾灯 MC18            ¥20  
链贴 SHIMANO XTR ¥5  
水壶    
水壶架 闪电铝合金 ¥10  
货架    
全车线 JAGWIRE套装 ¥20  
总价     ¥3,645  
posted @ 2008-03-18 17:33 大日如来 阅读(534) | 评论 (1)编辑 收藏
一开始是这样,某个程序在debug模式下写的一段附魔效果的代码,测试正常后提交。
我这里release编译,F5测试了没问题。提交测试人员后被告知没有附魔效果。我继续F5测试没任何问题,和测试人员争执后发现。。。
如果用挂着调试器没有任何问题,直接双击exe就是没有效果。

最后发现是一个变量没有在类构造的时候初始化。
是一个bool类型的变量,问题是,为什么挂这调试器这个变量就是true,直接双击exe这个变量就是false???
posted @ 2008-03-18 17:22 大日如来 阅读(2126) | 评论 (6)编辑 收藏
仅列出标题
共2页: 1 2 

<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

常用链接

留言簿(3)

随笔分类

随笔档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜