定时任务管理
Schedule
可通过web访问控制的定时任务系统。
配置文件
第一步首先就是配置好schedule.ini
文件。
为了能够交代清楚后面的逻辑,首先需要告知的是:定时任务的的子任务都是来源于数据库,
总共分为了三个数据表:scheduler_jobs、scheduler_vars、scheduler_tags。
- jobs:定时任务
- vars:变量配置
- tags:标签配置
jobs的记录首先按照server_id
分组,那么不同组可能会在不同的服务器执行。而不同的服务器
的工作目录、执行命令等可能又存在区别,所以通过vars配置变量去屏蔽不同的服务器之间的差异性。
因此在配置文件中需要指定这些区别。
; 基本配置模块,如pid文件、log文件路径、内存最大限制等。
[base]
; 此处省略,在demo中有
; 服务配置模块
;1对应的就是server_id=1的组别。
[server_1]
host = 127.0.0.1 ;线上最好不要写0.0.0.0和127.0.0.1,而是写真实的内网ip。
port = 3401 ;端口号,不同的组别端口号必须不同。
server = 1 ;最终DB的不同组可部署到不同服务器,为了屏蔽不同服务器
;之间的配置不同,通过`server`指定的变量替换jobs的占位符。
[server_2]
host = 127.0.0.1
port = 3402
server = 1
; DB模块
[db1]
; 此处省略,是DB连接的配置
第一件事情除了配置好配置文件之外,那就是初始化数据表。
文件在src/db/database.sql
。
工作原理
通过第一步配置文件的介绍,基本上能够知道工作机制的大概。
在sched.demo
中写好了一个shell
,可以帮助我们快速启动服务。首先可执行
cp sched.demo sched
然后在vim sched
。再执行sudo sh sched start
启动进程。
如果在linux
上,还可以执行sudo ln -s /path/to/sched /etc/init.d/
,最后别忘了执行
sudo chmod +x /etc/init.d/sched
。那么到这里以后就可以很方便的使用:
/sudo /etc/init.d/sched start server_id
启动服务了。
注意:这里的
server_id
是jobs
的字段server_id
,即分组。是一个必要参数。
启动的流程大致如:
执行Process.php
-> 加载配置文件 -> 初始化stream
->
( 接收web请求 -> 同步DB的数据 -> 启动子进程 -> 回收子进程 ) 这是一个循环的过程
后来再同步DB的数据
这一步骤中,还增加了防止主进程意外退出时,立即重新启动主进程导致多个相同子进程并发的情况处理。每个任务可以配置最大并发数量,通过refcount
记录目前已启动的子进程数。通过这两个数据的比较则可以控制单任务的最大并发数。
你可能已经注意到了,这个是基于内存管理的。那么既然是基于内存管理的,那么在内存的使用方面则需要特别注意。对于phper来说,写的最多的可能是业务方面的需求,不太会考虑到资源的回收。因为PHP
是单进程的,执行结束后则自动回收资源。而在这里就不得不去多加考虑内存方面的优化了。我虽然没有写PHP
常驻进程的经验,所以就从这里开始修炼。在内存回收方面,也是通过xdebug
和长时间的内存使用日志跟踪,最终使主进程的内存使用稳定下来了。主要是从以下几点:
- 变量的回收
- DB连接的关闭
- 输出缓冲的关闭
- web客户端请求连接的关闭
- 子进程资源的回收
但是即使对内存的回收做到了极致(何况我还没有:),在某些情况下依然会发现内存在缓缓上升。这是为什么呢?原因可能是因为:
推荐阅读:www.laruence.com/2011/03/04/1894.h...
1)PHP
是预先申请,然后自己内部分配。
2)数组申请完之后则不会再释放,这也就导致在数组变大时,即使已经将数组内的元素后来释放了,
但是该主进程占用的内存依然不会变小。
3)虽然通过top -p pid
可观察到主进程共占用的内存,但是内部实际使用的会比这个小。
所以不必对内存的总占用太过担心,实际使用的内存稳定性很重要。但是默认主进程最大可使用的内存是1024M
,
也可通过memory_limit
在schedule.ini
配置。以此来防止内存的溢出。
结合以上的理论,在本项目中可能导致内存增大的条件有:
- 子进程的数量上升
- web访问的并发数
目前已逐步上线,更多的问题需要后续跟踪发现。
自认为的优点
通过絮絮叨叨的以上说明,现在可以说说它的优点了。
- 最大的优点:定制化的定时任务管理,可伸缩性很强。这种模式可以运用到其他的用途。
如除了定时任务之外,还写了一个监控系统
guarder
,也是通过这种模式运作。
除此之外,也可自己增加登入授权、IP白名单。如果有需要,还可以增加每个任务的功能说明及任务重跑时的额外参数等。定制化是这个项目的最大特性。
- 最大并行数量的控制。
- web访问控制。
- 支持分布式服务。
TCP抓包
发起web请求,通过socket响应web请求。
于是尝试抓TCP的包 sudo tcpdump -i any tcp port 3499
,如下:
Client发起SYN请求连接
- Client超时重发
Server收到client.SYN,并且发送自己的SYN和ACK
- Server超时重发
Client响应ACK,告知WIN=408256.
- Client 响应 [TCP Dup ACK] 即 DACK,因为收到了Server的第二条 SYN+ACK。
[TCP Update Window] 接收方(server)窗口发生变化,通知Client
并发送ACK。- Server DACK。
思考:是我家里的网络太差了吗?为什么会发生这么频繁的网络丢包问题?难道是代码有问题吗?
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: