在这一节的开篇,让我们先解决上一节的“配置”话题。对于server对象,有很多配置项决定了服务端的行为,可以用set的函数进行配置的设置。

1、函数set:用于设置运行时的各项参数。服务器启动后通过 $serv->setting 来访问 Server->set 方法设置的参数数组。

Swoole\Server->set(array $setting): void

$setting:配置项数组。

注意:函数set必须在 Server->start() 前调用。

示例:

$server->set(array(
'reactor_num' => 2, // reactor thread num
'worker_num' => 4, // worker process num
'backlog' => 128, // listen backlog
'max_request' => 50,
'dispatch_mode' => 1,
));

每个配置项的意义,下面会进行介绍。

2、常用配置项

1) 属性reactor_num:设置启动的 Reactor 线程数。【默认值:CPU 核数】什么是reactor线程呢?点击这里查看上一节常识科普

说明:

通过此参数来调节主进程内事件处理线程的数量,以充分利用多核。默认会启用 CPU 核数相同的数量。
Reactor 线程是可以利用多核,如:机器有 128 核,那么底层会启动 128 线程。
每个线程能都会维持一个 EventLoop。线程之间是无锁的,指令可以被 128 核 CPU 并行执行。
考虑到操作系统调度存在一定程度的性能损失,可以设置为 CPU 核数 * 2,以便最大化利用 CPU 的每一个核。

建议设置为 CPU 核数的 1-4 倍,但最大不得超过 swoole_cpu_num() * 4。

2) worker_num:设置启动的 Worker 进程数。【默认值:CPU 核数】什么是Worker进程呢?点击这里查看上一节常识科普

说明:

如果业务代码是全异步 IO 的,这里设置为 CPU 核数的 1-4 倍最合理。
如果业务代码为同步 IO,需要根据请求响应时间和系统负载来调整,例如:100-500
默认设置为 swoole_cpu_num(),最大不得超过 swoole_cpu_num() * 1000
假设每个进程占用 40M 内存,100 个进程就需要占用 4G 内存,如何正确查看进程的内存占用请参考 Swoole 官方视频教程

举例:

如 1 个请求耗时 100ms,要提供 1000QPS 的处理能力,那必须配置 100 个进程或更多。
但开的进程越多,占用的内存就会大大增加,而且进程间切换的开销就会越来越大。所以这里适当即可。不要配置过大。

3) max_request:设置 worker 进程的最大任务数。【默认值:0 即不会退出进程】

说明:

一个 worker 进程在处理完超过此数值的任务后将自动退出,进程退出后会释放所有内存和资源。

这个参数的主要作用是解决由于程序编码不规范导致的 PHP 进程内存泄露问题。PHP 应用程序有缓慢的内存泄漏,但无法定位到具体原因、无法解决,可以通过设置 max_request 临时解决,但是项目要持久运行还是必须找到内存泄漏的代码并修复。

达到 max_request 不一定马上关闭进程,参考 max_wait_time。

SWOOLE_BASE 下,达到 max_request 重启进程会导致客户端连接断开。

当 worker 进程内发生致命错误或者人工执行 exit 时,进程会自动退出。master 进程会重新启动一个新的 worker 进程来继续处理请求。

4) max_wait_time:设置 Worker 进程收到停止服务通知后最大等待时间【默认值:3】

说明:

经常会碰到由于 worker 阻塞卡顿导致 worker 无法正常 reload, 无法满足一些生产场景,例如发布代码热更新需要 reload 进程。所以,我们加入了进程重启超时时间的选项。

管理进程收到重启、关闭信号后或者达到 max_request 时,管理进程会重起该 worker 进程。分以下几个步骤:

· 底层会增加一个 (max_wait_time) 秒的定时器,触发定时器后,检查进程是否依然存在,如果是,会强制杀掉,重新拉一个进程。

· 需要在 onWorkerStop 回调里面做收尾工作,需要在 max_wait_time 秒内做完收尾。

· 依次向目标进程发送 SIGTERM 信号,杀掉进程。

5) backlog:设置 Listen 队列长度

举例:

