前言

本系列已写了四篇文章,读本篇之前,可以先读前面几篇。
思考大纲:.Net架构篇:思考如何设计一款实用的分布式监控系统?
实践篇一:.NetCore实践篇:分布式监控客户端ZipkinTracer从入门到放弃之路
实践篇二:.NetCore实践篇:分布式监控系统zipkin踩坑之路(二)
实践篇三:.NetCore实践篇:成功解决分布式监控ZipKin聚合依赖问题(三)

简要回顾

zipkin

Zipkin是一种分布式跟踪系统。它有助于收集解决微服务架构中的延迟问题所需的时序数据
zipkin官网

zipkin4Net

zipkin4net是.NET客户端库。
zipkin4net

zipkin-dependencies

这是一个Spark作业,它将从您的数据存储区收集跨度,分析服务之间的链接,并存储它们以供以后在Web UI中呈现。

zipkin-dependencies

使用方法

如果内存不足时,java后跟上-Xmx1024m -Xms1024m参数,JAVA_OPTS的一些参数可参考Oracle官方说明配置默认JVM和Java参数

  1. # ex to run the job to process yesterday's traces on OS/X
  2. $ STORAGE_TYPE=cassandra3 java -jar zipkin-dependencies.jar `date -uv-1d +%F`
  3. # or on Linux
  4. $ STORAGE_TYPE=cassandra3 java -jar zipkin-dependencies.jar `date -u -d '1 day ago' +%F`

MySQL 存储

  1. * `MYSQL_DB`: 使用的数据库,默认是 "zipkin".
  2. * `MYSQL_USER` and `MYSQL_PASS`: MySQL授权, 默认是空.
  3. * `MYSQL_HOST`: 默认主机(域名/ip)是localhost
  4. * `MYSQL_TCP_PORT`: 默认端口是 3306
  5. * `MYSQL_USE_SSL`: 验证 `javax.net.ssl.trustStore` `javax.net.ssl.trustStorePassword`,默认不验证。

示例

  1. $ STORAGE_TYPE=mysql MYSQL_USER=root java -jar zipkin-dependencies.jar

详情参考:
zipkin-dependencies

实践

创建使用数据库

  1. mysql> create database mytestdb;
  2. Query OK, 1 row affected (0.01 sec)
  3. mysql> show databases;
  4. +--------------------+
  5. | Database |
  6. +--------------------+
  7. | information_schema |
  8. | mysql |
  9. | mytestdb |
  10. | performance_schema |
  11. | sys |
  12. | ttt |
  13. +--------------------+
  14. 7 rows in set (0.00 sec)
  15. mysql> use mytestdb
  16. Database changed

