前言

本系列已写了四篇文章,读本篇之前,可以先读前面几篇。
思考大纲:.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参数

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

MySQL 存储

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

示例

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

详情参考:
zipkin-dependencies

实践

创建使用数据库

mysql> create database mytestdb;
Query OK, 1 row affected (0.01 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| mytestdb |
| performance_schema |
| sys |
| ttt |
+--------------------+
7 rows in set (0.00 sec)
mysql> use mytestdb
Database changed

使用sql语句创建zipkin表

CREATE TABLE IF NOT EXISTS zipkin_spans (
`trace_id_high` BIGINT NOT NULL DEFAULT 0COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64bit',
`trace_id` BIGINT NOT NULL,
`id` BIGINT NOT NULL,
`name` VARCHAR(255) NOT NULL,
`parent_id` BIGINT,
`debug` BIT(1),
`start_ts` BIGINT COMMENT 'Span.timestamp():epoch micros used for endTs query and to implement TTL',
`duration` BIGINT COMMENT 'Span.duration():micros used for minDuration and maxDuration query'
)ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
ALTER TABLE zipkin_spans ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `id`) COMMENT'ignore insert on duplicate';
ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`, `id`) COMMENT 'forjoining with zipkin_annotations';
ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'forgetTracesByIds';
ALTER TABLE zipkin_spans ADD INDEX(`name`) COMMENT 'for getTraces and getSpanNames';
ALTER TABLE zipkin_spans ADD INDEX(`start_ts`) COMMENT 'for getTraces ordering andrange';
CREATE TABLE IF NOT EXISTS zipkin_annotations (
`trace_id_high` BIGINT NOT NULL DEFAULT 0COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64bit',
`trace_id` BIGINT NOT NULL COMMENT 'coincideswith zipkin_spans.trace_id',
`span_id` BIGINT NOT NULL COMMENT 'coincideswith zipkin_spans.id',
`a_key` VARCHAR(255) NOT NULL COMMENT'BinaryAnnotation.key or Annotation.value if type == -1',
`a_value` BLOB COMMENT'BinaryAnnotation.value(), which must be smaller than 64KB',
`a_type` INT NOT NULL COMMENT'BinaryAnnotation.type() or -1 if Annotation',
`a_timestamp` BIGINT COMMENT 'Used toimplement TTL; Annotation.timestamp or zipkin_spans.timestamp',
`endpoint_ipv4` INT COMMENT 'Null whenBinary/Annotation.endpoint is null',
`endpoint_ipv6` BINARY(16) COMMENT 'Null whenBinary/Annotation.endpoint is null, or no IPv6 address',
`endpoint_port` SMALLINT COMMENT 'Null whenBinary/Annotation.endpoint is null',
`endpoint_service_name` VARCHAR(255) COMMENT'Null when Binary/Annotation.endpoint is null'
)ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
ALTER TABLE zipkin_annotations ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `span_id`,`a_key`, `a_timestamp`) COMMENT 'Ignore insert on duplicate';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`, `span_id`)COMMENT 'for joining with zipkin_spans';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'forgetTraces/ByIds';
ALTER TABLE zipkin_annotations ADD INDEX(`endpoint_service_name`) COMMENT 'forgetTraces and getServiceNames';
ALTER TABLE zipkin_annotations ADD INDEX(`a_type`) COMMENT 'for getTraces';
ALTER TABLE zipkin_annotations ADD INDEX(`a_key`) COMMENT 'for getTraces';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id`, `span_id`, `a_key`) COMMENT 'fordependencies job';
CREATE TABLE IF NOT EXISTS zipkin_dependencies (
`day` DATE NOT NULL,
`parent` VARCHAR(255) NOT NULL,
`child` VARCHAR(255) NOT NULL,
`call_count` BIGINT
)ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
ALTER TABLE zipkin_dependencies ADD UNIQUE KEY(`day`, `parent`, `child`);

创建成功后,查询结果。

mysql> show tables;
+---------------------+
| Tables_in_mytestdb |
+---------------------+
| zipkin_annotations |
| zipkin_dependencies |
| zipkin_spans |
+---------------------+
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相同密码是可以登录成功的。所以问题出现在哪呢?

[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
Exception in thread "main" java.lang.RuntimeException: java.sql.SQLInvalidAuthorizationSpecException: Access denied for user 'root'@'localhost' (using password: NO)
at zipkin2.dependencies.mysql.MySQLDependenciesJob.hasTraceIdHigh(MySQLDependenciesJob.java:233)
at zipkin2.dependencies.mysql.MySQLDependenciesJob.run(MySQLDependenciesJob.java:184)
at zipkin2.dependencies.ZipkinDependenciesJob.main(ZipkinDependenciesJob.java:65)
Caused by: java.sql.SQLInvalidAuthorizationSpecException: Access denied for user 'root'@'localhost' (using password: NO)
at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.get(ExceptionMapper.java:173)
at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.getException(ExceptionMapper.java:110)
at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connectWithoutProxy(AbstractConnectProtocol.java:1115)
at org.mariadb.jdbc.internal.util.Utils.retrieveProxy(Utils.java:502)
at org.mariadb.jdbc.MariaDbConnection.newConnection(MariaDbConnection.java:154)
at org.mariadb.jdbc.Driver.connect(Driver.java:86)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at zipkin2.dependencies.mysql.MySQLDependenciesJob.hasTraceIdHigh(MySQLDependenciesJob.java:229)
... 2 more
Caused by: java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: NO)
Current charset is UTF-8. If password has been set using other charset, consider using option 'passwordCharacterEncoding'
at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.authentication(AbstractConnectProtocol.java:862)
at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.handleConnectionPhases(AbstractConnectProtocol.java:785)
at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connect(AbstractConnectProtocol.java:456)
at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connectWithoutProxy(AbstractConnectProtocol.java:1111)
... 8 more

追溯源码

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

public static final class Builder {
Map<String, String> sparkProperties = ImmutableMap.of(
"spark.ui.enabled", "false"
);
String db = getEnv("MYSQL_DB", "zipkin");
String host = getEnv("MYSQL_HOST", "localhost");
int port = Integer.parseInt(getEnv("MYSQL_TCP_PORT", "3306"));
String user = getEnv("MYSQL_USER", "");
String password = getEnv("MYSQL_PASS", "");
int maxConnections = Integer.parseInt(getEnv("MYSQL_MAX_CONNECTIONS", "10"));
boolean useSsl = Boolean.parseBoolean(getEnv("MYSQL_USE_SSL", "false"));
// local[*] master lets us run & test the job locally without setting a Spark cluster
String sparkMaster = getEnv("SPARK_MASTER", "local[*]");
// By default the job only works on traces whose first timestamp is today
long day = midnightUTC(System.currentTimeMillis());
/**
*为减少篇幅,中间设置属性部分代码省略。
*/
public MySQLDependenciesJob build() {
return new MySQLDependenciesJob(this);
}
}
/**
*为减少篇幅,中间部分代码省略。
*/
MySQLDependenciesJob(Builder builder) {
this.db = builder.db;
this.day = builder.day;
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
this.dateStamp = df.format(new Date(builder.day));
this.url = new StringBuilder("jdbc:mysql://")
.append(builder.host).append(":").append(builder.port)
.append("/").append(builder.db)
.append("?autoReconnect=true")
.append("&useSSL=").append(builder.useSsl).toString();
this.user = builder.user;
this.password = builder.password;
this.conf = new SparkConf(true)
.setMaster(builder.sparkMaster)
.setAppName(getClass().getName());
if (builder.jars != null) conf.setJars(builder.jars);
for (Map.Entry<String, String> entry : builder.sparkProperties.entrySet()) {
conf.set(entry.getKey(), entry.getValue());
}
this.logInitializer = builder.logInitializer;
}
void saveToMySQL(List<DependencyLink> links) {
try (Connection con = DriverManager.getConnection(url, user, password)) {
PreparedStatement replace = con.prepareStatement(
"REPLACE INTO zipkin_dependencies (day, parent, child, call_count, error_count) VALUES (?,?,?,?,?)");
for (DependencyLink link : links) {
replace.setDate(1, new java.sql.Date(day));
replace.setString(2, link.parent());
replace.setString(3, link.child());
replace.setLong(4, link.callCount());
replace.setLong(5, link.errorCount());
replace.executeUpdate();
}
} catch (SQLException e) {
throw new RuntimeException("Could not save links " + links, e);
}
}

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

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

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

mysql> show variables like 'character_set_database';
+------------------------+---------+
| Variable_name | Value |
+------------------------+---------+
| character_set_database | utf8mb4 |
+------------------------+---------+
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. [201804012]关于hugepages 3.txt

    [201804012]关于hugepages 3.txt --//有一段时间我一直强调安装oracle一定要配置hugepage,因为现在的服务器内存越来越大,如果还使用4K的页面表,如果内存表占用内 ...

  2. python-Tkinter整理总结

    笔者学习Tkinter模块也有好久时间了,现将学习的做以整理. tkinter简介(一) tkinter中lable标签控件(二) tkinter中button按钮控件(三) tkinter中entr ...

  3. WCF服务端开发和客户端引用小结

    1.服务端开发 1.1 WCF服务创建方式 创建一个WCF服务,总是会创建一个服务接口和一个服务接口实现.通常根据服务宿主的不同,有两种创建方式. (1)创建WCF应用程序 通过创建WCF服务应用程序 ...

  4. 洗礼灵魂,修炼python(18)--温故加知新

    类型转换: 1.str(),repr(),format():将非字符串数据转换为字符串 str():对象序列化的结果,相当于print输出 repr():程序中某个对象精确值 format():利用特 ...

  5. jquery常用表单操作

    //js将表单序列化成对象 $.fn.serializeObject = function () { var $els = $(this).find("[name]"); var ...

  6. NFS常见问题

    问题一:取消挂载失败 问题现象: umount /opt/data umount.nfs: /opt/data: device is busy umount.nfs: /opt/data: devic ...

  7. Linux 小知识翻译 - 「模块」

    说起module(模块),有的像「可热插拔的零部件」的意思. 在讨论Linux时提到的模块一般是指可以组装到内核中的模块. 模块这个概念是在硬件和程序设计领域中广泛使用的概念.我们这次说的模块特指Li ...

  8. vue打包速度优化

    这是一个很头疼的问题,webpack极大的简化了前端自动化配置,但是打包速度实在是不如人意.在此之前,本人也尝试过网友的一些方法,但是,很多坑,跳进去就出不来,经过多个项目实践,现总结一下我用到的优化 ...

  9. PHP开发小技巧①①—php实现手机号码显示部分

    从个人信息保护性的角度来讲,我们在开发过程中总会想办法去保护用户的一些个人信息.就如本篇博文所讲,我们有时会将用户的手机号码只显示出部分,这是很多网站都有做的功能.这个功能实现起来也是特别的简单,只需 ...

  10. 左侧多级菜单,高亮显示js

    左侧多级菜单,如果本页面是当前栏目,则左侧菜单高亮显示 <ul class="nav navbar-stacked" id="navs"> {ded ...