前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >swoole+php搭建高性能脚本服务

swoole+php搭建高性能脚本服务

原创
作者头像
恒恒
修改2018-12-07 11:20:49
1.1K0
修改2018-12-07 11:20:49
举报
文章被收录于专栏:恒恒的专栏恒恒的专栏

后台服务的业务逻辑中,或多或少需要一些异步去处理的脚本逻辑,例如业务的统计、上报、数据运算,定时监控等等。实现的方法也有很多,用linux自带的crontab,定时清理服务器上的日志就很常用,由于Python处理数据的优势,很多开发童鞋也会用python来跑一些需要运算的脚本,另外还有网上流行的一些脚本框架,一些大公司也有自己研发的框架服务。在最近的项目中,接触到swoole2+与php7+搭配的性能优越,普通4核心CPU,单机压测qps 10000+/s,突生灵感,除了用来搭后端服务,能不能用来搭一个脚本服务呢?

于是归纳了一下以前跑脚本的问题:

代码语言:javascript
复制
1、crontab:不能实现到秒级,最多到分钟级,这是很多开发的小痛点,当然想实现秒级也是可以滴,这么写:    
 ***** sleep 10;/usr/bin/myshell.sh     
 ***** sleep 20;/usr/bin/myshell.sh     
 ***** sleep 30;/usr/bin/myshell.sh    
 ***** sleep 40;/usr/bin/myshell.sh     
 ***** sleep 50;/usr/bin/myshell.sh
 变相实现10秒执行一次,但这做法有点low有木有,而且crontab多了比较离散,缺乏集中管理。当然这里可以用一些
 crontab的管理工具来维护。
2、搭一套同步服务框架,走服务请求来跑脚本,这里有个好处,本身的服务的很多方法函数,走脚本服务框架时可以复用。
   但传统服务框架thinkphp、CI等性能较低,脚本内的逻辑存在调用下游时,由于下游服务的不可靠性。导致超时阻塞,
   服务雪崩,影响其它脚本。
3、其它第三方架构,包括之前用公司内部的一些脚本大师,都不甚好用。要么存在同步阻塞,要么时间粒度太粗,要么缺
   少好的监控。

问题理清楚后,需求也就很清晰了:

代码语言:javascript
复制
1、时间粒度精确到秒。

2、有监控脚本,各脚本运行情况。

3、高性能,多任务同时在跑,不会相互影响。

表简单设计如下:

代码语言:sql
复制
CREATE TABLE `task` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `task_desc` varchar(256) NOT NULL COMMENT '任务描述',
  `task_name` varchar(128) NOT NULL COMMENT '任务名称,对应控制器',
  `task_crontab` varchar(128) NOT NULL COMMENT '每隔多久执行一次',
  `task_status` tinyint(4) NOT NULL DEFAULT '-1' COMMENT '-1未启用,0等待下次执行,1执行中',
  `runnings` smallint(6) NOT NULL DEFAULT '0' COMMENT '正在执行的进程数',
  `is_multy` tinyint(4) NOT NULL DEFAULT '0' COMMENT '1允许同时执行多个;0须等待上一次执行完才执行下一次,即使下次执行时间到。',
  `exec_times` int(11) NOT NULL DEFAULT '0' COMMENT '已累计执行次数',
  `err_times` int(11) NOT NULL DEFAULT '0' COMMENT '累计失败次数',
  `last_exec_time` datetime NOT NULL COMMENT '最后执行时间',
  `next_exec_time` datetime NOT NULL COMMENT '下一次准备执行时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='任务管理表'

例如下面添加了一条测试任务:

任务的名称对应脚本框架服务中有一个控制器,来处理脚本逻辑。

脚本服务的调度流程
脚本服务的调度流程

服务相关事项:

代码语言:javascript
复制
1、shell起多个task.sh进程去调脚本框架服务的main入口,脚本服务支持1w+qps/s,这里起多少个进程视情况定。
eg:#!/bin/bash
    while ((1));do
      exec main
    sleep 1
    done
2、用check_task.sh监控脚本task.sh是否运行。
    #!/bin/bash
    count=`ps aux|grep "task_idc"|grep -v 'grep'|wc -l`
    if [ $count -lt 1 ]; then
        echo `bash task_idc.sh 2>&1 &`
    fi
3、next_exec_time每个任务下一次执行时间,如果有任务这个时间小过了当前时间,所以有任务不健康,这里简单监控下。
    conn="mysql -h${HOSTNAME}  -P${PORT}  -u${USERNAME} -p${PASSWORD} ${DBNAME}"
    select_sql="select id,task_crontab,unix_timestamp(next_exec_time) from ${TABLENAME} where task_status>-1"
    ${conn} -s -e "${select_sql}">${FILE_PATH}
    IFS_OLD=${IFS}
    IFS=$'\n'
    NOWTIME=$(date +%s)
    IS_ALARM=0
    for line in `cat ${FILE_PATH}`
    do
        ID=$(echo ${line}|awk '{print $1}')
        SEC=$(echo ${line}|awk '{print $2}')
        TIME=$(echo ${line}|awk '{print $3}')
        if [ ${TIME} -lt $[ ${NOWTIME}-1800 ] ];then//时间可以自由定
                IS_ALARM=1
        fi
    done
    IFS=${IFS_OLD}
    if [ ${IS_ALARM} -eq 1 ];then
      //告警
    fi
4、脚本服务框架的本身是否运行的监控check_server.sh。

任务服务注意事项:

代码语言:javascript
复制
1、并发读取待执行任务,防止高并发时被读到同一条任务,利用MYSQL的DML的原子性保证。
2、拉待执行任务的时候,非超级任务,不可拉执行中的,超级任务才可以拉执行中,因为只有超级任务定义为,不需要等待上一
   次执行完,才执行下一次。
3、结束单条任务的时候,同样需要注意超级任务与非超级任务的区别来决定 runnings 和 status 的状态。

这套脚本服务主要用于php执行业务相关逻辑,当然php也可以运行shell脚本,但不支持python等其它一些语言的脚本调用。并没有高大尚的技术,充分发挥了swoole+php的性能,有更好的脚本框架的开发者,欢迎一起交流进步 ^ ^

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文档服务
文档服务(Document Service,DS)是腾讯云数据万象提供云上文档处理服务,支持多种类型的文件生成图片或 html 格式的预览,可以解决文档内容的页面展示问题,满足 PC、App 等多端的文档在线浏览需求。同时,本产品还提供文本隐私筛查能力,可以有效识别文本中的身份证号、银行卡号、手机号等敏感数据,满足数据可用性和隐私保护的各种要求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档