主动断开与客户端的连接

方法缺点:

  • PHP FastCGI 进程数有限,正在处理异步操作的php-cgi进程,无法处理新请求
  • 并发访问量较大,php-cgi进程数用满,新访问请求,将没有php-cgi去处理。Nginx服务器会出现: 502 Bad Gateway

fastCGI

在使用 fastCGI 和 PHP_FPM 时直接使用 fastcgi_finish_request() 方法。

1
2
3
4
5
// your code here
fastcgi_finish_request();
// run other process without the client attached.

php_mode

Apache 一般使用的是这种模式。

1
2
3
4
5
6
7
8
9
10
11
12
13
ob_end_clean();
header("Connection: close");
ob_start();
// your code here
$size = ob_get_length();
header("Content-Length: ". $size);
// send info immediately and close connection
ob_end_flush();
flush();
// run other process without the client attached.

消息队列

  1. 把要延迟处理的数据放入消息队列中
  2. 返回结果给客户端
  3. 使用定时任务拿取消息队列中的数据进行处理

概念

  • 拥有队列结构的中间件
  • 消息放入不需要立即处理
  • 会有另一个程序来按顺序处理这些数据

缺点

  • 并发量大
  • 耗时长

应用场景

  • 数据冗余
  • 系统解耦
    • 入队系统与出队系统分隔开,互不干扰
  • 流量削峰
  • 异步通信
  • 扩展性
    • 入队列的信息可以供给其他多个业务使用
  • 排序保证

队列实现方法

  1. 数据库(例如 MySQL)
    • 可靠性高、实现容易
    • 速度慢
  2. 缓存(例如 Redis)
    • 速度快
    • 单个消息过大时效率低
  3. 消息系统(例如 rabbitMq)
    • 专业性强、可靠
    • 学习成本高

消息处理触发机制

  1. 死循环
    • 易实现,但难维护
  2. 定时任务
    • 可均分压力,有处理上限
    • 需要注意时间间隔,不要等上一个任务没有完成,下一个任务就开始了
  3. 守护进程(类似 php-fpm / php-cg)

参考资料