net core 微服務框架 Viper 調用鏈路追蹤


1、Viper是什么?

  Viper 是.NET平台下的Anno微服務框架的一個示例項目。入門簡單安全穩定高可用全平台可監控。底層通訊可以隨意切換thrift grpc 自帶服務發現、調用鏈追蹤、Cron 調度、限流、事件總線、CQRS 、DDD、類似MVC的開發體驗,插件化開發

  一個不可監控的微服務平台是可怕的,出了問題 難以准確定位問題的根源, Anno則提供了一套完整的監控體系,包括鏈路追蹤服務占用的系統資源、系統自身 CPU、內存、硬盤使用率實時可監控等等。

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

體驗地址:(體驗用戶為anno 密碼123456 同一時間一個用戶只能在一個終端登錄用戶多的時候可能發生強制退出的情況,稍后登錄體驗)
http://140.143.207.244/

如果對Viper不了解可以看:

  1、 net core 微服務 快速開發框架 Viper 初體驗

  2、打不死的小強 .net core 微服務 快速開發框架 Viper 限流

2、Viper調用鏈追蹤 

  當我們進行微服務架構開發時,通常會划分出多個微服務,各服務之間通過RPC進行調用。一個業務操作,可能需要多個微服務的協同才能完成,在業務調用鏈路上任何一個微服務出現問題或者網絡出現問題,都會導致業務失敗。隨着業務越來越復雜,微服務之間的協作也越來越多,越來越復雜。如果不能直觀的看到整個調用鏈路,那么我們就無法快速、准確的定位問題、解決問題,有甚者出現服務之間出現死循環調用拖垮整個集群。這樣我們不僅不能嘗到微服務給我們帶來的好處,反而引入了一堆更復雜的問題。因此對於一個微服務系統鏈路追蹤是必要的。

   Viper為服務之間調用提供了一套完善的鏈路追蹤體系。通過Viper可以清晰的看到一個調用鏈(一次業務操作)經過了哪些微服務、每個服務消耗多少時間、是否出現異常、處理結果如何等等。通過鏈路追蹤體系可以分析整個業務的狀態,比如那個服務或者業務操作耗時異常需要優化,快速定位問題解決問題。從而更好的為整個微服務體系服務。

  不僅如此還可以幫助公司新入職員工梳理梳理業務脈絡,明白自己所處在的業務環節、預測系統可能發生的隱患,早發現早解決,防患於未然。

鏈路追蹤列表:

  單個鏈路追蹤示例:

  下面這個調用鏈路為:

   

   整個調用鏈路花費22毫秒,最后兩個調用為並行。

 

3、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 

2、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。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM