热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Jaeger链路追踪在项目中的应用

前言随着公司内部项目交互越来越多,一个请求的调用链路也会变长,如何快速定位接口问题也成为了项目中需要考虑的因素,链路追踪工具就是为了解决这个问题而生。常见的链路追踪工具:APM这是






前言

随着公司内部项目交互越来越多,一个请求的调用链路也会变长,如何快速定位接口问题也成为了项目中需要考虑的因素,链路追踪工具就是为了解决这个问题而生。常见的链路追踪工具:



  • APM
    这是Elasticsearch内置的一个链路追踪工具,支持主流的语言,如果你的应用是fpm的架构,并且想要最小的改动在项目中接入链路的话,这是一个不错的选择,只需要加一个扩展就行了。但由于我们的项目使用的大多数都是Hyperf框架,APM扩展会和Swoole冲突,所以放弃。


  • Jaeger
    这是Uber推出的一款比较成熟的链路追踪工具,关于它的介绍自己百度一下就行了,我们这里就选用的是jaegerHyperf框架已经有了jaeger的包,可以直接使用,这里主要是记录如何在传统框架接入jaeger


效果图:


一、接入


网上几乎搜不到php接入jaeger的有用的文章,全是长篇大论的理论知识,但对于php开发人员来讲,他只想直接精通,最好把代码扔脸上,所以,我就是来干这个事情的。


明确一点,一个请求有一个rootSpan(根),在上图中就是最开始的那个request,后续的所有需要记录的操作,比如dbredis都是requestchildSpan,他们是request的子级,而dbredis是同级fllowSpan,他们是兄弟关系,先用最简单的示例看一下(startActiveSpan这种方式不太好直接应用到服务中,这里只用作演示):



  • 安装包
    composer require jonahgeorge/jaeger-client-php


  • 测试代码

    // 初始化全局配置(可以放到框架启动的时候执行)
    $config = new Config(
    [
    'sampler' => [
    'type' => Jaeger\SAMPLER_TYPE_CONST,
    'param' => true,
    ],
    'logging' => true,
    // tags记录需要记录的参数有哪些,自定义
    "tags" => [
    'http.url' => 'http.url',
    'http.method' => 'http.method',
    'http.status_code' => 'http.status_code',
    'db.query' => 'db.query',
    'db.statement' => 'db.statement',
    'db.query_time' => 'db.query_time',
    'path' => 'request.path',
    'method' => 'request.method',
    'header' => 'request.header',
    'status_code' => 'response.status_code',
    ],
    // jaeger的地址,这个需要你提交搭建好jaeger服务
    "local_agent" => [
    "reporting_host" => "web-jaeger.your-domain.com",
    "reporting_port" => 5775
    ],
    // 使用udp协议传输数据
    'dispatch_mode' => Config::ZIPKIN_OVER_COMPACT_UDP,
    ],
    // 服务的名字,比如订单中心
    'order-center'
    );
    // 初始化配置
    $config->initializeTracer();
    // 全局的trancer对象,这是一个单例对象
    $tracer = GlobalTracer::get();
    // 创建一个根时间分段,startActiveSpan第一个参数是自定义当前操作的名称,这里定义成
    // request,代表一个请求,注意scope的代码结构,是一个包含的关系
    // 每一个span对应一个start和一个close,它们是成对出现。
    $scope = $tracer->startActiveSpan('request', []);
    // tag记录一些短参数,比如header头,请求方法等
    $scope->getSpan()->setTag("tag1", "value1");
    $scope->getSpan()->setTag("tag2", "value2");
    $scope->getSpan()->setTag("tag3", "value2");
    // log记录一些大的参数,比如请求的json
    $scope->getSpan()->log([
    "key1" => "value1",
    "key2" => 2,
    "key3" => true
    ]);
    // 创建$scope子分段
    $nestedSpanScope1= $tracer->startActiveSpan("db.query");
    $nestedSpanScope1->getSpan()->setTag("tag1", "value1");
    $nestedSpanScope1->getSpan()->setTag("tag2", "value2");
    $nestedSpanScope1->getSpan()->setTag("tag3", "value2");
    $nestedSpanScope1->getSpan()->log([
    "key1" => "value1",
    "key2" => 2,
    "key3" => true
    ]);
    // 创建$nestedSpanScope1的子分段
    $nestedSpanScope11 = $tracer->startActiveSpan("redis.get");
    $nestedSpanScope11->getSpan()->setTag("tag1", "value1");
    $nestedSpanScope11->getSpan()->setTag("tag2", "value2");
    $nestedSpanScope11->getSpan()->setTag("tag3", "value2");
    $nestedSpanScope11->getSpan()->log([
    "key1" => "value1",
    "key2" => 2,
    "key3" => true
    ]);
    $nestedSpanScope11->close();
    $nestedSpanScope12= $tracer->startActiveSpan("oa");
    // 假设oa接口返回的数据是这样的
    $oaResponseData = [];
    $nestedSpanScope12->getSpan()->setTag("http.url", "xxx.oa.com");
    $nestedSpanScope12->getSpan()->setTag("http.method", "POST");
    $nestedSpanScope12->getSpan()->setTag("http.status_code", 200);
    $nestedSpanScope12->getSpan()->log($oaResponseData);
    $nestedSpanScope12->close();
    $nestedSpanScope1->close();
    // 创建$scope的子分段
    $nestedSpanScope2 = $tracer->startActiveSpan("db.insert");
    $nestedSpanScope2->getSpan()->setTag("tag1", "value1");
    $nestedSpanScope2->getSpan()->setTag("tag2", "value2");
    $nestedSpanScope2->getSpan()->setTag("tag3", "value2");
    $nestedSpanScope2->getSpan()->log([
    "key1" => "value1",
    "key2" => 2,
    "key3" => true
    ]);
    // 创建$nestedSpanScope2的子分段
    $nestedSpanScope21 = $tracer->startActiveSpan("redis.hget");
    $nestedSpanScope21->getSpan()->setTag("tag1", "value1");
    $nestedSpanScope21->getSpan()->setTag("tag2", "value2");
    $nestedSpanScope21->getSpan()->setTag("tag3", "value2");
    $nestedSpanScope21->getSpan()->log([
    "key1" => "value1",
    "key2" => 2,
    "key3" => true
    ]);
    $nestedSpanScope21->close();
    $nestedSpanScope2->close();
    $scope->close();
    // 一个请求最终只有一个flush,表示把之前记录的span关系全部写入jaeger服务中
    $tracer->flush();

  • 层级结构

    order-center request
    |--- order-center db.query
    |--- order-center redis.get
    order-center db.insert
    |--- order-center redis.hge


