swoole-suport-tars
总体思路
在框架启动成功的时候,上报服务存活。
使用框架的或者swoole的定时器,实现每隔30s上报一次存活,可以在worker里面上报,也可以在task里面上报(注意可能worker都挂了,task还在)。
写一个入口文件(如index.php),根据Tars平台生成的PHP服务启停脚本,以及Tars平台下发的conf配置文件,完成PHP框架的配置转换(端口号、worker数量)和启停命令控制。
对于HTTP的服务,实现上面3步就可以跑着Tars里面了。对于其他各种功能(查看框架简介),可以根据实际情况自行引入Tarsphp的composer扩展。
对于tars或者pb等RPC协议的服务,需要解决网络协议与业务协议的打包解包(可以参照tarsphp tcpserver),如果能实现定制的代码自动生成,就更好了。
以swoft为例
修改composer.json,加入phptars的包,以及打包命令。
{
"require": {
...
"phptars/tars-server": "~0.1",
"phptars/tars-deploy": "~0.1",
"phptars/tars2php": "~0.1",
"phptars/tars-log": "~0.1",
"ext-zip" : ">=0.0.1"
...
},
"scripts": {
...
"deploy": "\\Tars\\deploy\\Deploy::run"
...
}
}
写一个用于调用Tars平台各种接口的class (src/app/Tars/Manage.php)
namespace App\Tars; use \Tars\report\ServerFSync; use \Tars\report\ServerFAsync; use \Tars\report\ServerInfo; use \Tars\Utils; class Manage { public function getNodeInfo(){ $conf = $this->getTarsConf(); if( !empty($conf) ){ $node = $conf['tars']['application']['server']['node']; $nodeInfo = Utils::parseNodeInfo($node); return $nodeInfo; }else{ return []; } } public function getTarsConf(){ $tars_conf = dirname(BASE_PATH,2).'/conf/'.env('PNAME').'.config.conf'; if( is_file($tars_conf) ){ $conf = Utils::parseFile($tars_conf); return $conf; }else{ var_dump('get tars_conf file error : '.$tars_conf); return []; } } public function keepAlive() { $pname = env('PNAME'); $pname = explode('.',$pname); $adapter = env('PNAME').'.objAdapter'; $application = $pname[0]; $serverName = $pname[1]; $masterPid = getmypid(); $nodeInfo = $this->getNodeInfo(); if( empty($nodeInfo) ){ var_dump('keepAlive getNodeInfo fail'); return null; } $host = $nodeInfo['host']; $port = $nodeInfo['port']; $objName = $nodeInfo['objName']; $serverInfo = new ServerInfo(); $serverInfo->adapter = $adapter; $serverInfo->application = $application; $serverInfo->serverName = $serverName; $serverInfo->pid = $masterPid; $serverF = new ServerFSync($host, $port, $objName); $serverF->keepAlive($serverInfo); $adminServerInfo = new ServerInfo(); $adminServerInfo->adapter = 'AdminAdapter'; $adminServerInfo->application = $application; $adminServerInfo->serverName = $serverName; $adminServerInfo->pid = $masterPid; $serverF->keepAlive($adminServerInfo); var_dump(' keepalive '); } }
在框架启动成功的时候,上报服务存活,这使用的swoft的框架的事件监听。 (src/app/Listener/APPStart.php)
namespace App\Listener; use Swoft\Bean\Annotation\Listener; use Swoft\Event\EventHandlerInterface; use Swoft\Event\EventInterface; use Swoft\Task\Event\TaskEvent; use Swoft\Event\AppEvent; use App\Tars\Manage; use Swoft\Memory\Table; /** * Task finish handler * * @Listener(AppEvent::APPLICATION_LOADER) */ class APPStart implements EventHandlerInterface { public static $num = 0; /** * @param \Swoft\Event\EventInterface $event */ public function handle(EventInterface $event) { //服务启动 只上报一次 TODO $manage = new Manage(); $manage->keepAlive(); } }
每隔30s上报一次存活,这里使用swoft框架注解试的定时任务。 (src/app/Tasks/TarsKeepAliveTask.php)
namespace App\Tasks; use App\Lib\DemoInterface; use App\Models\Entity\User; use Swoft\App; use Swoft\Bean\Annotation\Inject; use Swoft\HttpClient\Client; use Swoft\Redis\Redis; use Swoft\Rpc\Client\Bean\Annotation\Reference; use Swoft\Task\Bean\Annotation\Scheduled; use Swoft\Task\Bean\Annotation\Task; use App\Tars\Manage; /** * TarsKeepAlive task * * @Task("tarsKeepAlive") */ class TarsKeepAliveTask { /** * * @Scheduled(cron="*\/30 * * * * *") */ public function cronkeepAliveTask() { $manage = new Manage(); $manage->keepAlive(); return 'cron'; } }
写一个入口文件,来控制swoft框架的启停。 (src/index.php)
// tars 平台然后文件 // 读取tars conf配置 // 处理合成 env文件 $args = $_SERVER['argv']; $swoft_bin = dirname(__FILE__).'/bin/swoft '; $arg_cmd = $args[2]=='start' ? 'start -d' : $args[2] ; $cmd = "/usr/bin/php " . $swoft_bin . $arg_cmd; exec($cmd, $output, $r);
ps:可以参考下面的提交记录 https://github.com/dpp2009/swoftInTars/commit/97459b5012f9d7542a2a31d936c65ad8637ee1a0#diff-efc7d6cbd3cc43b894698099b51a99ab
Last updated