Hyperf微服务——四、第一个微服务的搭建
一、JSON RPC 服务
是一种基于 JSON 格式的轻量级的 RPC 协议标准,易于使用和阅读。在 Hyperf 里由 hyperf/json-rpc 组件来实现,可自定义基于 HTTP 协议来传输,或直接基于 TCP 协议来传输。
服务有两种角色,一种是 服务提供者(ServiceProvider),即为其它服务提供服务的服务,另一种是 服务消费者(ServiceConsumer),即依赖其它服务的服务,一个服务既可能是 服务提供者(ServiceProvider),同时又是 服务消费者(ServiceConsumer)。 而两者直接可以通过 服务契约 来定义和约束接口的调用,在 Hyperf 里,可直接理解为就是一个 接口类(Interface),通常来说这个接口类会同时出现在提供者和消费者下。
二、定义服务提供者
1.安装rpc相关依赖
#安装json-rpc协议
composer require hyperf/json-rpc
#安装rpc服务端
composer require hyperf/rpc-server
#安装rpc客户端
composer require hyperf/rpc-client
2.修改配置文件config/autoload/server.php ,增加TCP Server
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
use Hyperf\Server\Event;
use Hyperf\Server\Server;
use Swoole\Constant;
return [
'mode' => SWOOLE_PROCESS,
'servers' => [
//此处提供TCP Server (适配 jsonrpc 协议)
[
'name' => 'jsonrpc',
'type' => Server::SERVER_BASE,
'host' => '0.0.0.0',
'port' => 9503,
'sock_type' => SWOOLE_SOCK_TCP,
'callbacks' => [
Event::ON_RECEIVE => [\Hyperf\JsonRpc\TcpServer::class, 'onReceive'],
],
'settings' => [
'open_eof_split' => true,
'package_eof' => "\r\n",
'package_max_length' => 1024 * 1024 * 2,
],
],
//此处配置提供http服务,
[
'name' => 'http',
'type' => Server::SERVER_HTTP,
'host' => '0.0.0.0',
'port' => 9501,
'sock_type' => SWOOLE_SOCK_TCP,
'callbacks' => [
Event::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest'],
],
],
],
//其他配置
'settings' => [
Constant::OPTION_ENABLE_COROUTINE => true,
Constant::OPTION_WORKER_NUM => swoole_cpu_num(),
Constant::OPTION_PID_FILE => BASE_PATH . '/runtime/hyperf.pid',
Constant::OPTION_OPEN_TCP_NODELAY => true,
Constant::OPTION_MAX_COROUTINE => 100000,
Constant::OPTION_OPEN_HTTP2_PROTOCOL => true,
Constant::OPTION_MAX_REQUEST => 100000,
Constant::OPTION_SOCKET_BUFFER_SIZE => 2 * 1024 * 1024,
Constant::OPTION_BUFFER_OUTPUT_SIZE => 2 * 1024 * 1024,
],
'callbacks' => [
Event::ON_WORKER_START => [Hyperf\Framework\Bootstrap\WorkerStartCallback::class, 'onWorkerStart'],
Event::ON_PIPE_MESSAGE => [Hyperf\Framework\Bootstrap\PipeMessageCallback::class, 'onPipeMessage'],
Event::ON_WORKER_EXIT => [Hyperf\Framework\Bootstrap\WorkerExitCallback::class, 'onWorkerExit'],
],
];
3.安装统一接入层
#安装统一接入层
composer require hyperf/service-governance
#安装适配器
composer require hyperf/service-governance-consul
4.发布服务到consul
#发布配置文件
php bin/hyperf.php vendor:publish hyperf/service-governance
组件由 config/autoload/services.php 配置文件来驱动
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
return [
'enable' => [
'discovery' => true,
'register' => true,
],
'consumers' => [],
'providers' => [],
'drivers' => [
'consul' => [
'uri' => env('CONSUL_URI', 'http://127.0.0.1:8500'), //此处为自己的consul地址
'token' => '',
'check' => [
'deregister_critical_service_after' => '90m',
'interval' => '1s',
],
],
],
];
5.定义服务提供者
定义服务提供的接口,在app目录下创建JsonRpc目录并创建interface文件
<?php
namespace App\JsonRpc;
interface UserInterface
{
public function getUserInfoById($id);
}
定义实现接口的服务,在app目录下创建service目录并创建service文件
<?php
namespace App\Service;
use App\JsonRpc\UserInterface;
use Hyperf\RpcServer\Annotation\RpcService;
/**
* Class UserService
* @author Justin by 2022/6/17
* @package App\Service
* @RpcService(name="UserService", protocol="jsonrpc", server="jsonrpc", publishTo="consul")
*/
class UserService extends AbstructService implements UserInterface
{
/**
* @param $id
* @return array
*/
public function getUserInfoById($id) :array
{
return [];
}
}
@RpcService 共有 4 个参数:
name 属性为定义该服务的名称,这里定义一个全局唯一的名字即可,Hyperf 会根据该属性生成对应的 ID 注册到服务中心去;
protocol 属性为定义该服务暴露的协议,目前仅支持 jsonrpc-http, jsonrpc, jsonrpc-tcp-length-check ,分别对应于 HTTP 协议和 TCP 协议下的两种协议,默认值为 jsonrpc-http,这里的值对应在 Hyperf\Rpc\ProtocolManager 里面注册的协议的 key,它们本质上都是 JSON RPC 协议,区别在于数据格式化、数据打包、数据传输器等不同。
server 属性为绑定该服务类发布所要承载的 Server,默认值为 jsonrpc-http,该属性对应 config/autoload/server.php 文件内 servers 下所对应的 name,这里也就意味着我们需要定义一个对应的 Server;
publishTo 属性为定义该服务所要发布的服务中心,目前仅支持 consul、nacos 或为空,为空时代表不发布该服务到服务中心去,但也就意味着您需要手动处理服务发现的问题,要使用此功能需安装 hyperf/service-governance 组件及对应的驱动依赖,具体可参考 服务注册 章节;
以上配置完成后,在启动服务时,Hyperf 会提供HTTP服务和TCP服务,并自动地将 @RpcService 定义了 publishTo 属性为 consul 的服务注册到对应的服务中心去。
进入consulweb界面,可以看到UserService服务已经注册到服务中心。
至此,一个用户服务已经成功创建并注册到consul中心,其他服务可以通过consul发现该服务并调用
getUserInfoById接口。
三、服务调用
这是一个简单的服务内部调用接口实现方法的方式。
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace App\Controller;
use App\Lib\UserInfoInterface;
use Hyperf\Utils\ApplicationContext;
class IndexController extends AbstractController
{
public function index()
{
//通过容器依赖注入的方式进行RPC调用
$user_info = ApplicationContext::getContainer()->get(UserInfoInterface::class);
return $user_info->getUserInfoById(1);
}
}
至此,一个简单的微服务调用已经实现了。下面就可以根据实际的业务场景进行深度开发了。
后面会介绍如何进行跨服务间的RPC调用。