任务调度php
① 【协程】php yield关键词和协程的实现(二)
协程是一种编程逻辑的转变,使多个任务能交替运行,而不是按流程顺序执行。例如,当你有一个逻辑,每次调用这个文件时需要执行3个任务:写入300个文件、发送邮件给500个会员和插入100条数据。可以实现这3个功能,但问题是如何改成交替运行,即写入文件一次之后,马上去发送邮件,然后再去插入一条数据。代码1实现了这3个功能,但代码可读性差,扩展性也很差。
这时候我们就必须借助yield了。首先,我们得封装一个任务类,这个封装类可以更好地调用运行生成器函数,但只有这个还不够,我们还需要一个调度任务类来代替while循环。有了调度类和任务类,可以继续实现上面的功能。除了上面的两个类,task函数和代码1不同的地方就是多了个yield。运行代码,我们实现了可以调度任务,进行任务交叉运行的功能,这就是"协程"。
协程可以将多个不同的任务交叉运行。除了实现基本的调度功能,还需要解决任务和调度器之间的通信问题。我们封装了一个调用的封装类,同时在调度器的run方法中新增了一个返回当前任务id的函数。接着,修改了task1、task2、task3函数,让它们可以通过task_id获取调度器的信息。执行结果,当第一次执行时,会先调用getTaskId获取task_id,然后继续执行任务,这样我们就获取到了调度器分配给任务的task_id。
如果新增一个需求,比如在发送邮件时需要新增一个发送短信的子任务,当会员id大于200时则停止。这时,我们可以利用yieldCall来新增任务和杀死任务。同时,调度器Scheler类也需要有killTask的方法。有了新增和删除任务的功能,我们重新编写了task2以及新增了task4。
总结来说,协程只是一种编程逻辑,一种写代码的技巧。它帮助我们更好地切换代码中的任务。从上面的例子不难发现,其实协程的实现封装较为麻烦,并且在不需要协程的情况下也能实现这些功能。但为什么还要用协程呢?因为协程可以让代码更加简洁,任务相互之间独立区分开,使代码更加清爽。协程让我们可以更好地控制切换任务流。在一些特定场景下,如JS AJAX,协程能实现异步处理,提高效率,让CPU在等待IO操作时处理其他任务,实现更高效的任务调度。
② PHP线程安全与非线程安全的区别:如何选择用哪一个
首先,linux下的PHP,没有线程安全版和非线程安全版之分。从2000年10月20日发布的第一个Windows版的PHP3.0.17开始的都是线程安全的版本,直至5.2.1版本开始有Thread Safe(TS,线程安全)和None Thread Safe(NTS,非线程安全)之分。
因为,Linux/Unix系统采用的是多进程的工作方式,而Windows系统采用多线程的工作方式。即:Linux系统的任务调度基本单位是进程,Windows系统的任务调度基本单位是线程(本观点来自自学与总结,不能保证百分之百正确)。
所以,在Windows系统的IIS下以CGI方式运行PHP会非常慢,这是由于CGI模式是建立在多进程的基础之上的,而非多线程,且CGI模式对于每个HTTP请求都需要重新加载和卸载整个PHP环境,其消耗是巨大的。
于是,一般我们会把PHP配置成以ISAPI的方式来运行,ISAPI是多线程的方式,这样就快多了。但存在一个问题,很多常用的PHP扩展是以 Linux/Unix的多进程思想来开发的,这些扩展在ISAPI的方式运行时就会出错搞垮IIS。
为了兼顾IIS下PHP的效率和安全,微软给出了FastCGI的解决方案。FastCGI可以让PHP的进程重复利用,而不是每一个新的请求就重开一个进程。同时FastCGI也可以允许几个进程同时执行。这样既解决了CGI进程模式消耗太大的问题,又利用上了CGI进程模式不存在线程安全问题的优势。
因此,如果是使用ISAPI的方式来运行PHP就必须用Thread Safe(TS,线程安全)的版本;而用FastCGI模式运行PHP的话就没有必要用线程安全检查了,用None Thread Safe(NTS,非线程安全)的版本能够更好的提高效率。
名词解析:
IIS:Internet Information Services (互联网信息服务),是由微软公司提供的基于运行Microsoft Windows的互联网基本服务
CGI:Common Gateway Interface (通用网关接口),是外部应用程序(CGI程序)与Web服务器之间的接口标准
ISAPI:Internet Server Application Programming Interface (互联网应用程序接口),是为Microsoft所提的Internet server的API
FastCGI:CGI存在收到每个请求时都开辟一个进程等不足,FastCGI可以理解为是征对CGI的改进版
③ php如何每天定时执行
php做不到每天定时执行,只有java或者c可以,因为php是不访问页面就不会动得代码,但是有一个方法可以曲线救国
你写一个页面是你要每天定时执行的页面,然后视你的操作系统而言,做定时任务,定时去访问这个页面
如果是windows请使用任务计划功能
如果是linux请使用定时任务Cron,在定时的时候使用curl来访问你那个页面。以下我只贴出linux的解决方案,因为一般服务器都是linux的,windows的大家都会
=========================linux cron 入门 ============================
Linux操作系统定时任务系统 Cron 入门
cron是一个linux下的定时执行工具,可以在无需人工干预的情况下运行作业。由于Cron 是Linux的内置服务,但它不自动起来,可以用以下的方法启动、关闭这个服务:
/sbin/service crond start //启动服务
/sbin/service crond stop //关闭服务
/sbin/service crond restart //重启服务
/sbin/service crond reload //重新载入配置
你也可以将这个服务在系统启动的时候自动启动:
在/etc/rc.d/rc.local这个脚本的末尾加上:
/sbin/service crond start
现在Cron这个服务已经在进程里面了,我们就可以用这个服务了,Cron服务提供以下几种接口供大家使用:
1.直接用crontab命令编辑
cron服务提供crontab命令来设定cron服务的,以下是这个命令的一些参数与说明:
crontab -u //设定某个用户的cron服务,一般root用户在执行这个命令的时候需要此参数
crontab -l //列出某个用户cron服务的详细内容
crontab -r //删除没个用户的cron服务
crontab -e //编辑某个用户的cron服务
比如说root查看自己的cron设置:crontab -u root -l
再例如,root想删除fred的cron设置:crontab -u fred -r
在编辑cron服务时,编辑的内容有一些格式和约定,输入:crontab -u root -e
进入vi编辑模式,编辑的内容一定要符合下面的格式:*/1 * * * * ls >> /tmp/ls.txt
任务调度的crond常驻命令
crond 是linux用来定期执行程序的命令。当安装完成操作系统之后,默认便会启动此任务调度命令。crond命令每分锺会定期检查是否有要执行的工作,如果有要执行的工作便会自动执行该工作。
1、linux任务调度的工作主要分为以下两类:
*系统执行的工作:系统周期性所要执行的工作,如备份系统数据、清理缓存
*个人执行的工作:某个用户定期要做的工作,例如每隔10分钟检查邮件服务器是否有新信,这些工作可由每个用户自行设置。
2.crontab命令选项:
-u指定一个用户,
-l列出某个用户的任务计划,
-r删除某个用户的任务,
-e编辑某个用户的任务
3.cron文件语法:
分 小时 日 月 星期 命令
0-59 0-23 1-31 1-12 0-6 command (取值范围,0表示周日一般一行对应一个任务)
4.记住几个特殊符号的含义:
"*"代表取值范围内的数字,
"/"代表"每",
"-"代表从某个数字到某个数字,
","分开几个离散的数字
一、任务调度设置文件的写法
可用crontab -e命令来编辑,编辑的是/var/spool/cron下对应用户的cron文件,也可以直接修改/etc/crontab文件
具体格式如下:
Minute Hour Day Month Dayofweek command
分钟 小时 天 月 天每星期 命令
每个字段代表的含义如下:
Minute 每个小时的第几分钟执行该任务
Hour 每天的第几个小时执行该任务
Day 每月的第几天执行该任务
Month 每年的第几个月执行该任务
DayOfWeek 每周的第几天执行该任务
Command 指定要执行的程序
在这些字段里,除了“Command”是每次都必须指定的字段以外,其它字段皆为可选字段,可视需要决定。对于不指定的字段,要用“*”来填补其位置。
举例如下:
5 * * * * ls 指定每小时的第5分钟执行一次ls命令
30 5 * * * ls 指定每天的 5:30 执行ls命令
30 7 8 * * ls 指定每月8号的7:30分执行ls命令
30 5 8 6 * ls 指定每年的6月8日5:30执行ls命令
30 6 * * 0 ls 指定每星期日的6:30执行ls命令[注:0表示星期天,1表示星期1,以此类推,也可以用英文来表示,sun表示星期天,mon表示星期一等。]
30 3 10,20 * * ls 每月10号及20号的3:30执行ls命令[注:“,”用来连接多个不连续的时段]
25 8-11 * * * ls 每天8-11点的第25分钟执行ls命令[注:“-”用来连接连续的时段]
*/15 * * * * ls 每15分钟执行一次ls命令 [即每个小时的第0 15 30 45 60分钟执行ls命令 ]
30 6 */10 * * ls 每个月中,每隔10天6:30执行一次ls命令[即每月的1、11、21、31日是的6:30执行一次ls命令。 ]
每天7:50以root 身份执行/etc/cron.daily目录中的所有可执行文件
50 7 * * * root run-parts /etc/cron.daily [ 注:run-parts参数表示,执行后面目录中的所有可执行文件。 ]
二、新增调度任务
新增调度任务可用两种方法:
1、在命令行输入: crontab -e 然后添加相应的任务,wq存盘退出。
2、直接编辑/etc/crontab 文件,即vi /etc/crontab,添加相应的任务。
三、查看调度任务
crontab -l //列出当前的所有调度任务
crontab -l -u jp //列出用户jp的所有调度任务
四、删除任务调度工作
crontab -r //删除所有任务调度工作
五、任务调度执行结果的转向
例1:每天5:30执行ls命令,并把结果输出到/jp/test文件中
30 5 * * * ls >/jp/test 2>&1
注:2>&1 表示执行结果及错误信息。
编辑/etc/crontab 文件配置cron
cron服务每分钟不仅要读一次/var/spool/cron内的所有文件,还需要读一次/etc/crontab,因此我们配置这个文件也能运用cron服务做一些事情。用crontab配置是针对某个用户的,而编辑/etc/crontab是针对系统的任务。此文件的文件格式是:
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root //如果出现错误,或者有数据输出,数据作为邮件发给这个帐号
HOME=/ //使用者运行的路径,这里是根目录
# run-parts
01 * * * * root run-parts /etc/cron.hourly //每小时执行/etc/cron.hourly内的脚本
02 4 * * * root run-parts /etc/cron.daily //每天执行/etc/cron.daily内的脚本
22 4 * * 0 root run-parts /etc/cron.weekly //每星期执行/etc/cron.weekly内的脚本
42 4 1 * * root run-parts /etc/cron.monthly //每月去执行/etc/cron.monthly内的脚本
大家注意"run-parts"这个参数了,如果去掉这个参数的话,后面就可以写要运行的某个脚本名,而不是文件夹名了
例如: 1、在命令行输入: crontab -e 然后添加相应的任务,wq存盘退出。
2、直接编辑/etc/crontab 文件,即vi /etc/crontab,添加相应的任务
11 2 21 10 * rm -rf /mnt/fb
④ Docker容器里配置计划任务 crontab(DaoCloud+Docker +Laravel5)
深入研究了crontab的使用方法后,在自己电脑上成功实现定时任务功能。通过命令执行,添加crontab配置,实现每分钟执行特定命令,成功开启Laravel的任务调度。
尝试将crontab配置集成到Docker容器中,自动在容器启动时执行任务。具体步骤包括:
在项目中创建crontab配置文件
将配置文件复制到Docker容器内的指定目录
编写entrypoint.sh脚本,启动容器内的Apache服务与crontab
使用php:7.0.7-apache基础镜像,该镜像内已具备CMD指令用于启动Apache服务,但需增加脚本以同时启动Apache与crontab。确保容器内环境变量正确加载,以便在执行php artisan schele:run命令时获取应用配置,避免执行错误。
构建与运行Laravel5应用所需的Docker文件、crontab配置文件与entrypoint.sh脚本已经完成,能够满足大部分需求。此配置方法适用于希望在Docker容器内执行定时任务的开发者。
为帮助进阶开发者的技能提升,整理了一份包含分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6、laravel、YII2、Redis、Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点的高级进阶干货资料,有需求者可加入官方群获取。