iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >PHP并发场景的解决方案是什么
  • 613
分享到

PHP并发场景的解决方案是什么

2024-04-02 19:04:59 613人浏览 薄情痞子
摘要

本篇文章给大家分享的是有关PHP并发场景的解决方案是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。在秒杀,抢购等并发场景下,可能会出现超卖

本篇文章给大家分享的是有关PHP并发场景的解决方案是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

在秒杀,抢购等并发场景下,可能会出现超卖的现象,在php语言中并没有原生提供并发的解决方案,因此就需要借助其他方式来实现并发控制。

列出常见的解决方案有:

  • 使用队列,额外起一个进程处理队列,并发请求都放到队列中,由额外进程串行处理,并发问题就不存在了,但是要额外进程支持以及处理延迟严重,本文不先不讨论这种方法。利用数据库事务特征,做原子更新,此方法需要依赖数据库的事务特性。借助文件排他,在处理下单请求的时候,用flock锁定一个文件,成功拿到锁的才能处理订单。

  • 一、利用 Redis 事务特征

    Redis 事务是原子操作,可以保证订单处理的过程中数据没有被其它并发的进程修改。

    示例代码:

    <?php$Http = new swoole_http_server("0.0.0.0", 9509);  // 监听 9509 $http->set(array(  'Reactor_num' => 2, //reactor thread num  'worker_num' => 4  //worker process num)); $http->on('request', function (swoole_http_request $request, swoole_http_response $response) {  $uniqid = uniqid('uid-', TRUE);  // 模拟唯一用户ID  $redis = new Redis();  $redis->connect('127.0.0.1', 6379);  // 连接 redis   $redis->watch('rest_count'); // 监测 rest_count 是否被其它的进程更改   $rest_count = intval($redis->get("rest_count")); // 模拟唯一订单ID  if($rest_count > 0){    $value = "{$rest_count}-{$uniqid}"; // 表示当前订单,被当前用户抢到了     // do something ... 主要是模拟用户抢到单后可能要进行的一些密集运算    $rand = rand(100, 1000000);    $sum=0;    for ($i=0;$i<$rand;$i++){ $sum+=$i; }    // redis 事务    $redis->multi();    $redis->lPush('uniqids', $value);    $redis->decr('rest_count');    $replies = $redis->exec(); // 执行以上 redis 事务    // 如果 rest_count 的值被其它的并发进程更改了,以上事务将回滚    if(!$replies){      echo "订单 {$value} 回滚".PHP_EOL;    }  }  $redis->unwatch();}); $http->start();

使用 ab 测试

$ ab -t 20 -c 10 http://192.168.1.104:9509/

二、利用文件排他锁(阻塞模式)

阻塞模式下,如果进程在获取文件排他锁时,其它进程正在占用锁的话,此进程会挂起等待其它进程释放锁后,并自己获取到锁后,再往下执行。

示例代码:

