【狗头】谢谢腾讯抬举,我SkyWalking何德何能!

4,599 阅读8分钟

本文来源于公众号:勾勾的Java宇宙(微信号:Javagogo),莫得推广,全是干货!

原文链接:mp.weixin.qq.com/s/T9RHSCvM0… 作者:徐老板

勾哥:

最近腾讯的瓜实在多,QQ 团队刚闹出私自读取用户所有浏览器记录的事儿(反应慢的去看我二条!),紧接着腾讯云团队复制 SkyWalking 源码就被官方实锤。

据悉鹅厂已经开始整改了,我们且看吧。

正好之前请徐老板整理了 SkyWalking 的环境搭建和接入方式的小文儿,发出来求一波赞!

SkyWalking 环境搭建

apache-skywalking-apm-6.2.0.tar.gz

elasticsearch-6.6.1.tar.gz

kibana-6.6.1-darwin-x86_64.tar.gz

1. ElasticSearch 安装

下载完 elasticsearch-6.6.1.tar.gz 包之后,使用如下命令进行解压缩:

tar -zxf elasticsearch-6.6.1.tar.gz

解压完成之后,进入得到的 elasticsearch-6.6.1 目录中,执行如下命令后台启动 ElasticSearch 服务:

./bin/elasticsearch -d

ElasticSearch 启动的相关日志可以通过下面的命令进行查看:

tail -f logs/elasticsearch.log

最后,我们可以请求 localhost:9200 这地址,看到下图输出的这段 JSON 即安装成功:

2. Kibana 安装

Kibana 是一个开源的分析和可视化平台,主要用于和 Elasticsearch 一起工作,轻松实现 ElasticSearch 的查询和管理。

这里使用 ElasticSearch 作为 SkyWalking 的后端存储,在后续调试 SkyWalking 源码时,可能会直接查询 ElasticSearch 中的某些索引,所以这里一并安装 Kibana。

下载完 kibana-6.6.1-darwin-x86_64.tar.gz 安装包之后,我们使用如下命令进行解压:

tar -zxf  kibana-6.6.1-darwin-x86_64.tar.gz

解压完成后进入 kibana-6.6.1-darwin-x86_64 目录,修改 config/kibana.yml 文件:

# 指定上述 ElasticSearch监听的地址,其他配置不变
elasticsearch.hosts: ["http://localhost:9200"]

之后执行如下命令,启动 Kibana 服务:

./bin/kibana

最后我们通过访问 http://localhost:5601/ 地址即可进入 Kibana 界面:

3. SkyWalking 安装

下载完成 apache-skywalking-apm-6.2.0.tar.gz 包之后,执行如下命令解压缩:

tar -zxf apache-skywalking-apm-6.2.0.tar.gz

解压完成之后进入 apache-skywalking-apm-bin 目录,编辑 config/application.yml 文件,将其中 ElasticSearch 配置项以及其子项的全部注释去掉,将 h2 配置项及其子项全部注释掉,如下图所示,这样 SkyWalking 就从默认的存储 h2 切换成了 ElasticSearch :

接下来执行 ./bin/startup.sh 文件即可启动 SkyWalking OAP 以及 UI 界面,看到的输出如下:

>./bin/startup.sh
SkyWalking OAP started successfully!
SkyWalking Web Application started successfully!

我们可以在 logs/skywalking-oap-server.log 以及 logs/webapp.log 两个日志文件中查看到 SkyWalking OAP 以及 UI 项目的相关日志,这里不再展开。

最后访问 http://127.0.0.1:8080/ 即可看到 SkyWalking 的 Rocketbot UI 界面。

4. Skywalking Agent 目录结构

SkyWalking Agent 使用了 Java  Agent 技术,可以在无需手工埋点的情况下,通过 JVM 接口在运行时将监控代码段插入已有 Java 应用中,实现对 Java 应用的监控。SkyWalking Agent 会将服务运行过程中获得的监控数据通过 gRPC 发送给后端的 OAP 集群进行分析和存储。

SkyWalking 目前提供的 Agent 插件在 apache-skywalking-apm-bin/agent 目录下:

agent
    ├── activations
    │   ├── apm-toolkit-log4j-1.x-activation-6.2.0.jar
    │   ├── ...
    │   └── apm-toolkit-trace-activation-6.2.0.jar
    ├── config # Agent 配置文件
    │   └── agent.config
    ├── logs # 日志文件
    ├── optional-plugins # 可选插件
    │   ├── apm-customize-enhance-plugin-6.2.0.jar
    │   ├── apm-gson-2.x-plugin-6.2.0.jar
    │   └── ... ...
    ├── plugins # 当前生效插件
    │   ├── apm-activemq-5.x-plugin-6.2.0.jar
    │   ├── tomcat-7.x-8.x-plugin-6.2.0.jar
    │   ├── spring-commons-6.2.0.jar
    │   └── ... ...
    └── skywalking-agent.jar

