调研了市面上的监控方案,zipkin功能太弱,需要配合elk才能更好排查错误,CAT侵入太高,skywalking文档和社区不完善。但是skywalking功能是最强的。这篇文章的技术基础是java-agent探针技术,可以先看那文章了解原理。官方文档

整个skywalking包括4个部分:数据存储依赖(es,数据库等等),上报后台APM,看板(skywalking-ui)、上报客户端。上报是基于grpc的,启动存储服务后,启动APM服务,APM监控两个端口11800负责接收上报、12800负责提供查询。启动看板,8080就是看板端口,前后端分离的,前端是单页应用,刷新会报404。启动服务设置agent上报数据。

大概就是这么个逻辑。

搭建流程:

本地环境需要下载8.7.0版本,下载地址是skywalking 为什么是8.7.0呢?因为8.7.0以后agent与apm服务端分离了,apm我是编译通过了,agent一直编译失败我tm日了狗了。

配置上报后台:
config/application.yml

cluster:
  selector: ${SW_CLUSTER:standalone}
  standalone:
  ......一大堆
core:
  selector: ${SW_CORE:default}
  default:
  .....一大堆
storage:
  selector: ${SW_STORAGE:elasticsearch7}
  elasticsearch7:
    nameSpace: ${SW_NAMESPACE:""}
# es地址
    clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:localhost:9200}
    protocol: ${SW_STORAGE_ES_HTTP_PROTOCOL:"http"}
    connectTimeout: ${SW_STORAGE_ES_CONNECT_TIMEOUT:500}
    socketTimeout: ${SW_STORAGE_ES_SOCKET_TIMEOUT:30000}
    user: ${SW_ES_USER:""}
    password: ${SW_ES_PASSWORD:""}
  .......一大堆

注:这些大写的SW_XXX占位符可以-DSW_XXX=xxxx设置,也可以通过设置环境变量设置。这点在docker启动的时候有体现。

docker run --name oap --restart always -d -e SW_STORAGE=elasticsearch7 -e SW_STORAGE_ES_CLUSTER_NODES=elasticsearch:9200 -p 11800:11800 apache/skywalking-oap-server:8.7.0-es7

注:这里的elasticsearch之所以能够按名访问是因为他们在同一个docker网络下面。
启动后就可以收集数据了。

配置看板:
webapp/webapp.yml

spring:
  cloud:
    gateway:
      routes:
        - id: oap-route
          uri: lb://oap-service
          predicates:
            - Path=/graphql/**
    discovery:
      client:
        simple:
          instances:
            oap-service:
              - uri: http://127.0.0.1:12800
            # - uri: http://<oap-host-1>:<oap-port1>
            # - uri: http://<oap-host-2>:<oap-port2>

他是使用graphql风格的接口,同时做了负载均衡。看板后台将请求直接转发到收集后台的12800端口。启动后就访问8080就可以看到效果了。
或者你可以直接使用docker

docker run --name oap-ui --restart always -d -p 9400:8080 -e SW_OAP_ADDRESS=http://oap:12800 apache/skywalking-ui:8.7.0

配置agent:
agent/config/agent.config

# The service name in UI
agent.service_name=${SW_AGENT_NAME:Your_ApplicationName}
# Backend service addresses.
collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:10.10.2.241:11800}

plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:10.10.2.241}
plugin.toolkit.log.grpc.reporter.server_port=${SW_GRPC_LOG_SERVER_PORT:11800}
plugin.toolkit.log.grpc.reporter.max_message_size=${SW_GRPC_LOG_MAX_MESSAGE_SIZE:10485760}
plugin.toolkit.log.grpc.reporter.upstream_timeout=${SW_GRPC_LOG_GRPC_UPSTREAM_TIMEOUT:30}

注:日志上报在他的样例文件上是没有的需要自己添加。plugin.toolkit.log.grpc.reporter.XXXX。这也就意味着如果你需要使用docker它官方的agent镜像是不能适用与所有情况的,当然你可以将config目录和plugins目录挂载出来以解决插件选择与配置问题。

配置服务:
如果需要上报日志和打印traceId(tid)则需要添加对应的jar和配置文件
依赖引入:

        <dependency>
            <groupId>org.apache.skywalking</groupId>
            <artifactId>apm-toolkit-logback-1.x</artifactId>
            <version>${skywalking.version}</version>
        </dependency>

logback-spring.xml

<?xml version="1.0" encoding="utf-8" ?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <contextName>app-b</contextName>
    <property name="log.path" value="logs" />
    <property name="log.maxHistory" value="15" />
    <!-- 日志格式 -->
    <property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%tid] [%thread] %-5level %logger{36} -%msg%n" />

    <!--输出到控制台-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
                <pattern>${log.pattern}</pattern>
            </layout>
        </encoder>
    </appender>

    <!--输出到文件-->
    <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/info/info.%d{yyyy-MM-dd}.log</fileNamePattern>
            <MaxHistory>${log.maxHistory}</MaxHistory>
        </rollingPolicy>
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <!--格式化器-->
            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
                <pattern>${log.pattern}</pattern>
            </layout>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!--上报到skywalking-->
    <appender name="grpc-log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
                <pattern>${log.pattern}</pattern>
            </layout>
        </encoder>
    </appender>

    <root level="debug">
        <appender-ref ref="console" />
        <appender-ref ref="grpc-log"/>
    </root>

    <root level="info">
        <appender-ref ref="file_info" />
        <appender-ref ref="grpc-log"/>
    </root>
</configuration>

访问启动时可以设置参数以更改一些配置。

-javaagent:pathto/skywalking-agent.jar
-DSW_AGENT_NAME=A_app
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=10.10.2.241:11800
-DSW_GRPC_LOG_SERVER_HOST=10.10.2.241
-DSW_GRPC_LOG_SERVER_PORT=11800
-Dagent.instance_uuid=实例id,如果不设置,每次都会生成新的。

完整如下:

java -jar -javaagent:pathto/skywalking-agent.jar -DSW_AGENT_NAME=A_app -DSW_AGENT_COLLECTOR_BACKEND_SERVICES=10.10.2.241:11800 -DSW_GRPC_LOG_SERVER_HOST=10.10.2.241 -DSW_GRPC_LOG_SERVER_PORT=11800 demo.jar

注:SW_XXXX可以通过设置环境变量设置。

启动后再看版开启刷新可以看到你接入了,跑一下接口可以看到拓扑结构,链路和对应日志。

告警
skywaking的这项功能听说挺耗资源的,所有要谨慎。他有一个我非常中意的功能:webhook可以在告警的时候回调一个接口通知,这为告警带来了无限可能。可以接入一切通知。

config/alarm-settings.yml

rules:
  # Rule unique name, must be ended with `_rule`.告警规则
  service_resp_time_rule:
    metrics-name: service_resp_time
    op: ">"
    threshold: 1000
    period: 10
    count: 3
    silence-period: 5
    message: Response time of service {name} is more than 1000ms in 3 minutes of last 10 minutes.

webhooks:
   - http://127.0.0.1/notify/
#  - http://127.0.0.1/go-wechat/

规则与接口编写就不提了,你可以自己查阅官方文档。如果你希望在docker环境添加告警规则,你应该将/skywalking/ext-config目录挂载出来,然后将alarm-settings.yml放到你挂载的目录。如果你有新的告警逻辑,你应该将/skywalking/ext-libs挂载出来,然后将你的jar放到里面。(告警是APM服务端的功能)。

标签: skywalking

已有 2 条评论

  1. narutuo

    写的好,下次继续

  2. 李哥要转运维了啊

添加新评论