9、Hyperf 3 微服务系列 - Consul 集群
hi,我是温新,一名 PHPer
Hyperf 3 微服务代码已上传至 Github:https://github.com/ziruchu/hyperf3-microservice-code
学习目标:学习 consul 集群
生产环境中,服务一般都是以集群方式部署,服务部分一般是在 3~5 台服务器。本篇文章将使用 4 台服务器(虚拟机)来演示,其中有 3 台是 consul 服务器。
准备工作
项目说明
如果是一步一步来走,不出意外,你的项目和我的应该是一样的。本次集群的部署就是复制下面某个应用的代码。
note
note_consumer_user
note_consumer_user_9501
note_provider_user
note_provider_user_9601
准备 4 台服务器
注意:这 4 台服务器我全部使用的是 Rocky Linux 9.1。
服务器 IP | Consul 类型 | Node 节点 | 服务类型 |
---|---|---|---|
192.168.31.92 | server | server-01 | 服务者 |
192.168.31.93 | server | server-02 | 服务者 |
192.168.31.94 | server | server-03 | 服务者 |
192.168.31.90 | client | client-01 | 消费者 |
注意:确保 92、93、94 这三台服务器安装了 PHP。
Consul 集群部署
第一步:安装 Consul
我们需要在 92
、93
、94
这三台服务安装 Consul 服务,关于怎么安装这里就不再啰嗦了,参考:Hyperf 3 快速使用 - Hyperf 3 微服务系列 - Consul 服务注册与发现 - Rocky Linux 9.1 安装 Consul
第二步:复制项目代码
把 note_provider_user_9601 整体复制到其他 3 台服务器并重命名。
$ scp -r ./note_provider_user_9601/ hy@192.168.31.92:/www/note_provider_user_9602
$ scp -r ./note_provider_user_9601/ hy@192.168.31.93:/www/note_provider_user_9603
$ scp -r ./note_provider_user_9601/ hy@192.168.31.94:/www/note_provider_user_9604
第三步:修改 3 台服务器中代码
1、修改 note_provider_user_9602
# 修改 .env 文件
APP_NAME=node_provider_user_9602
DB_HOST=192.168.31.90
# 修改 config/autoload/server.php
'servers' => [
[
'name' => 'jsonrpc-http',
'type' => Server::SERVER_HTTP,
'host' => '0.0.0.0',
'port' => 9602,
'sock_type' => SWOOLE_SOCK_TCP,
'callbacks' => [
Event::ON_REQUEST => [\Hyperf\JsonRpc\HttpServer::class, 'onRequest'],
],
],
],
2、修改 note_provider_user_9603
# 修改 .env 文件
APP_NAME=node_provider_user_9603
DB_HOST=192.168.31.90
# 修改 config/autoload/server.php
'servers' => [
[
'name' => 'jsonrpc-http',
'type' => Server::SERVER_HTTP,
'host' => '0.0.0.0',
'port' => 9603,
'sock_type' => SWOOLE_SOCK_TCP,
'callbacks' => [
Event::ON_REQUEST => [\Hyperf\JsonRpc\HttpServer::class, 'onRequest'],
],
],
],
3、修改 note_provider_user_9604
# 修改 .env 文件
APP_NAME=node_provider_user_9604
DB_HOST=192.168.31.90
# 修改 config/autoload/server.php
'servers' => [
[
'name' => 'jsonrpc-http',
'type' => Server::SERVER_HTTP,
'host' => '0.0.0.0',
'port' => 9604,
'sock_type' => SWOOLE_SOCK_TCP,
'callbacks' => [
Event::ON_REQUEST => [\Hyperf\JsonRpc\HttpServer::class, 'onRequest'],
],
],
],
4、分别为这 3 台服务提供者添加如下代码,用于区分调用的是哪台服务器的服务
添加接口
<?php
// app/JsonRpc/Interface/UserServiceInterface.php
public function test();
实现接口
<?php
// app/JsonRpc/Service/UserService.php
use Hyperf\Utils\ApplicationContext;
use Hyperf\Contract\ConfigInterface;
public function test()
{
$host = '';
$config = ApplicationContext::getContainer()->get(ConfigInterface::class);
$servers = $config->get('server.servers');
$appName = $config->get('app_name');
foreach ($servers as $server) {
if ($server['name'] == 'jsonrpc-http') {
$host = $server['host'];
break;
}
}
return ResponseTool::success([
'app_name' => $appName,
'host' => $host,
]);
}
第四步:启动 Consul
1、服务端启动 consul
#
consul agent -server -bind=192.168.31.92 -client=0.0.0.0 -ui -bootstrap-expect=3 -data-dir=/usr/local/software/consul/data/ -node=server-01
consul agent -server -bind=192.168.31.93 -client=0.0.0.0 -ui -bootstrap-expect=3 -data-dir=/usr/local/software/consul/data/ -node=server-02
consul agent -server -bind=192.168.31.94 -client=0.0.0.0 -ui -bootstrap-expect=3 -data-dir=/usr/local/software/consul/data/ -node=server-03
2、消费端以 client 模式启动
consul agent -client=0.0.0.0 -data-dir=/usr/local/software/consul/data/ -ui -bind=192.168.31.90 -node=client-01
第五步:加入集群
# 位置 192.168.31.93(服务者)
# 显示认为 92 这台服务器是主节点
consul join 192.168.31.92
# 位置 192.168.31.94(服务者)
consul join 192.168.31.92
# 位置 192.168.31.90 (消费者)
consul join 192.168.31.92
所有 consul 加入 92 这台服务器,把它当作主节点。
服务启动后,每台服务可以访问 web 管理界面。
第六步:查看集群
$ consul members
Node Address Status Type Build Protocol DC Partition Segment
server-01 192.168.31.92:8301 alive server 1.15.1 2 dc1 default <all>
server-02 192.168.31.93:8301 alive server 1.15.1 2 dc1 default <all>
server-03 192.168.31.94:8301 alive server 1.15.1 2 dc1 default <all>
client-01 192.168.31.90:8301 alive client 1.15.1 2 dc1 default <default>
消费者调用服务者
消费者继续使用 note_consumer_user_9501
这个项目。
第一步:修改接口
<?php
// app/JsonRpc/Interface/UserServiceInterface.php
public function test();
第二步:实现接口方法
<?php
// app/JsonRpc/Service/UserService.php
public function test()
{
return $this->__request(__FUNCTION__);
}
第三步:控制器调用
<?php
// app/Controller/UserController.php
use App\Tools\ResponseTool;
#[GetMapping('/users/test')]
public function test()
{
return ResponseTool::success($this->userService->test());
}
第四步:测试 consule 集群
先调用获取用户方法
# 通过浏览器访问,刷新 N 次,都是一样的结果
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"
}
}
测试调用的哪个 consul 服务
# 多刷新几次,注意 app_name 的变化
http://192.168.31.90:9501/users/test
{
"code": 200,
"message": "success",
"data": {
"code": 200,
"message": "success",
"data": {
"app_name": "node_provider_user_9602",
"host": "0.0.0.0"
}
}
}
http://192.168.31.90:9501/users/test
{
"code": 200,
"message": "success",
"data": {
"code": 200,
"message": "success",
"data": {
"app_name": "node_provider_user_9604",
"host": "0.0.0.0"
}
}
}
从这个测试结果中,我们可以看到集群已经生效,而且正被我们使用者。
现在继续测试,断开一台 consul 服务器,然后进行测试,服务还是正常运行。
集群策略
集群已经搭建完成,也可以正常使用了,通过尽情的测试,它会在 92、93、94 这三个服务者中不断轮转,有点像 nginx 的负载均衡。现在回顾一下配置文件,来看看其中策略。
<?php
// 位置:note_consumer_user_9501 消费者服务
// 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;
}),
];
load_balancer
为负载均衡算法,默认值为 random
我是温新,本篇文章到此结束。