Swoole框架如何接入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的包,以及打包命令。
  1. {
  2. "require": {
  3. ...
  4. "phptars/tars-server": "~0.1",
  5. "phptars/tars-deploy": "~0.1",
  6. "phptars/tars2php": "~0.1",
  7. "phptars/tars-log": "~0.1",
  8. "ext-zip" : ">=0.0.1"
  9. ...
  10. },
  11. "scripts": {
  12. ...
  13. "deploy": "\\Tars\\deploy\\Deploy::run"
  14. ...
  15. }
  16. }
  • 写一个用于调用Tars平台各种接口的class (src/app/Tars/Manage.php)

    1. namespace App\Tars;
    2. use \Tars\report\ServerFSync;
    3. use \Tars\report\ServerFAsync;
    4. use \Tars\report\ServerInfo;
    5. use \Tars\Utils;
    6. class Manage
    7. {
    8. public function getNodeInfo(){
    9. $conf = $this->getTarsConf();
    10. if( !empty($conf) ){
    11. $node = $conf['tars']['application']['server']['node'];
    12. $nodeInfo = Utils::parseNodeInfo($node);
    13. return $nodeInfo;
    14. }else{
    15. return [];
    16. }
    17. }
    18. public function getTarsConf(){
    19. $tars_conf = dirname(BASE_PATH,2).'/conf/'.env('PNAME').'.config.conf';
    20. if( is_file($tars_conf) ){
    21. $conf = Utils::parseFile($tars_conf);
    22. return $conf;
    23. }else{
    24. var_dump('get tars_conf file error : '.$tars_conf);
    25. return [];
    26. }
    27. }
    28. public function keepAlive()
    29. {
    30. $pname = env('PNAME');
    31. $pname = explode('.',$pname);
    32. $adapter = env('PNAME').'.objAdapter';
    33. $application = $pname[0];
    34. $serverName = $pname[1];
    35. $masterPid = getmypid();
    36. $nodeInfo = $this->getNodeInfo();
    37. if( empty($nodeInfo) ){
    38. var_dump('keepAlive getNodeInfo fail');
    39. return null;
    40. }
    41. $host = $nodeInfo['host'];
    42. $port = $nodeInfo['port'];
    43. $objName = $nodeInfo['objName'];
    44. $serverInfo = new ServerInfo();
    45. $serverInfo->adapter = $adapter;
    46. $serverInfo->application = $application;
    47. $serverInfo->serverName = $serverName;
    48. $serverInfo->pid = $masterPid;
    49. $serverF = new ServerFSync($host, $port, $objName);
    50. $serverF->keepAlive($serverInfo);
    51. $adminServerInfo = new ServerInfo();
    52. $adminServerInfo->adapter = 'AdminAdapter';
    53. $adminServerInfo->application = $application;
    54. $adminServerInfo->serverName = $serverName;
    55. $adminServerInfo->pid = $masterPid;
    56. $serverF->keepAlive($adminServerInfo);
    57. var_dump(' keepalive ');
    58. }
    59. }
  • 在框架启动成功的时候,上报服务存活,这使用的swoft的框架的事件监听。 (src/app/Listener/APPStart.php)

    1. namespace App\Listener;
    2. use Swoft\Bean\Annotation\Listener;
    3. use Swoft\Event\EventHandlerInterface;
    4. use Swoft\Event\EventInterface;
    5. use Swoft\Task\Event\TaskEvent;
    6. use Swoft\Event\AppEvent;
    7. use App\Tars\Manage;
    8. use Swoft\Memory\Table;
    9. /**
    10. * Task finish handler
    11. *
    12. * @Listener(AppEvent::APPLICATION_LOADER)
    13. */
    14. class APPStart implements EventHandlerInterface
    15. {
    16. public static $num = 0;
    17. /**
    18. * @param \Swoft\Event\EventInterface $event
    19. */
    20. public function handle(EventInterface $event)
    21. {
    22. //服务启动 只上报一次 TODO
    23. $manage = new Manage();
    24. $manage->keepAlive();
    25. }
    26. }
  • 每隔30s上报一次存活,这里使用swoft框架注解试的定时任务。 (src/app/Tasks/TarsKeepAliveTask.php)

    1. namespace App\Tasks;
    2. use App\Lib\DemoInterface;
    3. use App\Models\Entity\User;
    4. use Swoft\App;
    5. use Swoft\Bean\Annotation\Inject;
    6. use Swoft\HttpClient\Client;
    7. use Swoft\Redis\Redis;
    8. use Swoft\Rpc\Client\Bean\Annotation\Reference;
    9. use Swoft\Task\Bean\Annotation\Scheduled;
    10. use Swoft\Task\Bean\Annotation\Task;
    11. use App\Tars\Manage;
    12. /**
    13. * TarsKeepAlive task
    14. *
    15. * @Task("tarsKeepAlive")
    16. */
    17. class TarsKeepAliveTask
    18. {
    19. /**
    20. *
    21. * @Scheduled(cron="*\/30 * * * * *")
    22. */
    23. public function cronkeepAliveTask()
    24. {
    25. $manage = new Manage();
    26. $manage->keepAlive();
    27. return 'cron';
    28. }
    29. }
  • 写一个入口文件,来控制swoft框架的启停。 (src/index.php)

    1. // tars 平台然后文件
    2. // 读取tars conf配置
    3. // 处理合成 env文件
    4. $args = $_SERVER['argv'];
    5. $swoft_bin = dirname(__FILE__).'/bin/swoft ';
    6. $arg_cmd = $args[2]=='start' ? 'start -d' : $args[2] ;
    7. $cmd = "/usr/bin/php " . $swoft_bin . $arg_cmd;
    8. exec($cmd, $output, $r);

ps:可以参考下面的提交记录 https://github.com/dpp2009/swoftInTars/commit/97459b5012f9d7542a2a31d936c65ad8637ee1a0#diff-efc7d6cbd3cc43b894698099b51a99ab