.NetCore實(shí)踐篇:成功解決分布式監(jiān)控ZipKin聚合依賴(lài)問(wèn)題(三)

前言

讀本篇文章之前,可以先讀前兩篇文章。為了照顧沒(méi)看過(guò)的朋友,我也會(huì)稍作復(fù)習(xí)。
思考大綱: .Net架構(gòu)篇:思考如何設(shè)計(jì)一款實(shí)用的分布式監(jiān)控系統(tǒng)?
實(shí)踐篇一:.NetCore實(shí)踐篇:分布式監(jiān)控客戶(hù)端ZipkinTracer從入門(mén)到放棄之路
實(shí)踐篇二:.NetCore實(shí)踐篇:分布式監(jiān)控系統(tǒng)zipkin踩坑之路(二)
上一章節(jié),我們遺留了兩個(gè)問(wèn)題,

聚合調(diào)用span傳送到zipkin時(shí),沒(méi)有產(chǎn)生聚合的span。

菜單dependencies沒(méi)有聚合數(shù)據(jù),zipkin-dependencies啟動(dòng)失敗問(wèn)題。

很慶幸,這兩個(gè)問(wèn)題都在本篇文章得到完美解決。沒(méi)有什么比一步一步解決問(wèn)題更開(kāi)心了,我又收集了一堆寶貴的鏈接。非常感謝社區(qū),所以我也將自己的實(shí)踐之路分享出來(lái),為.net社區(qū)繁榮增一點(diǎn)力氣。

zipkin復(fù)習(xí)

zipkin為分布式鏈路調(diào)用監(jiān)控系統(tǒng),聚合各業(yè)務(wù)系統(tǒng)調(diào)用延遲數(shù)據(jù),達(dá)到鏈路調(diào)用監(jiān)控跟蹤;
zipkin通過(guò)采集跟蹤數(shù)據(jù)可以幫助開(kāi)發(fā)者深入了解在分布式系統(tǒng)中某一個(gè)特定的請(qǐng)求時(shí)如何執(zhí)行的;

詳情如下
zipkin參考
zipkin官網(wǎng)

zipkin4net復(fù)習(xí)

zipkin4net是.NET客戶(hù)端庫(kù)。

它為您提供:

  • Zipkin 原語(yǔ)(跨度,注釋?zhuān)M(jìn)制注釋?zhuān)?.....)【Zipkin primitives (spans, annotations, binary annotations, ...)】
  • 異步跟蹤發(fā)送
  • 跟蹤傳輸抽象

詳情如下:
zipkin4net

zipkin-dependencies復(fù)習(xí)

