8、Hyperf 3 微服务系列 - Consul 服务注册与发现的使用

作者: 温新

分类: 【Hyperf 3 微服务系列】

阅读: 2123

时间: 2023-05-20 12:33:45

hi,我是温新,一名 PHPer

Hyperf 3 微服务代码已上传至 Github:https://github.com/ziruchu/hyperf3-microservice-code

学习目标:使用 consul

本篇文章将演示服务注册,然后消费者消费服务。在此之前先来看看已有的项目。

ll
    
note
note_consumer_user
note_provider_user

由于之前的代码内容是一样的,因此直接完整的复制原有的项目进行改造。一个服务提供者 note_provider_user_9601 和一个消费者 note_consumer_user_9501

note_provider_user_9601 提供者向 consul 服务中心注册服务,note_consumer_user_9501 从 consul 中发现服务。

服务注册,构建服务提供者

第一步:复制之前的服务提供者
cp -r note_provider_user note_provider_user_9601
    
cd shop_provider_user_9601

复制完成后,以下操作都在 note_provider_user_9601 中进行

第二步:.env 文件中修改项目名称
APP_NAME=node_provider_user_9601
第三步:修改 server.php 配置文件
<?php
// config/autoload/server.php
    
'servers' => [
    [
        'name' => 'jsonrpc-http',
        'type' => Server::SERVER_HTTP,
        'host' => '0.0.0.0',
        // 把端口修改为 9601
        'port' => 9601,
        'sock_type' => SWOOLE_SOCK_TCP,
        'callbacks' => [
            Event::ON_REQUEST => [\Hyperf\JsonRpc\HttpServer::class, 'onRequest'],
        ],
    ],
],
第四步:安装 consul 组件并生成配置文件
# 安装 consul 组件
composer require hyperf/service-governance-consul
    
# 生成配置文件
# 该命令会在 config/autoload 目录下生成 services.php 文件
php bin/hyperf.php vendor:publish hyperf/service-governance

services.php 配置文件内容如下:

<?php
// config/autoload/services.php
    
declare(strict_types=1);

return [
    'enable' => [
        // 开启服务发现
        'discovery' => true,
        // 开启服务注册
        'register' => true,
    ],
    // 服务消费者相关配置
    'consumers' => [],
    // 服务提供者相关配置
    'providers' => [],
    'drivers' => [
        // consul 配置
        'consul' => [
            // 服务中心地址
            'uri' => 'http://127.0.0.1:8500',
            // consul 权限控制所需要的 token
            'token' => '',
            'check' => [
                // 服务注销时间,若 consul 服务 90 分钟内没有收到心跳检测,
                // 那么 consul 就会从服务中心中提出当前关联的所有服务
                'deregister_critical_service_after' => '90m',
                // 健康检查时间,1 秒 检查一次
                'interval' => '1s',
            ],
        ],
    ],
];

到这里,所有准备工作就已经完成了,就差将服务发布到服务中心了。

第五步:通过注解将服务发布到 consul

把服务发布到 consul,通过注解中的 publishTo 参数,下面修改 UserService.php

<?php
// app/JsonRpc/Service/UserService.php
    
namespace App\JsonRpc\Service;

use App\JsonRpc\Interface\UserServiceInterface;
use App\Model\User;
use App\Tools\ResponseTool;
use Hyperf\RpcServer\Annotation\RpcService;
use Hyperf\ServiceGovernanceConsul\ConsulAgent;
use Hyperf\Utils\ApplicationContext;

#[RpcService(name: "UserService", protocol: "jsonrpc-http", server: "jsonrpc-http", publishTo: "consul")]
class UserService implements UserServiceInterface
{
	// 省略了 createUser getUserInfo 方法

    // 用于测试服务是否注册到服务中心
    public function test()
    {
        // 获取注册的服务
        $agent = ApplicationContext::getContainer()->get(ConsulAgent::class);

        return ResponseTool::success([
            'services' => $agent->services()->json(),
            'checks'   => $agent->checks()->json(),
        ]);
    }
}
第六步:测试 consul 服务

