主页/WordPress笔记/博客文章/开发文章/WordPress开发并发方案推荐

WordPress开发并发方案推荐

要实现并发执行(即即使上一次任务未完成,下一次任务也能按时启动),WordPress的内置定时任务无法满足需求。以下是几种可行的并发解决方案:


方案一:使用操作系统级Cron + HTTP请求(推荐)

原理:通过系统Cron直接触发HTTP请求,每次请求都是独立的PHP进程。

步骤:

  1. 创建触发端点(在主题的functions.php或插件中):
// 注册REST API端点
add_action('rest_api_init', function() {
    register_rest_route('concurrent/v1', '/run-a', [
        'methods'  => 'GET',
        'callback' => 'a_function',
        'permission_callback' => function() {
            // 安全验证:检查密钥
            return $_GET['key'] === 'YOUR_SECRET_KEY';
        }
    ]);
});

// 需要并发的函数
function a_function() {
    // 模拟耗时操作(超过10秒)
    sleep(15);
    error_log("[并发执行] 完成于: " . date('H:i:s'));
}
  1. 配置系统Cron(每10秒触发一次):
* * * * * curl "http://yoursite.com/wp-json/concurrent/v1/run-a?key=YOUR_SECRET_KEY"
* * * * * sleep 10; curl "http://yoursite.com/wp-json/concurrent/v1/run-a?key=YOUR_SECRET_KEY"

方案二:PHP多进程(pcntl扩展)

适用场景:命令行环境,需服务器支持pcntl扩展。

// 在独立PHP脚本中(例如:/path/to/concurrent.php)
function a_function() {
    sleep(15);
    file_put_contents('log.txt', '['.date('H:i:s').'] 完成'.PHP_EOL, FILE_APPEND);
}

// 主循环
while (true) {
    $pid = pcntl_fork();

    if ($pid == -1) {
        die('无法创建子进程');
    } elseif ($pid) {
        // 父进程:等待10秒后继续
        sleep(10);
    } else {
        // 子进程:执行任务
        a_function();
        exit; // 子进程结束
    }
}

启动方式

nohup php /path/to/concurrent.php > /dev/null &

方案三:消息队列(RabbitMQ + WP后台处理)

架构

WordPress → 发布任务 → RabbitMQ → 后台Worker(并发消费)
  1. 安装依赖
composer require php-amqplib/php-amqplib
  1. 发布任务(在WordPress中):
// 每10秒发布一次任务
function schedule_a_function() {
    require_once('vendor/autoload.php');

    $connection = new \PhpAmqpLib\Connection\AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
    $channel = $connection->channel();
    $channel->queue_declare('a_function_queue', false, true, false, false);

    $msg = new \PhpAmqpLib\Message\AMQPMessage('run');
    $channel->basic_publish($msg, '', 'a_function_queue');

    $channel->close();
    $connection->close();
}
// 通过WP-Cron或系统Cron调用 schedule_a_function
  1. Worker脚本(独立PHP进程):
// worker.php
require_once('vendor/autoload.php');

$connection = new \PhpAmqpLib\Connection\AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();

$callback = function ($msg) {
    a_function(); // 执行实际任务
    $msg->ack();
};

$channel->basic_qos(null, 5, null); // 并发5个进程
$channel->basic_consume('a_function_queue', '', false, false, false, false, $callback);

while (count($channel->callbacks)) {
    $channel->wait();
}

启动多个Worker

# 启动5个并发Worker
for i in {1..5}; do
    nohup php worker.php > /dev/null &
done

方案对比

方案并发能力复杂度可靠性适用场景
系统Cron + HTTP★★★★★★★★★通用场景,需服务器权限
PHP多进程(pcntl)★★★★★★★★★命令行环境,需pcntl扩展
消息队列(RabbitMQ)★★★★★★★★★★★★★★高并发、分布式系统
WordPress内置定时任务★★非并发场景(默认方案不支持)

关键注意事项

  1. 资源控制
  • 设置最大并发数(如通过Cron的sem或队列的prefetch_count
  • 监控服务器负载(避免进程堆积)
  1. 错误处理
   // 示例:捕获异常并记录
   try {
       a_function();
   } catch (Exception $e) {
       error_log('任务失败: ' . $e->getMessage());
   }
  1. 安全措施
  • HTTP端点必须验证密钥
  • 消息队列使用VPN/私有网络
  • 限制Cron任务的IP访问

对于大多数WordPress站点,方案一(系统Cron + HTTP端点) 是最佳平衡点,兼顾实现简单性和并发能力。若需企业级解决方案,推荐使用消息队列。