• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 14,  comments - 57,  trackbacks - 0
              寫這篇文章是對自己2011bug戰(zhàn)斗時光一個交代,隨著時間的推移,當(dāng)初印象深刻的痛苦和壓力慢慢消逝,到現(xiàn)在甚至是需要很長時間來弄清楚這中間的關(guān)系,趁著現(xiàn)在頭腦還算清楚,記錄下吧。

            場景管理

               為了說明Bug產(chǎn)生的原因,先描述下場景管理的實現(xiàn)方式吧。

              1、游戲場景是游戲地圖的一個實例(假設(shè)地圖是class),一個地圖可以創(chuàng)建多個場景,場景主要負(fù)責(zé)管理玩家的移動、廣播等處理。
              2、場景的廣播是采取經(jīng)典的九宮格方式來實現(xiàn)的,每一個格子的我們定義為Area對象,一個場景的格子組成其實是一個二維數(shù)組。
              3、玩家進入場景的時候,根據(jù)坐標(biāo)可以知道要進入哪個格子,每個格子內(nèi)會保留一個Head指針,標(biāo)記最新進入的玩家對象。玩家對象上有2個指針,標(biāo)記玩家所在格子的前一個和后一個對象。可以通過格子內(nèi)的Head指針便利Area內(nèi)的所有玩家對象。
              4、玩家移動切換格子的時候,先從原來的格子內(nèi)Leave,這會調(diào)用原來Area對象的Leave函數(shù)。再進入新的格子,調(diào)用Area的Enter函數(shù)。很明顯,Leave函數(shù)就是一個鏈表刪除操作,如果玩家是Head,則設(shè)置新的Head。
               Enter操作就是將新進入的玩家鏈接到原隊列里,新進入的玩家會被設(shè)置為Head。

            問題表現(xiàn)  

               根據(jù)上面的描述,如果一切按照正常程序,這個方案運轉(zhuǎn)是沒問題的。最初上線的時候,也沒有出現(xiàn)問題,但是在出了一個資料片之后,服務(wù)器基本上每隔半小時左右就會發(fā)現(xiàn)有死循環(huán)或者宕機問題。

            死循環(huán)的表現(xiàn)很明顯,就是在遍歷場景玩家的時候,出現(xiàn)死循環(huán)。宕機則更加復(fù)雜些,每次宕機位置不同,總的來說大概有3-4個地方,每個地方單看都不合常理。
            直接分析上面的表現(xiàn),都找不到真正的的原因,只好擴大搜索范圍了。
            比較倒霉的是那個資料片的主要系統(tǒng)都是我開發(fā)的,所以自然嫌疑最大,然后大家集中精力來分析我的代碼,由于每個人風(fēng)格都不同,所以大家看的不太明白的地方都會來問我,所以那個晚上基本就在解答設(shè)計疑問了。
            被輪了大半個晚上,知道凌晨2點,大家也沒分析出問題,只好先回去睡覺了。結(jié)果早上7點,測試給我打電話了,沒辦法只好跑過去了,一到公司,發(fā)現(xiàn)圍了一堆老大,老大們很嚴(yán)肅:這個問題很嚴(yán)重,必須盡快解決。
            沒辦法,只好繼續(xù)上陣了,戰(zhàn)斗到下午2點,突然靈光一閃,想到了原因,當(dāng)時感覺真的心力交瘁了,更加感慨的是其實這個問題真和我沒啥關(guān)系。。。


            原因

               真正導(dǎo)致這次事故的其實是一個小操作:玩家重登錄(手機玩家斷網(wǎng)的時候,服務(wù)器會保存一段時間在線狀態(tài))的時候,有的時候由于其他原因,會卡在不能地圖的物理層(不能行動的點),玩家完全不能移動。為了解決這個問題,有個同事在玩家重登錄的時候,直接設(shè)置了玩家的坐標(biāo)到一個可移動的點。
            這個看似無關(guān)緊要的操作,真正導(dǎo)致了服務(wù)器1天多時間內(nèi)不停的宕機。下面來記錄下分析過程吧。
            1、玩家在重登錄前,其實是在場景中的,也就是在一個具體的Area里。
            2、由于玩家上線后,直接設(shè)置了坐標(biāo),而我們后續(xù)的計算是通過坐標(biāo)來獲取Area對象的,其實這里就出現(xiàn)問題了,玩家其實是在A格子的鏈表上,但是根據(jù)坐標(biāo)計算獲得的格子是B。
            3、玩家移動后,切換格子,需要從原格子Leave,然后進入新的格子,但是基于上面的原因,所以其實涉及到的有3個格子,(1)、玩家真實所在的格子鏈表(A)。(2)、通過坐標(biāo)計算所得的格子(B),這個格子對象上會調(diào)用Leave操作。
              (3)要進入的新格子(C)。
            4、由于玩家其實在格子A,但是我們調(diào)用的是B.Leave(player);C.Enter(player),從這里看,肯定是有問題的,但是細看則不然,由于玩家對象是記錄了前一個和后一個對象,所以B.Leave本身并不會破壞B的鏈表結(jié)構(gòu),C.Enter看上去也沒問題,那么,問題在哪里?
            5、真正的原因其實是格子A對象被破壞了,B.Leave(player)上是將玩家從它自己的鏈表上刪除了,鏈表本身是沒有被破壞了,關(guān)鍵的原因是如果玩家在格子A是Head,那么實際上在玩家被刪除后,Head應(yīng)該被改變,但是由于操作的是格子B,所以,A其實被破壞了,很奇妙,這個對象沒有操作,卻被破壞了。后面的問題就簡單了,如果玩家進入的C就是A,則會是一個很明顯的死循環(huán),如果玩家進入的C是一個新的格子,則格子A的對象都不能被感知了。

             

             

             

            posted on 2012-07-15 22:13 feixuwu 閱讀(410) 評論(0)  編輯 收藏 引用

            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            <2014年4月>
            303112345
            6789101112
            13141516171819
            20212223242526
            27282930123
            45678910

            文章轉(zhuǎn)載請注明出處

            常用鏈接

            留言簿(11)

            隨筆分類

            隨筆檔案

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            国产99久久精品一区二区| 久久精品免费一区二区三区| 精品伊人久久久| 热re99久久6国产精品免费| 久久最近最新中文字幕大全 | 色偷偷久久一区二区三区| 国产激情久久久久影院老熟女| 久久精品三级视频| 99久久综合狠狠综合久久止| 久久天天躁狠狠躁夜夜躁2014| 国产午夜福利精品久久2021| 久久精品国产只有精品66 | 日韩十八禁一区二区久久 | 模特私拍国产精品久久| 国产一级做a爰片久久毛片| 老男人久久青草av高清| 国产亚洲精午夜久久久久久| 无码专区久久综合久中文字幕| 久久综合九色欧美综合狠狠 | 99久久久精品免费观看国产| 国内精品伊人久久久久777| 激情五月综合综合久久69| 国产精品久久亚洲不卡动漫| 亚洲精品午夜国产VA久久成人| 青青久久精品国产免费看| 国产999精品久久久久久| 国产精品久久免费| 久久久久久人妻无码| 性欧美大战久久久久久久久 | 中文字幕久久久久人妻| 一本色综合久久| 久久婷婷五月综合97色直播| 国产精品99久久不卡| 国产激情久久久久影院老熟女免费| 丁香五月网久久综合| 亚洲综合久久综合激情久久| 久久噜噜电影你懂的| 国产精品免费看久久久香蕉| 久久99久久无码毛片一区二区| 久久亚洲天堂| 色妞色综合久久夜夜|