其中,

  • agent.config 文件是 SkyWalking Agent 的唯一配置文件。

  • plugins 目录存储了当前 Agent 生效的插件。

  • optional-plugins 目录存储了一些可选的插件(这些插件可能会影响整个系统的性能或是有版权问题),如果需要使用这些插件,需将相应 jar 包移动到 plugins 目录下。

  • skywalking-agent.jar 是 Agent 的核心 jar 包,由它负责读取 agent.config 配置文件,加载上述插件 jar 包,运行时收集到的 Trace 和 Metrics 数据也是由它发送到 OAP 集群的。

skywalking-demo 示例

下面搭建 demo-webapp、demo-provider 两个 Spring-Boot 项目,并且接入 SkyWalking Agent 进行监控,具体结构如下:

demo-webapp 会 Dubbo 远程调用 demo-provider 的接口,而 Dubbo 依赖了 Zookeeper,所以要先安装 Zookeeper。

然后在 IDEA 中创建 skywalking-demo 项目,并在其中创建 demo-api,创建 demo-webappdemo-provider 两个 Module,如下图所示:

skywalking-demo 下面的 pom.xml 中,将父 pom 指向 spring-boot-starter-parent 并添加 demo-api 作为公共依赖,如下所示:

<project xmlns=...">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.1.RELEASE</version>
    </parent>
    <groupId>com.xxx</groupId>
    <artifactId>skywalking-demo</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>demo-api</module>
        <module>demo-webapp</module>
        <module>demo-provider</module>
    </modules>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.xxx</groupId>
                <artifactId>demo-api</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

demo-api 中只定义了 HelloService 接口,它是 Dubbo Provider 和 Dubbo Consumer 依赖的公共接口,如下:

public interface HelloService {
    String say(String name) throws Exception;
}

1. demo-provider 模块

这里的 demo-provider 扮演了 Dubbo Provider 的角色,在其 pom.xml 文件中引入了 Spring Boot 以及集成 Dubbo 相关的依赖,如下所示:

<dependencies>
    <!-- 引入公共API接口 -->
    <dependency>
        <groupId>com.xxx</groupId>
        <artifactId>demo-api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <!-- 引入spring-boot-starter以及dubbo和curator的依赖 -->
    <dependency>
        <groupId>com.alibaba.boot</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>0.2.0</version>
    </dependency>
    <!-- Spring Boot相关依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
</dependencies>

demo-provider 模块中的 DefaultHelloService 实现了 HelloService 接口,如下所示:

@Service
@Component
public class DefaultHelloService implements HelloService {

    public String say(String name) throws Exception{
        Thread.sleep(2000);
        return "hello" + name;
    }
}

resource/application.yml 配置文件中将 DefaultHelloService 实现注册到 Zookeeper 上对外暴露为 Dubbo Provider,具体配置如下:

dubbo:
  application:
    name: demo-provider # Dubbo Provider 的名字
  registry:
    # 注册中心地址,即前面启动的Zookeeper地址
    address: zookeeper://127.0.0.1:2181 
  protocol:
    name: dubbo # 指定通信协议
    port: 20880 # 通信端口,这里指的是与消费者间的通信协议与端口
  provider:
    timeout: 10000 # 配置全局调用服务超时时间,dubbo默认是1s,肯定不够用呀
    retries: 0 # 不进行重试
    delay: -1

DemoProviderApplication 中提供 Spring Boot 的启动 main() 方法,如下所示:

@EnableDubbo // 添加对 Dubbo支持的注解
@SpringBootApplication
public class DemoProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoProviderApplication.class, args);
    }
}

为了引入 Skywalking Agent 插件,还需要将 apache-skywalking-apm-bin/agent/config 目录下的 agent.config 配置文件拷贝到 demo-provider 模块的 resource 目录下,并修改其中的 agent.service_name

# The service name in UI
agent.service_name=${SW_AGENT_NAME:demo-provider}

很明显,agent.config 是一个 KV 结构的配置文件,类似于 properties 文件,value 部分使用 ${} 包裹,其中使用冒号 : 分为两部分,前半部分是可以覆盖该配置项的系统环境变量名称,后半部分为默认值。例如这里的 agent.service_name 配置项。

如果系统环境变量中指定了 SW_AGENT_NAME 值(注意,全是大写),则优先使用环境变量中指定的值,如果环境变量未指定,则使用 demo-provider 这个默认值。

除了系统环境变量的覆盖方式,SkyWalking Agent 还支持另外两种覆盖默认值的方式:

  • JVM 配置覆盖

