springboot1.5.x与自建的应用层APM系统落地实践
2019-04-29 本文已影响76人
慢黑八
APM简书 慢黑八
转载请注明原创出处,谢谢!
如果读完觉得有收获的话,欢迎点赞加关注
【概念篇】应用程序微服务化之后,我们想看到整个微服务的集群,上下游系统,服务依赖关系、流量分布、外部边界等内容。所以,监控(可观察性)是应用系统微服务化之后提出的一项基础性需求。今天,我们就来聊聊微服务监控(APM)的那些事。
采用系统分层的思想可视化监控分析可以分为3个层次
- 1、基建层:云主机、操作系统、云服务等基础指标,由云厂商负责提供。
- 2、工具层:k8s、docker、mesos、devops,由生态提供。
- 3、应用层:中间件、数据库、消息队列、缓存等中间件由微服务或云原生应用的开发者提供。
对于业务系统开发的人员来说,如何对应用层进行监控分析
成为了他们需要急需解决的问题。
接下来我们就来说说如何对 "应用层进行监控分析" ,先看下下面三个概念
- 1、日志(Logging):包含业务日志、系统日志、错误日志、警告日志等,分布式日志我们通常使用ELK进行收集,同时这也是比较简单的解决方案。
- 2、指标(Metrics):指标是可累加的,它具有原子性。每个指标都是一个逻辑计量单元,体现了一段时间之内相关指标的状态。例如:队列深度、请求执行时间、http请求数及自定义的一些业务指标等。通过定义和收集需要具备某时间范围的查询能力。Prometheus是基于指标的系统,它通过定义和收集不同的指标数据,提供基于时间维度的查询能力。结合Grafana(开源)进行展示。
- 3、追踪(Tracing):分布式追踪能力是最近几年技术人员最为关注的需求,由Twitter开源的ZipKin是目前运用最为刚广泛的分布式追踪系统,spring-cloud-sleuth是spring-cloud为zipkin开发的一组套件,使zipkin更好的结合在spring-cloud生态中。还有一些其他的开源分布式追踪系统也比较火,例如skywalking以及pinpoint、cat等。
所以,我们自建的APM系统,采用如下解决方案收集日志、指标、追踪3个维度的数据:
- 1、日志:使用log4j2+filebeat+kafka+logstash+elasticSearch作为日志的收集,使用Kibana进行展示
- 2、指标:使用Metrics/Prometheus-client+Prometheus+Tsdb进行指标的收集,使用Grafana进行展示
- 3、追踪:使用spring-cloud-sleuth+kafka+zipkinServer+elasticSearch作为链路数据的收集,使用zipkin-ui进行链路追踪数据的展示。
如下图,上面三个概念并不是相互独立的,往往会有一定的重叠,复杂和完善的监控系统一般是跨越多个维度的,下面我们具体来说一下重叠的部分: - 4、追踪+日志:通过简单的上下文传递,可以将请求的上下文ID输出到日志,让日志具备上
下文关联的能力
。可以根据traceid、spanid快速找到一次“请求范围内的日志
”。 - 5、日志+指标:可以通过解析系统现有的业务日志获取相关的指标数据,也可称为“
可聚合的事件汇总
”。 - 6、追踪+指标:指明基于
分布式追踪的数据分析(慢事务,错误,中间件调用等)
,应用间的关系(系统拓扑)
以及数据流向(系统调用关系)
。
【实践篇】 针对现有springboot1.5.x应用环境,与我们自建的apm系统进行整合。
一、现有环境
1、应用系统
springboot1.5 + JDK1.8等
2、APM系统
参见图1中的APM系统,包含elk6.7.1、grafana、Prometheus、tsdb、kafka、zipkinserver等
kibana http://test.tech.**bank.com/kibana/ 用户名:onec***_dev 密码:**bank
zipkinui http://test.tech.**bank.com/zipkin/
二、基于现有spring1.5.x 环境改造
1、追踪:使用spring-cloud-sleuth通过kafka传输zipkin链路数据到zipkinServer:
- pom.xml文件增加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
- application.properties应用配置中增加如下内容
your_application为你的应用程序名称
application.name: your_application
spring.kafka.producer.bootstrap-servers=ip:port
spring.kafka.producer.compression-type=gzip
spring.kafka.producer.acks=all
spring.kafka.producer.retries=3
spring.kafka.producer.batch-size=1048576
spring.kafka.producer.buffer-memory=6291456
spring.sleuth.sampler.percentage=1.0
spring.zipkin.sender.type=kafka
spring.zipkin.compression.enabled=true
spring.zipkin.service.name=your_application
spring.zipkin.message-timeout=1
2、日志:使用filebeat,收集json格式的log4j日志,通过kafka,logstash处理后存储至elastic search存储中,另外在日志中输出tracid、spanid、parentid等信息。
- 待filebeat收割的日志输出配置,修改应用程序log4j2.xml配置文件,添加以下appender块
注:filebeat以行位单位读取日志,下配置中,compact、eventEol需要全部配置位true,保证json格式日志按行输出
<!--以下是Properties中的改造-->
<Property name="PROJECT_NAME">your_application</Property>
<property name="LOG_PATH" value="/path/to" />
<property name="MAX_FILE_SIZE" value="1000MB" />
<!--以下是appenders中的改造-->
<RollingRandomAccessFile name="ALLJSON_LOG"
fileName="${LOG_PATH}/alljson.log"
filePattern="${LOG_PATH}/alljson-%d{yyyyMMdd-HHmmss.SSS}.log">
<JSONLayout charset="UTF-8" locationInfo="true"
properties="true" complete="false" compact="true" eventEol="true"
propertiesAsList="false" includeStacktrace="true">
<KeyValuePair key="serviceName" value="${PROJECT_NAME}" />
</JSONLayout>
<Policies>
<!--当日志大小达到1000MB时,以上述filePattern定义的格式进行打包压缩 -->
<SizeBasedTriggeringPolicy
size="${MAX_FILE_SIZE}" />
</Policies>
<DefaultRolloverStrategy max="10" /><!--压缩包数量不超过10 -->
</RollingRandomAccessFile>
<Async name="ASYNC_ALLJSON_LOG" bufferSize="262144">
<AppenderRef ref="ALLJSON_LOG" />
</Async>
<!--以下是Loggers中的改造-->
<root level="${LOG_ROOT_LEVEL}">
<appender-ref ref="CONSOLE" />
<appender-ref ref="ASYNC_ALLJSON_LOG"/>
</root>
- 因为log4j.xml中的<KeyValuePair>需要使用高版本log4j2,这里我使用2.11.2这个版本,并且排出logback
pom.xml引入高版本的log4j2依赖,如下:
<!-- 引入log4j2依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.2</version>
</dependency>
- filebeat安装配置:
1、下载filebeat wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.7.1-linux-x86_64.tar.gz
2、解压tar -xvf filebeat-6.7.1-linux-x86_64.tar.gz
3、进入 filebeat-6.7.1-linux-x86_64目录配置filebeat.yml文件
- type: log
# Change to true to enable this input configuration.
enabled: true
# Paths that should be crawled and fetched. Glob based paths.
paths:
#- /app/onecard-canary-service/logs/info.log
- /path/to/alljson.log
output.kafka:
enabled: true
hosts: ["IP:PORT"]
topic: 'topic.name'
partition.hash:
reachable_only: true
compression: gzip
max_message_bytes: 1000000
required_acks: 1
4、执行命令,运行filebeat: nohup ./filebeat -e -c filebeat.yml &
- 如果想在控制台或者其他的log appender中也看到traceid的相关信息,需要配置LOG_PATTERN.
<property name="LOG_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level [%X{X-B3-TraceId},%X{X-B3-SpanId},%X{X-B3-ParentSpanId},%X{X-Span-Export}]
%c{36} [%line] - %msg%n" />
%X{X-B3-TraceId},%X{X-B3-SpanId},%X{X-B3-ParentSpanId},%X{X-Span-Export}就是traceid、spanid、parentid的相关信息
3、指标:
未完、待续....