swoole / rfc

Swoole 提案
116 stars 3 forks source link

增强底层名字服务(服务端) #77

Open matyhtf opened 3 years ago

matyhtf commented 3 years ago

参考:https://github.com/swoole/community-chinese/issues/76

客户端支持 name_resolver 后,服务端可以在此基础上实现服务注册。

名字服务只支持IPv4IPv6协议的端口,对UnixSocket端口无效。

接口原型

interface RegisterInterface {
    function join(string $service_name, string  $ip, int $port);
    function leave(string  $service_name, string  $ip, int $port);
}

客户端

use function Swoole\Coroutine\run;
Co::set([
    'name_resolver' => [
        new Swoole\NameService\Redis('127.0.0.1', 6379),
    ],
]);

run(function () {
    echo Http\Get("http://user_service/path")->getBody();
});

服务端

use Swoole\Coroutine\Http\Server;
use function Swoole\Coroutine\run;

run(function () {
    $server = new Server("127.0.0.1", 8080);
    $server->set([
        'service_register' => [
            new Swoole\NameService\Redis('127.0.0.1', 6379),
            new Swoole\NameService\ZooKeeper('127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183'),
        ],
        'service_name' => 'user.service',
    ]);
    $server->handle('/', function ($req, $resp) {
        $resp->end('hello');
    });
    $server->start();
});

通过配置service_register选项实现服务注册,配置service_name设置服务名称。在:

包括TCPHTTPHTTP2WebSocketRedis\Server 协程和异步Server均支持此配置。

Client端不同name_resolver配置不同,service_register 配置项是的关系,底层会遍历service_register数组,依次调用每个service_registerjoin()方法。

service_registerPort级选项,某些端口如果不需要注册服务,可设置service_register => null 关闭

IP 地址

$server->set([
    'service_register' => [
        (new Swoole\NameService\Redis('127.0.0.1', 6379))->withAddress('127.0.0.1'),
        new Swoole\NameService\ZooKeeper('127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183'),
    ],
   'service_name' => 'user.service',
]);

端口

Register会自动获取Server\Port的端口,不需要外部传入。

续期

Server启动后底层会每隔一定时间调用RegisterInterface::join()方法向名字服务注册节点。可以在Register对象上使用withInterval($seconds)设置间隔时间。

$server->set([
    'service_register' => [
        (new Swoole\NameService\Redis('127.0.0.1', 6379))->withAddress('127.0.0.1')->withInterval(2),
        new Swoole\NameService\ZooKeeper('127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183'),
    ],
   'service_name' => 'user.service',
]);

上面例子会每隔2秒调用join()方法注册服务

健康检查

某些服务发现组件,如 consul 不需要Node主动续期,而是由服务发现主动进行健康检查,侦测节点是否存活。这时可以将join()间隔时间设置为0,不再主动续期。

当使用consul组件时会自动设置interval0

$server->set([
    'service_register' => [
        new Swoole\NameService\Consul('http://127.0.0.1:8500')->withHealthCheck($healthCheckConfig),
    ],
   'service_name' => 'user.service',
]);

限流策略

服务端在超过最大并发时拒绝新的请求,客户端收到服务器的拒绝信号后可以故障转移至其他节点,进行重试。