【问题标题】:php webservice doesn't handle multiple requests at the same timephp webservice不会同时处理多个请求
【发布时间】:2014-09-18 03:30:07
【问题描述】:

我开发了一个 web 服务 (PHP/MySQL),它通过 JSON 字符串简单地输出优惠券代码。

工作原理: 应用程序接收 1 个参数(电子邮件),然后向数据库表发出请求以获取尚未分配的优惠券代码。然后请求更新此优惠券代码的行并将“1”放入指定的列。 (选择/更新例程)

之后,JSON 输出如下:

echo '{"couponCode": "'. $coupon_code . '"}';

就是这样。

问题是 web 服务在大约 1 分钟内收到 10000 个请求。这一天只发生一次。如果我查看 apache 的原始日志,我可以看到它每次都收到 10000 个请求,但在我的表中只有 984 行已更新(即:提供 984 个优惠券代码)。我多次测试它,每次都在 980 到 986 之间变化。由 web 服务创建的日志文件没有显示任何错误,并且准确地反映了数据库中已更新的内容,每次更新在 980 到 986 行之间。

我的问题是:丢失的请求是怎么回事?是服务器内存不足,无法在这么短的时间内处理如此多的请求吗? (当我使用 5000 个请求进行测试时,它工作正常)

如果有帮助,这里是获取新优惠券代码的功能:

function getNewCouponCode($email){

$stmt = $this->connector->prepare("SELECT * FROM coupon_code WHERE email = '' ORDER BY id ASC LIMIT 1");
$stmt2 = $this->connector->prepare("UPDATE coupon_code SET email = :email WHERE id = :id");

try{

    $this->connector->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $this->connector->beginTransaction();
    $this->connector->exec("LOCK TABLES coupon_code WRITE");

    /*TRANSACTION 1*/
    $stmt->execute();
    $result["select"] = $stmt->fetch(PDO::FETCH_ASSOC);
    /*TRANSACTION 1*/

    /*TRANSACTION 2*/
    $stmt2->bindParam(":email", $email);
    $stmt2->bindParam(":id", $result["select"]["id"]);
    $result["update"] = $stmt2->execute();
    /*TRANSACTION 2*/

    $this->connector->commit();
    $this->connector->exec('UNLOCK TABLES');

    return $result;

}catch(Exception $e) {
    $this->connector->rollBack();
    $this->connector->exec('UNLOCK TABLES');
    $result["error"] = $e->getMessage();
    return $result;
}

}

提前致谢。

【问题讨论】:

    标签: php mysql apache web-services


    【解决方案1】:

    每分钟 986 个请求对于您设计的 PHP 应用程序和 Apache Web 服务器来说是一个相当大的负载。听起来您是在一台服务器上运行这一切。

    首先,无论是每分钟 10k 次猛击你的东西,都应该知道如果失败,稍后重试。为什么没有发生这种情况?如果那个远程系统在你的控制之下,看看你能不能修复它。

    接下来,您会发现 Nginx 的线程模型比 Apache 的线程模型更高效。

    现在,开始您的应用程序...看起来您实际上不需要SELECTUPDATE。为什么不只是更新,并检查结果?然后它本身就是原子的,你不必做这个表锁定的东西(这真的会减慢你的速度)。

    【讨论】:

    • 是的,它在单个服务器上运行。不,远程系统不在我的控制之下,但如果出现故障,我会询问是否有任何方法可以重试。我一定会看看 Nginx 的线程模型。我只尝试了UPDATE,但是这样一来,相同的优惠券代码经常被分配给不同的电子邮件......
    • @LeoStein 如果您的查询正确,那应该是不可能的。 UPDATE coupon_code SET email = :email WHERE email='' LIMIT 1 而且,无论如何,当您进行代码更改时,您绝对应该拥有第二台服务器。
    • 你是对的,它看起来像 UPDATE 只能工作。所以我想我的问题没有简单的解决方法,添加第二台服务器以实现冗余需要技能,不幸的是,我没有! Nginx 看起来你也需要具备服务器管理员知识才能玩......无论如何,谢谢你的时间。
    • @LeoStein 这实际上是一个非常简单的解决方案。更改为仅更新,事情将大大加快。安装 Nginx 和 PHP-FPM ......有很多教程。我建议一个,但我不知道你使用的是什么操作系统。无论如何,请按照教程进行操作,您将在半小时内启动并运行。当您将 Nginx 放在前面进行负载平衡时,添加辅助服务器变得很容易。由于您的大部分负载无论如何都是基于应用程序的,您可以将 Nginx 配置为通过一行配置在多台服务器上使用 PHP-FPM。一步一步,会更清晰。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-27
    • 2013-10-18
    • 2018-02-23
    • 1970-01-01
    • 2015-03-12
    相关资源
    最近更新 更多