文章目录
前⾔
在微服务架构中,“可观测性” 是微服务得以稳健运行的至关重要一环。在生产环境若缺乏良好的观测性工具和方法,就好比高空的⻜机在没有仪表板的情况下⻜行一样,两眼一抹黑,充满不确定性因素和未知⻛险,无法及时发现、定位、转移和修复错误。
业界通常将可观测性大致分为三大类:Metrics,Tracing 和 Logging。通常来说 Metrics 监控侧重于技术指标的收集与观测,如服务调用 QPS、响应时间、错误率和资源使用率;Logging 侧重于运行日志的采集、存储与检索;而Tracing则偏向于调用链的串联、追踪与APM分析。
Metrics比较火的方案就是Prometheus+Grafana,思路就是通过应用内埋入SDK,选择Pull或者Push的方式将数据收集到prometheus中,然后通过Grafana实现可视化。
Tracing也并不是可观测性提出后才诞生的概念,在微服务化的进程中就已经有Google的Dapper落地实践,并慢慢形成OpenTracing规范,这一规范又被多家第三方框架所支持,如Jaeger、Zipkin、skywalking等。
OpenTelemetry就是结合了OpenTracing + OpenCensus规范,约定并提供完成的可观测性套件。
背景
项目之前惯⽤的链路追踪组件是skywalking,skywalking针对服务端链路追踪⾮常⽅便,开箱即⽤,提供丰富UI,但是skywalking的⽅案对浏览器侧和app侧⽀持不完善,⽽恰好项⽬有这⽅⾯的需求。经过调研OpenTelemetry +Sentry整合的⽅案可以满⾜前后端服务的“可观测性”⽅案:
- OpenTelemetry专注数据采集,兼容OpenTracing和OpenCensus规范,提供数据采集和标准规范的统⼀,实现Metrics、Tracing、Logging的融合及⼤⼀统。同时开放的Collector设计,⽀持多种Vendor(Jaeger/Skywalking/Grafana/Sentry/Zipkin等等),更加灵活。
- Sentry更加专注前端⻚⾯采集(⻚⾯加载/路径/⽇志),包括⻚⾯异常数据;主要根据在于它独有的链路采集概念。⽀持Node.js、apple、android等等。
技术⽅案
使⽤Sentry+OpenTelemetry前后端全链路打通:
- 前端借助sentry sdk完成前端(浏览器、安卓、ios、node服务)指标数据采集,并通过header传递追踪信息到后端。
- 后端通过sentry-opentelemetry-agent+ Sentry SDK⽅案,sentry-opentelemetry-agent以⽆侵⼊⽅式按照otel标准采集应⽤指标数据,Sentry SDK采集应⽤issue数据。
整体架构如下:
Sentry私有化部署
Sentry的管理后台是基于Python Django开发的。这个管理后台由背后的Postgres数据库(管理后台默认的数据库,后续会以Postgres代指管理后台数据库并进⾏分享)、ClickHouse(存数据特征的
数据库)、relay、kafka、redis等⼀些基础服务或由Sentry官⽅维护的总共23个服务⽀撑运⾏。
在部署服务前,我们应该先对sentry整体架构和服务依赖有⼀定了解,⻅官⽅⽂档。
从上图所述,sentry整体架构包含四⼤板块,中继器、处理器、数据中台、web,应⽤通过agent和sdk将应⽤数据通过负载均衡器(NG)上报到中继器,由中继器缓存事件信息,并将事件消息推送到kafka,再由处理器消费事件,对事件进⾏预处理、处理、保存到数据库并将处理后的事件数据消息推送到数据中台kafka,最后由数据中台消费并将数据存储到Clickhouse,最后sentry web 对数据中台数据进⾏展⽰、分析、以及告警设置。
部署
环境准备
Sentry 提供并维护了⼀个最⼩的设置,可以开箱即⽤地⽤于简单的⾃托管存储库,⽅便使⽤者进⾏私有化部署。在整体架构中提到sentry管理平台由23个服务⽀撑运⾏,如果独⽴的部署和维护这23个服
务将是异常复杂和困难的,为了简单安装部署,官⽅提供了⾃动化脚本(./install.sh)使⽤Docker和Docker Compose以及基于bash的安装和升级脚本。该脚本将处理我们开始所需的所有事情,包括基线配置,然后会告诉我们运⾏ docker compose up -d 以启动Sentry。要部署sentry需要准备:
- 4C8G内存机器 200G(尽量⾜够磁盘需要存储数据
- 部署⽅式依赖于Docker 19.03.6+和Compose 1.24.1+(Docker Compose安装这⾥就不⼀⼀说明了)
具体步骤如下:
# 下载最新存储库
cd usr
mkdir software
cd software
chmod -R 777 /usr/software
wget https://github.com/getsentry/self-hosted/archive/refs/tags/23.11.2.tar.gz
tar -zxvf 23.11.2.tar.gz
cd self-hosted-23.11.2
# 执⾏./install.sh
./install.sh
############### 等待执⾏结束后,会提⽰创建完毕,运⾏ docker-compose up -d 启动服务
# 运⾏ docker-compose up -d 启动服务
docker-compose up -d
项目集成
前端
后端
sentry-opentelemetry监控主要包含3⼤板块:
- 通过agent探针⾃动化追踪Tracing、Metrics(sentry指标不包含cpu内存指标)
- 通过sentry sdk主动上报issue
- 使⽤OpenTelementry增强探针为⽇志注⼊TraceID
agent探针集成
后端微服务采⽤sentry-opentelemetry-agent+引⼊sdk完成⽇志注⼊TraceID和⾃定义事件追踪功能。
- agent引入
下载sentry-opentelemetry-agent-7.0.0.jar,并在⼯程⽬录创建agent⽬录(与src平⾏),如下图
2. 环境变量配置
基于nacos配置中⼼进⾏环境配置,配置中⼼增加如下配置
sentry:
dsn: http://7054f91f1c90d5cf2fea604f0fd798f7@192.168.128.43:9000/2
environment: prod
traces-sample-rate: 1.0
instrumenter: otel
3. 本地启动调试(idea)
如上图,使⽤idea启动项⽬调试agent,⼊⼝变量新增-javaagent引⼊sentry-opentelemetry-agent7.0.0.jar
# 这⾥亲测需要指定绝对路径,否则启动时会报找不到jar,从⽽导致服务⽆法启动
-javaagent:D:/myshopprophet/base-common-service/base-commonserver/agent/sentry-opentelemetry-agent-7.0.0.jar
# 这里需要显示指定none否则启动后会报打印大量警告日志,如果本身需要上报元数据和traces不用考虑
-Dotel.metrics.exporter=none
-Dotel.traces.exporter=none
启动项⽬后,登陆控制台检查Tracing、Metrics信息是否同步到sentry
如下图,如果成功便可以在Discover、Dashboards、Performance、Project Details菜单下观察到相关指标数据。
sentry sdk集成
针对接⼝异常、业务异常等事件需要通过sentry sdk主动上报。
step1引⼊依赖
<dependency>
<groupId>io.sentry</groupId>
<artifactId>sentry-spring-boot-starter</artifactId>
<version>7.0.0</version>// 这里的版本号应该和agent版本一致
</dependency>
step2配置环境变量
环境变量同agent弹出集成环境变量设置,sentry-spring-boot-starter⾃动装配sentry sdk配置,项⽬⽆需显⽰配置。
step3代码层⾯主动上报⽇志
// 省略
findAny().orElseThrow(() -> {
BusinessException e = new BusinessException("not support this bizType[" +
bizType + "]");
// log.info(Sentry.getSpan().toString());
Sentry.captureException(e);
return e;
});
step4登陆sentry.io查看异常事件
增强探针为⽇志注⼊TraceID
sentry-opentelemetry-agent⽇志注⼊traceID需要使⽤opentelemetry⽇志包,具体步骤如下:
step1引⼊opentelemetry⽇志包相关依赖
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-log4j-context-data-2.17-
autoconfigure</artifactId>
<version>1.23.0-alpha</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>1.23.1</version>
</dependency>
step2修改log42.xml配置
日志增加trace_id
<Properties>
<property name="app_name" value="${spring:spring.application.name}"/>
<property name="patternLayout">[%d{yyyy-MM-dd'T'HH:mm:ss.SSSZZ}]
[%level{length=5}] [%thread-%tid] [%logger] [traceId:%X{trace_id}]
[%X{hostName}] [%X{ip}] [${app_name}] [%F,%L,%C,%M] [%m] ## '%ex'%n</property>
<property name="rolling_pattern">%d{yyyy-MM-dd}-%i.gz</property>
<property name="every_file_size">10MB</propert