首页 > 其他分享 >crond脚本执行并发冲突问题

crond脚本执行并发冲突问题

时间:2022-11-30 12:08:08浏览次数:48  
标签:-- 0.0 并发 冲突 lock test flock php crond

在计划任务中,偶尔会看到重复执行的情况:

例如我们公司的计划任务举例:

*/2 * * * * root cd /opt/xxxx/test_S1/html/xxxx/admin; php index.php task testOne >/dev/null 2>&1
*/2 * * * * root cd /opt/xxxx/test_S1/html/xxxx/admin; php index.php task testTwo >/dev/null 2>&1

这是两分钟执行一次的任务,并不能保证每次开启的进程能够在两分钟内绝对的执行完毕关闭,进程一直堆积的话,可能会把系统资源给耗尽,导致系统宕机。

举例:

新建test.php文件,代码如下:

<?php
sleep(70);
?>

添加计划任务:

*/1 * * * * root cd /home/ganjincheng;php test.php

等待执行,发生堆积

root     26722  0.0  0.0   9232  1064 ?        Ss   12:05   0:00 /bin/sh -c cd /home/ganjincheng;php test.php
root 26744 0.0 0.0 112304 8840 ? S 12:05 0:00 php test.php
root 29102 0.0 0.0 9232 1060 ? Ss 12:06 0:00 /bin/sh -c cd /home/ganjincheng;php test.php
root 29116 0.1 0.0 112304 8840 ? S 12:06 0:00 php test.php
root 29906 0.0 0.0 103320 904 pts/3 S+ 12:06 0:00 grep test.php

解决方案

第一种,代码中控制并发

这种方法,就是对代码进行改造。增加是否有进程执行的判断。如下面的代码:

<?php  
$lockfile = '/tmp/mytest.lock';

if(file_exists($lockfile)){
exit();
}
file_put_contents($lockfile, date("Y-m-d H:i:s"));

sleep(70);

unlink($lockfile);
?>

这种判断文件是否不存在的方式,会有一个问题。那就是有可能程序未执行到最后,也就是没有删除之前创建的mytest.lock文件。这会导致,之后程序将不能正常执行。

第二种,数据库控制并发

可以将第一种方案转移到redis,memache中,进行键值判断。

如果计划任务是对数据库进行存取,那可以进行锁表操作。偶尔我们也可以利用唯一索引与联合索引的唯一性来避免重复插入情况

第三种,判断进程是否存在

举例:

$fp = popen("ps aux | grep 'test.php' | wc -l", "r");
$proc_num = fgets($fp);
if ($proc_num > 3) { //这里要注意为什么进程数要大于3,实际操作一遍你就明白了
exit;
}
sleep(70);

这种方式有一个弊端,就是ps命令要写的精确。避免把不是执行test.php脚本的进程也统计到。如:
我们通过vim打开test.php文件。就会导致上面命令误统计。所以当我们不小心vim打开test.php文件的时候,就执行不起来了。

第四种,使用linux的flock命令

让linux帮我们去判断啊,flock命令提供了文件锁的功能。命令参数如下:

[root@qkzj_Multi-Purpose_1A_113.107.248.124 ganjincheng]# flock -h
flock (util-linux-ng 2.17.2)
Usage: flock [-sxun][-w #] fd#
flock [-sxon][-w #] file [-c] command...
flock [-sxon][-w #] directory [-c] command...
-s --shared Get a shared lock
-x --exclusive Get an exclusive lock
-u --unlock Remove a lock
-n --nonblock Fail rather than wait
-w --timeout Wait for a limited amount of time
-o --close Close file descriptor before running command
-c --command Run a single command string through the shell
-h --help Display this text
-V --version Display version

配置举例:

*/1 * * * * root flock -xn /tmp/mytest.lock -c 'php ./test.php'

 

源码面前,了无秘密



标签:--,0.0,并发,冲突,lock,test,flock,php,crond
From: https://blog.51cto.com/zhenghongxin/5898185

相关文章

  • Spring Boot + @Async 太好用了,助你大大提升 API 并发能力!
    来源:https://developer.aliyun.com/article/694020异步调用几乎是处理高并发Web应用性能问题的万金油,那么什么是“异步调用”?“异步调用”对应的是“同步调用”,同步调用......
  • 集群环境下的并发问题
    通过加锁可以解决在单机情况下的一人一单安全问题,但是在集群模式下就不行了。有关锁失效原因分析由于现在我们部署了多个tomcat,每个tomcat都有一个属于自己的jvm,那么假设......
  • JAVA面试题--Java高并发
    Java高并发1.什么是进程2.什么是线程3.进程间如何通讯4.线程间如何通讯5.同步和异步有何不同,在什么情况下分别使用它们?举例说明6.进程调度算法7.Java中Unsafe类详......
  • 一招解决所有依赖冲突
    背景介绍最近遇到了这样一个问题,我们有一个jar包common-tool,作为基础工具包,被各个项目在引用。突然某一天发现日志很多报错。一看是NoSuchMethodError,意思是DisJun......
  • 《Go 语言并发之道》读书笔记(七)
    今天这篇笔记我们来学习Go限流限流是分布式系统中经常需要用到的技术,因为我们让请求没有限制,很容易就出现某个用户开很多线程把我们的服务拉跨,进而影响到别的用户。限流......
  • 如何在内网搭建SFTP服务器,并发布到公网可访问
    1.搭建SFTP服务器1.1下载freesshd服务器软件下载地址:freeSSHdandfreeFTPd选择freeFTPD.exe下载下载后,点击安装安装之后,它会提示是否启动后台服务,Yes安装后,点......
  • Go并发编程-context包
    作用context主要用来在goroutine之间传递上下文信息,包括:取消信号超时时间截止时间传值原理:contex接口Go里并没有直接为我们提供一个统一的context对象,而是......
  • Swift 2023:强调并发、泛型和 C++ 互操作性,开发 Swift 解析器
    AppleSwift团队的一名工程师兼语言工作组成员JohnMcCall在最新发布的一篇博客中介绍了Swift的2023年度计划。“Swift项目中有很多激动人心的工作正在进行,而且很......
  • 【Java并发入门】01 并发编程Bug的源头
    一、根本原因「CPU、内存、磁盘之间的速度差异」为了能同时执行多个任务,CPU发展出时间片轮转、多核等CPU要从内存中读数据太慢了,所以给自己设置了缓存CPU读磁盘更......
  • EasyNTS遇到IP冲突时,如何正确更改IP地址?
    在此前的文章中,我们分享过很多关于EasyNTS上云网关平台及硬件的技术性内容,感兴趣的用户可以翻阅往期的文章进行了解。EasyNTS具备内网穿透、组网运维、多协议视频流拉转推、......