使用sql语句创建zipkin表

  1. CREATE TABLE IF NOT EXISTS zipkin_spans (
  2. `trace_id_high` BIGINT NOT NULL DEFAULT 0COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64bit',
  3. `trace_id` BIGINT NOT NULL,
  4. `id` BIGINT NOT NULL,
  5. `name` VARCHAR(255) NOT NULL,
  6. `parent_id` BIGINT,
  7. `debug` BIT(1),
  8. `start_ts` BIGINT COMMENT 'Span.timestamp():epoch micros used for endTs query and to implement TTL',
  9. `duration` BIGINT COMMENT 'Span.duration():micros used for minDuration and maxDuration query'
  10. )ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
  11. ALTER TABLE zipkin_spans ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `id`) COMMENT'ignore insert on duplicate';
  12. ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`, `id`) COMMENT 'forjoining with zipkin_annotations';
  13. ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'forgetTracesByIds';
  14. ALTER TABLE zipkin_spans ADD INDEX(`name`) COMMENT 'for getTraces and getSpanNames';
  15. ALTER TABLE zipkin_spans ADD INDEX(`start_ts`) COMMENT 'for getTraces ordering andrange';
  16. CREATE TABLE IF NOT EXISTS zipkin_annotations (
  17. `trace_id_high` BIGINT NOT NULL DEFAULT 0COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64bit',
  18. `trace_id` BIGINT NOT NULL COMMENT 'coincideswith zipkin_spans.trace_id',
  19. `span_id` BIGINT NOT NULL COMMENT 'coincideswith zipkin_spans.id',
  20. `a_key` VARCHAR(255) NOT NULL COMMENT'BinaryAnnotation.key or Annotation.value if type == -1',
  21. `a_value` BLOB COMMENT'BinaryAnnotation.value(), which must be smaller than 64KB',
  22. `a_type` INT NOT NULL COMMENT'BinaryAnnotation.type() or -1 if Annotation',
  23. `a_timestamp` BIGINT COMMENT 'Used toimplement TTL; Annotation.timestamp or zipkin_spans.timestamp',
  24. `endpoint_ipv4` INT COMMENT 'Null whenBinary/Annotation.endpoint is null',
  25. `endpoint_ipv6` BINARY(16) COMMENT 'Null whenBinary/Annotation.endpoint is null, or no IPv6 address',
  26. `endpoint_port` SMALLINT COMMENT 'Null whenBinary/Annotation.endpoint is null',
  27. `endpoint_service_name` VARCHAR(255) COMMENT'Null when Binary/Annotation.endpoint is null'
  28. )ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
  29. ALTER TABLE zipkin_annotations ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `span_id`,`a_key`, `a_timestamp`) COMMENT 'Ignore insert on duplicate';
  30. ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`, `span_id`)COMMENT 'for joining with zipkin_spans';
  31. ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'forgetTraces/ByIds';
  32. ALTER TABLE zipkin_annotations ADD INDEX(`endpoint_service_name`) COMMENT 'forgetTraces and getServiceNames';
  33. ALTER TABLE zipkin_annotations ADD INDEX(`a_type`) COMMENT 'for getTraces';
  34. ALTER TABLE zipkin_annotations ADD INDEX(`a_key`) COMMENT 'for getTraces';
  35. ALTER TABLE zipkin_annotations ADD INDEX(`trace_id`, `span_id`, `a_key`) COMMENT 'fordependencies job';
  36. CREATE TABLE IF NOT EXISTS zipkin_dependencies (
  37. `day` DATE NOT NULL,
  38. `parent` VARCHAR(255) NOT NULL,
  39. `child` VARCHAR(255) NOT NULL,
  40. `call_count` BIGINT
  41. )ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
  42. ALTER TABLE zipkin_dependencies ADD UNIQUE KEY(`day`, `parent`, `child`);

创建成功后,查询结果。

  1. mysql> show tables;
  2. +---------------------+
  3. | Tables_in_mytestdb |
  4. +---------------------+
  5. | zipkin_annotations |
  6. | zipkin_dependencies |
  7. | zipkin_spans |
  8. +---------------------+
  9. 3 rows in set (0.00 sec)

启动zipkin-dependencies

最开始我的密码是【四个字母一个感叹号一个数字】,再执行启动命令时,密码那块给我报错自动换成【四个字母rm -f】,我修改成【四个字母一个#号一个数字】就能执行了

执行成功后,依然提示Access denied for user 'root'@'localhost' (using password: NO),但我在linux的命令中直接用mysql -u root -p相同密码是可以登录成功的。所以问题出现在哪呢?

  1. [root@izwz9fwifc2eniq3lbdzmgz cusD]# STORAGE_TYPE=mysql MYSQL_HOST=localhost MYSQL_TCP_PORT=3306 MYSQL_DB=mytestdb MYSQL_USER=XXXXX MYSQL_PASS=XXXXX java -Xmx1024m -Xms1024m -jar zipkin-dependencies.jar
  2. Exception in thread "main" java.lang.RuntimeException: java.sql.SQLInvalidAuthorizationSpecException: Access denied for user 'root'@'localhost' (using password: NO)
  3. at zipkin2.dependencies.mysql.MySQLDependenciesJob.hasTraceIdHigh(MySQLDependenciesJob.java:233)
  4. at zipkin2.dependencies.mysql.MySQLDependenciesJob.run(MySQLDependenciesJob.java:184)
  5. at zipkin2.dependencies.ZipkinDependenciesJob.main(ZipkinDependenciesJob.java:65)
  6. Caused by: java.sql.SQLInvalidAuthorizationSpecException: Access denied for user 'root'@'localhost' (using password: NO)
  7. at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.get(ExceptionMapper.java:173)
  8. at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.getException(ExceptionMapper.java:110)
  9. at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connectWithoutProxy(AbstractConnectProtocol.java:1115)
  10. at org.mariadb.jdbc.internal.util.Utils.retrieveProxy(Utils.java:502)
  11. at org.mariadb.jdbc.MariaDbConnection.newConnection(MariaDbConnection.java:154)
  12. at org.mariadb.jdbc.Driver.connect(Driver.java:86)
  13. at java.sql.DriverManager.getConnection(DriverManager.java:664)
  14. at java.sql.DriverManager.getConnection(DriverManager.java:247)
  15. at zipkin2.dependencies.mysql.MySQLDependenciesJob.hasTraceIdHigh(MySQLDependenciesJob.java:229)
  16. ... 2 more
  17. Caused by: java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: NO)
  18. Current charset is UTF-8. If password has been set using other charset, consider using option 'passwordCharacterEncoding'
  19. at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.authentication(AbstractConnectProtocol.java:862)
  20. at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.handleConnectionPhases(AbstractConnectProtocol.java:785)
  21. at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connect(AbstractConnectProtocol.java:456)
  22. at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connectWithoutProxy(AbstractConnectProtocol.java:1111)
  23. ... 8 more

