https://blog.csdn.net/smooth00/article/details/96479544html
做为一款APM和全链路监控平台,Skywalking算是挺出色的。Skywalking是APM监控平台的后起之秀,大有超越其余开源APM监控平台的趋势。它经过探针自动收集所需的指标,并进行分布式追踪。经过这些调用链路以及指标,Skywalking APM会感知应用间关系和服务间关系,并进行相应的指标统计。java
目前Skywalking支持h二、mysql、ElasticSearch做为数据存储,我就说一下,这三个种库的优缺点和使用要求:mysql
ElasticSearch不是自带的,须要安装,考虑到轻量级,我选用的是elasticsearch-6.2.4,缘由是包小免安装,解压完也才30多M,并且目前最新版本的Skywalking 6.2.0是可以支持该版本的ElasticSearch。linux
Skywalking启用ES,只须要配置文件设置以下:
web
storage: elasticsearch: nameSpace: ${SW_NAMESPACE:""} clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:localhost:9200} user: ${SW_ES_USER:""} password: ${SW_ES_PASSWORD:""} indexShardsNumber: ${SW_STORAGE_ES_INDEX_SHARDS_NUMBER:2} indexReplicasNumber: ${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:0} # Those data TTL settings will override the same settings in core module. recordDataTTL: ${SW_STORAGE_ES_RECORD_DATA_TTL:7} # Unit is day otherMetricsDataTTL: ${SW_STORAGE_ES_OTHER_METRIC_DATA_TTL:45} # Unit is day monthMetricsDataTTL: ${SW_STORAGE_ES_MONTH_METRIC_DATA_TTL:18} # Unit is month bulkActions: ${SW_STORAGE_ES_BULK_ACTIONS:2000} # Execute the bulk every 2000 requests bulkSize: ${SW_STORAGE_ES_BULK_SIZE:20} # flush the bulk every 20mb flushInterval: ${SW_STORAGE_ES_FLUSH_INTERVAL:10} # flush the bulk every 10 seconds whatever the number of requests concurrentRequests: ${SW_STORAGE_ES_CONCURRENT_REQUESTS:2} # the number of concurrent requests metadataQueryMaxSize: ${SW_STORAGE_ES_QUERY_MAX_SIZE:5000} segmentQueryMaxSize: ${SW_STORAGE_ES_QUERY_SEGMENT_SIZE:200}
另外若是,想让ES能同时被本地和远程访问到,能够改一下ES的配置文件,IP改成以下:sql
network.host: 0.0.0.0
我专门写了linux下的ES启动脚本(脚本放在skywalking的bin目录下,ES放在Skywalking的根目录下),因为ES不能以root用户启动,因此脚本里加了用户的自动建立:apache
#!/bin/bash check_user() { #判断用户是否存在passwd中 i=`cat /etc/passwd | cut -f1 -d':' | grep -w "$1" -c` if [ $i -le 0 ]; then echo "User $1 is not in the passwd" return 0 else #显示用户存在 echo "User $1 is in then use" return 1 fi } uname=elsearch check_user $uname if [ $? -eq 0 ] then #添加此用户 sudo useradd $uname passwd $uname --stdin "123456" echo "user $uname add!!!" fi Cur_Dir=$(cd "$(dirname "$0")"; pwd) chown $uname:$uname -R $Cur_Dir/../elasticsearch chmod -R 766 $Cur_Dir/../elasticsearch chmod -R 777 $Cur_Dir/../elasticsearch/bin su - $uname -c "nohup $Cur_Dir/../elasticsearch/bin/elasticsearch > $Cur_Dir/../elasticsearch/logs/output.log 2>&1 &" echo "elasticsearch start success!"
考虑到ES也是须要先启动,确保端口监听正常了,才能启动oapService,因此我改造了skywalking自带的启动脚本,加了端口监听判断: 后端
#!/usr/bin/env sh check_port() { grep_port=`netstat -tlpn | grep "\b$1\b"` echo "grep port is $grep_port" if [ -n "$grep_port" ] then echo "port $port is in use" return 1 else echo "port is not established,please wait a moment......" return 0 fi } PRG="$0" PRGDIR=`dirname "$PRG"` OAP_EXE=oapService.sh WEBAPP_EXE=webappService.sh elsearch_EXE=elasticsearchStart.sh "$PRGDIR"/"$elsearch_EXE" port=9200 echo "check $port" for i in $(seq 1 20) do check_port $port if [ $? -eq 0 ] then sleep 2s else break fi done "$PRGDIR"/"$OAP_EXE" "$PRGDIR"/"$WEBAPP_EXE"
以上的准备,就是为Skywalking应用ES存储作好了准备,可是Elasticsearch自己也是存在写入瓶颈的,也就是说ES也会崩溃,一但崩溃,就可能oapService关闭,或是致使skywalking页面大盘空白。api
咱们能够作些调优,skywalking写入ES的操做是使用了ES的批量写入接口。咱们能够调整这些批量的维度。尽可能下降ES索引的写入频率,如:bash
bulkActions: ${SW_STORAGE_ES_BULK_ACTIONS:4000} # Execute the bulk every 2000 requests bulkSize: ${SW_STORAGE_ES_BULK_SIZE:40} # flush the bulk every 20mb flushInterval: ${SW_STORAGE_ES_FLUSH_INTERVAL:30} # flush the bulk every 10 seconds whatever the number of requests concurrentRequests: ${SW_STORAGE_ES_CONCURRENT_REQUESTS:4} # the number of concurrent requests metadataQueryMaxSize: ${SW_STORAGE_ES_QUERY_MAX_SIZE:8000}
调用的源码以下:
BulkProcessor bulkProcessor = BulkProcessor.builder( client, new BulkProcessor.Listener() { @Override public void beforeBulk(long executionId, BulkRequest request) { ... } @Override public void afterBulk(long executionId, BulkRequest request, BulkResponse response) { ... } @Override public void afterBulk(long executionId, BulkRequest request, Throwable failure) { ... } }) .setBulkActions(10000) .setBulkSize(new ByteSizeValue(5, ByteSizeUnit.MB)) .setFlushInterval(TimeValue.timeValueSeconds(5)) .setConcurrentRequests(1) .setBackoffPolicy( BackoffPolicy.exponentialBackoff(TimeValue.timeValueMillis(100), 3)) .build();
参考博客:https://www.elastic.co/guide/en/elasticsearch/client/java-api/5.5/java-docs-bulk-processor.html
调整bulkActions默认2000次请求批量写入一次改到4000次;
bulkSize批量刷新从20M一次到40M一次;
flushInterval每10秒刷新一次堆改成每30秒刷新;
concurrentRequests查询的最大数量由5000改成8000。这种配置调优确实生效了,
重启服务后两三天了都没有出现过ES写入阻塞的问题。不过这种设置只是暂时的,你只能指望流量不突发,或者应用不增长。一旦遇到突发流量和应用的增长,ES写入瓶颈仍是会凸显出来。并且参数设置过大带来了一个新的问题,就是数据写入延时会比较大,一次服务交互发生的trace隔很久才能在skywalking页面上查询到。因此最终解决方案是优化ES的写入性能,具体优化能够参考别人的文章:https://www.easyice.cn/archives/207
另外做为开源化的平台,扩展性也是其中的优点,自己ES就是分布式全文检索框架,能够部署成高可用的集群,另外Skyawalking也是分布式链路跟踪系统,分布式既然是它应用的特性,那么怎么去构建集群化的监控平台,就彻底靠你本身的想象和发挥了。
另外附上Skywalking各模块完整的配置说明(为看不明白英文注释的人准备):
(1)Skywalking collector 配置
OAP(Collector)链路数据归集器,主要用于数据落地,大部分都会选择 Elasticsearch 6,OAP配置文件为 /opt/apache-skywalking-apm-6.2.0/config/application.yml,配置单点的 OAP(Collector)配置以下:
cluster: # 单节点模式 standalone: # zk用于管理collector集群协做. # zookeeper: # 多个zk链接地址用逗号分隔. # hostPort: localhost:2181 # sessionTimeout: 100000 # 分布式 kv 存储设施,相似于zk,但没有zk重型(除了etcd,consul、Nacos等都是相似功能) # etcd: # serviceName: ${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"} # 多个节点用逗号分隔, 如: 10.0.0.1:2379,10.0.0.2:2379,10.0.0.3:2379 # hostPort: ${SW_CLUSTER_ETCD_HOST_PORT:localhost:2379} core: default: # 混合角色:接收代理数据,1级聚合、2级聚合 # 接收者:接收代理数据,1级聚合点 # 聚合器:2级聚合点 role: ${SW_CORE_ROLE:Mixed} # Mixed/Receiver/Aggregator # rest 服务地址和端口 restHost: ${SW_CORE_REST_HOST:localhost} restPort: ${SW_CORE_REST_PORT:12800} restContextPath: ${SW_CORE_REST_CONTEXT_PATH:/} # gRPC 服务地址和端口 gRPCHost: ${SW_CORE_GRPC_HOST:localhost} gRPCPort: ${SW_CORE_GRPC_PORT:11800} downsampling: - Hour - Day - Month # 设置度量数据的超时。超时过时后,度量数据将自动删除. # 单位分钟 recordDataTTL: ${SW_CORE_RECORD_DATA_TTL:90} # 单位分钟 minuteMetricsDataTTL: ${SW_CORE_MINUTE_METRIC_DATA_TTL:90} # 单位小时 hourMetricsDataTTL: ${SW_CORE_HOUR_METRIC_DATA_TTL:36} # 单位天 dayMetricsDataTTL: ${SW_CORE_DAY_METRIC_DATA_TTL:45} # 单位月 monthMetricsDataTTL: ${SW_CORE_MONTH_METRIC_DATA_TTL:18} storage: elasticsearch: # elasticsearch 的集群名称 nameSpace: ${SW_NAMESPACE:"local-ES"} # elasticsearch 集群节点的地址及端口 clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:192.168.2.10:9200} # elasticsearch 的用户名和密码 user: ${SW_ES_USER:""} password: ${SW_ES_PASSWORD:""} # 设置 elasticsearch 索引分片数量 indexShardsNumber: ${SW_STORAGE_ES_INDEX_SHARDS_NUMBER:2} # 设置 elasticsearch 索引副本数 indexReplicasNumber: ${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:0} # 批量处理配置 # 每2000个请求执行一次批量 bulkActions: ${SW_STORAGE_ES_BULK_ACTIONS:2000} # 每 20mb 刷新一次内存块 bulkSize: ${SW_STORAGE_ES_BULK_SIZE:20} # 不管请求的数量如何,每10秒刷新一次堆 flushInterval: ${SW_STORAGE_ES_FLUSH_INTERVAL:10} # 并发请求的数量 concurrentRequests: ${SW_STORAGE_ES_CONCURRENT_REQUESTS:2} # elasticsearch 查询的最大数量 metadataQueryMaxSize: ${SW_STORAGE_ES_QUERY_MAX_SIZE:5000} # elasticsearch 查询段最大数量 segmentQueryMaxSize: ${SW_STORAGE_ES_QUERY_SEGMENT_SIZE:200}
(2)Skywalking webApp 配置
Skywalking 的 WebApp 主要是用来展现落地的数据,所以只须要配置 Web 的端口及获取数据的 OAP(Collector)的IP和端口,webApp 配置文件地址为 /opt/apache-skywalking-apm-6.2.0/webapp/webapp.yml 配置以下:
server: port: 9000 collector: path: /graphql ribbon: ReadTimeout: 10000 # 指向全部后端collector 的 restHost:restPort 配置,多个使用, 分隔 listOfServers: localhost:12800 security: user: # username admin: # password password: admin
(3)Skywalking Agent 配置 Skywalking 的 Agent 主要用于收集和发送数据到 OAP(Collector),所以须要进行配置 Skywalking OAP(Collector)的地址,Agent 的配置文件地址为 /opt/apache-skywalking-apm-6.2.0/agent/config/agent.config,配置以下:
# 设置Agent命名空间,它用来隔离追踪和监控数据,当两个应用使用不一样的名称空间时,跨进程传播链会中断。 agent.namespace=${SW_AGENT_NAMESPACE:default-namespace} # 设置服务名称,会在 Skywalking UI 上显示的名称 agent.service_name=${SW_AGENT_NAME:Your_ApplicationName} # 每 3秒采集的样本跟踪比例,若是是负数则表示 100%采集 agent.sample_n_per_3_secs=${SW_AGENT_SAMPLE:-1} # 启用 Debug ,若是为 true 则将把全部检测到的类文件保存在"/debug"文件夹中 # agent.is_open_debugging_class = ${SW_AGENT_OPEN_DEBUG:true} # 后端的 collector 端口及地址 collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:192.168.2.215:11800} # 日志级别 logging.level=${SW_LOGGING_LEVEL:DEBUG}