如 backlog => 128,此参数将决定最多同时有多少个等待 accept 的连接。

说明:

关于 TCP 的 backlog

· 我们知道 TCP 有三次握手的过程,客户端 syn=>服务端 syn+ack=>客户端 ack,当服务器收到客户端的 ack 后会将连接放到一个叫做 accept queue 的队列里面(linux2.2 之后握手过程分为 syn queue 和 accept queue 两个队列,syn queue 长度由 tcp_max_syn_backlog 决定)

· 队列的大小由 backlog 参数和配置 somaxconn 的最小值决定,我们可以通过 ss -lt 命令查看最终的 accept queue 队列大小,Swoole 的主进程调用 accept(高版本内核调用的是 accept4,为了节省一次 set no block 系统调用)

· 从 accept queue 里面取走。 当 accept queue 满了之后连接有可能成功(成功是通过 TCP 的重传机制,相关的配置有 tcp_synack_retries 和 tcp_abort_on_overflow)

· 也有可能失败,失败后客户端的表现就是连接被重置( 客户端收到 syn+ack 包就认为连接成功了,实际上服务端还处于半连接状态,有可能发送 rst 包给客户端,客户端的表现就是 Connection reset by peer

· 或者连接超时,而服务端会记录失败的记录,可以通过 netstat -s|grep 'times the listen queue of a socket overflowed 来查看日志。如果出现了上述现象,你就应该调大该值了。 幸运的是 Swoole 的 SWOOLE_PROCESS 模式与 PHP-FPM/Apache 等软件不同,并不依赖 backlog 来解决连接排队的问题。所以基本不会遇到上述现象。

6) dispatch_mode:数据包分发策略。【默认值:2】

说明:

建议:

无状态 Server 可以使用 1 或 3,同步阻塞 Server 使用 3,异步非阻塞 Server 使用 1

有状态使用 2、4、5

在UDP模式下:

dispatch_mode=2/4/5 时为固定分配,底层使用客户端 IP 取模散列到不同的 Worker 进程,算法为 ip2long(ClientIP) % worker_num

dispatch_mode=1/3 时随机分配到不同的 Worker 进程

dispatch_mode 配置在 SWOOLE_BASE 模式是无效的,因为 BASE 不存在投递任务,当收到客户端发来的数据后会立即在当前线程 / 进程回调 onReceive,不需要投递 Worker 进程。

注意:

dispatch_mode=1/3 时,底层会屏蔽 onConnect/onClose 事件,原因是这 2 种模式下无法保证 onConnect/onClose/onReceive 的顺序;

非请求响应式的服务器程序,请不要使用模式 1 或 3。例如:http 服务就是响应式的,可以使用 1 或 3,有 TCP 长连接状态的就不能使用 1 或 3。

Swoole最基本配置项就以上这些啦,这一篇到这里就结束了,其它的配置项,包括重启、心跳机制会在之后的文章中慢慢介绍。大家下期见

---------------------------  我是可爱的分割线  ----------------------------

最后博主借地宣传一下,漳州编程小组招新了,这是一个面向漳州青少年信息学/软件设计的学习小组,有意向的同学点击链接,联系我吧。

