net core 微服务框架 Viper 调用链路追踪

一、Viper是什么?

  Viper 是.NET平台下的Anno微服务框架的一个示例项目。入门简单安全稳定高可用全平台可监控。底层通信能够随意切换thrift grpc 自带服务发现、调用链追踪、Cron 调度、限流、事件总线、CQRS 、DDD、相似MVC的开发体验,插件化开发html

  一个不可监控的微服务平台是可怕的,出了问题 难以准肯定位问题的根源, Anno则提供了一套完整的监控体系,包括链路追踪服务占用的系统资源、系统自身 CPU、内存、硬盘使用率实时可监控等等。java

github:
https://github.com/duyanming/Viper
文档地址:
https://duyanming.github.io/git

体验地址:(体验用户为anno 密码123456 同一时间一个用户只能在一个终端登陆用户多的时候可能发生强制退出的状况,稍后登陆体验)
http://140.143.207.244/github

若是对Viper不了解能够看:web

  一、 net core 微服务 快速开发框架 Viper 初体验编程

  二、打不死的小强 .net core 微服务 快速开发框架 Viper 限流安全

二、Viper调用链追踪 

  当咱们进行微服务架构开发时,一般会划分出多个微服务,各服务之间经过RPC进行调用。一个业务操做,可能须要多个微服务的协同才能完成,在业务调用链路上任何一个微服务出现问题或者网络出现问题,都会致使业务失败。随着业务愈来愈复杂,微服务之间的协做也愈来愈多,愈来愈复杂。若是不能直观的看到整个调用链路,那么咱们就没法快速、准确的定位问题、解决问题,有甚者出现服务之间出现死循环调用拖垮整个集群。这样咱们不只不能尝到微服务给咱们带来的好处,反而引入了一堆更复杂的问题。所以对于一个微服务系统链路追踪是必要的。

   Viper为服务之间调用提供了一套完善的链路追踪体系。经过Viper能够清晰的看到一个调用链(一次业务操做)通过了哪些微服务、每一个服务消耗多少时间、是否出现异常、处理结果如何等等。经过链路追踪体系能够分析整个业务的状态,好比那个服务或者业务操做耗时异常须要优化,快速定位问题解决问题。从而更好的为整个微服务体系服务。服务器

  不只如此还能够帮助公司新入职员工梳理梳理业务脉络,明白本身所处在的业务环节、预测系统可能发生的隐患,早发现早解决,防患于未然。网络

链路追踪列表:架构

  单个链路追踪示例:

  下面这个调用链路为:

   

   整个调用链路花费22毫秒,最后两个调用为并行。

 

三、Viper&Anno 远程过程调用(RPC)

  Anno 框架底层Rpc采用了成熟的 thrift(首选推荐)grpc他们都有着高性能跨语言的特色,所以Anno框架也是一个跨语言的,能够轻松实现混合编程的框架。目前支持.net core、.net framework、java,更多的实现期待你们共同努力一块儿贡献。

  Thrift是一种接口描述语言和二进制通信协议,它被用来定义和建立跨语言的服务。它被看成一个远程过程调用(RPC)框架来使用,是由Facebook为“大规模跨语言服务开发”而开发的。目前托管在Apache,更多详细可翻阅网上资料。

  

  grpc 是一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。目前提供 C、Java 和 Go 语言版本,分别是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持.

  gRPC 基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩、单 TCP 链接上的多复用请求等特。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。

 

以Thrift为例来了解Anno框架

  Anno框架的 Thrift接口描述文件:

namespace csharp Anno.Rpc   #  命名空间
struct Micro {   #  服务信息
    1: string ip
    2: i32 port
    3: i32 timeout
    4: string name
    5: string nickname
    6: i32 weight
  }
service BrokerService {  #  Provider服务
    string broker(1:map<string,string>  input)
}
service BrokerCenter {  #  注册中心
    bool add_broker(1:map<string,string>  input)
    list<Micro> GetMicro(1:string  channel)
    string Invoke(1:map<string,string>  input)
}

服务之间通信的接口为 string broker(1:map<string,string> input),服务之间通信采用的是 Thrift的 二进制传输。