這是一個(gè)Spark作業(yè),它將從您的數(shù)據(jù)存儲(chǔ)區(qū)收集跨度,分析服務(wù)之間的鏈接,并存儲(chǔ)它們以供以后在Web UI中呈現(xiàn)(例如http://localhost:8080/dependency)。
什么是Spark?
Apache Spark 是專(zhuān)為大規(guī)模數(shù)據(jù)處理而設(shè)計(jì)的快速通用的計(jì)算引擎。
此作業(yè)以UTC時(shí)間分析當(dāng)天的所有跟蹤。這意味著您應(yīng)該將其安排在UTC午夜之前運(yùn)行。
支持所有Zipkin 存儲(chǔ)組件,包括Cassandra,MySQL和Elasticsearch。

詳情如下:
zipkin-dependencies

今日重點(diǎn)--成功啟動(dòng)zipkin-dependencies

上次被zipkin-dependencies的啟動(dòng)問(wèn)題卡了很晚,就結(jié)束了那篇文章,今天繼續(xù)解決問(wèn)題。我從網(wǎng)上搜到一篇類(lèi)似的博文 部署生產(chǎn)環(huán)境時(shí)踩到的一些坑,里面提到直接在tomcat的catalina.sh的JAVA_OPTS注釋處,加一行JAVA_OPTS="-server -Xms1024m -Xmx1624m -XX:PermSize=128M -XX:MaxPermSize=256m",即可解決。

#   JAVA_OPTS       (Optional) Java runtime options used when any command
#                   is executed.
#                   Include here and not in CATALINA_OPTS all options, that
#                   should be used by Tomcat and also by the stop process,
#                   the version command etc.
#                   Most options should go into CATALINA_OPTS.
JAVA_OPTS="-server -Xms1024m -Xmx1624m -XX:PermSize=128M -XX:MaxPermSize=256m"

tomcat啟動(dòng)成功。

[root@izwz9fwifc2eniq3lbdzmgz bin]# ./startup.sh 
Using CATALINA_BASE:   /usr/local/tomcat/apache-tomcat-8.5.32
Using CATALINA_HOME:   /usr/local/tomcat/apache-tomcat-8.5.32
Using CATALINA_TMPDIR: /usr/local/tomcat/apache-tomcat-8.5.32/temp
Using JRE_HOME:        /usr/lib/jdk1.8.0_181
Using CLASSPATH:       /usr/local/tomcat/apache-tomcat-8.5.32/bin/bootstrap.jar:/usr/local/tomcat/apache-tomcat-8.5.32/bin/tomcat-juli.jar
Tomcat started.

后來(lái)又搜到這條鏈接how to increase heap size?
原來(lái)直接在執(zhí)行java命令時(shí),追加-Xmx就行了,腦袋太死板,想不到這個(gè)點(diǎn)。

[root@izwz9fwifc2eniq3lbdzmgz cusD]# java -Xmx1024m -version
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

提示內(nèi)存不足,分配失敗。

[root@izwz9fwifc2eniq3lbdzmgz cusD]# STORAGE_TYPE=cassandra3  java -Xmx1024m -Xms1024m -jar zipkin-dependencies.jar `date -u -d '1 day ago' +%F`
Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000000d5550000, 715849728, 0) failed; error='Cannot allocate memory' (errno=12)
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (mmap) failed to map 715849728 bytes for committing reserved memory.
# An error report file with more information is saved as:
# /cusD/hs_err_pid6871.log

解決步驟:

執(zhí)行剛才的vi catalina.sh,清理掉設(shè)置的JAVA_OPTs信息,關(guān)掉mysql,重啟tomcat等步驟。利用freetop查看內(nèi)存消耗。

[root@izwz9fwifc2eniq3lbdzmgz cusD]# free -h
              total        used        free      shared  buff/cache   available
Mem:           1.8G        228M        1.2G        388K        396M        1.4G
Swap:            0B          0B          0B
[root@izwz9fwifc2eniq3lbdzmgz cusD]# STORAGE_TYPE=cassandra3  java -Xmx512m -Xms128m -jar zipkin-dependencies.jar `date -u -d '1 day ago' +%F`
18/09/17 16:42:21 INFO CassandraDependenciesJob: Running Dependencies job for 2018-09-16: 1537056000000000 ≤ Span.timestamp 1537142399999999
18/09/17 16:42:21 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
18/09/17 16:42:22 WARN Java7Support: Unable to load JDK7 types (annotations, java.nio.file.Path): no Java7 support added
Exception in thread "main" java.io.IOException: Failed to open native connection to Cassandra at {127.0.0.1}:9042

未能加載JDK7 types,不過(guò)日志級(jí)別為Warn,可以忽略。

啟動(dòng)成功后,dependency依然沒(méi)有數(shù)據(jù), 需要繼續(xù)查詢(xún)問(wèn)題。

今日重點(diǎn)--深思流程解決span聚合問(wèn)題

上次是由于啟動(dòng)問(wèn)題,今天解決了啟動(dòng)問(wèn)題,再看不到數(shù)據(jù),就需要深思整個(gè)流程了。
再讓我們回憶下下面這張圖,parentid為空,是不是意味著跨站點(diǎn)需要強(qiáng)指定parentid或站點(diǎn)名稱(chēng)?


繼續(xù)翻看zipkin4Net示例代碼,發(fā)現(xiàn)使用了IHttpClientFactoryCreateClient方法,又在ConfigureServices里指定了applicationName,也許這才是能顯示出聚合站點(diǎn)的關(guān)鍵!