Swoole从入门到入土(3)——TCP服务器[基本配置项]的更多相关文章

  1. 【Swoole】简单安装与创建TCP服务器

    pecl install swoole PHP的异步.并行.高性能网络通信引擎,使用纯C语言编写,提供了php语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,异步Redis,数据 ...

  2. php的异步非阻塞swoole模块使用(一)实现简易tcp服务器--服务端

    绑定tcp服务器的地址 $swserver = new swoole_server("127.0.0.1",9501); 设置tcp服务器装机容量(太危言耸听了-其实就是设置属性) ...

  3. HTTP从入门到入土(3)——TCP三次握手

    TCP三次握手 客户端与服务器之间互相发送HTTP请求响应之前需要先进行TCP连接,因为HTTP是一个无连接.无状态协议,不存在连接的概念,只有请求和响应的概念.而请求和响应实际上只是数据包,他们需要 ...

  4. php的异步非阻塞swoole模块使用(一)实现简易tcp服务器--客户端

    //实例化一个swoole客户端 $swclient = new swoole_client(SWOOLE_SOCK_TCP); //建立连接---如果连接无效则退出 )){ echo "连 ...

  5. Swoole学习(七)Swoole之异步TCP服务器的创建

    环境:Centos6.4,PHP环境:PHP7 <?php //创建TCP服务器 /** * $host 是swoole需要监听的ip,如果要监听本地,不对外服务,那么就是127.0.0.1;如 ...

  6. Swoole学习(二)Swoole之TCP服务器的创建

    环境:Centos6.4,PHP环境:PHP7 <?php //创建TCP服务器 /** * $host 是swoole需要监听的ip,如果要监听本地,不对外服务,那么就是127.0.0.1;如 ...

  7. swoole 创建tcp服务器

    server.php <?php /** * 创建tcp服务器 * Date: 2019/1/15 */ $serv = new swoole_server('127.0.0.1', 9501) ...

  8. Swoole系列(三):建立TCP服务器并发送数据测试

    <?php // 建立tcp服务器下 $host = '0.0.0.0'; $port = 9501; $serv = new swoole_server($host,$port); $serv ...

  9. 18-ESP8266 SDK开发基础入门篇--TCP 服务器 RTOS版,串口透传,TCP客户端控制LED

    https://www.cnblogs.com/yangfengwu/p/11112015.html 先规定一下协议 aa 55 02 01 F1 4C 控制LED点亮  F1 4C为CRC高位和低位 ...

  10. 17-ESP8266 SDK开发基础入门篇--TCP服务器 RTOS版,小试牛刀

    https://www.cnblogs.com/yangfengwu/p/11105466.html 现在开始写... lwip即可以用socket 的API  也可以用 netconn  的API实 ...

随机推荐

  1. Docker-01基本命令

    1.Docker安装 系统镜像为Centos7.x yum包更新到最新 sudo yum update 安装需要的软件包,yum-util提供yum-config-manager功能.另外两个是dev ...

  2. [转帖]能使 Oracle 索引失效的六大限制条件

    Oracle 索引的目标是避免全表扫描,提高查询效率,但有些时候却适得其反. 例如一张表中有上百万条数据,对某个字段加了索引,但是查询时性能并没有什么提高,这可能是 oracle 索引失效造成的.or ...

  3. [转帖]@Scope("prototype")的正确用法——解决Bean的多例问题

    https://www.jianshu.com/p/54b0711a8ec8 1. 问题,Spring管理的某个Bean需要使用多例   在使用了Spring的web工程中,除非特殊情况,我们都会选择 ...

  4. [转帖]Linux文件系统的几个性能测试软件小结

    https://developer.aliyun.com/article/297631#:~:text=Linux%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F%E7%9A% ...

  5. [转帖]windos的kafka设置账号密码

    1.kafka配置文件 server.properties增加 listeners=SASL_PLAINTEXT://127.0.0.1:9092 advertised.listeners=SASL_ ...

  6. [转帖]linux时间戳转换成时间指令_时间戳转换公式

    原文地址:http://wanping.blogbus.com/logs/28663569.html 1.时间戳转换为正常显示的时间格式 Freebsd 系统下: 转换命令为: date -r 111 ...

  7. overcommit_memory的简单学习

    overcommit_memory的简单学习 背景 前几天一个测试环境启动失败. 总是有如下的提示: Native memory allocation (mmap) failed to map 122 ...

  8. [转帖]鹅厂微服务发现与治理巨作PolarisMesh实践-上

    文章目录 概述 定义 核心功能 组件和生态 特色亮点 解决哪些问题 官方性能数据 架构原理 资源模型 服务治理 基本原理 服务注册 服务发现 安装 部署架构 集群安装 SpringCloud应用接入 ...

  9. 像elementui一样封装自定义按钮

    <template> <div> <button @click.prevent="coverHandler" class="btn-btn& ...

  10. 超级好用的elementui动态循环菜单

    <template> <div> <el-menu @select="selectMenu" :default-active="curren ...