首页 运维 脚本开发 查看内容

Swoole的优越性

2019-10-25 10:33 |来自: 互联网 1969 0

摘要: swoole与golang相比有哪些优势开发效率Go语言是本质上是静态语言,开发效率稍差,但性能更强,更适合底层软件的开发Swoole使用PHP语言,动态脚本语言,开发效率最佳,更适合应用软件的开发IO模型go语言使用单线程eventloop处理IO事件,多线程实现协程调度,执行用户层代码swoole使用多线程eventloop处 ...
关键词: swoole 支持 线程 代码 同步 27 开发 time 多进 阻塞

swoole与golang相比有哪些优势

开发效率

  • Go语言是本质上是静态语言,开发效率稍差,但性能更强,更适合底层软件的开发
  • Swoole使用PHP语言,动态脚本语言,开发效率最佳,更适合应用软件的开发

IO模型

  • go语言使用单线程eventloop处理IO事件,多线程实现协程调度,执行用户层代码
  • swoole使用多线程eventloop处理IO事件,多进程执行用户层php代码

Go对与IO事件的处理是单线程的,无法利用多核,吞吐量稍弱于swoole

在实际的TCP/UDP密集IO压测中,swoole表现要稍优于go

Go协程(goroutine)是运行在多线程上的,线程可以共享堆栈和文件描述符,功能更强大,在实现连接池、并发库方面更有优势。额外的带来的一个问题是,存在数据同步问题,需要用户自行考虑加锁。

Swoole的用户代码运行在多进程环境,无需考虑加锁问题。但无法直接访问内存和资源。需要借助Task进程实现中转。

swoole与node.js相比有哪些优势

CPU多核的利用

  • node.js没有内置对多线程/多进程的支持,用户必须使用cluster/child_process等扩展自行实现并行
  • swoole内置对多线程/多进程的支持,用户仅需配置参数即可

对于熟悉并行编程的程序员使用node.js cluster/child_process可以解决问题。但毕竟不是官方提供的,难免会产生BUG,需要开发者自己负责

对于不熟悉并行编程的程序员,并行会变得困难。很多技术人员采用了启动多个程序实例来解决此问题。

同步阻塞的支持

  • swoole同时支持同步/异步2种模式
  • node.js仅支持异步

为什么强调同步阻塞模式的支持。多进程同步阻塞模式是Unix世界40多年历史中最成熟的一种编程模式。配套的调试工具非常丰富完善,稳定性、成熟度、调度公平性、开发调试效率都是最佳的。多线程、异步回调、协程等模式编程虽然可以带来一定的性能提升,但复杂度过高,开发调试困难。

业务逻辑很重的程序,最佳的方式仍然是多进程同步阻塞。

协程本质上也是一种异步IO,无法利用现有的工具如strace,gdb进行调试

swoole中对于复杂业务逻辑,推荐使用同步阻塞

自动协议的支持

  • node.js没有内置通用协议处理的支持,需要自行实现代码
  • swoole内置了通用协议处理的支持,可以借助swoole提供的功能轻松实现

TCP心跳检测

  • swoole内置了对TCP心跳检测的支持

swoole协程

在swoole中,已经自带了协程管理器,以及异步io的扩展(redis.mysql,http客户端等),我们只要安装好swoole扩展,就可以直接使用协程了,例如以下代码:

```

$start_time = time();

/*for ($i = 0; $i <= 500; $i++) {

go(function ()use($i,$start_time){

$cli = new SwooleCoroutineHttpClient('www.baidu.com', 443,true);

$cli->setHeaders([

'Host' => "www.baidu.com",

"User-Agent" => 'Chrome/49.0.2587.3',

'Accept' => 'text/html,application/xhtml+xml,application/xml',

'Accept-Encoding' => 'gzip',

]);

$cli->set([ 'timeout' => 0.11]);

$cli->get('/');

$cli->close();

echo "协程{$i}已完成,耗时".(time()-$start_time).PHP_EOL;

});

}*/

$start_time = time();

for ($i = 0; $i <= 500; $i++) {

$url = 'https://www.baidu.com/';

$content = file_get_contents($url);

echo "普通{$i}已完成n";

}

echo "非携程完成时间:" . (time() - $start_time);

```

在非协程环境,它的执行顺序和执行时间如下:

而在注释掉非协程代码,协程环境运行下,它的执行顺序和时间如下:

为什么会这样呢?我说下具体的流程:

非协程流程

1:先执行$i=0

2:通过file_get_contents获取网页内容

3:获取成功后在进行输出: 普通0已完成

4:继续执行$i=1

...

协程流程

1:先执行$i=0

2:通过异步client类,去请求https://www.baidu.com

3:协程切换不等待获取网页内容,直接跳到$i=1

4:通过异步client类,去请求https://www.baidu.com

....

n:$i=0的请求内容已经完成,切换回$i=0后面的代码,输出"协程0已完成,耗时0"

n+1:通过异步client类,去请求https://www.baidu.com,协程切换不等待获取网页内容,直接跳到$i=n+2

n+2:$i=n的请求内容已经完成,切换回$i=n后面的代码,输出"协程n已完成,耗时5"

....

由这2个流程可以看出一个不同之处:非协程需要等待请求网页的时间,而协程直接跳过了等待的时间,继续往下执行,

也就是上面说的"小明烧开水的时间先去刷牙"

然后,由于协程没有了io耗时,执行速度大大提高,假设请求一次网站需要0.05秒,那500次循环就相当于节省了25秒,这就是为什么协程适合在高并发io场景的原因了

本文出处: https://www.toutiao.com/a6751016619478106638/
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部