# 同步阻塞与异步非阻塞适用场景 ## 异步的优势 * 高并发,同步阻塞IO模型的并发能力依赖于进程/线程数量,例如 php-fpm开启了200个进程,理论上最大支持的并发能力为200。如果每个请求平均需要100ms,那么应用程序就可以提供2000qps。异步非阻塞的并发能力几乎是无限的,可以发起或维持大量并发TCP连接 * 无IO等待,同步模型无法解决IOWait很高的场景,如上述例子每个请求平均要10s,那么应用程序就只能提供20qps了。而异步程序不存在IO等待,所以无论请求要花费多长时间,对整个程序的处理能力没有任何影响 ## 同步的优势 * 编码简单,同步模式编写/调试程序更轻松 * 可控性好,同步模式的程序具有良好的过载保护机制,如在下面的情况异步程序就会出问题 * Accept保护,同步模式下一个TCP服务器最大能接受 进程数+Backlog 个TCP连接。一旦超过此数量,Server将无法再接受连接,客户端会连接失败。避免服务器Accept太多连接,导致请求堆积 ## Swoole异步与同步的选择 Swoole不仅支持异步,还支持同步。什么情况下使用同步,什么情况下使用异步。这里说明一下。 * 我们不赞成用异步回调的方式去做功能开发,传统的PHP同步方式实现功能和逻辑是最简单的,也是最佳的方案。像node.js这样到处callback,只是牺牲可维护性和开发效率。 * 但有些时候很适合用异步,比如FTP、聊天服务器,smtp,代理服务器等等此类以通信和读写磁盘为主,功能和业务逻辑其次的服务器程序。 “PHP的扩展函数API全是同步的”,这个说法并不正确,实际上同步阻塞的地方主要是网络调用,文件读写。例如mysql_query需要与mysql数据库服务器通信,curl需要调用网络,file_get_contents需要读写文件,以及其他fopen/fwrite/fread/fgets/fputs这些都是阻塞的API。除此之外PHP的array/string/mbstring等函数是非阻塞的。 swoole提供了异步的socket客户端,异步的mysql,而且1.6.12还提供了异步文件读写和异步DNS查询的功能。另外还提供了task/finish的API,完全可以解决阻塞IO问题。