本文来源于公众号:勾勾的Java宇宙(微信号:Javagogo),莫得推广,全是干货!
原文链接:mp.weixin.qq.com/s/T9RHSCvM0… 作者:徐老板
勾哥:
最近腾讯的瓜实在多,QQ 团队刚闹出私自读取用户所有浏览器记录的事儿(反应慢的去看我二条!),紧接着腾讯云团队复制 SkyWalking 源码就被官方实锤。
据悉鹅厂已经开始整改了,我们且看吧。
正好之前请徐老板整理了 SkyWalking 的环境搭建和接入方式的小文儿,发出来求一波赞!
SkyWalking 环境搭建
apache-skywalking-apm-6.2.0.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-webapp、demo-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 --- [main] c.a.d.r.zookeeper.ZookeeperRegistry : [DUBBO] Register: dubbo://172.17.32.91:20880/com.xxx.service.HelloService
# demo-provider 启动成功
2020-02-01 12:12:16.269 INFO 58600 --- [ main] com.xxx.DemoProviderApplication : Started DemoProviderApplication in 4.635 seconds (JVM running for 9.005)
2. demo-webapp 模块
demo-webapp 模块的 pom.xml 与 demo-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),拒绝水文,收获干货!