php - 当我使用 Linux task-crontab 时如何同时解决多个问题
问题描述
这里有一个问题:我需要执行一个任务,每分钟将许多数据放入另一个 mysql 数据库;如果第一个任务尚未完成,则第二个任务开始;因此,存在多个并发问题;如何解决问题?
我有一些想法,第一,让任务的执行时间小于下一个任务的开始时间;第二,让任务支持多进程;但是,我不知道如何编写代码?
public function execute(Input $input, Output $output)
{
$tele_data = Telesales::field('*')->where([['create_time','<',time()-48*3600],['customer_label','in',[2,6,7]],['virtual_sale','=','0']])->whereRaw('phone is not null')->select()->toArray();
foreach($tele_data as $key=>$value) {
static::pushTeleToIdc($value);
}
}
private static function pushTeleToIdc($data = []) {
$res = Telesales::where('id',$value['id'])->update(['virtual_sale'=>'1']);
if(!$res) {
return;
}
$url = config('idc.tele_url');
$key = config('idc.tele_key');
$channel = config('idc.tele_channel');
$time = time();
$sign = md5($key.$channel.$time);
$urls = $url."?channel=".$channel."&sign=".$sign."&time=".$time;
$require_params = config('idc.require_params');
foreach($require_params as $key=>$value) {
if(array_key_exists($key,$data) && !empty($data[$key])) {
$d[$key] = $data[$key];
}else{
$d[$key] = empty($value)?'':$value[array_rand($value,1)];
}
}
$d['register_time'] = $d['create_time'];
$res = post_url($urls,$d);
$result = json_decode($res,true);
if (isset($result['code']) && $result['code'] != 0){
Log::init(['single'=>'tpushidc'])->error($res);
}
}
你能帮我解决问题吗?
解决方案
最简单的做法是设置一个标志来告知进程已经在进行中,并在函数开始时检查是否是这种情况。我不知道你想如何设置代码的可见性,所以我留给你将 $myFile 提取到文件/类范围(文件路径也是如此,你可能想要使用一些 /var 或 /这些东西的日志文件夹)。
所以要点是:我们创建一个文件,如果它不存在或其中有一个 0 - 这意味着我们可以开始工作。另一方面,如果文件的内容为 1,则进程会死掉,每次运行它都会死掉,直到第一个完成并将文件的内容重写为 0(这意味着进程不在进步了)。
public function execute(Input $input, Output $output)
{
if ($this->isProcessInProgress()) {
die('Process is in progress');
}
$this->startProcess();
$tele_data = [...];
foreach($tele_data as $key=>$value) {
static::pushTeleToIdc($value);
}
$this->finishProcess();
}
private function isProcessInProgress() {
$myFile = 'tele_to_idc_process.txt';
$handle = fopen($myFile, 'r');
if (!$handle)
return false;
$status = fread($handle, 1);
fclose($handle);
return (bool) $status;
}
private function startProcess() {
$myFile = 'tele_to_idc_process.txt';
$handle = fopen($myFile, 'w');
if (!$handle)
return;
$status = fwrite($handle, '1');
fclose($handle);
}
private function finishProcess() {
$myFile = 'tele_to_idc_process.txt';
$handle = fopen($myFile, 'w');
if (!$handle)
return;
$status = fwrite($handle, '0');
fclose($handle);
}
如果文件不存在,您可能会收到警告,您可以使用 @fopen 而不是 fopen 来禁止它
推荐阅读
- java - 运行 jdbc 程序时线程“主”java.sql.SQLException 中的异常?
- mongodb - MongoDb 关闭 - 缺少索引文件
- sql - 如何替换 SQL 查询中的字符串
- webassembly - Web 程序集二进制文件会小于 JavaScript/TypeScript 包吗?
- c# - 删除 dotnet 应用程序中的 kubernetes pod
- c# - 已检索数据但未保存或更新 ASP.NET Core 3.1
- angular - 离子电容相机,生成全画质图像并显示,无需生成Base64和DataUri
- javascript - 基于所选儿童数量的动态年龄字段
- python - sqlite3.programmingerror 提供的绑定数量不正确。当前语句使用 1 并且提供了 15
- python - 如何在一行打印语句中的 for 循环中的多个值?