TarsPHP
1 Intro
tars-client
The PHP ability to call the tars service is provided in the tars-client, including:
- Call the instance of the remote service;
- Call stat info report
- Automatic failover
tars-server
Tars-server provides the underlying server framework and supports the following features:
- High performance service based on swoole1.x/2.x
- Support two protocol modes: tup protocol and tars stream
- Support three kinds of servers: http, TCP and timer
- Reporting, monitoring and log integration
- Tars platform publish support
tars-config
The ability module to pull configuration files from the configuration service of the tars platform.
tars-deploy
The module that packs the business code of tars-server.
tars-extension
The PHP extension code that tars relies on
tars-log
Modules of remote log writing by tars
tars-monitor
The function modules of main dispatching report and characteristic report of tars
tars-registry
The function module of tars for master addressing
tars-report
The module of keeping alive service reporting by tars
tars-utils
Modules of configuration file parsing by tars
tars2php
The tool of automatic code generation can automatically generate server and client code.
2 Create Http HelloWorld
Directory structure description
- scripts: Store the scripts required by the business, such as tars2php.sh, which is responsible for generating the code required by the client according to the tars file
- src: The directory of business logic mainly includes the following structure:
- component: The basic class of the storage controller is convenient for all controllers to share
- conf: The configuration required by the business is just a demo. If the configuration is distributed from the platform, it will be written to this folder by default;
- controller: C layer in MVC model
- servant: The client source code generated by tars2php, the directory name can be completely customized, and only needs to be distinguished during use;
- composer.json: Explain project dependencies
- index.php: The entry file of the whole service. The file name can be customized, but the private template on the platform must be changed. Add the entry field under the server
- services.php: Declare the base namespace name of the entire project
- tars: The TCP service depends on the example.tars file under this folder and the tars.client.proto.php file, which are necessary for generating code under the service. This will be explained in the following guide line.
Service Deployment
- Enter operation => template
The platform will provide a template for PHP named tars.tarsphp.default
You must first modify the execution path of PHP in it
- Enter operation => deploy
App = match tars.proto.php in the tar folder below
Server Name = match tars.proto.php in the tar folder below
Server Type = tars_php
Template = tars.tarsphp.default
obj = match tars.proto.php in the tar folder below
NodeName = tarsnode node ip
Port = server port
Port Type = TCP
Protocol = NOT TARS
Notice:
- Protocol type HTTP service must select non tars
- The number of threads corresponds to the number of processes in swoole
- The maximum number of connections, maximum queue length and queue timeout are not valid for PHP services
Develop Guideline
Basic steps:
- Create a new directory structure, and fix it to scripts, src, and tars
- Create
src/composer.json
{
"name": "tars/helloworld/phphttp",
"description": "tars php http hello world",
"require": {
"phptars/tars-server": "~0.2",
"phptars/tars-deploy": "~0.1",
"phptars/tars2php": "~0.1",
"phptars/tars-log": "~0.1",
"ext-zip": ">=0.0.1"
},
"autoload": {
"psr-4": {
"PHPHttp\\": "./"
}
},
"minimum-stability": "stable",
"scripts": {
"deploy": "\\Tars\\deploy\\Deploy::run"
}
}
- Create
src/index.php
<?php
/**
* Platform entrypoint
*/
require_once __DIR__.'/vendor/autoload.php';
use \Tars\cmd\Command;
//php index.php conf restart
$config_path = $argv[1];
$pos = strpos($config_path, '--config=');
$config_path = substr($config_path, $pos + 9);
$cmd = strtolower($argv[2]);
$class = new Command($cmd, $config_path);
$class->run();
- This will cause platform and requirement initialization.
- Create
src/services.php
<?php
return [
// Hello is the object name
'Hello' => [
'namespaceName' => 'PHPHttp\\', // psr4 root namespace
'saveTarsConfigFileDir' => 'src/conf/', // config directory
'saveTarsConfigFileName' => ['',], // Config files which need to be pulled from Tars framework.
'monitorStoreConf' => [
//'className' => Tars\monitor\cache\RedisStoreCache::class,
//'config' => [
// 'host' => '127.0.0.1',
// 'port' => 6379,
// 'password' => ':'
//],
'className' => Tars\monitor\cache\SwooleTableStoreCache::class,
'config' => [
'size' => 40960
]
],
'registryStoreConf' => [
'className' => Tars\registry\RouteTable::class,
'config' => [
'size' => 200
]
],
'protocolName' => 'http', //http, json, tars or other
'serverType' => 'http', //http(no_tars default), websocket, tcp(tars default), udp
],
];
namespaceName should match the psr4 settings in composer.json.
monitorStoreConf is the stats report storage configuration
- className is the storage class name. Use
\Tars\monitor\cache\SwooleTableStoreCache::class
for swoole_table as default. tars-monitor allow you to use redis redis instead. You can also build your own storage class by implement\Tars\monitor\contract\StoreCacheInterface
.
- run
composer install
- Create
tars/tars.proto.php
to define your servant
<?php
return [
'appName' => 'HelloWorld',
'serverName' => 'PHPHttp',
'objName' => 'Hello',
];
- appName, serverName, objName should be exactly as the servant you deployed.
- Create
src/component/Controller.php
<?php
namespace PHPHttp\component;
use Tars\core\Request;
use Tars\core\Response;
class Controller
{
protected $request;
protected $response;
public function __construct(Request $request, Response $response)
{
$this->request = $request;
$this->response = $response;
}
public function getResponse()
{
return $this->response;
}
public function getRequest()
{
return $this->request;
}
public function cookie($key, $value = '', $expire = 0, $path = '/', $domain = '', $secure = false, $httponly = false)
{
$this->response->cookie($key, $value, $expire, $path, $domain, $secure, $httponly);
}
// send raw data to client
public function sendRaw($result)
{
$this->response->send($result);
}
public function header($key, $value)
{
$this->response->header($key, $value);
}
public function status($http_status_code)
{
$this->response->status($http_status_code);
}
}
- This is the base class for all Controllers.
- Create
src/controller/IndexController.php
<?php
namespace PHPHttp\controller;
use PHPHttp\component\Controller;
use Tars\client\CommunicatorConfig;
use Tars\App;
class IndexController extends Controller
{
public function actionIndex()
{
$this->sendRaw('Hello Tars!');
}
}
- The accessable url for this action is
http://{machine_ip}:9000/index/index
- Run
composer run-script deploy
insrc
directory to build deployment package. - Upload
src/PHPHttp_xxx.tar.gz
and deploy
- You can find app logs in
/data/app/tars/app_log/HelloWorld/PHPHttp
if the service if failed to start.
3. Create Tars HelloWorld
Directory structure description
- scripts: Store the scripts required by the business, such as tars2php.sh, which is responsible for generating the code required by the client according to the tars file
- src: The directory of business logic mainly includes the following structure:
- component: The basic class of the storage controller is convenient for all controllers to share
- conf: The configuration required by the business is just a demo. If the configuration is distributed from the platform, it will be written to this folder by default;
- impl: Tars api logic
- servant: The client source code generated by tars2php, the directory name can be completely customized, and only needs to be distinguished during use;
- composer.json: Explain project dependencies
- index.php: The entry file of the whole service. The file name can be customized, but the private template on the platform must be changed. Add the entry field under the server
- services.php: Declare the base namespace name of the entire project
- tars: The TCP service depends on the example.tars file under this folder and the tars.client.proto.php file, which are necessary for generating code under the service. This will be explained in the following guide line.
Deploy servant
AppName = HelloWorld
ServerName = PHPTars
ObjName = Hello
Develop guideline
- Create
scripts/tars2php.sh
#!/bin/bash
cd ../tars/
php ../src/vendor/phptars/tars2php/src/tars2php.php ./tarsclient.proto.php
- Use this script to generate code based on the definations in tarsclient.proto.php
- Create
src/composer.json
{
"name": "tars/helloworld/phptars",
"description": "tars php hello world",
"require": {
"phptars/tars-server": "~0.2",
"phptars/tars-deploy": "~0.1",
"phptars/tars2php": "~0.1",
"phptars/tars-log": "~0.1",
"ext-zip": ">=0.0.1"
},
"autoload": {
"psr-4": {
"PHPTars\\": "./"
}
},
"minimum-stability": "stable",
"scripts": {
"deploy": "\\Tars\\deploy\\Deploy::run"
},
"repositories": {
"packagist": {
"type": "composer",
"url": "https://mirrors.aliyun.com/composer/"
}
}
}
- Run
composer install
after composer.json created.
- Create platform entrypoint
src/index.php
<?php
/**
* platform entrypoint
*/
require_once __DIR__.'/vendor/autoload.php';
use \Tars\cmd\Command;
//php index.php conf restart
$config_path = $argv[1];
$pos = strpos($config_path, '--config=');
$config_path = substr($config_path, $pos + 9);
$cmd = strtolower($argv[2]);
$class = new Command($cmd, $config_path);
$class->run();
- Create service config file
src/services.php
<?php
return [
// Hello is the ObjName in service deploy form
'Hello' => [
'home-api' => '\PHPTars\servant\HelloWorld\PHPTars\Hello\SayHelloTafServiceServant',
'home-class' => '\PHPTars\impl\SayHello',
'protocolName' => 'tars', //http, json, tars or other
'serverType' => 'tcp', //http(no_tars default), websocket, tcp(tars default), udp
],
];
- Create
tars/tars.proto.php
<?php
return [
'appName' => 'HelloWorld',
'serverName' => 'PHPTars',
'objName' => 'Hello',
];
- Create
tars/tarsclient.proto.php
<?php
return array(
'appName' => 'HelloWorld',
'serverName' => 'PHPTars',
'objName' => 'Hello',
'withServant' => true, // The tars2php.sh script will generate server code for true, client code for false.
'tarsFiles' => array(
'./SayHello.tars', // tars file location based on tars directory. Only support one file for tars server.
),
'dstPath' => '../src/servant', // The target direcoty for code generating. Location is based on scripts directory
'namespacePrefix' => 'PHPTars\servant',
);
- Define the code generating parameters
- Create
tars/SayHello.tars
module SayHelloTafServiceServant
{
interface SayHelloTafService
{
int greeting(string name, out string greeting); // out stands for output parameter.
};
};
- You can learn more about tars defination in tars protocol doc
- Run
cd scripts && ./php2tars.sh
to generate tars code
- Create
src/impl/SayHello.php
to implement tars API
<?php
namespace PHPTars\impl;
use PHPTars\servant\HelloWorld\PHPTars\Hello\SayHelloTafServiceServant;
class SayHello implements SayHelloTafServiceServant
{
public function greeting($name, &$greeting)
{
$greeting = "PHPTars says hello to $name";
return 0;
}
}
- This class is what we set in
home-class
. seesrc/services.php
- Run
composer run-script deploy
in src directory to build a deployment package - Deploy tars service to node
- You can access HelloWorld.PHPHttp service page to test this API on debug tool.
- You can find app logs in
/data/app/tars/app_log/HelloWorld/PHPTars
on node machine if service is failed to start.
4. Create Tars HelloWorld Client
- Let’s call the tars API in PHPHttp project.
- Copy
SayHello.tars
totars/SayHello.tars
- Create
tars/tarsclient.proto.php
<?php
return array(
'appName' => 'HelloWorld',
'serverName' => 'PHPHttp',
'objName' => 'Hello',
'withServant' => false, //false for client code generating
'tarsFiles' => array(
'./SayHello.tars',
),
'dstPath' => '../src/servant',
'namespacePrefix' => 'PHPHttp\servant',
);
- Execute
scripts/php2tars.php
to generate client code.
- Add new action to
src/controller/IndexController.php
public function actionTestGreeting()
{
$config = new \Tars\client\CommunicatorConfig();
$config->setLocator(\Tars\App::$tarsConfig['tars']['application']['client']['locator']);
$userService = new \PHPHttp\servant\HelloWorld\PHPTars\Hello\SayHelloTafServiceServant($config);
$greeting = '';
$return = $userService->greeting('Frank Lee', $greeting);
$this->sendRaw(json_encode(compact('return', 'greeting')));
}
PHPHttp\servant\HelloWorld\PHPTars\Hello\SayHelloTafServiceServant
is generated by tars2php.sh\Tars\App::$tarsConfig
will be initialized by tars configs after service started.\Tars\App::$tarsConfig['tars']['application']['client']['locator']
is the location of registry object which provide route service for tars nodes.- !!!! Tars is a multi-language platform. We must initialize parameters with proper type before we made the call. !!!!
- Package you code and deploy
- You can check the result by access
http://{machine_ip}/index/TestGreeting