PHP能够不堵塞其他请求吗?

陈其文
  • 393

前端发起了多个请求,其中有一个请求A需要获取视频流地址。
因为这个视频流地址是临时地址,所以需要后端去第三方获取。
现在遇到的问题是:

如果前端发起A请求,后面所有的请求都被堵塞。具体表现为,A耗时16s,后面的5个请求耗时也是16s,其他请求全部堵塞。
如果前端不发起A请求,所有请求都很快。

A请求获取的是一个列表,大约30个视频地址。
后端通过循环请求的方式从第三方获取数据,造成了服务器的堵塞。

请问这样的情况,后端有没有办法快速解决?

我们的后端说需要两个月研究一下!!!

回复
阅读 1.6k
9 个回答

这样的耗时操作不能在php的控制器去一次搞定, 因为第三方服务器请求数据的速度是未知的。
建议采用异步轮训的方式。

前端发起第一波请求, 之后, 后端将请求保存到缓存或者数据库, 进入请求处理队列, 然后立即返回就行。

然后前端发起轮训请求,不断地查询视频地址是否准备好了。 如果后端的视频地址准备完成, 就返回给前端。

后端则需要有一个专门的守护进程, 处理队列中的请求任务。

这样做不会阻塞。

一次js请求在php端遍历30次去第三方请求,等于建立了30次网络链接,而且还得按顺序访问,肯定慢啊。

你可以前端发30次请求,请求30个地址,即php一次只请求一个视频地址。
php没法异步,但js请求可以发多个。这时30次请求就是异步的了。

curl 可以同时请求多个请求哦,批处理只会耗费单个最长请求的时间,而不需要循环的所有请求时长总和。如果你们是fpm运行的话,这个方案应该就可以解决了。

另外你们如果是fpm的话,很有可能是你们某个其他的地方的锁阻塞了所有的请求,而不是因为curl循环请求

正常来说不会阻塞,是不是在windows下用了nginx导致的?或者是在linux下调整fpm配置中的子进程数量测试下。

用缓存。定时任务请求接口提前获取相应数据并存入redis,前端接口读的时候先读redis,有的话直接返回就快很多。

应该是不会发生阻塞的,应该是编码或者发起请求的方式出现了问题,php应该在读写数据库,文件,session等会加锁,然后才会导致后面的请求挂起等待前面的请求执行完才继续.所以之后再看这些情况

php服务器环境都是多进程阻塞模式, 这种情况处理不好, 确实会阻塞请求.

这种情况可以用 workman 或 swoole 创建一个非阻塞服务器, 这个服务器中转 前端请求和视频服务数据. 不占用什么资源.

也可以直接配置 nginx 代理, 把请求转后视频服务器.

我怎么感觉 是 php-fpm 或啥地方的问题
或者 你们用的是 php -S 0.0.0.0:80 这种?

不然这个阻塞不应该出现呀

尴尬而不失微笑
  • 2
新手上路,请多包涵

前端请求是否合理
一般服务端会开启多个php进程,如果是只有一个,那是会阻塞的,
可以让服务端多开几个php进程,并行处理

宣传栏