在MixV2.1之前版本一直是基于多进程SwooleServer开发的,与目前主流的Swoole框架相同。V2.1开始基于Swoole的Coroutine/Server开发(单线程协程)的MixAll,让Server端也可以使用完全同步的编程方式,底层自动实现异步IO。Reactor+Manager+Worker多进程优缺点Master+Worker进程模型是一种广泛使用的传统模型,比如Nginx和PHP-FPM都采用这种模型,但是Swoole的模型多了一个Manager进程。优点:自重启:Reactor+Manager+Worker进程架构最大的优势就是当Worker出现异常时,程序的Manager进程可以自己重启一个Worker进程,不需要借助第三方(比如supervisor,下午2)。可以利用多CPU:由于多进程模型,Worker进程在多个CPU中执行,所以可以利用多核。阻塞影响小:由于Reactor多线程负责连接处理,多个Worker进程负责执行PHP代码,所以单个Worker的阻塞IO不会影响其他请求(协程模式,会影响分配的进程totheprocessbutnotcompleted)Request)缺点:编码复杂,不够灵活:SwooleServer在启动前后的类属性操作范围,对于不熟悉的用户非常不友好,容易掉坑,理解难度大。在处理一些全局服务时,需要进行跨进程处理,这就带来了并发安全锁的问题,并且无法在代码中同时启动多个服务器或者随意启停服务器。平滑关闭难:由于程序在很多Worker进程中执行,如果有耗时任务,多进程模型很难精细控制每个子进程去执行管道的所有请求,然后全部退出流程顺利有序。SwooleServer虽然提供了异步安全重启功能,但是大部分框架都没有处理onWorkerExit,用户很难在框架的基础上进行扩展。单线程协程的优缺点单线程模型在新软件领域非常流行,比如Redis和Node.js都是单线程模型,优缺点和Reactor+Manager刚好相反+Worker,而Mix针对这些缺点提供了解决方案。缺点:无法自行重启:MixV2.1这个问题普遍存在于所有的单进程程序中,包括Golang和Node.js开发的程序。当发生致命异常时,进程会导致进程退出。由于它是单个进程,因此无法自行重启。两者都需要借助第三方(如:supervisor、pm2),不能使用多CPU:因为是单进程模型,在一个CPU中执行,所以不能像Node.js那样使用多核(有使用docker部署时没有这样的问题)。阻塞影响大:单进程模型由于服务端和业务逻辑在一个进程中一起执行,当遇到阻塞IO时,所有的请求处理都会一起阻塞,导致响应时间变长,长期阻塞也会造成服务无法接收到新的请求,Swoole虽然Hook有大量的阻塞IO可以支持协程,但是还有很多扩展无法支持,所以这个问题最为突出。优点:编码简单灵活:由于是单进程单线程模型,所有服务器都是基于Swoole的Coroutine/Server开发,完全同步编程,代码非常简单易懂。也没有多进程带来的问题:跨进程对象属性发散问题,并发安全锁问题,Server也可以随意启动N,随意停止。平滑关机简单:单线程模型,处理信号只需要处理一个进程,退出也只需要处理一个进程。由于采用同步编程方式,出口处理逻辑也非常简单易懂。缺点的解决方法从上面的分析可以总结出:单线程更简单,更灵活,但是最大的缺点就是阻塞和多CPU利用的问题。MixV2.1是如何解决这些问题的:多CPU利用:与Node.js解决这个问题的方法是一样的,通过开启多个进程来解决多CPU利用问题,因为同一个端口只能绑定一个程序,所以多次开启只能绑定不同的端口,势必会增加反向代理的复杂度。但是,Linuxv3.10或更高版本的内核中已经添加了端口复用功能。Mix内置的Server只需要在启动的时候加上-r参数就可以在Linux中开启多端口复用,实现类似Node.js的解决多CPU利用的效果,看例子。阻塞:在单进程单线程模型中,要彻底解决PHP历史遗留的阻塞IO问题,执行阻塞代码的唯一方法是将其集中放到一个或多个其他进程中,类似于Swoole的Task,但不同的是,Mix获取到执行结果是一种同步编程方式。Mix会封装一个同步执行器,在代码中调用同步执行器,并传入一个闭包。闭包中包含阻塞IO调用代码,调用后同步获取结果(协程方式)。闭包代码会通过unixsocket传递给同步执行器的进程执行,执行完成后返回结果。同步执行进程和其他服务器一样,可以自己添加代码,可以在启动时加上-r参数端口复用。这样,Mix将阻塞代码集中在同步执行器进程上,完全避免了阻塞。影响。解决了这些问题后,综合考虑单线程协程显然更符合Mix短小精悍易用的定位。MixV2.1是迄今为止唯一一个完全使用Coroutine/Server的框架。
