16、Hyperf 3 微服务系列 - Hyperf 3 使用 Zipkin 分布式调用链追踪

作者: 温新

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

阅读: 2887

时间: 2023-05-29 16:00:53

hi,我是温新,一名 PHPer

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

了解分布式调用链之前,先来看一个问题,如下:

我们在某视频购买了会员,但是并没有升级为 VIP 用户,还是普通用户。由于拆分了很多服务,不知道是哪一个服务出现了问题,此时该如何去定位问题?

hyperf 官方提供了一款非常好用的分布式调用链追踪组件—— hyperf/tracer。该组件可以对和各个跨网络请求进行追踪分析,包括请求方法、异常、Guzzle HTTP 调用、Redis 调用、DB 调用都可以进行监听,还能通过可视化界面进行监控管理。

安装 Zipkin

我这里是在 192.168.31.90 这台服务器进行安装的 zipkin。

使用 docker 进行安装

# 安装
docker pull openzipkin/zipkin
# 启动
docker run --name zipkin -d -p 9411:9411 openzipkin/zipkin

安装完成后,可以通过 http://192.168.31.90:9411/ 进行访问,如下图:

Hyperf 调用链追踪

说明:

1、仍旧使用 Nacos 作为注册中心;

2、使用 192.168.31.90 服务器的 shop_consumer_user_9502 项目作为消费者;

3、使用 192.168.31.92 服务器的 shop_provider_user_9605 项目作为服务提供者。

配置服务提供者

当前位置:192.168.31.92 中的 shop_provider_user_9605

第一步:安装组件
# 安装调用链追踪组件
composer require hyperf/tracer
# 可选
# hyperf/tracer 组件默认安装了 Zipkin 相关依赖
# 若要看 redis 效果,可以安装该组件
composer require hyperf/cache
第二步:生成 hyperf/tracer 配置文件

1、生成配置文件

php bin/hyperf.php vendor:publish hyperf/tracer

2、修改配置文件

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

use Zipkin\Samplers\BinarySampler;

return [
    // 默认为 zipkin,且没有开启服务
    'default' => env('TRACER_DRIVER', 'zipkin'),
    'enable' => [
        'guzzle' => env('TRACER_ENABLE_GUZZLE', false),
        'redis' => env('TRACER_ENABLE_REDIS', false),
        'db' => env('TRACER_ENABLE_DB', false),
        'method' => env('TRACER_ENABLE_METHOD', false),
        'exception' => env('TRACER_ENABLE_EXCEPTION', false),
    ],
    'tracer' => [
        'zipkin' => [
            'driver' => Hyperf\Tracer\Adapter\ZipkinTracerFactory::class,
            'app' => [
                'name' => env('APP_NAME', 'skeleton'),
                // 本地服务器 IP
                'ipv4' => '192.168.31.92',
                'ipv6' => null,
                'port' => 9602,
            ],
            'options' => [
                // 注意:这里是 Zipkin 服务所在的服务器 IP
                'endpoint_url' => env('ZIPKIN_ENDPOINT_URL', 'http://192.168.31.90:9411/api/v2/spans'),
                'timeout' => env('ZIPKIN_TIMEOUT', 1),
            ],
            'sampler' => BinarySampler::createAsAlwaysSample(),
        ],
    ],
    
	// 省略了没有写出来的配置
];

3、配置 .env 文件,开启 Zipkin 服务

APP_NAME=note_provider_user_9605
TRACER_ENABLE_GUZZLE=true
TRACER_ENABLE_REDIS=true
TRACER_ENABLE_DB=true
TRACER_ENABLE_METHOD=true
TRACER_ENABLE_EXCEPTION=true
第三步:配置中间件

配置完驱动之后,采集信息还需要配置一下中间件才能启用采集功能。

<?php
// config/autoload/middlewares.php
return [
    'jsonrpc-http' => [
        \Hyperf\Tracer\Middleware\TraceMiddleware::class,
    ],
];
第四步:编写业务代码

1、添加接口方法

<?php
// app/JsonRpc/Interface/UserServiceInterface.php    
public function getUserInfoFromCache(int $id);

2、实现接口方法

<?php
// app/JsonRpc/Service/UserService.php
    
public function getUserInfoFromCache(int $id)
{

    $user = User::query()->find($id);
    if (empty($user)) {
        throw new \RuntimeException('没有该用户');
    }

    return ResponseTool::success($user->toArray());
}

配置服务消费者

当前位置:192.168.31.90 中的 shop_consumer_user_9502

第一步:安装组件
composer require hyperf/tracer
第二步:生成配置文件

