Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 648|回复: 0

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

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-4-18 17:33:00 | 显示全部楼层 |阅读模式

    前言

    读本篇文章之前,可以先读前两篇文章。为了照顾没看过的朋友,我也会稍作复习。
    思考大纲: .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示例代码,发现使用了 IHttpClientFactory CreateClient 方法,又在 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的情况下,内存模式下依然能实时聚合,上篇文章的结论是本人不熟悉所导致。

    参考资料

    源码

    源码已上传范存威的github

    总结

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

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

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-22 17:31 , Processed in 0.062769 second(s), 27 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表