PHP没有数据库连接池怎么破?PHP环境下使用Nginx ngx_http_limit_req_module模块的高负载解决方案

原创 2015年07月09日 10:56:11

线上运行了一套辅助系统是利用了开源的PHP改的,之前也没怎么玩过PHP,没想到这玩意儿还是有不少坑的。突然某一天一个用户做线上活动推广,然后短时间内涌进来了上万的请求,然后数据库连接耗尽,短时间内几乎拖垮了整个系统。导致系统奔溃的有多方面原因,今天主要针对PHP没有数据库连接池的原因来分析。

在PHP里,数据库连接在请求到达时建立,请求结束时释放。如果同时几千个请求到达,那就同时会建立几千个数据库连接,非常恐怖。而且PHP木有比较好的数据库连接池驱动方案,所以我们得另想办法。

解决这种问题有三种办法:
1.使用Mysql Proxy中间件。Mysql Proxy提供了连接池管理的功能。但是我们没有采用此方法,因为情况紧急,没有人熟悉这玩意儿。
2.使用PHP-FPM。PHP-FPM是PHP的一个FastCGI进程管理器。通过配置可以控制同时处理PHP请求的进程数。
具体可以参考:http://www.linuxde.net/2013/06/14638.html
但是我们也没用使用此方案,因为安装配置过程比较麻烦。
3.使用Nginx的ngx_http_limit_req_module来控制请求。
此模块可以通过自定义的键值来限制请求频率。限制的方法就像漏斗,每秒固定处理请求数,然后推迟超出的请求,最后超出最大值的直接503返回拒绝。
我们使用了此方案,是因为只需简单配置,而且可以灵活控制限制请求的场景。例如,对于静态资源的请求我们不做限制,而对于PHP的请求做限制。还可以从URL地址里提取出变量信息作为键,来达到更细的请求限制。
下面贴部分我们的配置给大家讲解下。

http {
    ......
    limit_req_zone $limit_key zone=limit_one:50m rate=30r/s;
    #定义limit_key为Key的变量名,用于后面赋值,每个Key都有自己的计数器。limit_one为zone的名称。rate表示每秒最多接受30个同时请求。
    server {
        ......
        if ( $request_uri ~* .*php.* ) {
              set $limit_one $binary_remote_addr;
              #对于全部PHP首先有个默认的Key,使用客户端的IP作为Key。相当于每个客户端IP都会在zone的限制内。
         }
        if ( $query_string ~* .*id/(\d+)\.php.* ) {
              set $limit_one $1;
              #提取id后面的值作为Key。
        }
        if ( $query_string ~* .*appid/wx(.*)\.html.* ) {
              set $limit_one $1;
              #提取appid作为Key。
        }
        limit_req zone=limit_one burst=200;
        #限制limit_one在此server内的漏斗容量为200。假设一个Key对应的请求数为200,那么第一秒内在处理的为30个请求,其余的170个请求在等待排队。假设一个Key对应的请求数为300,那么超出200的部分将直接返回503。
        .......
    }
}

参考:http://www.ttlsa.com/nginx/nginx-limiting-the-number-of-requests-ngx_http_limit_req_module-module/
官方文档:http://nginx.org/en/docs/http/ngx_http_limit_req_module.html

Nginx模块 ngx_http_limit_req_module 限制请求速率

The ngx_http_limit_req_module module (0.7.21) is used to limit the request processing rate per a def...
  • loophome
  • loophome
  • 2016年02月29日 20:47
  • 3848

nginx限制连接数(ngx_http_limit_conn_module)模块

ngx_http_limit_conn_module 对于一些服务器流量异常、负载过大,甚至是大流量的恶意攻击访问等,进行并发数的限制;该模块可以根据定义的键来限制每个键值的连接数,只有那些正在被处理...
  • wanglei_storage
  • wanglei_storage
  • 2016年04月06日 17:05
  • 2534

Nginx模块 ngx_http_limit_conn_module 限制连接数

The ngx_http_limit_conn_module module is used to limit the number of connections per the defined key...
  • loophome
  • loophome
  • 2016年02月29日 19:29
  • 1291

Nginx防攻击工具教程一 ngx_http_limit_conn_module

要限制用户的连接数可以通过Limit zone模块来达到目的,即限制同一用户IP地址的并发连接数。    该模块提供了两个命令limit_zone和limit_conn,其中limit_zone只能...
  • babydavic
  • babydavic
  • 2013年04月17日 10:10
  • 5946

nginx限制连接数ngx_http_limit_conn_module模块

一. 前言 我们经常会遇到这种情况,服务器流量异常,负载过大等等。对于大流量恶意的攻击访问,会带来带宽的浪费,服务器压力,影响业务,往往考虑对同一个ip的连接数,并发数进行限制。下面说说ng...
  • joeyon
  • joeyon
  • 2015年08月03日 11:28
  • 487

PHP连接池实现的一种想法

虽然现在名义上是PHP开发,不过做这数据分析的事,平时工作大部分用的是JAVA。C语言出身,学的语言比较多,JAVA还算熟悉,不过之前一直都没用连接池。第一次遇到连接池是在学校的时候女朋友用连接池出现...
  • frf12
  • frf12
  • 2017年01月22日 10:01
  • 1172

PHP没有数据库连接池怎么破?PHP环境下使用Nginx ngx_http_limit_req_module模块的高负载解决方案

线上运行了一套辅助系统是利用了开源的PHP改的,之前也没怎么玩过PHP,没想到这玩意儿还是有不少坑的。突然某一天一个用户做线上活动推广,然后短时间内涌进来了上万的请求,然后数据库连接耗尽,短时间内几乎...
  • shootyou
  • shootyou
  • 2015年07月09日 10:56
  • 3654

完美解决64位操作系统配置 php无法加载mysql模块问题

今天配置php 的时候,发现没配起mysql ,wordpress提示我需要 mysql 的module之后上google搜索,大多数都是说php.ini 没加载起 之后看phpin...
  • zalion
  • zalion
  • 2014年04月02日 15:33
  • 7177

Laravel 的 Homestead 开发环境部署

https://phphub.org/topics/2 Homestead 与 虚拟机 Laravel 努力在整个PHP开发过程中提供令人愉快的开发体验,当然也包括本地的开发环境。 首先...
  • xyxjn
  • xyxjn
  • 2016年08月18日 17:16
  • 2832

Nginx模块(upstream和ngx_http_limit_req_module)使用

如何有效的防刷?限制某个IP某一时间段的访问次数是一个让人头疼的问题,起初有同事说自己写LUA脚本进行控制,后面再Nginx网上找到对应的模块ngx_http_limit_req_module...
  • LoveJavaYDJ
  • LoveJavaYDJ
  • 2016年12月30日 16:54
  • 510
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:PHP没有数据库连接池怎么破?PHP环境下使用Nginx ngx_http_limit_req_module模块的高负载解决方案
举报原因:
原因补充:

(最多只允许输入30个字)