追溯源码

逼不得已,走上查看源码之路,Idea打开zipkin-dependencies/mysql源码,查看相关部分代码。

  1. public static final class Builder {
  2. Map<String, String> sparkProperties = ImmutableMap.of(
  3. "spark.ui.enabled", "false"
  4. );
  5. String db = getEnv("MYSQL_DB", "zipkin");
  6. String host = getEnv("MYSQL_HOST", "localhost");
  7. int port = Integer.parseInt(getEnv("MYSQL_TCP_PORT", "3306"));
  8. String user = getEnv("MYSQL_USER", "");
  9. String password = getEnv("MYSQL_PASS", "");
  10. int maxConnections = Integer.parseInt(getEnv("MYSQL_MAX_CONNECTIONS", "10"));
  11. boolean useSsl = Boolean.parseBoolean(getEnv("MYSQL_USE_SSL", "false"));
  12. // local[*] master lets us run & test the job locally without setting a Spark cluster
  13. String sparkMaster = getEnv("SPARK_MASTER", "local[*]");
  14. // By default the job only works on traces whose first timestamp is today
  15. long day = midnightUTC(System.currentTimeMillis());
  16. /**
  17. *为减少篇幅,中间设置属性部分代码省略。
  18. */
  19. public MySQLDependenciesJob build() {
  20. return new MySQLDependenciesJob(this);
  21. }
  22. }
  23. /**
  24. *为减少篇幅,中间部分代码省略。
  25. */
  26. MySQLDependenciesJob(Builder builder) {
  27. this.db = builder.db;
  28. this.day = builder.day;
  29. SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
  30. df.setTimeZone(TimeZone.getTimeZone("UTC"));
  31. this.dateStamp = df.format(new Date(builder.day));
  32. this.url = new StringBuilder("jdbc:mysql://")
  33. .append(builder.host).append(":").append(builder.port)
  34. .append("/").append(builder.db)
  35. .append("?autoReconnect=true")
  36. .append("&useSSL=").append(builder.useSsl).toString();
  37. this.user = builder.user;
  38. this.password = builder.password;
  39. this.conf = new SparkConf(true)
  40. .setMaster(builder.sparkMaster)
  41. .setAppName(getClass().getName());
  42. if (builder.jars != null) conf.setJars(builder.jars);
  43. for (Map.Entry<String, String> entry : builder.sparkProperties.entrySet()) {
  44. conf.set(entry.getKey(), entry.getValue());
  45. }
  46. this.logInitializer = builder.logInitializer;
  47. }
  48. void saveToMySQL(List<DependencyLink> links) {
  49. try (Connection con = DriverManager.getConnection(url, user, password)) {
  50. PreparedStatement replace = con.prepareStatement(
  51. "REPLACE INTO zipkin_dependencies (day, parent, child, call_count, error_count) VALUES (?,?,?,?,?)");
  52. for (DependencyLink link : links) {
  53. replace.setDate(1, new java.sql.Date(day));
  54. replace.setString(2, link.parent());
  55. replace.setString(3, link.child());
  56. replace.setLong(4, link.callCount());
  57. replace.setLong(5, link.errorCount());
  58. replace.executeUpdate();
  59. }
  60. } catch (SQLException e) {
  61. throw new RuntimeException("Could not save links " + links, e);
  62. }
  63. }

