我开发了一个网络服务 (PHP/MySQL),它通过 JSON 字符串简单地输出优惠券代码。
工作原理:应用程序收到 1 个参数(电子邮件),然后向数据库表发出请求以获取尚未分配的优惠券代码。然后请求更新此优惠券代码的行并将 “1” 放入分配的列中。 (SELECT/UPDATE例程)
之后输出的JSON是这样的:
echo '{"couponCode": "'. $coupon_code . '"}';
就这些。
问题是网络服务在大约 1 分钟内收到 10000 个请求。这种情况一天只发生一次。如果我查看 apache 的原始日志,我可以看到它每次都收到了 10000 个请求,但在我的表中只有 984 行已更新(即:给出了 984 个优惠券代码)。我测试了很多次,每次都在 980 到 986 之间变化。 Web 服务创建的日志文件没有显示任何错误,并准确反射(reflect)了数据库中已更新的内容,每次在 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;
}
}
提前致谢。
最佳答案
每分钟 986 个请求对于您设计的 PHP 应用程序和 Apache Web 服务器来说是一个相当大的负载。听起来您是在一台服务器上运行这一切。
首先,无论什么东西每分钟敲打你 10k 次,都应该知道如果失败了稍后重试。为什么没有发生这种情况?如果该远程系统在您的控制之下,看看您是否可以修复它。
接下来,您会发现 Nginx 的线程模型比 Apache 的线程模型更高效。
现在,开始您的应用程序……您似乎并不需要先执行 SELECT
然后再执行 UPDATE
。为什么不只是更新并检查结果?然后它本身就是原子的,你不必做这个表锁定的东西(这真的会减慢你的速度)。
关于php webservice不能同时处理多个请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25898511/