終于從歡躍數碼出來了。離開了成都。
這邊很迅速的辦好了各種手續,房子也租上了,白菜也搬過來了。東西還沒有寄到,主要是車,可能老馬都還沒給寄。
有點流水賬的感覺了。。。其實這段時間事情太多了。也算了經歷了人生一大轉折,正式轉型到管理層了。有很多想法。慢慢來。
在裝新的工作機。卡位暫時安排在程序這邊。
裝補丁要重啟機器了。下次慢慢寫。
posted @
2009-10-12 13:00 大日如來 閱讀(277) |
評論 (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 大日如來 閱讀(1417) |
評論 (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 大日如來 閱讀(299) |
評論 (0) |
編輯 收藏
快到都江堰叻
從都江堰包車到青城后山
早飯+男女配角
農家樂后得小溪
早上準備爬山叻
男女配角全面登場
開始上山叻
體力很充沛,還可以拍風景
某猛男中招,拉肚子叻
剛開始走就吃!
嘎嘎
個性男
上主題,哇哈哈哈哈
實際上大部分路都在推和抗
還有體力拍風景
背包跑到某男身上去叻。。汗一個。
某男開始執掌相機
真得很耗體力。。。
到叻山腳至半山得纜車
又一村,我得車車止步于此。。。實在可惜。
我得體力透支,艱難得在往上爬
還好沒抗車上來,萬佛洞得棧道實在BT
天王殿門口,目標在望
多謝2位帥哥一路陪我
下又一村做得纜車,45,貴就一個字。。。
又一村取上車,因為還要騎回成都,本來打算繼續做纜車,結果被告知要排至少2個小時隊
一咬牙一跺腳,推下山
相機被某男拿走,沒得照片叻。
回到后山,居然輕松爬上回去得半山,然后放坡57到前山。
都江堰一頓30晚飯。
吃到天黑,摸黑30碼拉回成都。
到家10:30不到。
最后總結。。抗車上山是個很拉風很自虐得行為。
準備上山得路上旁邊賣黃瓜得都在說 小伙子,車子上不去得。
半路上不斷有人嘀咕,自行車怎么上得山
上了山只想爽快得吼出來。
其實我也不太懂怎么會抗車上山,一開始只是退了農家樂得房子,寄存下來不放心,爬叻一截就只剩一個想法,一定要上去。
posted @
2008-05-12 00:38 大日如來 閱讀(277) |
評論 (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 大日如來 閱讀(2340) |
評論 (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 大日如來 閱讀(2467) |
評論 (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 大日如來 閱讀(545) |
評論 (1) |
編輯 收藏
一開始是這樣,某個程序在debug模式下寫的一段附魔效果的代碼,測試正常后提交。
我這里release編譯,F5測試了沒問題。提交測試人員后被告知沒有附魔效果。我繼續F5測試沒任何問題,和測試人員爭執后發現。。。
如果用掛著調試器沒有任何問題,直接雙擊exe就是沒有效果。
最后發現是一個變量沒有在類構造的時候初始化。
是一個bool類型的變量,問題是,為什么掛這調試器這個變量就是true,直接雙擊exe這個變量就是false???
posted @
2008-03-18 17:22 大日如來 閱讀(2160) |
評論 (6) |
編輯 收藏