Swoole笔记(五)
配置说明
$server->set(array(
'daemonize' => true,
'log_file' => '/www/log/swoole.log',
'reactor_num' => 2,
'worker_num' => 2,
'task_worker_num' => 4,
'max_request' => 100,
));
daemonize
设置是否后台运行。默认是false。设置daemonize => 1
时,程序将转入后台作为守护进程运行。长时间运行的服务器端程序必须启用此项。
如果不启用守护进程,当ssh终端退出后,程序将被终止运行。
注意:
- 启用守护进程后,标准输入和输出会被重定向到 log_file。
- 如果未设置log_file,将重定向到
/dev/null
,所有打印屏幕的信息都会被丢弃。
log_file
指定swoole错误日志文件。在swoole运行期发生的异常信息会记录到这个文件中。默认会打印到屏幕。
注意log_file不会自动切分文件,所以需要定期清理此文件。通过重新打开日志,可以实现按天记录日志。
log_level
设置swoole_server错误日志打印的等级,范围是0-5。低于log_level设置的日志信息不会抛出。默认是0 也就是所有级别都打印。
0 =>DEBUG
1 =>TRACE
2 =>INFO
3 =>NOTICE
4 =>WARNING
5 =>ERROR
reactor_num
reactor线程数,通过此参数来调节主进程内事件处理线程的数量,以充分利用多核。默认会启用CPU核数相同的数量。reactor_num
一般设置为CPU核数的1-4倍,在swoole中reactor_num
最大不得超过CPU核数*4
。
Swoole的主进程是一个多线程的程序。其中有一组很重要的线程,称之为Reactor线程。它就是真正处理TCP连接,收发数据的线程。Reactor线程进行协议解析,将请求投递到Worker进程。
推荐配置:CPU核数。
注意:reactor_num
必须小于或等于worker_num
。如果设置的reactor_num
大于worker_num
,那么swoole会自动调整使reactor_num
等于worker_num
。
worker_num
设置启动的worker进程数。worker_num >= 1
,至少会有一个,默认是 1。设置方法:
- 业务代码是全异步非阻塞的,这里设置为CPU的1-4倍最合理。
- 业务代码为同步阻塞,需要根据请求响应时间和系统负载来调整。
比如1个请求耗时100ms,要提供1000QPS的处理能力,那必须配置100个进程或更多。但是需要考虑内存占用。假设每个进程占用40M内存,那100个进程就需要占用4G内存。
推荐配置:CPU核数*2。
task_worker_num
配置task进程的数量,配置此参数后将会启用task功能。如果业务用不到异步任务,可以不设置。一旦设置次参数,必须设置onTask/onFinish
2个事件回调。
注意:
- task进程内不能使用
swoole_server->task
方法 - task进程内不能使用
mysql-async/redis-async/swoole_event
等异步IO函数
推荐配置:根据实际异步任务比重设置。
dispatch_mode
数据包分发策略。可以选择3种类型,默认为2。一般情况下,HttpServer可以使用1、3;WebSocketServer可以使用默认的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)
。
dispatch_mode
配置在BASE模式是无效的,因为BASE不存在投递任务。
max_request
设置worker进程的最大任务数,默认为0。
这个参数的主要作用是解决PHP进程内存溢出问题。一个worker进程在处理完超过max_request数值的任务后将自动退出,进程退出后会释放所有内存和资源。
例如设置为3,假设有2个worker进程,执行5次请求,必然会有一个worker进程会退出并被重新拉起一个新的。如果不设置,就不会执行这个操作。
PHP应用程序有缓慢的内存泄漏,但无法定位到具体原因、无法解决,可以通过设置max_request解决。
如果代码没有内存泄露的问题,没有每访问一次,内存就增加一点,那不设置(默认为0)也不会有内存泄露。反之,max_request,就可以限制内存无限制增长,从而防止内存泄露。(参考http://group.swoole.com/question/106049)
task_max_request
类似于max_request,默认为5000。用于设置task进程的最大任务数。一个task进程在处理完超过此数值的任务后将自动退出。这个参数是为了防止PHP进程内存溢出。如果不希望进程自动退出可以设置为0。
max_conn (max_connection)
服务器程序,最大允许的连接数,如max_conn => 10000, 此参数用来设置Server最大允许维持多少个tcp连接。超过此数量后,新进入的连接将被拒绝。
- 默认值为
ulimit -n
的值。系统的ulimit -n
可能太小,需要手动设置。例如ulimit -n 65535
。 - 最大不得超过操作系统
ulimit -n
的值,否则会报一条警告信息,并重置为ulimit -n
的值。 - 此参数不要调整的过大,根据机器内存的实际情况来设置。
heartbeat_idle_time、heartbeat_check_interval
heartbeat_idle_time与heartbeat_check_interval配合使用。表示连接最大允许空闲的时间。如:
array(
'heartbeat_idle_time' => 600, //表示连接最大允许空闲的时间
'heartbeat_check_interval' => 60, //表示每隔少秒轮循一次
);
表示每60秒遍历一次,一个连接如果600秒内未向服务器发送任何数据,此连接将被强制关闭。
- 启用heartbeat_idle_time后,服务器并不会主动向客户端发送数据包,而是被动等待客户端发送心跳。
- 如果只设置了heartbeat_idle_time未设置heartbeat_check_interval底层将不会创建心跳检测线程,PHP代码中可以调用heartbeat方法手工处理超时的连接。
open_eof_check、package_eof
设置EOF字符串。package_eof最大只允许传入8个字节的字符串。
array(
'open_eof_check' => true, //打开EOF检测
'package_eof' => "\r\n", //设置EOF
)
打开EOF检测,此选项将检测客户端连接发来的数据,当数据包结尾是指定的字符串时才会投递给Worker进程。否则会一直拼接数据包,直到超过缓存区或者超时才会中止。当出错时swoole底层会认为是恶意连接,丢弃数据并强制关闭连接。
常见的Memcache/SMTP/POP等协议都是以\r\n结束的,就可以使用此配置。开启后可以保证Worker进程一次性总是收到一个或者多个完整的数据包。
open_eof_split
EOF检测不会从数据中间查找eof字符串,所以Worker进程可能会同时收到多个数据包,需要在应用层代码中自行explode("\r\n", $data)
来拆分数据包。
1.7.15版本增加了open_eof_split,支持从数据中查找EOF,并切分数据。
pid_file
在Server启动时自动将master进程的PID写入到文件,在Server关闭时自动删除PID文件。(1.9.5+支持)
$server->set(array(
'pid_file' => __DIR__.'/server.pid',
));
其它参数详见:配置选项-Swoole-Swoole文档中心
https://wiki.swoole.com/wiki/page/274.html
服务器调优
常见优化参数:
# 内核优化
ulimit -n 65535
net.core.somaxconn = 262144
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_syncookies = 1
# nginx优化
worker_rlimit_nofile 65535;
use epoll;
worker_connections 65535;
keepalive_timeout 60;
内核优化如何修改:
1、ulimit参数直接运行ulimit -SHn 65535
即可,可以使用ulimit -n
查看;
2、其它参数优化示例:
net.core.somaxconn
对应文件/proc/sys/net/core/somaxconn
:
# 查看
cat /proc/sys/net/core/somaxconn
# 修改
echo 65535 > /proc/sys/net/core/somaxconn
net.ipv4.tcp_tw_recycle
对应文件/proc/sys/net/ipv4/tcp_tw_recycle
:
# 查看
cat /proc/sys/net/ipv4/tcp_tw_recycle
# 修改
echo 65535 > /proc/sys/net/ipv4/tcp_tw_recycle
3、也可以修改/etc/sysctl.conf
文件:
# 调高系统的 IP 以及端口数据限制,从可以接受更多的连接
net.ipv4.ip_local_port_range = 2000 65000
net.ipv4.tcp_window_scaling = 1
# 设置协议栈可以缓存的报文数阀值,超过阀值的报文将被内核丢弃
net.ipv4.tcp_max_syn_backlog = 3240000
# 调高 socket 侦听数阀值
net.core.somaxconn = 3240000
net.ipv4.tcp_max_tw_buckets = 1440000
# 调大 TCP 存储大小
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_congestion_control = cubic
# tcp重新回收
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
修改配置之后需要执行以下命令使之生效:
sysctl -p /etc/sysctl.conf
相关应用
1、https://github.com/matyhtf/framework
2、衍生开源项目-Swoole-Swoole文档中心
https://wiki.swoole.com/wiki/page/p-open_source.html
3、moell-peng/webim: PHP + Swoole 实现的简单聊天室
https://github.com/moell-peng/webim
参考
1、Server-Swoole-Swoole文档中心
https://wiki.swoole.com/wiki/page/p-server.html
2、swoole_study/Swoole的进程模型.md at master · szyhf/swoole_study
https://github.com/szyhf/swoole_study/blob/master/Swoole的进程模型.md
Swoole笔记(五)的更多相关文章
- C#可扩展编程之MEF学习笔记(五):MEF高级进阶
好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...
- 《MFC游戏开发》笔记五 定时器和简单动画
本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9332377 作者:七十一雾央 新浪微博:http:// ...
- (转)Qt Model/View 学习笔记 (五)——View 类
Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...
- java之jvm学习笔记五(实践写自己的类装载器)
java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...
- Crazyflie笔记五: CRTP 实时通信协议(一)(转)
源:Crazyflie笔记五: CRTP 实时通信协议(一) 这里详细介绍了 Crazyflie 的 CRTP实时通信协议的相关内容,由于内容很长,分几篇博文来讲述.这里是第一节内容.欢迎交流:301 ...
- Learning ROS for Robotics Programming Second Edition学习笔记(五) indigo computer vision
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...
- Typescript 学习笔记五:类
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- Django开发笔记五
Django开发笔记一 Django开发笔记二 Django开发笔记三 Django开发笔记四 Django开发笔记五 Django开发笔记六 1.页面继承 定义base.html: <!DOC ...
- ES6学习笔记<五> Module的操作——import、export、as
import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...
- muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor
目录 muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor Connector 系统函数connect 处理非阻塞connect的步骤: Connetor时序图 Accep ...
随机推荐
- 在外围获取APP的机密信息
叶孤城原创,转载须授权. 小白:偷窥狂,不,叶城主,怎么还不发起攻击,还在外围搞什么? 叶孤城:闭嘴,能外围解决的问题就不要破解,你以为你会天外飞仙啊! 小白:-- 本文解决一个问题:通过抓包分析出重 ...
- hdu3015 Disharmony Trees
Problem Description One day Sophia finds a very big square. There are n trees in the square. They ar ...
- uva11059(最大乘积)
Problem D - Maximum Product Time Limit: 1 second Given a sequence of integers S = {S1, S2, ..., Sn}, ...
- 在Flex中推断是否在组件之外单击的技巧
在Flex中推断是否在组件之外单击的技巧 昨天在做Flex开发的时候.遇到了这样一种操作,之前也遇到过.那时的办法不是非常好,今天又碰上了类似的问题,先看一张图吧! watermark/2/text/ ...
- SSM学习(二)mybatis和spring的集成
上一篇文章大概搭建了一下ssm的框架,其实还是不完整,我们往项目中添加了spring和mybatis的配置文件,还差一个spring mvc的配置文件,在resource中在新建一个Applicati ...
- vue.js使用webpack发布,部署到服务器上之后在浏览器中可以查看到vue文件源码
webpack+vue 2.0打包发布之后,将发布的文件部署到服务器中之后,浏览器中访问的时候会出现一个webpack文件夹,里边会显示vue文件源码 如果不想让vue源文件显示出来,可以在confi ...
- 工作随笔——ember框架去除url上的#号
因为工作原因,接触到了一套非常好的前端框架--ember. ember框架高度封装,学习曲线比较陡峭. ember对于url更新的配置在config/environment.js >> l ...
- NodeJs学习笔记(四)---单元测试
sailsjs框架用了一段时间了,感觉如果功能复杂了,非常难以处理,想用一下单元测试,看是否能解决问题. sailsjs的官方文档使用的是mocha,我搜索了一些资料,主要参考了朴灵 ...
- TCP/IP的那些事--子网掩码
当前互联网使用的主要是IPv4协议,它是第一个被广泛使用,构成现今互联网的基础的协议.但是,随着用户数量的增多,IPv4包含的IP资源在不断减少.或许你会想,不是还有IPv6吗?IPv6的容量足以应付 ...
- JAVA NIO学习一:NIO简介、NIO&IO的主要区别
在前面学习了IO之后,今天我们开始进入NIO学习环节,首先我们会NIO做一个简单的介绍,让大家认识NIO,然后会和IO进行一个对比认识进行区分.好了,下面我们就开始学习: 一.NIO简介 1.概述 从 ...