例如这里的 agent.service_name 配置项,如果在 JVM 启动之前,明确中指定了下面的 JVM 配置:

-Dskywalking.agent.service_name = demo-provider
# "skywalking."是 Skywalking环境变量的默认前缀

则会使用该配置值覆盖 agent.config 配置文件中默认值。

  • 探针配置覆盖

如果将 Java Agent 配置为如下:

-javaagent:/path/skywalking-agent.jar=agent.service_name=demo-provider
# 默认格式是 -javaagent:agent.jar=[option1]=[value1],[option2]=[value2]

则会使用该 Java Agent 配置值覆盖 agent.config 配置文件中 agent.service_name 默认值。

如果四种配置同时出现,则优先级如下:

探针配置 > JVM配置 > 系统环境变量配置 > agent.config 文件默认值

编辑好 agent.config 配置文件之后,我们需要在启动 demo-provider 之前通过参数告诉 JVM SkyWalking Agent 配置文件的位置,IDEA 中的配置如下图所示:

最后启动 DemoProviderApplication 这个入口类,可以看到如下输出:

# 查找到 agent.config 配置文件
INFO 2020-02-01 12:12:07:574 main SnifferConfigInitializer :  Config file found in ... agent.config. 
# 查找到 agent目录
DEBUG 2020-02-01 12:12:07:650 main AgentPackagePath :  The beacon class location is jar:file:/Users/xxx/... 
# Dubbo Provider 注册成功
2020-02-01 12:12:16.105  INFO 58600 --- [mainc.a.d.r.zookeeper.ZookeeperRegistry      :  [DUBBORegister: dubbo://172.17.32.91:20880/com.xxx.service.HelloService
# demo-provider 启动成功
2020-02-01 12:12:16.269  INFO 58600 --- [           maincom.xxx.DemoProviderApplication          : Started DemoProviderApplication in 4.635 seconds (JVM running for 9.005)

2. demo-webapp 模块

demo-webapp 模块的 pom.xmldemo-provider 中的 pom.xml 相比,多引入了 spring-boot 对 Web 开发的依赖,以及 SkyWalking 提供的 apm-toolkit-trace 依赖用来获取 TraceId

  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

<!-- apm-toolkit-trace 这个依赖主要用来获取 TraceId -->
<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-trace</artifactId>
    <version>6.2.0</version>
</dependency>

首先,在 HelloWorldController 中提供了两个接口:

  • /hello/{words} 接口:通过 Dubbo 远程调用 demo-provider 暴露的接口
  • /err 接口:直接抛出 RuntimeException 异常

HelloWorldController 的具体实现如下:

@RestController
@RequestMapping("/")
public class HelloWorldController {
    @Reference
    private HelloService helloService;

    @GetMapping("/hello/{words}")
    public String hello(@PathVariable("words") String words) 
            throws Exception{
        Thread.sleep(1000);
        // TraceContext 工具类定义在 apm-toolkit-trace 依赖包中
        log.info("traceId:{}", TraceContext.traceId());
        ActiveSpan.tag("hello-trace", words);
        String say = helloService.say(words);
        Thread.sleep(1000);
        return say;
    }

    @GetMapping("/err")
    public String err() {
        String traceId =  TraceContext.traceId();
        log.info("traceId:{}", traceId);
        ActiveSpan.tag("error-trace activation""error");
        throw new RuntimeException("err");
    }

resources/application.yml 文件中会配置 demo-webapp 监听的端口、Zookeeper 地址以及 Dubbo Consumer 的名称等等,具体配置如下:

server:
  port: 8000

dubbo:
  application:
    name: demo-webapp # Dubbo Consumer名字
  registry:
    address: zookeeper://127.0.0.1:2181 # 注册中心地址,即 Zookeeper地址

demo-webpp 模块也需要在 resource 目录下添加 agent.config 配置文件,并修改其 agent.service_name 配置项,如下所示:

# The service name in UI
agent.service_name=${SW_AGENT_NAME:demo-webapp}

demo-webpp 模块的入口 main() 方法与 demo-provider 相同,不再赘述。

为了接入 SkyWalking Agent,启动 demo-webapp 项目之前也需要配置相应的 VM options 参数,指定 agent.config 配置文件的地址,如下图所示:

最后,启动 demo-webapp 项目,通过浏览器访问 http://localhost:8000/hello/xxx 地址得到正常相应,访问 http://localhost:8000/err 得到 500 响应,即表示启动成功。

到此为止,SkyWalking Agent 的基本接入方式就介绍完了。


欢迎关注公众号 勾勾的Java宇宙(微信号:Javagogo),拒绝水文,收获干货!