swoole啟動2萬個定時器對性能有影響嗎?

假設有2萬個物聯網設備,以mac為唯一標識,長連接到TCP伺服器,資料庫有實時的數據需要發給設備,如果有就馬上發給設備,如果沒有就什麼都不做,一種方案是每個設備開啟一個屬於自己的定時器,查詢資料庫時帶上設備的mac,只查詢屬於該設備的信息,用連接池,這種方案有個好處,由於只查詢了屬於設備的信息,返回結果後不需要循環就直接返回給設備了,缺點是設備多查詢資料庫次數多了,另一種方案是只開啟一個定時器,查詢資料庫時把所有的信息都查出來,然後循環下發給對應的設備,這樣有個好處,查詢資料庫次數很少了,但是每次都返回了很多數據,還要循環下發給對應的設備,各有千秋吧,不知道哪種好?個人認為最後一種方案好


你的這兩種方案的主體思路仍然是在伺服器端用Swoole的周期性定時器函數swoole_timer_tick定時輪詢資料庫,2萬個Swoole定時器不是性能瓶頸,定時器回調函數里的資料庫輪詢操作才是性能瓶頸.

而且這樣的設計也體現不出Swoole事件驅動的編程思想,你可以考慮使用Redis提供的消息驅動的訂閱發布功能PubSub,具體操作就是:

1.每個客戶端(物聯網設備)保持一個到Swoole的長連接(協議任選,如MQTT).

2.每個長連接在伺服器端用Swoole內置的非同步Redis客戶端訂閱(Sub)一個頻道,頻道名假設為設備的MAC地址,做到唯一.

3.每當有某個設備的數據寫入資料庫時,寫入操作的同時,使用Redis客戶端發布(Pub)一條消息到對應設備的Redis頻道,因為Redis的PubSub機制,該設備在第2步的訂閱(Sub)操作會馬上獲取到這條消息,從而把這條消息推送給設備終端.


首先不建議直接用長連接!

而且你的方案有點問題!

說說我的思路~

首先物聯網設備!連接伺服器註冊自己的信息!

主要一些設備信息!

MAC 名稱 IP 通信埠!

然後有任務!伺服器查詢資料庫!

找到設備IP埠!

然後下發任務!

如果任務列表比較多!可以非同步!列隊處理!

這樣穩定性和性能都會比較好!

還有一個方案!被動等待設備查詢任務!

伺服器不主動!所以任務丟進任務列表!

物聯網設備定時查詢!

建議使用第一個方案!

而且中間還涉及通信加密!


用swoole_http_server套一層tcpserver

設備連TCPserver埠, 用Table保存mac和fd的對應關係

原來寫資料庫的操作改成調swoole_http_server的介面

在介面里找到mac對應的fd就可以直接發送信息了, 然後再寫資料庫


大哥,這個樣子,資料庫估計感覺有點夠嗆啊,而且這種情況我個人認為如果自己造輪子的話應該考慮用緩存。因為你每次只需要最新的數據,沒必要用資料庫查一次新,直接把最新的數據緩存一份。尤其如果是有感測器,一刻不停的發送,再加上還是必須得關係型資料庫的話,你每次查詢查詢要血崩啊。

另外,不是很建議長連接。設想一種情況,伺服器斷線後重新上線(當然,如果你大規模機群加異地雙活,當我沒說),然後瞬間所有設備同時請求,感覺不是很好。

當然,我對以上言論完全不負責任,哈哈。


推薦閱讀:

現在國內中小型的IT行業的公司,asp.net和php哪個應用得比較普遍?
如何編寫不可維護的php代碼?
「Facebook 開發的高性能PHP虛擬機 HHVM 比官方的 PHP解釋器 快超過9倍」的說法是否屬實?
Zend opcode是如何被執行的?是要編譯為機器碼再執行嗎?
能在郵件中嵌入PHP嗎?

TAG:PHP | 高並發 | TCP | 資料庫連接池 | Swoole |