能夠選擇7種類型,默認爲2
1,輪循模式,收到會輪循分配給每個Worker進程
2,固定模式,根據鏈接的文件描述符分配Worker。這樣能夠保證同一個鏈接發來的數據只會被同一個Worker處理
3,搶佔模式,主進程會根據Worker的忙閒狀態選擇投遞,只會投遞給處於閒置狀態的Worker
4,IP分配,根據客戶端IP進行取模hash,分配給一個固定的Worker進程。能夠保證同一個來源IP的鏈接數據總會被分配到同一個Worker進程。算法爲 ip2long(ClientIP) % worker_num
5,UID分配,須要用戶代碼中調用 Server->bind() 將一個鏈接綁定1個uid。而後底層根據UID的值分配到不一樣的Worker進程。算法爲 UID % worker_num,若是須要使用字符串做爲UID,可使用crc32(UID_STRING)
7,stream模式,空閒的Worker會accept鏈接,並接受Reactor的新請求mysql
使用建議redis
無狀態Server可使用1或3,同步阻塞Server使用3,異步非阻塞Server使用1, 有狀態使用二、四、5
dispatch_mode 4,5兩種模式,在1.7.8以上版本可用
dispatch_mode=1/3時,底層會屏蔽onConnect/onClose事件,緣由是這2種模式下沒法保證onConnect/onClose/onReceive的順序, 非請求響應式的服務器程序,請不要使用模式1或3算法
UDP協議sql
dispatch_mode=2/4/5時爲固定分配,底層使用客戶端IP取模散列到不一樣的Worker進程,算法爲 ip2long(ClientIP) % worker_num
dispatch_mode=1/3時隨機分配到不一樣的Worker進程服務器
BASE模式swoole
dispatch_mode配置在BASE模式是無效的,由於BASE不存在投遞任務,當Reactor線程收到客戶端發來的數據後會當即在當前線程/進程回調onReceive,不須要投遞Worker進程。網絡
Lock用來實現數據同步, Lock類支持5種鎖的類型異步
注意:勿在onReceive等回調函數中建立鎖, 不然底層的GlobalMemory內存會持續增加, 形成內存泄漏socket
swoole_lock->__construct(int $type, [string $lockfile])
$type爲鎖的類型
$lockfile, 當類型爲SWOOLE_FILELOCK時必須傳入, 指定文件鎖的路徑
注意每一種類型的鎖支持的方法都不同。如讀寫鎖、文件鎖能夠支持$lock->lock_read()。另外除文件鎖外, 其餘類型的鎖必須在父進程內建立, 這樣fork出的子進程之間才能夠互相爭搶鎖。不要循環建立/銷燬鎖的對象, 不然會發生內存泄漏函數
swoole_lock->lock()
加鎖操做。若是有其餘進程持有鎖, 那這裏將進入阻塞, 直到持有鎖的進程unlock. 加鎖成功返回true
swoole_lock->trylock()
加鎖操做。與lock方法不一樣的是, trylock()不會阻塞, 它會當即返回。
加鎖成功返回true, 此時能夠修改共享變量
加鎖失敗返回false, 表示有其餘進程持有鎖
swoole_lock->unlock()
解鎖成功返回true
swoole_lock->lock_read()
僅鎖定讀. 在持有讀鎖的過程當中, 其餘進程依然能夠得到讀鎖, 能夠繼續發生讀操做, 但不能$lock->lock()或$lock->trylock(), 這兩個方法是獲取獨佔鎖, 在獨佔鎖加鎖時, 其餘進程沒法再進行任何加鎖操做, 包括讀鎖.
當另一個進程得到了獨佔鎖(調用$lock->lock/$lock->trylock)時, $lock->lock_read()會發生阻塞, 直到持有獨佔鎖的進程釋放鎖
只有SWOOLE_RWLOCK和SWOOLE_FILELOCK類型的鎖支持只讀加鎖
swoole_lock->trylock_read()
此方法與lock_read相同, 可是非阻塞的
swoole_lock->lockwait(float $timeout = 1.0) : bool;
加鎖操做,做用與swoole_lock->lock一致,但lockwait能夠設置超時時間。
$timeout傳入超時時間,默認爲1秒, 在規定的時間內未得到鎖,返回false, 加鎖成功返回true
只有Mutex類型的鎖支持lockwait
Swoole提供瞭如下的Coroutine對象
Coroutine\Channel
Coroutine\Client
Coroutine\Http\Client
Coroutine\Http2\Client
Coroutine\Redis
Coroutine\Socket
Coroutine\MySQL
Coroutine\PostgreSQL
這些Coroutine只適合在一個進程中作處理. 例如你須要在一個onRequest方法裏, 同時請求多個mysql和redis, 那麼使用Coroutine可使這些請求並行, 達到節約網絡時間的目的.Coroutine不適合在Server中建立, 又須要在多個進程中處理的場景, 例如你在server裏建立了一個socket, 但願在各個worker裏面調用.