namespace frontend
{
    public class Startup : CommonStartup
    {
        public override void ConfigureServices(IServiceCollection services)
        {
            services.AddHttpClient("Tracer").AddHttpMessageHandler(provider =>
                TracingHandler.WithoutInnerHandler(provider.GetService<IConfiguration>()["applicationName"]));
        }

        protected override void Run(IApplicationBuilder app, IConfiguration config)
        {
            app.Run(async (context) =>
            {
                var callServiceUrl = config["callServiceUrl"];
                var clientFactory = app.ApplicationServices.GetService<IHttpClientFactory>();
                using (var httpClient = clientFactory.CreateClient("Tracer"))
                {
                    var response = await httpClient.GetAsync(callServiceUrl);
                    if (!response.IsSuccessStatusCode)
                    {
                        await context.Response.WriteAsync(response.ReasonPhrase);
                    }
                    else
                    {
                        var content = await response.Content.ReadAsStringAsync();
                        await context.Response.WriteAsync(content);
                    }
                }
            });
        }
    }
}

繼續(xù)按照示例代碼,修改我們的邏輯,封裝一個(gè)可供其他站點(diǎn)調(diào)用的HTTPHelper幫助類(lèi),提供能追蹤站點(diǎn)的GetAsync方法,

namespace Demo.ZipkinCommon
{
    public class HTTPHelper : ControllerBase
    {
        /// <summary>
        /// 獲取
        /// </summary>
        /// <param name="url"></param>
        /// <param name="keyValues"></param>
        /// <param name="timeout"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        public static async Task<string> GetAsync(string url, Dictionary<string, string> keyValues, int timeout = 0, Encoding encoding = null)
        {
            if (encoding == null)
            {
                encoding = Encoding.UTF8;
            }
            var appName = ConfigureSettings.AppSettingConfig["applicationName"];

            using (var httpClient = new HttpClient(new TracingHandler(appName)))
            {
                var response = await httpClient.GetAsync(url);
                if (!response.IsSuccessStatusCode)
                {
                    return response.ReasonPhrase;
                }
                else
                {
                    var content = await response.Content.ReadAsStringAsync();
                    return content;
                }
            }
        }
    }
}

兩個(gè)站點(diǎn)的Add方法做出修正,然后查看監(jiān)控?cái)?shù)據(jù)。

 [HttpPost]
        public IActionResult Add([FromBody]User user)
        {
            _userService.AddUser(user);

            //模擬調(diào)用其他站點(diǎn)請(qǐng)求。
            var url = $"{ConfigEx.WebSite}/user/get?id={user.Id}";
            var content = HTTPHelper.GetAsync(url, null);
            return Content(content.Result);
        }

監(jiān)控spans有兩級(jí)了,達(dá)到了我們要的效果
監(jiān)控層級(jí)

點(diǎn)開(kāi)查看效果
站點(diǎn)聚合
聚合效果圖

經(jīng)測(cè)試,重啟linux后,不開(kāi)啟zipkin-dependencies的情況下,內(nèi)存模式下依然能實(shí)時(shí)聚合,上篇文章的結(jié)論是本人不熟悉所導(dǎo)致。

參考資料

how to increase heap size?
部署生產(chǎn)環(huán)境時(shí)踩到的一些坑
Linux下如何同時(shí)注釋多行/同時(shí)取消多行注釋
利用Zipkin追蹤Mysql數(shù)據(jù)庫(kù)調(diào)用鏈
微服務(wù)調(diào)用鏈追蹤中心搭建
微服務(wù)監(jiān)控zipkin+asp.net core
Zipkin實(shí)踐:Python項(xiàng)目中跟蹤系統(tǒng)導(dǎo)入Zipkin

源碼

源碼已上傳范存威的github

總結(jié)

基于內(nèi)存模型的存儲(chǔ),執(zhí)行效果演示到此結(jié)束。在這個(gè)過(guò)程中,提升了我java一些知識(shí),.NetCore依賴(lài)注入,加深了zipkin整體流程的理解。
下篇文章大體方向是zipkin數(shù)據(jù)持久化和集群,以及zipkin如何跟蹤mongodb和Redis。

本篇到此結(jié)束,感謝觀看!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容