二、项目应用

先不写了,过会儿再写




laravel
分布式事务
swoole
hyperf
php


推荐阅读
  • 如何通过swoole加速laravel的问题?
    这篇文章主要介绍了关于如何使用swoole加速laravel,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下再来复习一下吧,导致php慢的各种因素中解析性语言的 ... [详细]
  • php怎么做rpc通信(RPC通信)
    导读:很多朋友问到关于php怎么做rpc通信的相关问题,本文编程笔记就来为大家做个详细解答,供大家参考,希望对大家有所帮助!一起来看看吧!本文目录一览: ... [详细]
  • 电商系统设计艺术——秒杀业务设计
    一、秒杀场景人多货少,只有少量的人能够抢购成功。高并发,秒杀业务在开始之前流量比较平稳,开始后流量会直线性的上升。持续时间短࿰ ... [详细]
  • redis 获取不到_redis 缓存锁的实现方法
    1.redis加锁分类redis能用的的加锁命令分表是INCR、SETNX、SET2.第一种锁命令INCR这种加锁的思路是,key不存在,那么key的值 ... [详细]
  • 本文介绍了一个适用于PHP应用快速接入TRX和TRC20数字资产的开发包,该开发包支持使用自有Tron区块链节点的应用场景,也支持基于Tron官方公共API服务的轻量级部署场景。提供的功能包括生成地址、验证地址、查询余额、交易转账、查询最新区块和查询交易信息等。详细信息可参考tron-php的Github地址:https://github.com/Fenguoz/tron-php。 ... [详细]
  • 我如何在Laravel中使用bitpay,我发现了这个' ... [详细]
  • 使用版本:1.8.0及以上使用条件:1.开启async-redisphp--riswoole(如果没有开启,重新编译安 ... [详细]
  • PHP 的 Web 運行原理 ( 4 ) - Reactor 的實現之 Swoole
    本篇文章,咱們將要在說明另一個在php實現reactor模式的東西本篇文章分為以下幾個章節:swoole官網寫到: ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 1.使用升级命令update的问题composerupdate提示下面的错误:1、Warning:Thisdevelopmentbuildofcomposer ... [详细]
  • wordpress php 7.0,WordPress升级PHP版本至7.2
    网站终归是自己建才靠谱。但随之而来,烦恼也多起来。WordPress建站,非常好用,其自身的升级十分方便。但WordPress完全基于PH ... [详细]
  • 【宇润日常疯测007】Swoole 协程与传统 fpm 同步模式比较
    为什么80%的码农都做不了架构师?如果说数组是PHP的精髓,数组玩得不6的,根本不能算是会用PHP。那协程对于Swoole也是同理& ... [详细]
  • PHP socket服务端与客户端的简易通信
    今天学习socket通信的同时,顺便整理了下以前初识socket的知识。现在关于php的socket通信,有些框架已经十分成熟了,比如swoole和workerman,这两个大家可以学习学 ... [详细]
  • Swoole在PHP-fpmapache中如何使用task功能?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人 ... [详细]
  • php在哪里好找工作(php学到什么程度可以找到工作)
    导读:本篇文章编程笔记来给大家介绍有关php在哪里好找工作的相关内容,希望对大家有所帮助,一起来看看吧。本文目录一览:1、php去哪个城 ... [详细]
author-avatar
江西小毒i哈
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有