.NetCore实践篇:成功解决分布式监控ZipKin聚合依赖问题(三)

前言

读本篇文章之前,可以先读前两篇文章。为了照顾没看过的朋友,我也会稍作复习。
思考大纲: .Net架构篇:思考如何设计一款实用的分布式监控系统?
实践篇一:.NetCore实践篇:分布式监控客户端ZipkinTracer从入门到放弃之路
实践篇二:.NetCore实践篇:分布式监控系统zipkin踩坑之路(二)
上一章节,我们遗留了两个问题,

聚合调用span传送到zipkin时,没有产生聚合的span。

菜单dependencies没有聚合数据,zipkin-dependencies启动失败问题。

很庆幸,这两个问题都在本篇文章得到完美解决。没有什么比一步一步解决问题更开心了,我又收集了一堆宝贵的链接。非常感谢社区,所以我也将自己的实践之路分享出来,为.net社区繁荣增一点力气。

zipkin复习

zipkin为分布式链路调用监控系统,聚合各业务系统调用延迟数据,达到链路调用监控跟踪;
zipkin通过采集跟踪数据可以帮助开发者深入了解在分布式系统中某一个特定的请求时如何执行的;

详情如下
zipkin参考
zipkin官网

zipkin4net复习

zipkin4net是.NET客户端库。

它为您提供:

  • Zipkin 原语(跨度,注释,二进制注释,......)【Zipkin primitives (spans, annotations, binary annotations, ...)】
  • 异步跟踪发送
  • 跟踪传输抽象

详情如下:
zipkin4net

zipkin-dependencies复习

这是一个Spark作业,它将从您的数据存储区收集跨度,分析服务之间的链接,并存储它们以供以后在Web UI中呈现(例如http://localhost:8080/dependency)。
什么是Spark?
Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎。
此作业以UTC时间分析当天的所有跟踪。这意味着您应该将其安排在UTC午夜之前运行。
支持所有Zipkin 存储组件,包括Cassandra,MySQL和Elasticsearch。

详情如下:
zipkin-dependencies

今日重点--成功启动zipkin-dependencies

上次被zipkin-dependencies的启动问题卡了很晚,就结束了那篇文章,今天继续解决问题。我从网上搜到一篇类似的博文 部署生产环境时踩到的一些坑,里面提到直接在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启动成功。

[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.

后来又搜到这条链接how to increase heap size?
原来直接在执行java命令时,追加-Xmx就行了,脑袋太死板,想不到这个点。

[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)

提示内存不足,分配失败。

[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

解决步骤:

执行刚才的vi catalina.sh,清理掉设置的JAVA_OPTs信息,关掉mysql,重启tomcat等步骤。利用freetop查看内存消耗。

[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,不过日志级别为Warn,可以忽略。

启动成功后,dependency依然没有数据, 需要继续查询问题。

今日重点--深思流程解决span聚合问题

上次是由于启动问题,今天解决了启动问题,再看不到数据,就需要深思整个流程了。
再让我们回忆下下面这张图,parentid为空,是不是意味着跨站点需要强指定parentid或站点名称?


继续翻看zipkin4Net示例代码,发现使用了IHttpClientFactoryCreateClient方法,又在ConfigureServices里指定了applicationName,也许这才是能显示出聚合站点的关键!

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);
                    }
                }
            });
        }
    }
}

继续按照示例代码,修改我们的逻辑,封装一个可供其他站点调用的HTTPHelper帮助类,提供能追踪站点的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;
                }
            }
        }
    }
}

两个站点的Add方法做出修正,然后查看监控数据。

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

            //模拟调用其他站点请求。
            var url = $"{ConfigEx.WebSite}/user/get?id={user.Id}";
            var content = HTTPHelper.GetAsync(url, null);
            return Content(content.Result);
        }

监控spans有两级了,达到了我们要的效果
监控层级

点开查看效果
站点聚合
聚合效果图

经测试,重启linux后,不开启zipkin-dependencies的情况下,内存模式下依然能实时聚合,上篇文章的结论是本人不熟悉所导致。

参考资料

how to increase heap size?
部署生产环境时踩到的一些坑
Linux下如何同时注释多行/同时取消多行注释
利用Zipkin追踪Mysql数据库调用链
微服务调用链追踪中心搭建
微服务监控zipkin+asp.net core
Zipkin实践:Python项目中跟踪系统导入Zipkin

源码

源码已上传范存威的github

总结

基于内存模型的存储,执行效果演示到此结束。在这个过程中,提升了我java一些知识,.NetCore依赖注入,加深了zipkin整体流程的理解。
下篇文章大体方向是zipkin数据持久化和集群,以及zipkin如何跟踪mongodb和Redis。

本篇到此结束,感谢观看!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容