内容简介:php工程师在开发过程中,往往以只需要串行编写业务逻辑即可,完全不用考虑并发。通常部署时配置好nginx, fpm就行。就这样接口便并发的提供web服务了。那到底是怎么实现的呢?一个来自客户端的请求,首先会到达nginx这样的web服务器,然后通过fastcgi协议将请求传递到php这样的处理程序,php执行后返回结果给nginx,nginx最终返回客户端。nginx是高并发服务器,这里我们不细说。主要看看php是怎么实现并发的。fpm(Fastcgi Process Manager),支持fastcgi
介绍
php工程师在开发过程中,往往以只需要串行编写业务逻辑即可,完全不用考虑并发。通常部署时配置好nginx, fpm就行。就这样接口便并发的提供web服务了。那到底是怎么实现的呢?一个来自客户端的请求,首先会到达nginx这样的web服务器,然后通过fastcgi协议将请求传递到 php 这样的处理程序,php执行后返回结果给nginx,nginx最终返回客户端。nginx是高并发服务器,这里我们不细说。主要看看php是怎么实现并发的。
fpm(Fastcgi Process Manager),支持fastcgi外,主要功能是进程管理。以多进程方式工作,由一个master进程与多个worker进程组成,master进程主要功能是管理worker进程,例如维持worker数量在一定范围内。而worker进程则是真正处理请求的,对于单个worker进程,是串行执行接收到的每个请求。这种简单的实现就导致有多少个worker最多同时处理的请求数量就有多少。这也是不能高并发的主要原因。
实现
多进程实现是靠fork这个系统调用完成。
-
master初始化后,按配置要求fork出worker进程,自身进入事件循环处理中。 worker退出执行请求处理逻辑
2. worker正常执行max_requests个请求正常退出
细节
1. master如何获取worker的运行信息?
这里是通过共享内存来通信的。在master初始化过中,会进行scoreboard结构的分配(每个worker pool分配一个)。每个worker在处理请求的过程中,会先后将
fpm_request_accepting,
fpm_request_reading_headers,
fpm_request_info,
fpm_request_executing,
fpm_request_end,
fpm_request_finished置位到request_stage, master就可以直接在获取worker状态,例如在多个worker都在等待请求时,减少worker数到最小空闲数。
2. master进入事件循环有哪些处理?
信号处理 : master对接收到的信息进行处理,比如收到关闭信息,则发送信号给worker进程(master与worker进程通信的主要方式是信号)
进程检查定时器 : 每隔一段时间,根据不同策略将worker数量维持在要求的范围内。
超时检查定时器 : 若一个请求处理时长超过request_terminate_timeout, 那master便会发送term信号杀掉worker.
3. 若多个worker同时获取一个请求?
若多个worker都阻塞在fcgi_accept_request, 突然有一个请求到达,为了防止多个进程对accept进行抢占,php在这里加入了锁机制。FCGI_LOCK, FCGI_UNLOCK, 在 linux 中没实现。因为在linux2.6内核中, accept系统调用已不存在惊群了。
存在的问题
1. fpm是通过多进程实现并发的。并发主要受限于进程的数量,进程的数量又受限于系统的内存,cpu。一般服务器开500+ worker就可以了。但是这些worker又不能充分利用系统资源,主要是大多处理要集中在操作mysql, redis这样的远程资源上了,发起请求后,worker本身就阻塞等待中。真是受限于资源,不能太多进程,而在手的进程又不能完全发送作用。
2. worker串行化处理max_requests个请求,不能高并发。fastcgi_finish_request这些也只是优先返回客户端响应,还是阻塞处理后续逻辑。
3. 基于上面1,2两点,我们知道了php处理能力有限。在特殊情况下,会导致后果呢? 1. 依赖的redis,mysql被慢查询拖住时,多个worker会同时请求超时,到时后续请求得不到处理,直接导致一段时间内请求雪崩。这时应该重启fpm还是解决后端数据资源? 2. 若你的php接口中还代理了其他服务,请合理设置超时,原因同上。
4. max_requests的初衷是为了避免第三方扩展引起的内存泄漏问题。但是,在请求均匀的情况下,多个 worker同时结束,master为了维持worker平衡,会瞬间大量fork,从监控来看会发生锯齿状。百度技术人员通过对max_requests进行随机,优化了这种情况,可以参考:
http://www.sohu.com/a/163046759_487482
总结
通过fpm这个进程管理器,php实现了让开发者不考虑并发,专注于业务开发,保证了较快的开发效率,但是又是这种简单的多进程实现的并发,不能承载高并发的业务。在技术选型上,开发者要牢记这一点!
微信公众号 :
溜溜技术
以上所述就是小编给大家介绍的《PHP 的多进程并发》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Python多进程并发与多线程并发编程实例总结
- Java多线程并发:进程调度算法
- Python并发:多线程与多进程
- 15分钟读懂进程线程、同步异步、阻塞非阻塞、并发并行,太实用了!
- 进程:进程生命周期
- Python 知识巩固:通过主进程带起多个子进程实现多进程执行逻辑
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。