Gavin 发了几个workerman改进意见,这里记录下
发几个关于workerman的意见
一 没有主进程启动与结束回调
这两个回调的一个用途是用于与外部工具协作,例如服务发现。主要是方便在
在runAll前执行启动是不可取的,因为此时workerman的资源尚未载入,一些可能需要获取的信息尚未生成。
在register_shutdown_function或者在onWorkerStop进行结束回调也是不可取的,workerman并未提供方法判断当前进程是主进程还是worker进程。
二 注册回调函数的方式并不好
这个属于见仁见智,但主流做法是使用on($event, callable $callback)进行注册,我也更倾向于这个做法,包装起来更方便。另一个原因是,call_user_func本身有性能损失,因为相当于多了一级函数调用,回调注册的方式可以直接$callback($args);callable本身会进行类型检查;总之是好处多多。
即使是为了兼容性,也可以使用__set魔术方法把对这几个回调的注册转换为on()的形式。
三 Worker类的可见性与初始化配置
Worker有大量的属性,public和protected都有。但是,php并不能简单设置readonly或者writeonly属性,以至于有些应该只读的属性,如$id,也是可写的;有些应该只写的属性,如onXxxxx,也是可读的。当然,一个正确的基于workerman的程序不应该非法读写这些属性;只是,如果可以用较低的成本(事实上,对于程序性能毫无成本)提高这方面的可靠性,应该是值得一做的。
四 与composer的协作
如果我的观察没错的话,workerman是依赖于自带的Autoloader.php的,同时也在composer.json里面定义了psr自动加载。
当然,因为作为一个常驻型的程序,autoload带来的性能损失可以忽略不计;但是,对于使用composer管理包的开发者来说,似乎并无此必要。
以上意见,有的可能属于鸡蛋里挑骨头,请酌情考虑。
一 没有主进程启动与结束回调
这个建议很好,当时开发也考虑过,但是最后还是决定不给用户在主进程上编程的入口
原因是
1、主进程要保持稳定性,加入业务代码很有可能导致不稳定
2、子进程会自动继承主进程的这部分业务代码,导致子进程行为也不可控(大多数phper不会理解或者考虑到这个问题)。比如在主进程Start时数据库数据库连接/redis/memcache在子进程是不可用的,主进程start的定时器在子进程也会运行,导致和预期不一致
全局的onStart 和 onStop可以有很多种方法,比如
1、在worker->id为0的进程的onWorkerStart/onWorkerStop中做
2、单独启动一个worker进程在onWorkerStart/onWorkerStop去做
3、写个shell启动脚本,在start或者stop执行一段自己想要的业务逻辑
总之在主进程编码很危险,无法保证每个phper都有多进程编程经验,所以workerman不打算提供这种机制,避免因为代码质量问题造成不稳定和不必要的问题投诉。目前来看有主进程start/stop回调的需求用户很少的。
二 注册回调函数的方式并不好
恩像Gavin所说,见仁见智,各有优势吧,目前这种设置回调属性的方法避免了一次函数调用,性能高一些。
另外就是能够自动提示,少敲了很多代码。这些是小问题,不爽可以直接继承worker加个on('message',func)方法也没问题。
另外$callback($args);这种如果$callback是类方法,会直接报错(这个之前有测试过,当时php版本是5.3,不知道高php版本是否ok)。所以workerman使用了call_user_func方法
三 Worker类的可见性与初始化配置
这个建议不错,但是感觉严格限制缺少了灵活性。
有些属性确实是建议只读的,比如说worker->id,但是覆盖了也没有问题,默认值可以看做是建议值吧。
onXXX不仅是可写的,也应该是可读的,方便用户判断当前设置的是什么回调
四 与composer的协作
如果国内每个用workerman的phper都会用composer,并且每个项目都用自觉使用composer,并且composer官网国内访问非常通畅,那么就可以把autoloader.php去掉,但是貌似上面任何一个条件都不能保证,所以还得给个默认的autoloader.php
非常感谢Gavin的建议
看walker回答问题,都能学到很多。赞!
作者大大可以在码云弄个分库的。。我想提交pr 同性交友网貌似被墙了 打不开了