Swoole-src: PHP Swoole 从入门到放弃

Created on 20 Jun 2017  ·  6Comments  ·  Source: swoole/swoole-src

被Swoole文档上各种“高XX”说得口水流了一地。天真的我,决定花些时间,把自己项目的新业务迁移到swoole平台上来。

今天谨以此文纪念我为了swoole而逝去的时光!

以下是这段时间以来尝试过程中的各种痛:


高可用。可以通过给主进程发USR1信号来热更新代码,过程很优雅。我只要一个信号就全GET到了。

  • 事实上。这有个蛋疼的前提:你必须先把server段的代码与worker段的业务代码分开。因为woker重启后,只能reload 启动后include进来的代码。这就操了大蛋了。

高效编码。提供了协程,可以用同步的代码,得到异步的善果!nodejs还要async/await一下呢!
* 事实上。使用协程有两个条件!
1. 只能在指定的地方使用,要是在别的地方使用,得用个回调,把代码包起来。与便与其它业务代码隔离开!
2. 只能使用提供的几样东西。用开发者的话说:缓存只能使用redis,数据库只能用mysql。
* 这里还有更多其它蛋疼的事:
1. worker 中不能使用同步代码。因为它会阻塞整个完美的worker进程。顿时PHP的很多的第三方库成了废物。即便要用,也要丢到task进程中去。
2. task 进程有队列,但是,它只做了内部私有封装了的队列。还提出了若干条不清不楚的使用时的限制。如果任务失败,自己不收集,就无法重现。如果宕机,所有队列里的事,全了了账。队列里的事务也都成了悬案。这一点与laravel的队列比起来,可用性差得太TM远了!
3. 逃不过的回调。其实PHP其它扩展也有异步的,譬如:ext-pgsql。可以用swoole的Event监听pgsql的socket可获得兼容的异步,但回调的问题就回来了。swoole重要的服务定义也是全程用回调的。包括worker/task/server/process这些对象生命周期。
4. 不兼容。使用swoole的协程,其它不足不能用其它的异步PHP库做弥补,因为它们各自的event-loop不同。这一点怪不得swoole开发者。如果共用,不是通晓底层的大师级操刀,会出现各种稀奇古怪的问题。
5. 功能弱。这一点主要表现在websocket Server这个对象上。swoole的websocket。声称自动的握手使用的是XX协议。但不支持使用websocket的内部的“协议”。如果带上协议名,就会拒绝。并且还有个让人蛋疼!如果自己实现握手协议,在很多版本中,它会自动地在返回的header中加入其它的头,导致被客户端拒绝!这一点开发者对此无能为力,因为swoole的response对象中的header,开发者只能加,不能改,不能删。它还不支持accept。什么样来路的请求都是直接到握手,如果要拒绝accept一些不合法的来源都不能轻易做到。
6. 奇葩的异步http client。设计得还是满好的。但不知道什么原因,使用它请求腾讯的服务器,就是不稳定。40%会被拒。但如果使用nodejs 的 request。就能做到100%稳定!


二进制分发。一次编译分发到各种平台。

  • 一来,分发的需求不大。不同的环境需要不同的定制,服务器环境与开发环境的配置注定不能完全相同。
  • 二来,编译起来就坑死人了。简单编译很多“高XX”的东西得不到。如果编译的系统有类库缺失,在configure中不会中止,只会在check的时候放个小小的'no'结尾。三个不同的系统平台上编译一下,包你眼花。PHPer对C的make了解并不深,很难编译出一个真正满意的结果。缺失类库的情况下编译出的so文件,放到PHP里后,一运行,PHP就会出一个segmentfault。并且有些第三方库要到放源码内部编译,有的是在外部单独编译安装。其中jemalloc库编译的时候还得加上专门为支持swoole而用的函数前缀。而文档对这里讲解,我就“呵呵”了。

社区及支持

  • 哎!今天我就是在这里把swoole骂上天,恐怕傲慢的开发者也未必能看到我!虽然swoole项目天天有更新,但swoole开发者是在做他自己的事。我们swoole的用户如同苍蝇!

Most helpful comment

  1. 必须要在worker进程include的php代码才可以reload,这是swoole进程模型决定。无法更改,实际上你切换到其他类似语言的多进程服务,也会有此限制。除非使用runkit类似的热加载工具才能实现
  2. 异步回调、同步阻塞、协程,3种方式当然各有优点缺点。不同的场景下选择不同的模式。
  3. 异步http client 连接被拒绝,这个你需要抓包分析,找到具体的原因。
  4. task的队列只是用来多进程间通信的内存队列,出现致命错误或者进程退出自然会丢失
  5. swoole与其他php同步阻塞库兼容问题,如果你要用其他同步IO的库,就直接用同步模式

All 6 comments

驾驭不了,勿喷。

呵呵

  1. 必须要在worker进程include的php代码才可以reload,这是swoole进程模型决定。无法更改,实际上你切换到其他类似语言的多进程服务,也会有此限制。除非使用runkit类似的热加载工具才能实现
  2. 异步回调、同步阻塞、协程,3种方式当然各有优点缺点。不同的场景下选择不同的模式。
  3. 异步http client 连接被拒绝,这个你需要抓包分析,找到具体的原因。
  4. task的队列只是用来多进程间通信的内存队列,出现致命错误或者进程退出自然会丢失
  5. swoole与其他php同步阻塞库兼容问题,如果你要用其他同步IO的库,就直接用同步模式

@matyhtf
感受到了温暖!
是的,matyhtf所言是中肯的事实。

刚开始我没有意识到,按文档的描述沉入了好多幻想。这一番折腾,明白过来了,我当前的业务还是不能使用swoole,我很遗憾。
上文不是对swoole项目的否定,是对我的幻想的否定。
中国的开发者用C为PHP构建了一个如此宏大的项目,是值得敬佩的!
我早年,用过C,知道用C写点能用的东西,有多不容易!

我们目前的团队都是业务时间来开发支持 Swoole 的,中国公司的特点就是员工为公司工作加班较多,所以没办法像其他国外开源项目组织那样能够有这么多时间的投入。

Github Issue一般是在我们有空余时间后会逐个查看和确认,如果确实存在 BUG,会予以解决。感谢你的支持和谅解。

@blusewang 有合适的建议或者是发现BUG,可以逐个提出issue,一起推进,有各种感慨和心情,也欢迎到swoole的群里吐槽 :-)

Was this page helpful?
0 / 5 - 0 ratings