限时 5折! 详情

hyperf 实战之链路追踪

1632 0 0

前面我们实现了提问题、问题详情、热门榜单、问题搜索、问题列表等一系列接口,假设榜单的数据异常了,但是详情接口返回正常,现在我们不能直接看出具体问题,这个时候我们怎么快速定位问题?看日志,打断点是我们日常中常用的解决方法,今天要给大家介绍的是链路追踪,链路追踪常用于微服务中,hyperf 官方提供了一款非常好用的分布式调用链追踪组件—— hyperf/tracer。tracer 组件可以在分布式系统中追踪一个请求的处理过程,包括对 Guzzle HTTP 调用、Redis 调用、DB 调用进行了监听或 AOP 切面处理,以实现对调用链的传播与追踪,通过可视化界面非常方便监控整个链路。

我们今天讲解的内容主要有3点,包括

  1. Zipkin
  2. 阿里云链路追踪
  3. Trace 服务

首先用 docker 安装 Zipkin 并直接启动它。

docker pull openzipkin/zipkin
docker run --name zipkin -d -p 9411:9411 openzipkin/zipkin

浏览器访问 http://127.0.0.1:9411/ 可以看到 zipkin 的管理后台。

安装 tracer 组件

composer require hyperf/tracer

新增配置文件

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

默认情况下这些追踪不会打开,我们需要通过更改 config/autoload/opentracing.php 配置文件内的 enable 项内的开关来打开对某些远程调用的追踪。

.env 新增配置

TRACER_DRIVER=zipkin

去购买

还有90%的精彩内容,购买继续阅读

登录 后发布评论
  • 阿里云使用Zipkin接入一直在检查接入状态检查

  • 阿里云链路追踪打开 集群配置和上面不一样呢,有时间了麻烦更新一下吧

  • 请教一下, tracer 日志怎么包含Logger? 在业务代码中,一些逻辑下需要写日志的,这些日志如果可以在tracer 日志内体现,将非常方便排查

    • 自问自答吧:
      1. 封装一个类似于laravel的Log门面
      2. 使用上下文获取span , 例如:$span = Context::get( 'tracer.root' );
      3. 在span内写入log内容, 例如:
      $span->log( [
      'level' => $method ,
      'message' => is_array( $arguments[0] ) ? json_encode( $arguments[0] ) : $arguments[0] ,
      'context' => is_array( $arguments[1] ) ? json_encode( $arguments[1] ) : $arguments[1] ,
      ] );

      当然,示例只是一个示例,各位需要考虑健壮性,处理异常等情况

  • 请问一下“Installation failed, reverting ./composer.json and ./composer.lock to their original content.”这个问题怎么解决呢?百度了三板斧也没效果:删除 composer.lock、composer clearcache、composer update

  • public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
    if ($lang = $request->getHeaderLine('lang')) {
    $this->translator->setLocale($lang);
    }

    // zipkin链路追踪 trace
    $span = Context::get('tracer.root');
    //这里输出的是null
    var_dump($span);
    $response = Context::get(ResponseInterface::class);
    $response = $response->withHeader('Trace-Id', $span->getContext()->getContext()->getTraceId());
    Context::set(ResponseInterface::class, $response);

    return $handler->handle($request);
    }

    $span = Context::get('tracer.root');输出是null

    [root@gometer ~]# curl 192.168.63.160:9541/question/1
    {"code":500,"message":"Call to a member function getContext() on null"}
    [root@gometer ~]#

    • composer info | grep hyperf/tracer 看下版本多少

    • 解决了,中间件顺序问题

      <?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 [
      'http' => [
      #注意:TraceMiddleware::class中间件放到GlobalMiddleware::class上面,否则GlobalMiddleware::class中的 $span = Context::get('tracer.root');获取的null
      \Hyperf\Tracer\Middleware\TraceMiddleware::class, // zipkin链路追踪
      \App\Middleware\GlobalMiddleware::class, // 全局中间件
      \Hyperf\Validation\Middleware\ValidationMiddleware::class, // 验证器
      ],
      ];

    • 666老铁