200分求最佳化建議,該如何解決
來源:互聯網
上載者:User
200分求最佳化建議
問題是這樣的:
a -> b -> c
a是我們的合作方,他們負責通過http協議給我們同步資料。
b是我們,負責接收a推過來的資料,做商務邏輯處理後,再把整理好的資料推給我們的合作方c(有很多c)。
我的程式整體架構是這樣的:
1 有一個入口檔案,其實就是個php檔案,負責接收a的資料,存入資料庫。
2 我用nohup命令調用php cli模式開了一個php進程運行一個php檔案在系統幕後處理下面的事情:從資料庫中一次取出10條資料,迴圈fetch出每一條,然後根據商務邏輯,根據每條資料的不同,轉寄給不同的c(其實就是要訪問不同的url)。
a給我同步資料的時候,一秒可能會來10幾條,他們是多線程發包。而我這邊經過入庫,一次取出10條資料,迴圈推送到不同的url地址,在收到他們介面給我響應的'ok'後,做標記,然後推送下一條資料,如果在我設定的逾時時間5秒後還沒有收到對方的'ok',則重發,逾時時間依然是5秒,共重發2次。等於一條資料最多推送3次,3次都推不過去的話就不管了。並且,我在每次推送資料間設定sleep了1秒。
遇到的問題:
正常情況下,推一條資料應該大概在2秒以內,但如果某個c,他的介面受網路原因或程式的問題,我3次推送都沒推過去(也就是說他的介面響應速度大於5秒或根本沒響應),它會令我的資料隊列最多懈怠18秒的時間。這會令推送速度大大降低!我今天看了下,我的資料隊列比正常速度大概慢了一個小時。請問有什麼好的方法解決這個問題嗎?
php本身不支援多線程,我無法設定不同的線程去給不同的c推送資料。所以一個c的介面響應慢,會影響所有的c,影響整個資料隊列。
不知有沒有朋友做過這方面的東西,指教點經驗。除了要求c提高介面響應速度,和保證網路暢通外。有沒有我自己這邊解決問題的方法?我的一些合作方它們用的都是java,可以建立線程池多線程發包,但php這點比較無奈。
其實在以前,我採用的方式是同步轉寄,也就是接到a的資料後,立刻處理商務邏輯,然後立刻把資料同步轉寄給c,不入隊列。這樣是沒有上述問題的,但這樣會產生很多其它問題,所以我現在才改成這種隊列的方式。
我想了兩個解決方案不知是否可行:
1 php本身不支援多線程,但linux下的curl,wget,或apache帶的ab。它們支援多線程的,我是否可以用php去調用它們來實現多線程推資料?給每個不同的c分配一個線程,這樣,一個c堵塞,不會影響其它的c。
2 不支援多線程,我用多進程,我給每個不同的c開一個單獨的php進程,這樣也可以避免c之間互相影響。但我不清楚開這麼多進程無限死迴圈著運行會對作業系統有多大影響。目前我們這個業務大概有10個c。
希望大家給點意見,指點下,謝謝!
------解決方案--------------------
開多進程,給每個c開一個單獨的php進程,
影響,就同時開2個,一直用,一個監視一些其它進程,一個做檔案操作,都死迴圈樣運行,
沒發現死迴圈 本身對負載有影響。當調度檔案操作的時候,肯定會影響負載。cpu/硬碟讀寫夠強,應該沒問題吧,或者減少到5個,每個對應2個c
------解決方案--------------------
頻繁查庫不知到是否有瓶頸,如果是a來的直接資料,沒有作處理,不如除了存庫,另外放到記憶體,產生隊列,讓php進程去記憶體隊列拿
------解決方案--------------------
用SOAP解決
------解決方案--------------------
用SOAP解決可行性高
原理是,soap監聽接收資料
然後soap後台啟動多進程
------解決方案--------------------
對了,不如不等待返回
x.php一直運行,定時從記憶體隊列獲得資料,並給記憶體中資料作個標記,然後處理後推送c端,但不等待返回
x.php擷取資料時,在一段時間內只獲得無標記的資料
c端返回要求,發到另外一個,m.php,接收返回,並和記憶體隊列對比,刪除符合的
------解決方案--------------------
PHP CLI模式在非WIN下可以多線程 但很弱
HTTP是無狀態協議 完全可以多進程來做 但其中有個嚴重的問題
A-> 10+/S
->C 10/5S
也就是說 C的發送速度要低於A的接收速度 造成前一個C還未退出就再啟動一個C 最後堆積了N個進程系統崩潰 或者每個C一個進程 造成很大的資料延遲
可以給每個C單獨一個進程 但每次不限於10條 應該是積壓了幾條就發幾條 這樣能有效控制進程數量和延遲 最大延遲基本上就是已耗用時間+傳輸時間
再或者每個C單獨進程+多線程 弄個列隊每個線程10條 積壓超過10條就啟動新的線程 基本上每個進程啟動20個線程就足夠保證同步了
資料提供俺的做法是被動訪問 畢竟使用者不多 幾K節點的XML產生發送 負載都不算高 而且可以利用緩衝
呵呵 SOAP可能更合適 可需要上遊和下遊一起支援
------解決方案--------------------
我的建議:
1、把你當前的處理B->C的php cli程式放到apache下,即http://www.x.com/b2c.php
2、開一個獨立的php CLI進程php.exe db_read.php,去迴圈讀資料庫並將讀取的欄位提交給b2c.php
你可以一次提交10個都沒問題,因為apache支援多線程:)
------解決方案--------------------
我不大瞭解這個,不過前段時間看到一個“伺服器推”技術。或許有用。
另外,我說說sql查詢這塊兒,假設你的sql資料庫沒有太多最佳化的話,每次查詢10條,這樣速度會有瓶頸,當然,或許資料的要求對於這個查詢完全能夠滿足。
以你的推送速度來推理,建議一次性讀取資料比如100條,暫存為一個檔案,檔案操作畢竟比資料庫操作要快。
推送出去10條刪除10條,當只剩下10條的時候,再讀取100條。這樣能減少資料庫的讀取次數。
想要最佳化,就要最佳化到牙齒。其它的方面恕我沒有想到什麼方式,材疏學淺,幫不上忙了。
------解決方案--------------------
開多進程,給每個c開一個單獨的php進程,
影響,就同時開2個,一直用,一個監視一些其它進程,一個做檔案操作,都死迴圈樣運行,
------解決方案--------------------
引用樓主 ShadowSniper 的文章:
問題是這樣的:
a -> b -> c
a是我們的合作方,他們負責通過http協議給我們同步資料。
b是我們,負責接收a推過來的資料,做商務邏輯處理後,再把整理好的資料推給我們的合作方c(有很多c)。
我的程式整體架構是這樣的:
1 有一個入口檔案,其實就是個php檔案,負責接收a的資料,存入資料庫。