PHP Swoole 从入门到放弃

作者 bluse wang 日期 2017-06-20
PHP Swoole 从入门到放弃

被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而用的函数前缀。而文档对这里讲解,我就“呵呵”了。

社区及支持

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