Socket配置参数

reactor_num

Reactor线程数,reactor_num => 2,通过此参数来调节主进程内事件处理线程的数量,以充分利用多核。默认会启用CPU核数相同的数量。

reactor_num一般设置为CPU核数的1-4倍,在swoole中reactor_num最大不得超过CPU核数*4

swooleReactor线程是可以利用多核,如:机器有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可以使用13,同步阻塞Server使用3,异步非阻塞Server使用1
  • 有状态使用245

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_num
  • dispatch_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程序与该管理进程失去父子进程关系。

转自:https://wiki.swoole.com/wiki/page/274.html











猜你喜欢

转载自blog.csdn.net/weixin_41380972/article/details/79818335