然并卵,看完之后,没看出明显问题。难道还是我自己的mysql配置问题?还是启动部分的参数问题?代码部分也是有些疑惑,password和root为什么没放进url里,难道是为了安全考虑么?

  1. this.url = new StringBuilder("jdbc:mysql://")
  2. .append(builder.host).append(":").append(builder.port)
  3. .append("/").append(builder.db)
  4. .append("?autoReconnect=true")
  5. .append("&useSSL=").append(builder.useSsl).toString();
  6. this.user = builder.user;
  7. this.password = builder.password;

文中还提到 Current charset is UTF-8. If password has been set using other charset, consider using option 'passwordCharacterEncoding',编码格式是否有不同呢?
查看mysql数据库及表编码格式

  1. mysql> show variables like 'character_set_database';
  2. +------------------------+---------+
  3. | Variable_name | Value |
  4. +------------------------+---------+
  5. | character_set_database | utf8mb4 |
  6. +------------------------+---------+
  7. 1 row in set (0.01 sec)

参考链接

https://jira.mariadb.org/browse/CONJ-480
https://samebug.io/exceptions/2980875/java.sql.SQLInvalidAuthorizationSpecException/could-not-connect-access-denied-for-user
将请求参数作为UTF-8编码的字符串传递[重复]

zipkin
zipkin集成到node,C#
微服务之分布式跟踪系统(springboot+zipkin+mysql)
第二十九章 springboot + zipkin + mysql
Linux下的Mysql用命令执行sql文件
修改MySQL管理员密码
zipkin-server

总结

由于启动zipkin-dependencies链接mysql报Access denied for user 'root'@'localhost' (using password: NO)错误,本次持久化之路最终失败。但由于我直接使用【mysql -u 用户 -p】是能登录成功的,所以我猜测了以下原因:

  • 客户端自己的bug,和我服务器mysql版本不兼容?
  • 编码问题,编码两者不符?
  • 用户名和密码没有共享全局,只对一个数据库有效?

别人的博文是面向教学成功编程,我的是面向失败编程,也别有一番趣味。留下疑问,待日后解决调。虽然失败了,但我又收集了一堆链接,增添了mysql一些故障解决的认识。

今天换了一款个人很喜欢的皮肤,会根据h1,h2自动生成目录,之前的博文我也都检查了下,有很大失位的我都调整了过来,不标准的暂时不改了,我以后的博文都按照要求的格式写,排版美观度提升了很多,感谢作者bndong,如果有打算使用这个皮肤的,一定要开启控件显示公告。

