开发必读
1、务必详读本开发手册
阅读开发手册太重要了,不管怎样,开发前多读几遍手册就对了,读了事半功倍,不读事倍功半,读了就会发现坑越来越少,不读就可能会给自己不断的挖坑。
2、务必详读本开发手册的"常见问题"章节
常见问题 章节集中列举了大家开发中经常遇到的共性问题,所以习惯性的上这里来转一转,好处多多。
3、务必详读workerman官方手册
PHPCreeper是基于workerman开发的,所以很多玩法都是继承自workerman,但是workerman要求开发者具备一定的开发功底,自然PHPCreeper同样也有这个要求,故务必详读workerman官方手册,这样会起到事半功倍的效果,而且也会避开很多不是坑的坑。
4、阅读并运行爬山虎自带的样例脚本
爬山虎源码根目录下有一个 Examples/start.php 样例脚本,开发之前建议先看它而后运行它。
5、PHPCreeper只能运行在命令行
由于PHPCreeper是基于PHP-CLI模式运作的,所以重要的话说三遍:
只能从命令行启动运行!! 只能从命令行启动运行!! 只能从命令行启动运行!!
6、禁止使用exit、die、sleep等语句
业务执行exit、die语句会导致进程退出,并显示WORKER EXIT UNEXPECTED错误。 当然,进程退出了会立刻重启一个新的进程继续服务。如果需要返回,可以调用 return 语句。
7、业务代码里禁止死循环
业务代码里禁止死循环,否则会导致控制权无法交还给PHPCreeper,从而导致无法处理对端消息或引起业务阻塞。
8、修改代码后记得要重启
PHPCreeper是常驻内存的框架,修改代码后,除非变动的代码是放在单独的文件里,此时可以使用reload指令热加载,否则必须重启PHPCreeper才能看到最新代码的效果。
9、长连接应用必须加心跳
重要的话说三遍:长连接必须加心跳!!长连接必须加心跳!!长连接必须加心跳!!
长连接长时间不通讯肯定会被防火墙干掉而断开,如果不加心跳就等着老板KO你吧。
10、避免类和常量的重复定义
由于PHPCreeper会缓存编译后的PHP文件,所以要避免多次require/include相同的类或者常量的定义文件。建议使用 require_once/include_once
加载文件。
11、关于类方法以及属性操作
wokerman中的Worker类有很多可直接操作的属性,例如:$worker->name = 'taskWorker'
,但是在PHPCreeper中我们不推荐直接操作对象属性,要求一律通过暴露的公共方法来操作,比如上述操作的对应方案是:$worker->setName('taskWorker')
。
12、严格区分主进程和子进程
禁止在主进程中初始化 mysql、redis、memcache 等连接资源, 因为主进程初始化的连接可能会被子进程自动继承(尤其是使用单例的时候),所有进程都持有同一个连接,服务端通过这个连接返回的数据在多个进程上都可读,会导致数据错乱。同样的,如果任何一个进程关闭连接(例如daemon模式运行时主进程会退出导致连接关闭),都导致所有子进程的连接都被一起关闭,并发生不可预知的错误,例如mysql gone away 错误。推荐在 onXXXStart 回调里面初始化连接资源。
务必注意脚本代码是运行在主进程还是子进程:
一般写在 PHPCreeper::runAll()
之前运行的代码隶属主进程,
写在 onXXX回调
里运行的代码隶属子进程。另外写在 PHPCreeper::runAll()
后面的代码永远都不会被执行。
举个例子:
<?php
//自动加载
require_once '/path/to/vendor/autoload.php';
//引入爬山虎
use PHPCreeper\PHPCreeper;
//引入生产器
use PHPCreeper\Producer;
//运行在主进程
$producer = new Producer();
//赋值过程运行在主进程
$producer->onProducerStart = function($producer){
//onXXX回调部分运行在子进程
};
//这行代码之后的任何代码永远都不会被执行
PHPCreeper::runAll();