牙牙窩

          BlogJava 聯系 聚合 管理
            8 Posts :: 21 Stories :: 10 Comments :: 0 Trackbacks
              今年真的是郁悶透頂了。項目組居然叫我去做我從來沒有做過的接口方面的編程,搞得我焦頭爛額。

              因為沒有經驗,寫的代碼亂七八糟,出了好多問題,不過,也學了不少東西。

              首先就是Socket的編程,我只是在學習JAVA時寫了一些socket方面的例子,從來就沒有仔細研究過,組長居然叫我設計一個JAVA的接口平臺。胡弄了一通之后,系統上線了。但是問題就來了。

              首先第一個問題,長連接必須有心跳。因為之前協議中沒有定義心跳協議,而我又沒有經驗,所以等真正上線之后才發現,如果長連接沒有心跳,很容易導致在Socket連接中,長時間沒有通訊的話,就會導致連接雖然保持,但不能正常通訊的問題。

              第二個問題,必須加入流量控制。這個問題出現在業務高峰期時,會接收到大量請求,這時業務系統的處理速度跟不上請求發起方,導致大量請求積壓在Socket服務器端,導致JVM崩潰。這個問題我之前是使用了JAVA5中所帶的ExecutorService,通過設置固定的線程池數量的方式做流量控制,后來發現不行,線程會不斷增加,導致JVM崩潰。不知道是我代碼問題還是ExecutorService本身的問題。建議使用BlockingQueue來做隊列,我目前用起來還是比較穩定。

              第三個問題,是由上面的問題衍生出來的一個問題,就是效率問題。我之前的線程處理方式是每接到一個請求,會在主線程實例化一個線程實例,再把線程放到線程池中運行,這個方式除了導致上面的問題以外,而且效率很慢,我稱之為“推”的方式。現在經過改良后,在服務起來之后,先事先運行固定數量的線程,然后所有線程都從同一個BlockingQueue中獲取指令,我稱之為“拉”的方式。這種方式讓程序效率提高了很多,省去了每次生成對象的過程。而且這個設計本身也實現了處理量的控制。

              第四個問題,就是指令的返回問題。在處理每個異步指令的過程時,對于返回指令,通常的做法是將返回結果指令放入隊列中,然后再逐一返回。這個做法就存在了一個隱患,就是當服務器的進程core掉,或者因其它原因中斷,所有的返回指令都會丟失。建議的做法是在得到返回指令之后,將要返回的結果指令持久化,通常是放入數據表或者緩存文件中,然后再操作,這樣的話,當重啟進程,也可以重新讀取返回指令,最大可能保證接口的數據準確性。

              第五個問題,其實跟上面有一些接近,就是做接口程序,有一個大原則,就是一切有跡可尋。在受理時要寫日志,執行業務時要記錄、返回結果時要入庫。總之讓運維人員可以很方便的定位問題,排除問題。否則,只能麻煩自己啦!

              至于其它錯誤我就不一一羅列了,總之在錯誤中進步,還是學到不少知識。呵呵~~


          posted on 2007-12-19 10:43 大牙 閱讀(486) 評論(2)  編輯  收藏

          Feedback

          # re: 接口開發一些自己的失誤、經驗和總結 2010-05-07 16:08 寶貝兔
          可不可以把您現在實現的客戶端長連接的代碼給我貼一段出來,我現在都不知道怎么在客戶端建立長連接?  回復  更多評論
            

          # re: 接口開發一些自己的失誤、經驗和總結 2010-06-13 09:47 444
          @寶貝兔
          - -保留socket不就可以了嗎??  回復  更多評論
            


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 山西省| 盐城市| 彭水| 泾阳县| 长宁区| 平顺县| 青神县| 新源县| 呼伦贝尔市| 麻栗坡县| 沽源县| 东海县| 嵊泗县| 克东县| 武威市| 亚东县| 河北区| 易门县| 茂名市| 开封市| 平定县| 乐山市| 韶关市| 锡林郭勒盟| 罗田县| 罗江县| 宜昌市| 吴桥县| 普兰县| 驻马店市| 将乐县| 嵩明县| 营口市| 汉寿县| 南开区| 阳城县| 大安市| 额尔古纳市| 岗巴县| 习水县| 公安县|