现在很多phper转go开发,大部分都是冲着go的静态语言和协程去的,当然还有钱多。
但是php自己其实也有协程支持,那就是 swoole 了。
工作原因,有幸接触了一段时间swoole和go,希望对比下两者的区别。
首先,网上很多大神关于swoole和go的对比,有的还是比较详细的。
比如swoole官方就有一个对比swoole和go的文章: https://wiki.swoole.com/wiki/diff/?id=1018&version=1&compare=current
知乎大神文章: https://zhuanlan.zhihu.com/p/93141701
感兴趣的话,可以 拜读一下。
文章基本是围绕,swoole是单进程协程切换,go是MGP模型切换。
swoole 的单进程模型 不能共享资源,没有线程并发问题,协程切换依赖io等等。
对比下来,基本都是go性能比较突出。
确实,go的性能比php高出不少,但同时也比php的学习和使用成本高很多。而且,目前go的开发框架大都是基于beego或者gin,说好用真实有点昧良心,相比之下基于swoole的hyperf、mix-php都是开箱即用,包含了大部分需要的功能,二开也成本不高。
总的来说,go的性能确实比php要高,但是使用成本也高出不少,同时由于静态语言天然的特性,比php这种弱类型语言在开发时的成本也要高出不少。
基于协程的框架,抗并发性能基本都没大问题,如果后端存储能撑得住,server端的并发基本不会有问题。
swoole直播案例
上一节中,我们为每个连接都创建了一个goroutine来读取其中的消息,现在我们将这个读取消息的方法实现一下。我们在application目录下新建controllers目录,并在其中创建一个MessageController.go文件。
首先我们新建一个MessageController的结构体,内容如下
这个结构体包括两个内容,一个是我们将连接放在数组之后,返回的索引,另一个是连接本身.
这个是具体的方法。
我们首先设置了一下读消息的大小、超时时间以及超时后需要的操作。
超时时间如果设置为0,那么就是永不超时。之前在这里直接写0,被告知需要传一个time.Time类型的数据。最终谷歌后才得到了这个值time.Time{}为"0001-01-01 00:00:00 +0000 UTC"。
我们将用户手法消息的内容定义为一个结构体,然后将用户的订阅信息的json通过json.unmarshal转换成这个结构体。
之后的switch操作与我们在Swoole中的操作基本雷同,在查询到login之后,调用service中 的login方法来进行注册。
下一节中我们再介绍具体的注册逻辑。
性能上Swoole毕竟是C语言开发的,在某些地方如内存管理、数据结构、通信协议解析上肯定要比PHP开发的workerman高。功能上swoole提供的高级特性很多,列举几个workerman没有的吧,比如SSL/TLS隧道加密、http2.0、异步mysql驱动、异步redis驱动、异步的http/websocket客户端、process、lock、atomic、table。另外Swoole 2.0内置了PHP原生协程的支持,PHP代码也可以使用类似于Go语言的协程来实现高并发的网络服务器。
外部依赖上workerman需要依赖很多额外的第三方PHP扩展来实现,局限性比较大,这些扩展并非是PHP官方维护的,维护性方面良莠不齐,有些扩展连PHP7都不支持,数年没人维护。而Swoole基本上无依赖,底层的代码全部可控。