reactor_num

Reactor線程數,reactor_num => 2,通過此參數來調節主進程內事件處理線程的數量,以充分利用多核。默認會啓用CPU核數相同的數量。reactor_num一般設置為CPU核數的1-4倍,在swoole中reactor_num最大不得超過CPU核數*4swooleReactor線程是可以利用多核,如:機器有128核,那麼底層會啓動128線程。每個線程能都會維持一個EventLoop。線程之間是無鎖的,指令可以被128CPU並行執行。考慮到操作系統調度存在一定程度的性能損失,可以設置為CPU核數*2,以便最大化利用CPU的每一個核。

reactor_num必須小於或等於worker_num。如果設置的reactor_num大於worker_num,那麼swoole會自動調整使reactor_num等於worker_num
1.7.14以上版本在超過8核的機器上reactor_num默認設置為8

worker_num

設置啓動的worker進程數。

  • 業務代碼是全異步非阻塞的,這裏設置為CPU的

1-4

  • 倍最合理
  • 業務代碼為同步阻塞,需要根據請求響應時間和系統負載來調整

比如1個請求耗時100ms,要提供1000QPS的處理能力,那必須配置100個進程或更多。但開的進程越多,佔用的內存就會大大增加,而且進程間切換的開銷就會越來越大。所以這裏適當即可。不要配置過大。

  • 每個進程佔用

40M

  • 內存,那

100

  • 個進程就需要佔用

4G

  • 內存

max_request

設置worker進程的最大任務數,默認為0,一個worker進程在處理完超過此數值的任務後將自動退出,進程退出後會釋放所有內存和資源。

這個參數的主要作用是解決PHP進程內存溢出問題。PHP應用程序有緩慢的內存泄漏,但無法定位到具體原因、無法解決,可以通過設置max_request解決。max_request

  • 只能用於同步阻塞、無狀態的請求響應式服務器程序
  • 在swoole中真正維持客户端TCP連接的是master進程,worker進程僅處理客户端發送來的請求,因為客户端是不需要感知Worker進程重啓的
  • 純異步的Server不應當設置

max_request

  • 使用Base模式時

max_request

  • 是無效的

當worker進程內發生致命錯誤或者人工執行exit時,進程會自動退出。master進程會重新啓動一個新的worker進程來繼續處理請求

max_conn (max_connection)

服務器程序,最大允許的連接數,如max_connection => 10000, 此參數用來設置Server最大允許維持多少個TCP連接。超過此數量後,新進入的連接將被拒絕。max_connection

  • 最大不得超過操作系統

ulimit -n

  • 的值,否則會報一條警告信息,並重置為

ulimit -n

  • 的值

max_connection

  • 默認值為

ulimit -n

  • 的值
WARN    swServer_start_check: serv->max_conn is exceed the maximum value[100000].

最大上限

底層使用了SESSION_LIST來實現session_id(虛擬fd)與真實fd的對應,因此除了max_sockets限制之外,max_connection還受限於SW_SESSION_LIST_SIZE宏的設置。目前SW_SESSION_LIST_SIZE底層的值為1M,請勿設置max_connection超過1M

內存佔用

max_connection參數不要調整的過大,根據機器內存的實際情況來設置。Swoole會根據此數值一次性分配一塊大內存來保存Connection信息,可使用gdb跟蹤運行中的進程,打印p sizeof(swConnection) 得到準確的數值。在1.9.16版本中一個TCP連接的Connection信息,需要佔用224字節。

最小設置

此選項設置過小底層會拋出錯誤,並設置為ulimit -n的值。

最小值為(serv->worker_num + SwooleG.task_worker_num) * 2 + 32

serv->max_connection is too small.

dispatch_mode

數據包分發策略。可以選擇3種類型,默認為2

  • 1,輪循模式,收到會輪循分配給每一個worker進程
  • 2,固定模式,根據連接的文件描述符分配worker。這樣可以保證同一個連接發來的數據只會被同一個worker處理
  • 3,搶佔模式,主進程會根據Worker的忙閒狀態選擇投遞,只會投遞給處於閒置狀態的Worker
  • 4,IP分配,根據客户端IP進行取模hash,分配給一個固定的worker進程。可以保證同一個來源IP的連接數據總會被分配到同一個worker進程。算法為 

ip2long(ClientIP) % worker_num

  • 5,UID分配,需要用户代碼中調用 $serv-> bind() 將一個連接綁定1個uid。然後swoole根據UID的值分配到不同的worker進程。算法為 

UID % worker_num

  • ,如果需要使用字符串作為UID,可以使用

crc32(UID_STRING)

使用建議

  • 無狀態

Server

  • 可以使用

1

3

  • ,同步阻塞

Server

  • 使用

3

  • ,異步非阻塞

Server

  • 使用

1

  • 有狀態使用

2

4

5

dispatch_mode 4,5兩種模式,在1.7.8以上版本可用
dispatch_mode=1/3時,底層會屏蔽onConnect/onClose事件,原因是這2種模式下無法保證onConnect/onClose/onReceive的順序
非請求響應式的服務器程序,請不要使用模式1或3

UDP協議

dispatch_mode=2/4/5

  • 時為固定分配,底層使用客户端IP取模散列到不同的worker進程,算法為

ip2long(ClientIP) % worker_numdispatch_mode=1/3

  • 時隨機分配到不同的worker進程

BASE模式

dispatch_mode配置在BASE模式是無效的,因為BASE不存在投遞任務,當Reactor線程收到客户端發來的數據後會立即在當前線程/進程回調onReceive,不需要投遞Worker進程。

daemonize

守護進程化。設置daemonize => 1時,程序將轉入後台作為守護進程運行。長時間運行的服務器端程序必須啓用此項。

如果不啓用守護進程,當ssh終端退出後,程序將被終止運行。

  • 啓用守護進程後,標準輸入和輸出會被重定向到 

log_file

  • 如果未設置

log_file

  • ,將重定向到 

/dev/null

  • ,所有打印屏幕的信息都會被丟棄
  • 啓用守護進程後,

CWD

  • (當前目錄)環境變量的值會發生變更,相對路徑的文件讀寫會出錯。PHP程序中必須使用絕對路徑

systemd

使用systemd管理Swoole服務時,請勿設置daemonize = 1。主要原因是systemd的機制與init不同。init進程的PID1,程序使用daemonize後,會脱離終端,最終被init進程託管,與init關係變為父子進程關係。但systemd是啓動了一個單獨的後台進程,自行fork管理其他服務進程,因此不需要daemonize,反而使用了daemonize = 1會使得Swoole程序與該管理進程失去父子進程關係。

  • systemd