在说到swoole的时候,首先需要知道PHP是属于单线程。他执行代码得逻辑也是由上而下的执行,如果现在出现这样一个场景,加入需要请求10个url,那按着PHP得逻辑,就需要for循环10次去请求url,然后获取数据,若是一个url请求的时间需要2秒,那最后得到数据,所需的时间,最起码要20秒。这就是PHP单线程的一个弊端问题。若是需要解决这样的情况,需要怎样做呢。若是不用到swoole。同样需要减少10个curl地址请求的时间,但是也要获取数据,那需要怎样做呢?其实也能做到,最Low的方式就是,你写个10个方法,然后每个方法请求一个url,接着呢,你同时请求10个方法,那也能有效的减少curl请求,获取到数据的时间,若是你通过这样的方式,其实你就会发现,你这样做的原理,就是Nginx处理高并发的原理,当你PHP的10个方法,同时请求的时候,加入Nginx 开启的work_process 是4个,那Nginx通过,master主进程,分配给创建好的4个woker子进程,接着进行执行你PHP请求的方法,假设worker子进程一次只能处理一个,那就相当于,Nginx一次就能处理4个curl请求,10个,那就需要,3次,一次2.5秒,那就是7.5秒。
从刚才的假设中,可以知道,同时开启N个进程,他就能同时干N件事,当然这是在你服务器顶得住的前提下。因此swoole的进程做的类似就是这样一件事。至于swoole是怎么安装,他的书写规范是怎样的我就不说了,官方文档有,这次主要就是来实践一下,他的进程的强大。
首先我们先做一个PHP最基础的10次curl请求,然后来记录他的时间,接着在做一个swoole进程来记录他的时间,从而来比较一下,至于curl请求的时间是不确定的,因此写一个方法,通过sleep()来模拟。话不多说,贴代码。
![](https://img.haomeiwen.com/i7074766/85e3ac5e386ec684.png)
![](https://img.haomeiwen.com/i7074766/35a853353578815c.png)
通过,php curl.php 来执行这个文件,可以看到,所需的耗时需要20秒时间。
若是用swoole进程呢?
![](https://img.haomeiwen.com/i7074766/507c0e08810d2f3a.png)
![](https://img.haomeiwen.com/i7074766/dbbf67e09bbb6149.png)
从时间上可以看到,从开始到结束,所需消耗的时间,只需2秒,这时候,应该明白,进程得作用,以及swoole进程的强大了吧?
当然,关于swoole进程里面也有很多坑,去阅读文档的时候,就会发现,当子进程将数据写入管道的时候,父进程在读取管道得时候,他的read()方法,是同步阻塞读取,什么意思呢?我同样通过代码举例。
![](https://img.haomeiwen.com/i7074766/d521ac8e4045122f.png)
![](https://img.haomeiwen.com/i7074766/67c7e96f51871414.png)
可以看到,将读取管道内容放到循环中,最后请求结束所需的时间,也是需要20秒,那这个为什么呢?
那是因为同步堵塞的状态就是,当我循环第一次,开启一个进程,接着进程开始执行,curlData,由于sleep了2秒,read()方法就在那里等着,等你2秒过后,把数据写入管道,我在继续读取,读到数据以后,接着走下面一步,开始下一步的循环。因此,每次循环都要等待2秒,从而导致所需的时间为20秒。
从代码中也能看到,wait()这个方法,理论上也是可以,在for循环中,当子进程创建好以后,数据写入管道了,可以直接把子进程回收了。但是swoole官方文档中说到:wait()它是默认为堵塞状态的。因此,若是写在循环上面,也会出现等待状态。可以看一下案例
![](https://img.haomeiwen.com/i7074766/581568e102df3d9e.png)
![](https://img.haomeiwen.com/i7074766/849fba1545004af9.png)
可以看到,在堵塞状态中,也需要耗时20秒,那如何解决这个问题呢,很简单,只需要,将他的堵塞状态改为非堵塞就OK了
![](https://img.haomeiwen.com/i7074766/6db269d8835de722.png)
![](https://img.haomeiwen.com/i7074766/93d35698953cbbfd.png)
可以看到,耗时又变为2秒了。
所说的这些就是,在写进程中所出现和需要规避的问题
网友评论