本文介绍了一个采用微服务架构的项目中,由于服务数量多且访问量大,需要使用开源APM工具来监控系统性能。通过对比,选择了SkyWalking作为APM工具。在搭建过程中,使用ES作为存储,避免错误产生。文章还提到了安装Java环境、配置Agent和启动ES和OAP的步骤。总结:文章介绍了在使用微服务架构的项目中,如何通过开源APM工具来监控系统性能,以及使用ES作为存储的方法。文章中详细说明了Java环境的安装、Agent的配置和ES和OAP的启动步骤。
在公司项目中,我们采用了微服务架构,导致服务数量众多,无法进行人工监控。由于项目访问量巨大,若要通过日志查找某个方法的性能问题非常困难。然而,我们不容忽视系统性能问题的存在。目前,市面上有几个出色的开源APM(应用性能管理)检测工具可供选择。
在选择APM工具时,我们考虑到项目不希望对其他代码造成侵入,而且希望选择一个性能损耗较低的工具。此外,我们也重视工具的社区活跃度和文档完善程度。经过对以下表格中参数的比较,我们发现相对而言,SkyWalking更具优势。因此,团队决定采用SkyWalking作为APM工具。
本次搭建用ES作为存储,最开始用H2作内存存储,最后再接入ES,避免环节过多产生不可预知的错误
环境介绍:
本教程采用虚拟机(CentOS7) + Docker的方法进行部署,这种做法的优点在于通过使用Docker容器来隔离不同的组件,可以迅速而便捷地模拟生产环境。
docker network create --subnet=172.18.0.0/16 mynet
# SkyWalking APM docker run -dit --net mynet --ip 172.18.0.30 -p 8090:8090 --name sw --privileged centos /usr/sbin/init # Java App docker run -dit --net mynet --ip 172.18.0.31 -p 8080:8080 --name javaApp --privileged centos /usr/sbin/init # ES docker run -dit --net mynet --ip 172.18.0.32 --name es1 --privileged centos /usr/sbin/init
由于ES和SkyWalking 都需要Java环境,所以安装Java提出来放到最前面
# 安装java yum -y install java-1.8.0-openjdk java-1.8.0-openjdk-devel which # 环境变量设置 cat > /etc/profile.d/java8.sh <<EOF export JAVA_HOME=$(dirname $(dirname $(readlink $(readlink $(which javac))))) export PATH=\$PATH:\$JAVA_HOME/bin export CLASSPATH=.:\$JAVA_HOME/jre/lib:\$JAVA_HOME/lib:\$JAVA_HOME/lib/tools.jar EOF source /etc/profile.d/java8.sh
SkyWalking OAP 即架构图中的下部分SkyWalking Observability Analysis Platform,如下图所示
本次下载安装的是apache-skywalking-apm-es7-8.3.0.tar.gz,其他版本请参考:http://skywalking.apache.org/downloads/
apache-skywalking-apm-es7-8.3.0.tar.gz
注意安装之前一点要先安装Java环境,否则启动不成功但是启动脚本还是会显示启动成功。
yum install -y wget vim telnet cd ~ # 下载 wget https://downloads.apache.org/skywalking/8.3.0/apache-skywalking-apm-es7-8.3.0.tar.gz # 解压 tar xf apache-skywalking-apm-es7-8.3.0.tar.gz -C /usr/local mv /usr/local/apache-skywalking-apm-bin-es7 /usr/local/skywalking-8.3.0
# 启动OAP /usr/local/skywalking-8.3.0/bin/oapService.sh # 查看日志 tail -f /usr/local/skywalking-8.3.0/logs/skywalking-oap-server.log
查看OAP监听端口
grep 'gRPCPort:' /usr/local/skywalking-8.3.0/config/application.yml gRPCPort: ${SW_CORE_GRPC_PORT:11800} gRPCPort: ${SW_RECEIVER_GRPC_PORT:0} gRPCPort: ${SW_RECEIVER_JAEGER_PORT:14250}
可以看到SkyWalking OAP默认监听端口为11800,测试下端口是否通
telnet 127.0.0.1 11800 # 出现下面回显说明端口通 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'.
vim /usr/local/skywalking-8.3.0/webapp/webapp.yml
SkyWalking UI默认端口为8080与很多中间件有冲突,改成其他的,本例为8090
server: port: 8090
启动
# 启动UI /usr/local/skywalking-8.3.0/bin/webappService.sh
访问一下http://192.168.108.100:8090,如果能访问,说明启动成功
所谓Agent是指SkyWalking在不同平台(如Java Python等)上收集监控数据的组件。在这里,我们以Java应用(比如Spring Boot)为例,收集Java应用生成的各类监控数据。
随便准备个Jar包能跑的就行,此处我的jar名字为admin-2.0.1.RELEASE.jar
admin-2.0.1.RELEASE.jar
作为一名IT工程师,我们需要在每台收集机器上复制一份代理(Agent)。由于我们使用的是Docker容器,所以需要将代理复制到宿主机,然后再复制到运行JavaWeb的机器上。这意味着每台机器都需要复制一次代理。
# 拷贝agent到宿主机 docker cp sw:/usr/local/skywalking-8.3.0/agent /tmp # 再从宿主机拷贝到目标容器 docker cp /tmp/agent/ javaApp:/root/javaApp/agent
配置Agent
vim /root/javaApp/agent/config/agent.config
collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:172.18.0.30:11800} agent.sample_n_per_3_secs=${SW_AGENT_SAMPLE:1}
运行jar包,指定-javaagent与skywalking.agent.service_name,后者就是SkyWalking UI上显示的名字
-javaagent
skywalking.agent.service_name
nohup java -javaagent:/root/javaApp/agent/skywalking-agent.jar -Dskywalking.agent.service_name=admin -jar admin-2.0.1.RELEASE.jar > admin.log 2>&1 &
h2被设计为一种内存存储系统,其主要目标是提供快速验证和响应的能力。然而,h2的性能还不足以支撑线上系统的正常运行,因此在线上环境中需要选择更可靠的存储解决方案。
从专业角度而言,ES(Elasticsearch)是一种非常理想的选择。首先,ES以其卓越的搜索速度而闻名,非常适合满足后台查询的需求。其次,ES是一种分布式存储系统,能够有效解决大数据量的问题。
参考: 安装并运行 Elasticsearch
首先进入容器
docker exec -it es1 bash
常用工具安装
yum install -y wget
在Download Elasticsearch选择合适的平台下载好包,我下载的是elasticsearch-7.10.1-linux-x86_64.tar.gz
elasticsearch-7.10.1-linux-x86_64.tar.gz
# 下载 cd ~ && wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.10.1-linux-x86_64.tar.gz # 解压 tar -zxvf elasticsearch-7.10.1-linux-x86_64.tar.gz # 拷贝 cp -r elasticsearch-7.10.1 /usr/local/ # 运行 /usr/local/elasticsearch-7.10.1/bin/elasticsearch
运行后此时你会得到一个报错:java.lang.RuntimeException: can not run elasticsearch as root
java.lang.RuntimeException: can not run elasticsearch as root
原因很明显,不能用root运行,那么新建用户再运行
# 新建用户 adduser elasticsearch # 赋权 chown -R elasticsearch /usr/local/elasticsearch-7.10.1 # 切换用户再执行 su elasticsearch /usr/local/elasticsearch-7.10.1/bin/elasticsearch # 后台执行 /usr/local/elasticsearch-7.10.1/bin/elasticsearch -d
测试,如果curl 127.0.0.1:9200有类似以下回显说明成功
curl 127.0.0.1:9200
{ "name" : "74e37036a2ee", "cluster_name" : "elasticsearch", "cluster_uuid" : "L8xK0ZqZSUKn3dZ05NJfcg", "version" : { "number" : "7.10.1", "build_flavor" : "default", "build_type" : "tar", "build_hash" : "1c34507e66d7db1211f66f3513706fdf548736aa", "build_date" : "2020-12-05T01:00:33.671820Z", "build_snapshot" : false, "lucene_version" : "8.7.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" }
此时发现只能用127.0.0.1访问,不能用 curl 172.18.0.32:9200访问,因为没设置network.host,下面设置一下,顺便加上允许跨域的设置http.cors.enabled、http.cors.allow-origin,sed -i '$a内容' file 是在文件末尾追加
curl 172.18.0.32:9200
network.host
http.cors.enabled
http.cors.allow-origin
sed -i '$a内容' file
sed -i '$ahttp.cors.enabled: true' /usr/local/elasticsearch-7.10.1/config/elasticsearch.yml sed -i '$ahttp.cors.allow-origin: "*"' /usr/local/elasticsearch-7.10.1/config/elasticsearch.yml sed -i '$anetwork.host: 172.18.0.32' /usr/local/elasticsearch-7.10.1/config/elasticsearch.yml
此时启动es,发现启动失败,报错如下:
[2021-01-13T13:46:30,780][INFO ][o.e.t.TransportService ] [a622d8352de5] publish_address {172.18.0.12:9300}, bound_addresses {172.18.0.12:9300} [2021-01-13T13:46:31,039][INFO ][o.e.b.BootstrapChecks ] [a622d8352de5] bound or publishing to a non-loopback address, enforcing bootstrap checks [2021-01-13T13:46:31,066][ERROR][o.e.b.Bootstrap ] [a622d8352de5] node validation exception [2] bootstrap checks failed [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144] [2]: the default discovery settings are unsuitable for production use; at least one of [discovery.seed_hosts, discovery.seed_providers, cluster.initial_master_nodes] must be configured [2021-01-13T13:46:31,069][INFO ][o.e.n.Node ] [a622d8352de5] stopping ... [2021-01-13T13:46:31,094][INFO ][o.e.n.Node ] [a622d8352de5] stopped [2021-01-13T13:46:31,095][INFO ][o.e.n.Node ] [a622d8352de5] closing ... [2021-01-13T13:46:31,116][INFO ][o.e.n.Node ] [a622d8352de5] closed [2021-01-13T13:46:31,119][INFO ][o.e.x.m.p.NativeController] [a622d8352de5] Native controller process has stopped - no new native processes can be started
考虑以下句子:当绑定地址不是本地回环地址时,执行引导程序检查。绑定非127.0.0.1地址时,Elasticsearch(ES)认为该部署用于生产环境,并强制执行适用于生产环境的启动检查。如果检查发现不符合条件,则阻止服务器启动。要修复此错误,需要进行以下修改:
[1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144] [2]: the default discovery settings are unsuitable for production use; at least one of [discovery.seed_hosts, discovery.seed_providers, cluster.initial_master_nodes] must be configured
# 切换到root用户执行 sed -i '$avm.max_map_count=262144' /etc/sysctl.conf sysctl -p
# 追加这句配置 sed -i '$adiscovery.seed_hosts: ["172.18.0.32"]' /usr/local/elasticsearch-7.10.1/config/elasticsearch.yml
# 配置集群名称,后面OAP要用 sed -i '$acluster.name: my-application' /usr/local/elasticsearch-7.10.1/config/elasticsearch.yml
此时再次启动就不会报错了,如果还是报错,请根据es的报错提示进行更改
试一下用本机IP能访问不:curl 172.18.0.32:9200
vim /usr/local/skywalking-8.3.0/config/application.yml
作为一名IT工程师,我们的主要任务是配置存储系统,选择器可根据需求进行选择,只有在进行了选择之后,才会生效。在配置过程中,我们特别关注的是nameSpace和clusterNodes这两个选项。
storage: selector: ${SW_STORAGE:elasticsearch7} elasticsearch7: nameSpace: ${SW_NAMESPACE:"my-application"} clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:172.18.0.32:9200} indexShardsNumber: ${SW_STORAGE_ES_INDEX_SHARDS_NUMBER:1} # Shard number of new indexes indexReplicasNumber: ${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:1} # Replicas number of new indexes
启动OAP
# 启动OAP /usr/local/skywalking-8.3.0/bin/oapService.sh # 查看日志 tail -f /usr/local/skywalking-8.3.0/logs/skywalking-oap-server.log
启动后发现SkyWalking OAP报错如下:
2021-01-23 08:12:58,935 - org.apache.skywalking.oap.server.starter.OAPServerBootstrap - 57 [main] ERROR [] - method [HEAD], host [http://172.18.0.32:9200], URI [/_template/my-application_alarm_record?master_timeout=30s], status line [HTTP/1.1 503 Service Unavailable] org.elasticsearch.ElasticsearchStatusException: method [HEAD], host [http://172.18.0.32:9200], URI [/_template/my-application_alarm_record?master_timeout=30s], status line [HTTP/1.1 503 Service Unavailable] at org.elasticsearch.client.RestHighLevelClient.parseResponseException(RestHighLevelClient.java:1767) ~[elasticsearch-rest-high-level-client-7.5.0.jar:7.5.0]
去看了下ES后台,也报错了
org.elasticsearch.discovery.MasterNotDiscoveredException: null at org.elasticsearch.action.support.master.TransportMasterNodeAction$AsyncSingleAction$2.onTimeout(TransportMasterNodeAction.java:230) [elasticsearch-7.10.1.jar:7.10.1] at org.elasticsearch.cluster.ClusterStateObserver$ContextPreservingListener.onTimeout(ClusterStateObserver.java:335) [elasticsearch-7.10.1.jar:7.10.1]
而且ES一直在提醒如下内容
[2021-01-23T08:25:07,993][WARN ][o.e.c.c.ClusterFormationFailureHelper] [3546a7854be2] master not discovered yet, this node has not previously joined a bootstrapped (v7+) cluster, and this node must discover master-eligible nodes [master] to bootstrap a cluster: have discovered
这是ES主节点配置有问题,现在我们就一台ES,所以配置这台为主节点,加入如下配置
vi /usr/local/elasticsearch-7.10.1/config/elasticsearch.yml node.name: node-1 cluster.initial_master_nodes: ["node-1"]
再次依次重新启动ES和OAP就没有问题了
参考链接:https://zhuanlan.zhihu.com/p/346605953
江苏纵目信息科技有限公司是一家专注于运维监控软件产品研发与销售的高科技企业。覆盖全链路应用性能监控、IT基础设施监控、物联网数据采集数据观测等场景,基于Skywalking、Zabbix、ThingsBoard等开源体系构建了ArgusAPM、ArgusOMS、ZeusIoT等产品,致力于帮助各行业客户构建集聚可观测性的统一运维平台、物联网大数据平台。
一体化运维观测
全链路应用性能监控
©2023 江苏纵目科技有限公司 苏ICP备18050677号-1 版权与免责申明 版权申述