<?php$http = new swoole_http_server("0.0.0.0", 9510); $http->set(array(  'reactor_num' => 2, //reactor thread num  'worker_num' => 4  //worker process num)); $http->on('request', function (swoole_http_request $request, swoole_http_response $response) {   $uniqid = uniqid('uid-', TRUE);  $redis = new Redis();  $redis->connect('127.0.0.1', 6379);   $fp = fopen("lock.txt", "w+");   // 阻塞(等待)模式, 要取得独占锁定(写入的程序)  if(flock($fp,LOCK_EX))  //锁定当前指针  {   // 成功取得锁后,放心处理订单    $rest_count = intval($redis->get("rest_count"));    $value = "{$rest_count}-{$uniqid}";    if($rest_count > 0){      // do something ...      $rand = rand(100, 1000000);      $sum=0;      for ($i=0;$i<$rand;$i++){ $sum+=$i; }       $redis->lPush('uniqids', $value);      $redis->decr('rest_count');    }    // 订单处理完成后,再释放锁    flock($fp,LOCK_UN);  }  fclose($fp); }); $http->start();

使用 ab 测试

$ ab -t 20 -c 10 http://192.168.1.104:9510/

三、利用文件排他锁(非阻塞模式)

非阻塞模式下,如果进程在获取文件排他锁时,其它进程正在占用锁的话,此进程会马上判断获取锁失败,并且继续往下执行。

示例代码:

<?php$http = new swoole_http_server("0.0.0.0", 9511); $http->set(array(  'reactor_num' => 2, //reactor thread num  'worker_num' => 4  //worker process num)); $http->on('request', function (swoole_http_request $request, swoole_http_response $response) {   $uniqid = uniqid('uid-', TRUE);  $redis = new Redis();  $redis->connect('127.0.0.1', 6379);   $fp = fopen("lock.txt", "w+");   // 非阻塞模式, 如果不希望 flock() 在锁定时堵塞,则给 lock 加上 LOCK_NB  if(flock($fp,LOCK_EX | LOCK_NB))  //锁定当前指针  {   // 成功取得锁后,放心处理订单    $rest_count = intval($redis->get("rest_count"));    $value = "{$rest_count}-{$uniqid}";    if($rest_count > 0){      // do something ...      $rand = rand(100, 1000000);      $sum=0;      for ($i=0;$i<$rand;$i++){ $sum+=$i; }       $redis->lPush('uniqids', $value);      $redis->decr('rest_count');    }    // 订单处理完成后,再释放锁    flock($fp,LOCK_UN);  } else {   // 如果获取锁失败,马上进入这里执行    echo "{$uniqid} - 系统繁忙,请稍后再试".PHP_EOL;  }  fclose($fp); }); $http->start();

使用 ab 测试

$ ab -t 20 -c 10 http://192.168.1.104:9511/

最后给出三种处理方式的测试结果比较

redis 事务方式:

......Concurrency Level:   10Time taken for tests:  20.005 secondsComplete requests:   17537Failed requests:    0Total transferred:   2578380 byteshtml transferred:    0 bytesRequests per second:  876.62 [#/sec] (mean)Time per request:    11.407 [ms] (mean)Time per request:    1.141 [ms] (mean, across all concurrent requests)Transfer rate:     125.86 [Kbytes/sec] received......

文件排他锁(阻塞模式):

......Concurrency Level:   10Time taken for tests:  20.003 secondsComplete requests:   8205Failed requests:    0Total transferred:   1206282 bytesHTML transferred:    0 bytesRequests per second:  410.19 [#/sec] (mean)Time per request:    24.379 [ms] (mean)Time per request:    2.438 [ms] (mean, across all concurrent requests)Transfer rate:     58.89 [Kbytes/sec] received......

文件排他锁(非阻塞模式):

......Concurrency Level:   10Time taken for tests:  20.002 secondsComplete requests:   8616Failed requests:    0Total transferred:   1266846 bytesHTML transferred:    0 bytesRequests per second:  430.77 [#/sec] (mean)Time per request:    23.214 [ms] (mean)Time per request:    2.321 [ms] (mean, across all concurrent requests)Transfer rate:     61.85 [Kbytes/sec] received......

经测试结果对比,redis 事务方式优于文件排他锁方式,而文件排他锁方式中,非阻塞模式优于阻塞模式。

以上就是PHP并发场景的解决方案是什么,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注编程网PHP编程频道。

--结束END--

本文标题: PHP并发场景的解决方案是什么

本文链接: https://www.lsjlt.com/news/61810.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • PHP并发场景的解决方案是什么
    本篇文章给大家分享的是有关PHP并发场景的解决方案是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。在秒杀,抢购等并发场景下,可能会出现超卖...
    99+
    2024-04-02
  • Flink+HBase场景化的解决方案是什么
    Flink+HBase场景化的解决方案是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Flink+HBase所提供实时计算场景解决方案。实时计算市场竞争分析...
    99+
    2023-06-19
  • Redis高并发场景下秒杀超卖解决方案(秒杀场景)
    目录1 什么是秒杀2 为什么要防止超卖3 单体架构常规秒杀3.1 常规减库存代码3.2 模拟高并发3.3 超卖现象3.4 分析原因4 简单实现悲观乐观锁解决单体架构超卖4.1 悲观锁...
    99+
    2024-04-02
  • Redis:高并发场景下的数据存储解决方案
    Redis:高并发场景下的数据存储解决方案随着互联网的迅速发展,高并发场景下的数据存储已成为各大企业关注的焦点。在面对海量请求和快速响应的需求时,传统的关系型数据库面临性能瓶颈。而Redis作为一种高性能的非关系型数据库,逐渐成为高并发场景...
    99+
    2023-11-07
    解决方案 数据存储 高并发
  • C++高并发场景下读多写少的优化方案是什么
    这期内容当中小编将会给大家带来有关C++高并发场景下读多写少的优化方案是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。概述一谈到高并发的优化方案,往往能想到模块水平拆分、数据库读写分离、分库分表,加缓...
    99+
    2023-06-26
  • php并发方案的作用是什么
    本篇内容介绍了“php并发方案的作用是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!支持并发请求处理在高并发的web环境下,处理大量的请...
    99+
    2023-07-05
  • php的几种并发解决方案
    解决方案1:文件锁 一.阻塞模式:(只要有其他进程已经加锁文件,当前进程会一直等其他进程解锁文件) public function index(){ f ...
    99+
    2023-09-06
    php mysql 数据库
  • Java架构高并发的解决方案是什么
    Java架构高并发的解决方案是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1.应用和静态资源分离刚开始的时候应用和静态资源是保存在一起的,当并发量达到一定程度的时候就需要...
    99+
    2023-06-16
  • php并发方案有什么用
    随着Internet的不断发展,web应用程序已经成为了现代社会的重要组成部分。而随之而来的访问量也使得多用户同时访问成为一个问题。如何处理大量用户的请求是每个web应用程序开发人员所必须面对的重大问题之一。本文将探讨PHP并发方案的用处。...
    99+
    2023-05-14
    php
  • Golang高并发场景中的锁管理策略是什么?
    锁管理策略提升 golang 高并发性能锁类型: 互斥锁(mutex),读写锁(rwmutex),原子操作最佳实践:最小化锁的粒度避免死锁使用读写锁使用原子操作实战案例: 使用互斥锁保护...
    99+
    2024-05-10
    golang 并发 go语言
  • python并发场景锁的使用方法
    目录前言加锁的原因代码实现可重入锁总结前言 如果你学过操作系统,那么对于锁应该不陌生。锁的含义是线程锁,可以用来指定某一个逻辑或者是资源同一时刻只能有一个线程访问。这个很好理解,就好...
    99+
    2024-04-02
  • Java中关于OOM的场景及解决方法是什么
    这期内容当中小编将会给大家带来有关Java中关于OOM的场景及解决方法是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。OOM for Heap=>例如:java.lang.OutOfMemory...
    99+
    2023-06-17
  • 高并发解决方案
    好的,下面是高并发解决方案的详细教程: 水平扩展    - 水平扩展是指增加机器数量,通过将负载分散到多个机器上来解决高并发问题。常用的方式包括负载均衡、分布式缓存等。    - 负载均衡:将流量分发到多台服务器上,防止单台服务器过载。 ...
    99+
    2023-09-22
    数据库 服务器 缓存
  • MySQL在并发场景下的问题及解决思路是怎样的
    本篇文章为大家展示了MySQL在并发场景下的问题及解决思路是怎样的,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1、背景对于数据库系统来说在多用户并发条件下提高并发...
    99+
    2024-04-02
  • 浅谈C++高并发场景下读多写少的优化方案
    目录概述分析双缓冲工程实现上需要攻克的难点核心代码实现简单说说golang中双缓冲的实现相关文献来源:https://www.cnblogs.com/longbozhan/p/157...
    99+
    2024-04-02
  • django高并发解决的方法是什么
    Django是一个使用Python编写的开源Web框架,可以帮助开发者快速构建高性能的Web应用程序。在处理高并发的情况下,以下是一...
    99+
    2023-10-09
    django
  • dubbo解决高并发的方法是什么
    Dubbo解决高并发的方法主要包括以下几个方面: 1.集群部署:将Dubbo服务提供者部署在多台服务器上,通过负载均衡策略将请求均匀...
    99+
    2024-04-03
    dubbo
  • 如何使用php函数解决高并发场景下的性能问题?
    高并发场景是指系统在同一时间段内接收到大量的请求。在这种情况下,系统的性能会受到很大的挑战,因为处理大量请求可能会导致服务器响应时间过长,甚至造成系统崩溃。为了解决高并发场景下的性能问题,PHP提供了一些函数和技巧。下面将介绍一些常见的方法...
    99+
    2023-10-21
    PHP性能优化 并发处理 函数调用
  • PHP实践:分布式场景下的Session共享解决方案实现
    🏆作者简介,黑夜开发者,全栈领域新星创作者✌,CSDN博客专家,阿里云社区专家博主,2023年6月CSDN上海赛道top4。 🏆数年电商行业从业经验,历任核心研发...
    99+
    2023-08-30
    php 分布式 开发语言 session共享
  • PHP 并发处理:容器技术是否是最佳解决方案?
    随着互联网业务的发展,越来越多的网站需要处理大量的并发请求。对于 PHP 开发者来说,如何高效地处理并发请求成为一个重要的问题。目前,容器技术被认为是一个非常优秀的解决方案,那么,容器技术是否是最佳解决方案呢?本文将从容器技术的优缺点以及...
    99+
    2023-10-28
    并发 容器 load
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作