??原创文章,转载请注明出处。由于本人水平有限,文中错漏之处在所难免,希望大家多多批评指正。本文的内容过多,我们分成四篇聊,此为第二篇。
??通过前面的分析与对比,我们最终选择了SkyWalking(下文简称SW)来做链路监控。考虑到SW是开源的系统,从以往的经历来看,开源的并且达到了系统级别的,一般都是有雷的,不注意的话偷偷爆个雷,所有关联的系统可能都会受到影响,严重的时候会让你很后悔使用了这个系统。而如果使用的是分布式追踪系统的话,在暴雷时会更加的严重,因为它不是独立部署的,是要集成到每一个系统实例的容器中,出问题的时候会直接牵连到容器内的其他服务。所以本着小心求证的原则,在正式上线使用之前,我们先在测试环境简单部署一套SW,初步尝试下系统接入,既有助于对数据体量、集群配置和工作人力的预估,也可以探探雷,提前发现问题,实际验证下是否适合我们,方便我们后续工作的风险把控。整个部署过程我们使用MacOS Mojave操作系统进行演示,可能与Linux会存在细微差别。
- 机器:因为资源紧张,审批从严,只拿到了1台虚拟机。
- 硬件[虚拟机]:4C/8GB/50GB[HDD]/100Mbps[LAN]
- 软件[64-Bit]:CentOS[7.4]/JDK[1.8.0_91]/Docker[18.09.7]/Docker Compose[1.18.0]
- CD工具:公司自研的系统,全界面化操作,这里就叫他tard吧。提供了容器管理,docker镜像配置,环境变量配置,打包,上下线等功能。
- SkyWalking:使用Apache官方Docker镜像,版本号6.3.0。友情提示,推荐大家使用6.3.0或者更高的版本,因为低版本有个雷,后面再详细聊。
??提到需要简单、快速的部署,我们首先想到的就是使用Docker,而且SW是有官方Docker镜像的,可以放心的拿来使用,省去了我们自己做镜像的时间。这次我们主要使用Docker和Docker Compose部署SW,包括服务编排,容器发布与管理。读者需要对基本的Docker命令有所了解,如果没有使用过,这里强推一波Docker。Docker真的是个好东西啊,超级好用,属于那种一旦用过就离不开的程序,也有助于我们的思维扩展,强烈建议大家学习一下。
我们只有1台机器,只有8个G的内存,初步猜测只能部署单机版,不过我们还是想以集群的方式部署SW。因为集群最能真实的模拟线上的环境,也比单机版更容易暴露问题,而且1台机器也不是不可以部署集群,这样的话我们就再挣扎下,先统计集群版和单机版都需要部署多少个实例,看看有没有运行集群的可能性。
最小集群配置 | skywalking-ui | skywalking-oap-server | ZooKeeper | Elasticsearch | 共计 |
---|---|---|---|---|---|
实例数量 | 2 | 2 | 3 | 2 | 9 |
最小单机配置 | skywalking-ui | skywalking-oap-server | ZooKeeper | Elasticsearch | 共计 |
---|---|---|---|---|---|
实例数量 | 1 | 1 | 0 | 1 | 3 |
结合实例数量和每个实例正常工作大概需要的内存量,可以看到集群和单机的差别还是很大的。考虑到集群版就算可以正常启动,在后面的读写压力下性能也不会太好,内存溢出的概率也很大,所以对这次的情况来说单机版更适合。不过有转机的是,如果大家再仔细的想下,这些组件当中只有Elasticsearch(下文简称ES)对内存的要求比较高,最耗内存,而在平时的使用中我们已经验证过ES集群的读写性能和稳定性了,这次其实可以忽略ES的测试,主要验证SW集群的问题。这样我们就可以采用SW集群 + ES单机混合搭配的方式,减少虚拟机的内存压力,实现集群部署。通过后面的试验,我们发现这种混合的方式是行得通的,而且也很好的满足了我们本次的需求。最终采用的部署配置如下:
集群 + 单机混合配置 | skywalking-ui | skywalking-oap-server | ZooKeeper | Elasticsearch | 共计 |
---|---|---|---|---|---|
实例数量 | 2 | 2 | 3 | 1 | 8 |
从零部署的过程中实际操作有很多,这里省略虚拟机的网络配置、防火墙配置、处理FD限制等操作系统级别的操作,省略JDK、Docker、Docker Compose等软件的安装操作,请大家自行安装调试,我们直接上关键的部分。
提前下载好镜像文件(这步可以省略)
# 我们使用6.3.0版本的SW,下载过程如图1所示。
macos$ docker pull apache/skywalking-ui:6.3.0
macos$ docker pull apache/skywalking-oap-server:6.3.0
图1 使用docker下载镜像
# 思考下ZooKeeper使用什么版本?
# skywalking-oap-server:6.3.0的镜像文件中有一个oap-lib目录,存放了所有的依赖。
# 我们发现它使用的ZooKeeper客户端版本号是3.4.10,如图2所示。
# 所以ZooKeeper服务最好也使用3.4.10版本
macos$ docker pull zookeeper:3.4.10
图2 skywalking-oap-server:6.3.0依赖的ZooKeeper版本
# 6.3.0版本的SW只能兼容6.3.2或者更高版本的ES,如图3所示。
# 因为运维同学使用的是6.4.2版本,我们最好和运维保持一致。
macos$ docker pull elasticsearch:6.4.2
图3 SkyWalking官网对ES的版本要求说明
# 下载完成后,应该可以看到如图4所示的四个镜像文件。
macos$ docker images
图4 查看本地镜像
我们使用的docker-compose.yml配置文件
version: "3"
services:
elasticsearch:
image: elasticsearch:6.4.2
container_name: elasticsearch
restart: always
ports:
- 9200:9200
- 9300:9300
ulimits:
memlock:
soft: -1
hard: -1
environment:
- discovery.type=single-node
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms1536m -Xmx1536m -Xmn512m -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m"
- TZ=Asia/Shanghai
oap1:
image: apache/skywalking-oap-server:6.3.0
container_name: oap1
depends_on:
- elasticsearch
- zk1
- zk2
- zk3
links:
- elasticsearch
- zk1
- zk2
- zk3
restart: always
ports:
- 11801:11800
- 12801:12800
environment:
SW_CLUSTER: zookeeper
SW_CLUSTER_ZK_HOST_PORT: zk1:2181,zk2:2181,zk3:2181
SW_STORAGE: elasticsearch
SW_STORAGE_ES_CLUSTER_NODES: elasticsearch:9200
SW_STORAGE_ES_INDEX_SHARDS_NUMBER: 1
SW_STORAGE_ES_INDEX_REPLICAS_NUMBER: 0
TZ: Asia/Shanghai
oap2:
image: apache/skywalking-oap-server:6.3.0
container_name: oap2
depends_on:
- elasticsearch
- zk1
- zk2
- zk3
links:
- elasticsearch
- zk1
- zk2
- zk3
restart: always
ports:
- 11802:11800
- 12802:12800
environment:
SW_CLUSTER: zookeeper
SW_CLUSTER_ZK_HOST_PORT: zk1:2181,zk2:2181,zk3:2181
SW_STORAGE: elasticsearch
SW_STORAGE_ES_CLUSTER_NODES: elasticsearch:9200
SW_STORAGE_ES_INDEX_SHARDS_NUMBER: 1
SW_STORAGE_ES_INDEX_REPLICAS_NUMBER: 0
TZ: Asia/Shanghai
ui1:
image: apache/skywalking-ui:6.3.0
container_name: ui1
depends_on:
- oap1
- oap2
links:
- oap1
- oap2
restart: always
ports:
- 8081:8080
environment:
SW_OAP_ADDRESS: oap1:12800,oap2:12800
TZ: Asia/Shanghai
ui2:
image: apache/skywalking-ui:6.3.0
container_name: ui2
depends_on:
- oap1
- oap2
links:
- oap1
- oap2
restart: always
ports:
- 8082:8080
environment:
SW_OAP_ADDRESS: oap1:12800,oap2:12800
TZ: Asia/Shanghai
zk1:
image: zookeeper:3.4.10
restart: always
container_name: zk1
ports:
- 2181:2181
environment:
ZOO_MY_ID: 1
ZOO_SERVERS: server.1=zk1:2888:3888 server.2=zk2:2888:3888 server.3=zk3:2888:3888
zk2:
image: zookeeper:3.4.10
restart: always
container_name: zk2
ports:
- 2182:2181
environment:
ZOO_MY_ID: 2
ZOO_SERVERS: server.1=zk1:2888:3888 server.2=zk2:2888:3888 server.3=zk3:2888:3888
zk3:
image: zookeeper:3.4.10
restart: always
container_name: zk3
ports:
- 2183:2181
environment:
ZOO_MY_ID: 3
ZOO_SERVERS: server.1=zk1:2888:3888 server.2=zk2:2888:3888 server.3=zk3:2888:3888
创建容器,启动服务
# 指定配置文件docker-compose.yml的路径,在后台启动所有服务。
# 如图5所示,会显示容器的创建结果。
macos$ docker-compose -f ./docker-compose.yml up -d
图5 启动所有服务
# 查看容器是否启动成功,如图6所示。
macos$ docker ps
图6 查看容器状态
到这里SW集群就部署完毕了。有些同学可能会发现在集群启动的过程中oap1和oap2两个容器会经常的重启,别慌,不是你做错了什么,这个是正常现象,等一会就稳定了。
推荐到SkyWalking官网下载Agent的安装包,网速还是不错的。请根据各自的操作系统下载对应的安装包,如图7所示。
图7 SW安装包,二选一
我们下载的安装包是完整的All-In-One安装包,解压后我们会看到安装包内有Agent,OAP Server,Web UI三个组件。由于我们只需要Agent,所以只提取agent文件夹就可以了,如图8所示。
图8 从安装包中提取agent
说到这里可能会有一部分同学觉得不太理解,尤其是很少使用Docker,对部署流程了解较少的同学,他们可能会疑惑:”读者原本是想参考文章中的代码、命令来尝试部署测试,tard是你们公司的内部系统,我们没法使用,如果用更加通用的Docker会不会更好?“。
解释这个问题前先简单说下背景。和很多的公司一样,我们也是有一套标准的打包发布流程的,tard有一套自己的使用规范,关于这一点曾经与运维的同学简单了解过。出于安全的考虑,tard会要求所有的系统只能使用公司统一的基础镜像,或者以基础镜像为底做出来的其他镜像,tard也会限制很多的docker命令不可以使用。同时tard自身还有一些功能待完善,比如在创建docker镜像的时候,基础镜像只支持解压War包,暂不支持其他的压缩格式,所以tard只支持添加War包;容器启动时唯一可以执行的命令是运行Tomcat等等。(PS:tard为部分功能是留了口子的,如果项目组有什么特殊需求可以走运维部门的技术支持流程,由运维同学再细看是否可以处理。有些限制是可以解决的,有些暂时还是不可以,具体的细节没有深入了解。)
要实现前文说的整个接入过程无任何代码侵入,只需要简单修改镜像的配置就可以完成接入的这个目标,我们需要将Agent做到基础镜像里面,这样只需要修改发布系统依赖的基础镜像就可以使用Agent了。常规做法一般是将Agent文件夹压缩成tar包或者zip包,上传,然后在镜像内解压就可以了。可是tard只支持添加War包,怎么办?这是我们遇到的一个问题,请大家思考一下再向下阅读。
考虑到大概率上只会做一次基础镜像,我们就尽量简单点,不需要走申请创建新代码仓库的审批流程,最好可以利用已有的Web系统,复用原有的打包配置。这样我们从现有系统的git代码仓库拉出来了一个分支,命名为sw-agent。
保留Maven中使用maven-assembly-plugin插件打包的配置,删除其他无关代码。将SW安装包中的agent文件夹添加到项目中,commit、push到仓库,如图9所示。
图9 将sw的agent文件夹添加到分支中
我们能够拿到sw-agent.war,就可以开始做基础镜像了。
# Dockerfile
FROM 公司统一的基础镜像:JDK8+Tomcat8版本
ADD sw-agent.war /opt
WORKDIR /opt
# 解压后删除War包多余的文件,最终的结果就和使用tar包、zip包一样了
RUN jar xf sw-agent.war && rm -rf sw-agent.war META-INF
#做好的镜像我们暂时命名为skywalking-agent-6.3:1.0
修改发布系统的基础镜像,然后再将agent加入到Tomcat的运行时参数里面。
# 修改基础镜像,使用skywalking-agent-6.3:1.0
FROM skywalking-agent-6.3:1.0
省略......
# 修改Tomcat的环境配置脚本setenv.sh
省略......
# 加入这一段脚本代码
AGENT_BOOTSTRAP="/opt/skywalking/agent/skywalking-agent.jar"
if [ -f $AGENT_BOOTSTRAP ]; then
# SW_AGENT_NAME:我们要追踪的系统的名称。
# SW_AGENT_COLLECTOR_BACKEND_SERVICE:SW OAP服务地址和端口号。
CATALINA_OPTS="$CATALINA_OPTS -DSW_AGENT_NAME=${SW_AGENT_NAME} -DSW_AGENT_COLLECTOR_BACKEND_SERVICES=${SW_AGENT_COLLECTOR_BACKEND_SERVICES} -javaagent:$AGENT_BOOTSTRAP"
fi
在系统启动之前,我们需要先为上面留的两个运行时变量赋值。我个人更喜欢以环境变量的方式配置系统,简单、改动更加方便,具体的配置如下所示。
# 指定被追踪的系统的名称,不可重复。
SW_AGENT_NAME=ATS-WZ
# Agent需要将生产的数据上报给我们部署的服务实例oap1,oap2。
# 使用过程中在这里发现了一个雷,标记下。
SW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11801,127.0.0.1:11802
实例启动成功以后,打开SW的首页[ http://127.0.0.1:8081, http://127.0.0.1:8082 ],UI文本会默认使用英文显示,可以通过右下角的中英文切换功能切换语言。如果能在当前服务中看到我们配置的系统名称ATS-WZ,就表示接入成功了,如图11所示,至此SkyWalking Agent我们就部署完毕了。
图11 SW可以识别被追踪的系统了
???整个的接入、使用与测试过程中我们发现了几个雷,包括上面说的在低版本的SW上可能会出现一些问题的雷。我们都一一标记、收集整理了,打算在后面总结的时候我们再集中一一拆解,本节只是试验与探雷,至于排雷后面再聊。不过有一些雷可能会导致接入出现问题,我们可以先简单说一下,以免影响大家使用。
大概率是OAP服务挂了,可以检查一下。
问题表现:SW首页没有数据,并且在agent日志中可以看到如图12所示的报错。
图12 Agent日志报错
很大的可能是我们配置的环境变量SW_AGENT_COLLECTOR_BACKEND_SERVICES有问题。一些同学会想的很全面,他们考虑到了负载均衡的问题,使用的是OAP集群的域名,考虑的很好很充分,只不过SW不支持。我们通过查看SW的源码可以发现,SW是不支持域名的,只支持 ip1:port1,ip2:port2 这种格式,如图13所示。
图13 从源码中可以推断出OAP服务地址的配置格式
问题表现:SW页面上有很多的区域都没有数据,或者说响应很慢。打开Chrome浏览器的开发者工具可以发现,SW页面发出的很多接口请求都超时失败了,超时时间大约为10秒。查看ui1和ui2的日志可看到如图14所示的错误。
图14 UI日志中的错误
这个问题一般是因为连接、请求超时,主要问题在于OAP服务或者ES性能不足,造成连接超时、响应超时甚至无响应。从根本上解决这个问题的办法,一般是调整优化OAP服务或者ES的性能。
我们也可以使用一个临时方案,UI的时间不够,那我们就延长下UI的时间。可以修改UI的超时配置,默认为10秒,测试和生产环境都可以适当的延长这个值,我们将ReadTimeout延长到了30秒。同时增加ConnectTimeout配置,也设置为30秒,如图15所示。
图15 延长超时时间
问题表现:在追踪页面里,我们可以看到所有被追踪接口的调用链路。我们可以再前进一步,打开某一个接口的调用链路详情,我们希望可以拿到这个接口的入参和出参。不过可惜的是,大多时候我们是拿不到这个接口的入参和出参的,如图16所示。
图16 在接口详情里面拿不到接口的入参和返参
??在整个的安装、使用、测试过程中,我们遇到了一些问题,不过幸运的是通过查阅官方文档以及阅读SW源码,我们发现问题是可控的,是可以解决的。这次也让我们尝到了使用熟悉的技术带给我们的好处,尤其是在这种时间紧迫的情况下,让我们可以做到对项目更可控,更有信心。在验证完SW的适用性、稳定性和读写性能以后,我们将针对SW做一定的开发与扩展以满足我们的业务需要,这些内容让我们慢慢再聊。
Tard使用文档
SkyWalking官方文档
原文:https://www.cnblogs.com/whslowly/p/11511141.html