链路分析设计总结

1.背景

目前公司采用的是服务化设计,(什么是服务化?),服务化带来便利的同时也带了了一个问题。那就是请求链路长,通常一个api访问会访问到多个服务。这样就导致查询一个访问需要查询好几个服务。链路分析就是解决的就是把这些访问的信息都串联起来。

2.日志设置

以上要考虑的问题有两个:

  1. 如何把这些不同服务器上的日志串联起来
  2. 如何保证这个接口的访问顺序

一个接口访问到了A服务,A服务访问了B服务,B服务访问了C服务。返回结果后A服务有访问了D服务,D服务又访问了B服务。

怎么记录他的链路来整体做分析?

解决1的办法,用一个唯一的request_id来串联起来所有的服务。

解决2的办法就是设置一个rpc_version.

rpc_version的设置规则:

  1. 当前服务的(server)的版本规则 “rpc_version.rpc_server_version”
  2. 当前服务请求其他服务(此时该请求作为了client)的版本规则 “rpc_version => rpc_server_version”

此时请求的日志规则

A服务器日报

2018-07-10 17:45:26 [INFO] {"input":{"get":{"_url":"/abc/efg","id":"7336"},"post":[]},"client_ip":"10.33.142.56","request_id":"2018071017452642453","rpc_version":"1","consume":0.214,"response":    {"errno":0,"error":"","request_id":"2018071017452642453"}}

2018-07-10 17:45:30 [INFO] {"path":"/abc/efg","get":"","post":{"id":7336},"request_id":"2018071017453065890","rpc_version":"1=>1.1","consume":0.191,"client_ip":"8.8.8.8"}

2018-07-10 17:45:30 [INFO] {"path":"/abc/efg","get":"","post":{"id":7336},"request_id":"2018071017453065890","rpc_version":"1=>1.2","consume":0.191,"client_ip":"8.8.8.8"}

B服务器日报

2018-07-10 17:45:26 [INFO] {"input":{"get":{"_url":"/abc/efg","id":"7336"},"post":[],"client_ip":"9.9.9.9","request_id":"2018071017452642453","rpc_version":"1.1","consume":0.214,"response":{"errno":0,"error":"","request_id":"2018071017452642453"}}

2018-07-10 17:45:30 [INFO] {"path":"/abc/efg","get":"","post":{"id":7336},"request_id":"2018071017453065890","rpc_version":"1.1=>1.1.1","consume":0.191,"client_ip":"8.8.8.8"}

C服务器日志

2018-07-10 17:45:26 [INFO] {"input":{"get":{"_url":"/abc/efg","id":"7336"},"post":[]},"client_ip":"9.9.9.9","request_id":"2018071017452642453","rpc_version":"1.1.1","consume":0.214,"response":{"errno":0,"error":"","request_id":"2018071017452642453"}}

D服务器日志

2018-07-10 17:45:26 [INFO] {"input":{"get":{"_url":"/abc/efg","id":"7336"},"post":[]},"client_ip":"9.9.9.9","request_id":"2018071017452642453","rpc_version":"1.2","consume":0.214,"response":{"errno":0,"error":"","request_id":"2018071017452642453"}}

通过上面的日志我们可以得到

  1. 通过request_id=2018071017452642453 可以找到所有的日志

  2. 然后通过rpc_version来把他们顺序串联起来。

例如上述日志

服务器A发起请求此时版本号1

发起了对服务器B的请求,A服务器上的版本信息 “rpc_version”:”1=>1.1”

B服务器上打印的日志为 “rpc_version”:”1.1”,同时发起了对C服务器的请求。

B服务器上打印的日志为 “rpc_version”:”1.1=>1.1.1”,同时发起了对C服务器的请求。

C服务器上打印到的日志 “rpc_version”:”1.1.1”

返回A服务器后 A服务器发起了对D服务器的请求”rpc_version”:”1=>1.2”

D服务器打印日志 “rpc_version”:”1.2”

这样访问路径就串联起来了

主要代码如下:

<?php
class Context 
{
      private static $request_id = null;
      private static $rpc_version = null;
      private static $rpc_client_version = 0; // 1.1这种形式
      private static $rpc_server_version = null; // 1=>1.1这种形式

    //初始化操作
    public static function init()
    {
        self::setRequestId();
        self::setRpcVersion();
    }

    //设置request_id
    public static function setRequestId() 
    {
        $request_id = $_GET['request_id']; 
        if (empty($request_id)){
            self::$request_id = date("YmdHis") . rand(10000, 99999);     
        } else {
            self::$request_id = $request_id; 
        } 
    }

   //获取全局的request_id
   public static function getRequestId()
   {
        return self::request_id;
   }

   //设置RPC版本
   public static function setRpcVersion() 
   {
        $rpc_version = $_GET['rpc_version'];
        if (empty($rpc_version)){
            self::$rpc_version = 1;
        } else {
            self::$rpc_version = $rpc_version; 
        }
   }

   //获取rpc版本
   public static function getRpcServerVersion()
   {
        self::$rpc_server_version++;
        return sprintf("d%.d%", self::$rpc_version, self::$rpc_server_version); 
   }

   //获取服务端rpc版本
   public static function getRpcClientVersion()
   {
       $rpc_server_version = self::getRpcServerVersion();
       self::$rpc_client_version =   sprintf("s%=>s%", self::$rpc_version, self::$rpc_server_version);
   }

}

//初始化
Context::init();

$rpc_version = Context::getRpcClientVersion(); 
$request_id = Context::getRequestId();


//一个服务在调用另一个服务的时候
//对URL做拼接
$url = $url."?rpc_version=".$rpc_version."&request_id=".$request_id;
3.链路分析

以上日志rpc_version规则的设定好后,接下来分析就是靠数据组装了。

  1. 通过request_id从ES中获取相关的日志信息。
  2. 获取日志信息后根据rpc_version吧日志串联起来,至于怎么串联就根据自己的需求去处理了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值