日志

PHP基于pcntl的多进程编程

PHP可以通过PHP的进程控制函数(PCNTL)实现多进程,要注意的是,PCNTL只在UNIX LIKE OS下有效,windows是不支持的,另外如果你在编译时没有加入这个扩展则需要自行安装.

pcntl_fork

首先我们需要了解一个非常重要的函数,pcntl_fork().

pcntl_fork —— 在当前进程当前位置产生分支(子进程).fork创建了一个子进程,父进程和子进程都从fork的位置开始向下继续执行,不同的是父进程执行过程中,得到的fork返回值为子进程号(PID),而子进程得到的是0.通过fork创建的子进程可以看成是父进程的一个拷贝,无论是数据空间还是指令指针都完全一致,但从fork之后开始这两个父子进程就再也没有任何继承关系,两者可以看成是两个独立的进程,而fork返回值的差异可以作为父子进程的区分,也是多进程编程实现的关键.另外,如果fork失败,则会返回-1.

Talk is cheap show me the code:

#!/usr/bin/env php
<?php
date_default_timezone_set("asia/shanghai");

$pid = pcntl_fork();
if ($pid==-1) {
    die('fork失败');
} else if ($pid==0) {
    //子进程执行
    $sec = 10;
    echo date('H:i:s') .'| 我是子进程 (PID:' . posix_getpid() . ')' . ',我休眠' . $sec . '秒后结束' . PHP_EOL;
    
} else if ($pid>0) {
    //父进程执行
    $sec = 15;
    echo date('H:i:s') . '| 我是父进程 (PID:' . posix_getpid() . '),我创建了一个子进程 (PID:' . $pid . ')' . ',我休眠' . $sec . '秒后结束' . PHP_EOL;
}
sleep($sec);
echo date('H:i:s') . '| 进程(PID:'.posix_getpid().')结束' . PHP_EOL;
exit(0);

/**********************************输出*************************************
16:22:13| 我是父进程 (PID:28082),我创建了一个子进程 (PID:28083),我休眠15秒后结束
16:22:13| 我是子进程 (PID:28083),我休眠10秒后结束
16:22:23| 进程(PID:28083)结束
16:22:28| 进程(PID:28082)结束
****************************************************************************/

僵尸进程

阅读全文

日志

通过nginx限制连接数和请求数

有时候服务器会遭到大流量的恶意访问,这种攻击最直接的影响就是导致服务器持续高压,严重影响正常访问,导致这种情况的原因有很多,对于一些低配置的服务器可能只需要一次简单的恶意压测就可以导致服务器502.对于这种情况,我们可以考虑对相同IP的并发连接数和请求频率进行限制,nginx本身自带了两个模块可以作为解决方案,即ngx_http_limit_conn_module和ngx_http_limit_req_module.

  • ngx_http_limit_conn_module

简介:ngx_http_limit_conn_module是一个可以根据指定key来限制连接数的模块,尤其用于根据单个IP限制连接数.

语法:limit_conn_zone key zone=name:size;

上下文:http(即nginx配置的http作用域)

说明:开辟一个名为name,大小为size的共享内存区域,用于存储一系列key(s)的状态,特别是包含各个key的连接数,其中key可以是变量、文本或二者的组合(nginx 1.7.6之前只可以包含一个变量),另外1MB共享内存可以存储3.2万个32-byte状态(在32位平台中存储状态占用32bytes)或1.6万个64-byte(64位平台),当共享内存空间不足时,之后的请求会导致服务器返回503(Service Temporarily Unavailable) 错误.

语法:limit_conn zone number;

上下文:http ,server,location

说明:设置共享内存区域zone,使zone指定的key的连接数不大于number个,当超过这个number值时服务器会返回503(Service Temporarily Unavailable) 错误.

例子:设定一个名为addr的10MB共享内存,以客户端ip作为键,限制每个客户端ip最大并发连接数为5

http{
    ...
    # $binary_remote_addr是客户端ip地址,它和$remote_addr的区别在于它是固定4字节长度
    limit_conn_zone $binary_remote_addr zone=addr:10m;
    server {
    ...
        location ~ \.php$ {
            limit_conn addr 5;
        }
    ...
    }
    ...
}
  • ngx_http_limit_req_module

阅读全文