一、hera概述
1.1 什么是hera
hera是一款由美团点评开源的分布式应用监控与追踪系统,专注于解决微服务架构下的性能监控、故障诊断和链路追踪问题。它借鉴了google dapper的设计理念,并结合了互联网企业的实际需求进行了优化和改进。
1.2 核心特性
- 全链路追踪:支持跨服务、跨线程的调用链追踪
- 实时监控:提供实时的性能指标和业务监控
- 可视化分析:通过web界面直观展示调用链路和性能数据
- 低侵入性:通过agent方式实现,对业务代码影响小
- 高性能:采用异步上报机制,对应用性能影响极小
- 多维分析:支持按应用、接口、机器等多维度分析
1.3 架构组件
- hera-agent:数据采集代理,部署在应用服务器
- hera-collector:数据收集器,接收agent上报的数据
- hera-query:查询服务,提供数据查询接口
- hera-web:可视化界面,展示监控数据
- hera-alarm:告警服务,配置监控告警规则
1.4 工作原理
- agent通过字节码增强技术植入到应用中
- 收集trace、span、metric等数据
- 异步上报到collector
- 数据存储到elasticsearch或hbase
- 通过web界面进行可视化展示
二、springboot集成hera详细步骤
2.1 环境准备
2.1.1 依赖版本
<!-- pom.xml 添加依赖管理 -->
<properties>
<spring-boot.version>2.7.14</spring-boot.version>
<hera.version>2.0.0</hera.version>
</properties>
2.1.2 下载hera组件
从github下载最新版本:
# hera仓库地址:https://github.com/meituan-dianping/hera wget https://github.com/meituan-dianping/hera/releases/download/v2.0.0/hera-distribution-2.0.0.tar.gz tar -zxvf hera-distribution-2.0.0.tar.gz
2.2 部署hera服务端
2.2.1 修改配置文件
# hera-collector/config/application.yml
server:
port: 8081
storage:
type: elasticsearch
elasticsearch:
cluster-nodes: localhost:9200
index-prefix: hera
# hera-web/config/application.yml
server:
port: 8080
query:
service-url: http://localhost:8082
2.2.2 启动服务
# 启动collector cd hera-collector/bin ./startup.sh # 启动query cd hera-query/bin ./startup.sh # 启动web cd hera-web/bin ./startup.sh
2.3 springboot应用集成
2.3.1 添加maven依赖
<!-- pom.xml -->
<dependencies>
<!-- springboot基础依赖 -->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
<version>${spring-boot.version}</version>
</dependency>
<!-- hera agent core -->
<dependency>
<groupid>com.meituan.hera</groupid>
<artifactid>hera-agent-core</artifactid>
<version>${hera.version}</version>
</dependency>
<!-- hera springboot starter -->
<dependency>
<groupid>com.meituan.hera</groupid>
<artifactid>hera-spring-boot-starter</artifactid>
<version>${hera.version}</version>
</dependency>
<!-- 其他依赖 -->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-aop</artifactid>
</dependency>
</dependencies>
2.3.2 配置文件
# application.yml
server:
port: 8080
spring:
application:
name: demo-service
# hera配置
hera:
enabled: true
app-name: ${spring.application.name}
env: dev
collector:
host: localhost
port: 8081
trace:
enable: true
sample-rate: 1.0 # 采样率
metrics:
enable: true
interval: 60s # 上报间隔
2.3.3 启动类配置
// demoapplication.java
import com.meituan.hera.spring.boot.autoconfigure.enablehera;
import org.springframework.boot.springapplication;
import org.springframework.boot.autoconfigure.springbootapplication;
@springbootapplication
@enablehera // 启用hera监控
public class demoapplication {
public static void main(string[] args) {
springapplication.run(demoapplication.class, args);
}
}
2.4 业务代码增强
2.4.1 创建示例controller
// usercontroller.java
import com.meituan.hera.trace.annotation.trace;
import org.springframework.web.bind.annotation.*;
@restcontroller
@requestmapping("/api/users")
public class usercontroller {
@getmapping("/{id}")
@trace // 添加追踪注解
public user getuser(@pathvariable long id) {
// 模拟业务逻辑
try {
thread.sleep(100);
} catch (interruptedexception e) {
e.printstacktrace();
}
return new user(id, "user" + id);
}
@postmapping
@trace(name = "createuser") // 自定义span名称
public user createuser(@requestbody user user) {
// 业务处理
return user;
}
@getmapping("/list")
public list<user> listusers(@requestparam int page,
@requestparam int size) {
// 分页查询
return userservice.getusers(page, size);
}
}
// user.java
public class user {
private long id;
private string name;
// 构造方法、getter、setter省略
}
2.4.2 添加service层追踪
// userservice.java
import com.meituan.hera.trace.annotation.trace;
import org.springframework.stereotype.service;
@service
public class userservice {
@trace
public user getuserbyid(long id) {
// 模拟数据库查询
simulatedatabasequery();
return new user(id, "user" + id);
}
@trace(name = "batchquery")
public list<user> getusers(int page, int size) {
list<user> users = new arraylist<>();
for (int i = 0; i < size; i++) {
users.add(new user((long) i, "user" + i));
}
return users;
}
private void simulatedatabasequery() {
try {
thread.sleep(50);
} catch (interruptedexception e) {
thread.currentthread().interrupt();
}
}
}
2.4.3 添加feign客户端支持
// userfeignclient.java
import org.springframework.cloud.openfeign.feignclient;
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.pathvariable;
@feignclient(name = "user-service", url = "${user.service.url}")
public interface userfeignclient {
@getmapping("/users/{id}")
user getuser(@pathvariable("id") long id);
}
// 配置类
@configuration
public class feignconfig {
@bean
public feign.okhttp.okhttpclient okhttpclient() {
return new feign.okhttp.okhttpclient();
}
}
2.5 自定义监控指标
2.5.1 自定义metric
// custommetrics.java
import com.meituan.hera.metrics.api.metricregistry;
import com.meituan.hera.metrics.api.counter;
import org.springframework.stereotype.component;
import javax.annotation.postconstruct;
@component
public class custommetrics {
private counter userlogincounter;
private counter apierrorcounter;
@postconstruct
public void init() {
userlogincounter = metricregistry.getcounter("user.login.count");
apierrorcounter = metricregistry.getcounter("api.error.count");
}
public void recordlogin() {
userlogincounter.inc();
}
public void recordapierror() {
apierrorcounter.inc();
}
}
2.5.2 业务监控切面
// monitoraspect.java
import com.meituan.hera.trace.tracecontext;
import org.aspectj.lang.proceedingjoinpoint;
import org.aspectj.lang.annotation.around;
import org.aspectj.lang.annotation.aspect;
import org.springframework.stereotype.component;
@aspect
@component
public class monitoraspect {
private final custommetrics custommetrics;
public monitoraspect(custommetrics custommetrics) {
this.custommetrics = custommetrics;
}
@around("@annotation(org.springframework.web.bind.annotation.getmapping) || " +
"@annotation(org.springframework.web.bind.annotation.postmapping)")
public object monitorapi(proceedingjoinpoint joinpoint) throws throwable {
long starttime = system.currenttimemillis();
string traceid = tracecontext.gettraceid();
try {
object result = joinpoint.proceed();
long duration = system.currenttimemillis() - starttime;
// 记录成功指标
recordsuccessmetrics(joinpoint, duration);
return result;
} catch (exception e) {
custommetrics.recordapierror();
throw e;
}
}
private void recordsuccessmetrics(proceedingjoinpoint joinpoint, long duration) {
string methodname = joinpoint.getsignature().getname();
// 记录到监控系统
}
}
2.6 高级配置
2.6.1 过滤器配置
// tracefilter.java
import com.meituan.hera.trace.tracecontext;
import org.springframework.core.annotation.order;
import org.springframework.stereotype.component;
import javax.servlet.*;
import javax.servlet.http.httpservletrequest;
import java.io.ioexception;
@component
@order(1)
public class tracefilter implements filter {
@override
public void dofilter(servletrequest request,
servletresponse response,
filterchain chain)
throws ioexception, servletexception {
httpservletrequest httprequest = (httpservletrequest) request;
// 从请求头获取trace信息
string traceid = httprequest.getheader("x-trace-id");
string spanid = httprequest.getheader("x-span-id");
if (traceid != null) {
tracecontext.settraceid(traceid);
}
if (spanid != null) {
tracecontext.setspanid(spanid);
}
try {
chain.dofilter(request, response);
} finally {
tracecontext.clear();
}
}
}
2.6.2 线程池配置
// threadpoolconfig.java
import com.meituan.hera.trace.instrument.async.traceableexecutorservice;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import java.util.concurrent.executorservice;
import java.util.concurrent.executors;
@configuration
public class threadpoolconfig {
@bean("traceableexecutor")
public executorservice traceableexecutor() {
executorservice executor = executors.newfixedthreadpool(10);
return new traceableexecutorservice(executor);
}
}
三、验证与测试
3.1 启动应用测试
# 启动springboot应用
mvn spring-boot:run
# 测试api
curl http://localhost:8080/api/users/1
curl -x post http://localhost:8080/api/users \
-h "content-type: application/json" \
-d '{"id": 2, "name": "test user"}'
3.2 查看hera监控界面
- 访问
http://localhost:8080(hera web界面) - 查看应用列表,确认demo-service已注册
- 点击进入调用链查询
- 查看具体的trace详情
3.3 日志配置
# application.yml 追加日志配置
logging:
level:
com.meituan.hera: debug
pattern:
console: "%d{yyyy-mm-dd hh:mm:ss} [%thread] %-5level %logger{36} [traceid:%x{traceid}] - %msg%n"
四、生产环境部署建议
4.1 性能优化配置
# application-prod.yml
hera:
enabled: true
app-name: ${spring.application.name}
env: prod
collector:
host: hera-collector.prod.svc.cluster.local
port: 8081
trace:
enable: true
sample-rate: 0.1 # 生产环境降低采样率
metrics:
enable: true
interval: 30s
buffer:
size: 10000
flush-interval: 5s
4.2 kubernetes部署配置
# deployment.yaml
apiversion: apps/v1
kind: deployment
metadata:
name: demo-service
spec:
replicas: 3
template:
spec:
containers:
- name: app
image: demo-service:latest
env:
- name: hera_agent_opts
value: "-javaagent:/app/agent/hera-agent.jar"
- name: hera_app_name
value: "demo-service"
- name: hera_env
value: "prod"
volumemounts:
- name: hera-agent
mountpath: /app/agent
volumes:
- name: hera-agent
configmap:
name: hera-agent-config
五、总结
5.1 集成优势
- 全链路追踪能力:完整展示请求在微服务间的流转路径
- 性能监控全面:涵盖响应时间、吞吐量、错误率等关键指标
- 故障定位快速:通过traceid快速定位问题服务和方法
- 系统扩展性强:支持大规模微服务集群的监控需求
- 社区生态完善:美团点评背书,社区活跃,文档齐全
5.2 注意事项
- 采样率配置:生产环境应根据流量调整采样率,避免存储压力
- agent版本:确保agent版本与hera服务端版本兼容
- 网络配置:确保应用服务器能访问hera collector
- 存储规划:根据数据量合理规划elasticsearch集群规模
- 安全考虑:生产环境应配置访问权限控制
5.3 最佳实践
- 渐进式接入:先从核心服务开始,逐步推广到全站
- 告警配置:结合hera-alarm设置合理的性能告警阈值
- 定期维护:定期清理过期数据,优化查询性能
- 团队培训:确保开发团队了解如何利用hera进行问题排查
- 持续优化:根据业务发展不断调整监控策略和配置
通过集成hera,企业可以构建完整的可观测性体系,显著提升微服务架构下的运维效率和故障处理能力,为业务稳定运行提供有力保障。
以上就是springboot集成hera实现分布式应用监控与追踪解决方案的详细内容,更多关于springboot hera分布式应用监控与追踪的资料请关注代码网其它相关文章!
发表评论