.NetCore实践篇:分布式监控Zipkin持久化之殇的更多相关文章

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

    前言 读本篇文章之前,可以先读前两篇文章.为了照顾没看过的朋友,我也会稍作复习. 思考大纲: .Net架构篇:思考如何设计一款实用的分布式监控系统? 实践篇一:.NetCore实践篇:分布式监控客户端 ...

  2. .NetCore实践篇:分布式监控系统zipkin踩坑之路(二)

    前言 <牧神记>有一句话说的好,破心中神.当不再对分布式,微服务,CLR畏惧迷茫的时候,你就破了心中神. zipkin复习 第一篇: .Net架构篇:思考如何设计一款实用的分布式监控系统? ...

  3. NetCore实践篇:分布式监控客户端ZipkinTracer从入门到放弃之路

    前言 本文紧接上篇.Net架构篇:思考如何设计一款实用的分布式监控系统?,上篇仅仅是个思考篇,跟本文没有太大的关系.但有思考,结合现有的开源组件,实践起来更易理解起来,所以看本文之前,应该先看下上篇博 ...

  4. .Net架构篇:思考如何设计一款实用的分布式监控系统?

    前言 无论从最早期的unix操作系统,还是曾经大行其道的单体式应用,还是现在日益流行的微服务架构,始终都离不开监控的身影.如windows的任务管理器,linux的top命令,都可以看作是监控的面板. ...

  5. 微服务监控zipkin+asp.net core

    0.目录 整体架构目录:ASP.NET Core分布式项目实战-目录 监控目录:微服务监控zipkin.skywalking以及日志ELK监控系列 一.zipkin介绍 zipkin是一种分布式跟踪系 ...

  6. 分布式监控系统Zabbix-3.0.3-完整安装记录(7)-使用percona监控MySQL

    前面已经介绍了分布式监控系统Zabbix-3.0.3-完整安装记录(2)-添加mysql监控,但是没有提供可以直接使用的Key,太过简陋,监控效果不佳.要想更加仔细的监控Mysql,业内同学们都会选择 ...

  7. LNMP+zabbix分布式监控搭建及版本升级

    LNMP+zabbix分布式监控搭建需要组件:gcc gcc-c++ openssl* pcre pcre-devel gd gd-devel libjpeg-devel libpng-devel l ...

  8. zabbix 分布式监控(proxy)源码安装

    安装分布式监控(代理节点) 1.下载软件zabbix-3.2.1.tar.gz 1.1 解压 wget http://nchc.dl.sourceforge.net/project/zabbix/ZA ...

  9. 大众点评开源分布式监控平台 CAT 深度剖析

    一.CAT介绍 CAT系统原型和理念来源于eBay的CAL的系统,CAT系统第一代设计者吴其敏在eBay工作长达十几年,对CAL系统有深刻的理解.CAT不仅增强了CAL系统核心模型,还添加了更丰富的报 ...

随机推荐

  1. Socks5 RFC1928协议中文版

    除了这个意译版rfc1928外,其他人写的好像也有错误,都是一知半解. ☆ RFC 1928意译版(非直译版) http://www.ietf.org/rfc/rfc1928.txt http://w ...

  2. 软件工程-CMM与CMMI

    CMM CMMI

  3. FUSE 文件系统 example部分 源码注释 (libfuse 2.9.9)

    本篇文章主要是针对fuse-2.9.9 Example 部分 给出的源码,结合官方文档,以及网上的资料给出注释,希望能给正在学习的你们一点帮助. Hello.c /* FUSE: Filesystem ...

  4. Windows下cwrsync客户端与rsync群辉存储客户端数据同步

    cwRsync简介 cwRsync是Rsync在Windows上的实现版本,Rsync通过使用特定算法的文件传输技术,可以在网络上传输只修改了的文件. cwRsync主要用于Windows上的远程文件 ...

  5. pip更新及Requirement already up-to-date解决方法

    pip更新及Requirement already up-to-date解决方法 文:铁乐与猫 2018-9-11 更新命令 将pip更新到最新版本 python -m pip install --u ...

  6. js入门-文本框输入特定内容控制另一个文本框

    在填写表单时,有时需要某些文本框隐藏,当一文本框输入特定内容时才会显示隐藏的文本框,这一功能可以用onchange事件或oninput事件实现.下面对比下两种方法实现的区别: onchange()定义 ...

  7. MySQL 1130 - Host 127.0.0.1 is not allowed to connect to this MySQL server

    在开发中为了让开发更方便,在本地配置环境,希望可以直接访问服务器上的MySQL数据库,更方便的管理数据库, 需要在本地远程连接linux服务器的本地数据库,直接用数据库管理工具连接出现如下报错1130 ...

  8. SAP SQVI 快速浏览器

    SQVI可向SQL一样连接多个表浏览数据. 1.输入T-CODE:SQVI. 2.新建一个新查询case 输入CASE 名.点击新建,在弹出的窗口中输入标题,在数据源中可选择单个表查询,或者选择表连接 ...

  9. 17秋 软件工程 团队第五次作业 Alpha Scrum10

    17秋 软件工程 团队第五次作业 Alpha Scrum10 今日完成的任务 世强:Android客户端成员列表完善.APP前端子部门和活动中心界面与数据交互: 港晨:Web前端主页的接口对接: 树民 ...

  10. 错误: 无法访问InstrumentationTestRunner 找不到android.test.InstrumentationTestRunner的类文件

    错误: 无法访问InstrumentationTestRunner找不到android.test.InstrumentationTestRunner的类文件