能够选择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里面调用.