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

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

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

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

举例:

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

<?php
sleep();
?>

添加计划任务:

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

等待执行,发生堆积

root       0.0  0.0      ?        Ss   :   : /bin/sh -c cd /home/ganjincheng;php test.php
root 0.0 0.0 ? S : : php test.php
root 0.0 0.0 ? Ss : : /bin/sh -c cd /home/ganjincheng;php test.php
root 0.1 0.0 ? S : : php test.php
root 0.0 0.0 pts/ S+ : : 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(); unlink($lockfile);
?>

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

第二种,数据库控制并发

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

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

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

举例:

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

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

第四种,使用linux的flock命令

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

[root@qkzj_Multi-Purpose_1A_113.107.248. ganjincheng]# flock -h
flock (util-linux-ng 2.17.)
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

配置举例:

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

crond脚本执行并发冲突问题的更多相关文章

  1. 使用并发 ssh 连接来提升捞日志脚本执行效率

    问题背景 公司有个简单粗暴的日志服务,它部署在多台机器实例上,收集的日志记录在每台机器本地硬盘,写一个小时自动切换日志文件,硬盘空间写满了自动回卷,大约可以保存两三天的历史数据.为什么说它粗暴呢?原来 ...

  2. 分布式缓存重建并发冲突和zookeeper分布式锁解决方案

    如果缓存服务在本地的ehcache中都读取不到数据. 这个时候就意味着,需要重新到源头的服务中去拉去数据,拉取到数据之后,赶紧先给nginx的请求返回,同时将数据写入ehcache和redis中 分布 ...

  3. crond不执行原因分析

    自己写了个脚本,让crond来周期性执行脚本进行备份,但是在crontab -e里面加入了执行脚本之后,发现没有执行,后来分析了一下,crond不执行的原因主要有以下几个方面: 1.crond服务没启 ...

  4. Mego开发文档 - 处理并发冲突

    处理并发冲突 数据库并发是指多个进程或用户同时访问或更改数据库中的相同数据的情况.并发控制是指用于确保存在并发更改时数据一致性的特定机制. Mego实现了乐观并发控制,这意味着它可以让多个进程或用户独 ...

  5. asp.net core 系列之并发冲突

    本文介绍如何处理多个用户并发更新同一实体(同时)时出现的冲突 . 主要是两种:一种,检查属性并发冲突,使用 [ConcurrencyCheck] ;另一种,检测行的并发冲突,使用 rowversion ...

  6. MySQL事物(一)事务隔离级别和事物并发冲突

    数据库的操作通常为写和读,就是所说的CRUD:增加(Create).读取(Read).更新(Update)和删除(Delete).事务就是一件完整要做的事情.事务是恢复和并发控制的基本单位.事务必须始 ...

  7. Linq to Sql并发冲突及处理策略

    0. 并发冲突的示例 单用户的系统现在应该比较罕见了,一般系统都会有很多用户在同时进行操作:在多用户系统中,涉及到的一个普遍问题:当多个用户“同时”更新(修改或者删除)同一条记录时,该如何更新呢?   ...

  8. Shell 脚本进程并发&进程数控制

    Shell 都以串行的方式自上而下执行命令,不适用需要大量作业的场景. 学习此篇shell脚本进程并发,能够大大提高工作效率~ 通过wait 和 & 后台符号 可以实现并行,但无法控制进程数. ...

  9. Elasticsearch由浅入深(四)ES并发冲突、悲观锁与乐观锁、_version乐观锁并发

    ES并发冲突 举个例子,比如是电商场景下,假设说,我们有个程序,工作的流程是这样子的: 读取商品信息(包含了商品库存) 用户下单购买 更新商品信息(主要是将库存减1) 我们比如咱们的程序就是多线程的, ...

随机推荐

  1. mpg123解码相关

    int attribute_align_arg mpg123_decode(mpg123_handle *mh, const unsigned char *inmemory, size_t inmem ...

  2. sql日期查询

    select getdate() ,getdate()) ,getdate()) ) ,getdate())) ,getdate())) Select datename(weekday, getdat ...

  3. WeakHashMap, NOT A CACHE

    Overview Base Map的实现 基于WeakReference的Entity实现 基于Reference和ReferenceQueue实现 它的弱引用是键,而不是值 它的key会被全自动回收 ...

  4. linux之badblocks命令

    简介 该命令用来检测硬盘坏道.硬盘坏道问题,如忽视,会随着使用而扩大面积,严重损坏硬盘.一般采用检测坏道,进而屏蔽重分区的方式复用硬盘. 语法 badblock(选项)(参数) -b<区块大小& ...

  5. [Selenium] 在Grid模式下打印出当前Case是在哪台Node上运行

    AAAbstractFlow() public void getComputerNameOfNode(WebDriver driver){ String CIHub = Environment.get ...

  6. MySQL 系列(二)Jdbc

    MySQL 系列(二)Jdbc 一.Jdbc 基本操作 import java.sql.Connection; import java.sql.DriverManager; import java.s ...

  7. Photoshop AI插件

    文字识别 图像识别 图像分割 Photoshop插件有哪些? 有哪些可用的数据集?

  8. 创建 Android 项目

    创建 Android 项目 上一页下一页 您也应该阅读 项目概览 本课向您介绍如何使用 Android Studio 创建新的 Android 项目并介绍该项目中的一些文件. 在 Android St ...

  9. Ubuntu的常识使用了解4

    寻找文件的「名称」 在Linux系统当中,文件的数量非常非常的多, 需要使用查找工具来高效查找指定文件位置:

  10. java中父类的静态方法不能被重写

    Java中父类的静态方法确实不能被重写的,但是有的人可能去做实验发现在子类中去重写父类static方法时,并没什么问题.这里我来具体解释下. public class Parent { public ...