测试之前,启动 consul 服务和 note_provider_user_9601 服务。

使用 postman 进行测试:

POST http://192.168.31.90:9601
参数 
{
    "jsonrpc": "2.0",
    "method": "/user/test",
    "params": {
    },
    "id": "",
    "context": []
}

返回结果
{
    "jsonrpc": "2.0",
    "id": "",
    "result": {
        "code": 200,
        "message": "success",
        "data": {
            "services": {
                "UserService-0": {
                    "ID": "UserService-0",
                    "Service": "UserService",
                    "Tags": [],
                    "Meta": {
                        "Protocol": "jsonrpc-http"
                    },
                    "Port": 9601,
                    "Address": "192.168.31.90",
                    "TaggedAddresses": {
                        "lan_ipv4": {
                            "Address": "192.168.31.90",
                            "Port": 9601
                        },
                        "wan_ipv4": {
                            "Address": "192.168.31.90",
                            "Port": 9601
                        }
                    },
                    "Weights": {
                        "Passing": 1,
                        "Warning": 1
                    },
                    "EnableTagOverride": false,
                    "Datacenter": "dc1"
                }
            },
            "checks": {
                "service:UserService-0": {
                    "Node": "localhost.localdomain",
                    "CheckID": "service:UserService-0",
                    "Name": "Service 'UserService' check",
                    "Status": "passing",
                    "Notes": "",
                    "Output": "HTTP GET http://192.168.31.90:9601/: 200 OK Output: ",
                    "ServiceID": "UserService-0",
                    "ServiceName": "UserService",
                    "ServiceTags": [],
                    "Type": "http",
                    "Interval": "1s",
                    "Timeout": "",
                    "ExposedPort": 0,
                    "Definition": [],
                    "CreateIndex": 0,
                    "ModifyIndex": 0
                }
            }
        }
    },
    "context": []
}

通过测试发现,已经成功注册了 IDUserService-0 的服务,其状态 "Status": "passing", 是正常状态。

第七步:访问 web 界面查看服务

访问地址:http://192.168.31.90:8500

服务发现,构建消费者使用服务

第一步:复制之前的消费者
cp -r note_consumer_user note_consumer_user_9501
    
cd note_consumer_user_9501

复制完成后,以下操作都在 note_consumer_user_9501中进行

复制完成后,什么都不动,继续走下面的步骤。

第二步:安装 consul 组件
composer require hyperf/service-governance-consul
第三步:修改 services.php 配置
<?php
// config/autoload/services.php

// 服务接口
$services = [
    'UserService' => \App\JsonRpc\Interface\UserServiceInterface::class,
];

return [
    'consumers' => value(function () use($services) {
        $consumers = [];
        foreach ($services as $name => $interface) {
            $consumers[] = [
                'name'          => $name,
                'service'       => $interface,
                'load_balancer' => 'random',
                'registry'      => [
                    'protocol' => 'consul',
                    'address'  => 'http://192.168.31.90:8500'
                ]
            ];
        }
        return $consumers;
    }),
];
第四步:测试使用消费者

测试之前,启动 note_consumer_user_9501 服务。

下面使用 postman 进行测试:

GET http://192.168.31.90:9501/users/show?id=1

返回数据
{
    "code": 200,
    "message": "success",
    "data": {
        "id": 1,
        "name": "李四",
        "gender": 1,
        "created_at": "2023-03-21 04:37:43",
        "updated_at": "2023-03-21 04:37:43"
    }
}

下面通过终端测试

$ curl http://192.168.31.90:9501/users/show?id=1
{"code":200,"message":"success","data":{"id":1,"name":"李四","gender":1,"created_at":"2023-03-21 04:37:43","updated_at":"2023-03-21 04:37:43"}}

还可以通过浏览器访问。

本篇文章结束,我是温新。

请登录后再评论