1、生成配置文件

php bin/hyperf.php vendor:publish hyperf/tracer

2、修改配置文件

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

use Zipkin\Samplers\BinarySampler;

return [
    'default' => env('TRACER_DRIVER', 'zipkin'),
    'enable'  => [
        'guzzle'    => env('TRACER_ENABLE_GUZZLE', false),
        'redis'     => env('TRACER_ENABLE_REDIS', false),
        'db'        => env('TRACER_ENABLE_DB', false),
        'method'    => env('TRACER_ENABLE_METHOD', false),
        'exception' => env('TRACER_ENABLE_EXCEPTION', false),
    ],
    'tracer' => [
        'zipkin' => [
            'driver'  => Hyperf\Tracer\Adapter\ZipkinTracerFactory::class,
            'app'     => [
                'name' => env('APP_NAME', 'skeleton'),
                'ipv4' => '192.168.31.90',
                'ipv6' => null,
                'port' => 9502,
            ],
            'options' => [
                'endpoint_url' => env('ZIPKIN_ENDPOINT_URL', 'http://192.168.31.90:9411/api/v2/spans'),
                'timeout'      => env('ZIPKIN_TIMEOUT', 1),
            ],
            'sampler' => BinarySampler::createAsAlwaysSample(),
        ],  
    ],
];

3、配置 .env 文件,开启 Zipkin 服务

APP_NAME=note_consumer_user_9502
TRACER_ENABLE_GUZZLE=true
TRACER_ENABLE_REDIS=true
TRACER_ENABLE_DB=true
TRACER_ENABLE_METHOD=true
TRACER_ENABLE_EXCEPTION=true
第三步:配置 JsonRPC 追踪开关

JsonRPC 的链路追踪并不在统一配置当中,暂时还属于 Beta 版本的功能。

我们只需要配置 aspects.php,加入以下 Aspect 即可开启。

提示:不要忘了在对端,添加对应的 TraceMiddleware

<?php
 // config/autoload/aspects.php
return [
    Hyperf\Tracer\Aspect\JsonRpcAspect::class,
];
第四步:配置中间件
<?php
// config/autoload/middlewares.php
return [
    'http' => [
        \Hyperf\Tracer\Middleware\TraceMiddleware::class,
    ],
];
第五步:编写业务代码

1、添加接口方法

<?php
// app\JsonRpc\Interface\UserServiceInterface.php
    
public function getUserInfoFromCache(int $id);

2、实现接口方法

<?php
// app\JsonRpc\Service\UserService.php
    
public function getUserInfoFromCache(int $id)
{
    return $this->__request(__FUNCTION__, compact('id'));
}

3、编写控制器代码

<?php
// app\Controller\UserController.php

#[GetMapping('/users/getUserInfoFromCache')]
public function getUserInfoFromCache()
{
    $id = (int) $this->request->input('id');

    $result = $this->userService->getUserInfoFromCache($id);
    if ($result['code'] != ResponseCode::SUCCESS) {
        throw new  \RuntimeException($result['message']);
    }

    return ResponseTool::success($result['data']);
}

最后启动服务者和消费者。

测试

测试一:使用 postman 或浏览器测试
$ curl http://192.168.31.90:9502/users/getUserInfoFromCache?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"
    }
}

1、现在打开 Zipkin 后台,然后点 + 号,选择 note_consumer_user_9502,然后点击 run query,就能看到查询结果了。

2、点击 SHOW 查看详情

从详情中可以看到 jsonrpc、request、db 等操作。

测试二:服务器出错

现在我们查询一条不存在的记录,然后看看链追踪中是什么情况。

$ curl http://192.168.31.90:9502/users/getUserInfoFromCache?id=111
{
    "code": -32000,
    "message": "node_provider_user_9605-0.0.0.0:9605-没有该用户"
}

1、我们来看看 Zipkin 中的情况:

2、查看详情

从结果中可以发现,对于出错的请求,调用链会被标记上红色符号,点击该请求就可以进入到详情界面查看具体情况。

还可以查看 SQL 语句,点击一下 db:query 就可以了,这里不截图了。

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

请登录后再评论
tiancheng 2024-04-26 18:03:18
链路追踪只能追踪到消费者请求provider的请求,那我如何继续跟踪provider下面的数据库或者Redis的一些操作呢。再或者说我provider还请求了支付服务、日志服务,这些链路不能进行一整条的追踪吗
dkd 2024-01-17 16:59:43
文章的格式不对呢 没法看😂
2024-01-25 12:13:07
这个是由于富文本与 markdown 的显示不兼容导致的,后续会处理哦