/// <summary>
    /// Engine 常量
    /// </summary>
    public static class Eng
    {
        /// <summary>
        /// 命名空间
        /// </summary>
        public const string NAMESPACE = "channel";
        /// <summary>
        ////// </summary>
        public const string CLASS = "router";
        /// <summary>
        /// 方法
        /// </summary>
        public const string METHOD = "method";
    }
channel、router、method此三个参数是远程过程调用过程当中的必须参数
以插件 Anno.Plugs.LogicService为例
namespace Anno.Plugs.LogicService
{
    using Anno.CommandBus;

    public class PlatformModule : BaseModule
    {
        --------------省略-------------------
        /// <summary>
        /// 获取用户功能
        /// </summary>
        /// <returns></returns>
        [AnnoInfo(Desc = "获取用户功能")]
        public ActionResult GetFunc()
        {
            return _platformQuery.GetFunc(Profile);
        }
    }
}    
channel 对应:Anno.Plugs.Logic
router  对应:Platform
method  对应:GetFunc
 
保留关键字:TraceId,PreTraceId,AppName,AppNameTarget,GlobalTraceId,TTL,X-Original-For
TraceId:一次Rpc调用成为一个span,这个调用的惟一标识为TraceId
PreTraceId:服务之间相互调用的时候PreTraceId用来标识父子关系的父TraceId
AppName:当前服务名称
AppNameTarget:目标服务名称
GlobalTraceId:一次用户操做或者是系统人物成为一个调用链,这个调用链的惟一标识为GlobalTraceId
TTL:跨越的服务次数
X-Original-For:web调用的时候的用户IP 

二、Viper调用链追踪体系解析 

  Viper的调用链式内嵌在 Anno.Rpc.Client中的,Rpc调用以前建立追踪对象sys_trace记录Request参数,调用完成以后完善响应Response结果而且把追踪对象sys_trace写入内存队列中。而后定时定量发送到追踪服务器。

伪代码以下:

   /// <summary>
    /// 追踪队列池
    /// </summary>
    public static class TracePool
    {
     //内存队列
private static ConcurrentQueue<sys_trace> TraceQueue { get; set; } = new ConcurrentQueue<sys_trace>();      //业务处理后推送追踪对象到内存队列 TraceQueue public static void EnQueue(sys_trace trace, string result) { if (trace != null) { trace.UseTimeMs = (DateTime.Now - trace.Timespan).TotalMilliseconds; trace.Response = result; TraceQueue.Enqueue(trace); } }
     //建立追踪对象
public static sys_trace CreateTrance(Dictionary<string, string> input) { return new sys_trace() { Timespan = DateTime.Now, InputDictionary = input }; } /// <summary> /// 批量发送调用链到 追踪服务器(定时任务会定时调用TryDequeue) /// </summary> internal static void TryDequeue() { if (TraceQueue.IsEmpty) { return; } List<sys_trace> traces = new List<sys_trace>(); ReTryDequeue: while (!TraceQueue.IsEmpty && traces.Count < 100) { TraceQueue.TryDequeue(out sys_trace trace);
   ------------转换追踪对象--------------
if (trace.Rlt) { trace.Response = null; } traces.Add(trace); } if (traces.Count <= 0) { return; } Dictionary<string, string> inputTrace = new Dictionary<string, string> { {Const.Enum.Eng.NAMESPACE, "Anno.Plugs.Trace"}, {Const.Enum.Eng.CLASS, "Trace"}, {Const.Enum.Eng.METHOD, "TraceBatch"}, {"traces", Newtonsoft.Json.JsonConvert.SerializeObject(traces)} };
       //发送追踪数据 Connector.BrokerDns(inputTrace);
if (!TraceQueue.IsEmpty) { traces.Clear(); goto ReTryDequeue; } } }

  

Viper

github:
https://github.com/duyanming/Viper
文档地址:
https://duyanming.github.io/

体验地址:(体验用户为anno 密码123456 同一时间一个用户只能在一个终端登陆用户多的时候可能发生强制退出的状况,稍后登陆体验)
http://140.143.207.244/

 

关于Viper的更多内容,随后更新。敬请关注。开源不易,感谢Star。

相关文章
相关标签/搜索