![图片[1]-【实战教程】Spring Boot集成SkyWalking:轻松实现用户ID、URL和IP的自定义标签追踪](https://share.0f1.top/wwj/typora/2025/03/11/202503111441586.webp)
为什么需要自定义标签?
在微服务架构中,追踪用户请求的完整链路至关重要。SkyWalking作为一款优秀的APM工具,提供了基础的链路追踪功能,但在实际业务场景中,我们常常需要知道:
- 是哪个用户发起的请求?
- 请求的具体URL是什么?
- 请求来自哪个IP地址?
通过添加这些自定义标签,我们可以:
- 快速定位特定用户遇到的问题
- 分析不同接口的性能瓶颈
- 识别可能的异常访问来源
效果示意:
| SkyWalking追踪详情 |
|--------------------------------------------------|
| 追踪ID: 123e4567-e89b-12d3-a456-426614174000 |
| 服务名: user-service |
| 操作名: /api/users/profile |
| 耗时: 230ms |
| |
| 自定义标签: |
| ✓ userid: 10086 |
| ✓ url: https://example.com/api/users/profile |
| ✓ ip: 203.0.113.195 |
|--------------------------------------------------|
实现方案一:使用过滤器(Filter)
过滤器是实现这一功能的最简单方式,它能拦截所有的HTTP请求。
package com.example.config;
import org.apache.skywalking.apm.toolkit.trace.ActiveSpan;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class SkyWalkingTagFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// 获取用户ID(根据你的认证机制实现)
String userId = getUserIdFromRequest(request);
if (userId != null) {
ActiveSpan.tag("userid", userId);
}
// 添加URL标签
String url = request.getRequestURL().toString();
ActiveSpan.tag("url", url);
// 添加IP标签
String clientIp = getClientIp(request);
ActiveSpan.tag("ip", clientIp);
// 继续请求链
filterChain.doFilter(request, response);
}
private String getUserIdFromRequest(HttpServletRequest request) {
// 根据你的认证机制实现
// 例如,如果使用Spring Security:
// Authentication auth = SecurityContextHolder.getContext().getAuthentication();
// return auth != null && auth.isAuthenticated() ? auth.getName() : "anonymous";
// 或者从会话属性中获取:
return (String) request.getSession().getAttribute("userId");
}
private String getClientIp(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
}
过滤器工作流程:
客户端请求 → [SkyWalkingTagFilter] → 添加自定义标签(userid/url/ip) → 继续请求处理 → 返回响应
实现方案二:使用拦截器(Interceptor)
如果你更喜欢Spring MVC的拦截器机制,这里提供另一种实现方式:
package com.example.config;
import org.apache.skywalking.apm.toolkit.trace.ActiveSpan;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class SkyWalkingTagInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// 获取用户ID
String userId = getUserIdFromRequest(request);
if (userId != null) {
ActiveSpan.tag("userid", userId);
}
// 添加URL标签
String url = request.getRequestURL().toString();
ActiveSpan.tag("url", url);
// 添加IP标签
String clientIp = getClientIp(request);
ActiveSpan.tag("ip", clientIp);
return true;
}
private String getUserIdFromRequest(HttpServletRequest request) {
// 根据你的认证机制实现
return (String) request.getSession().getAttribute("userId");
}
private String getClientIp(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
}
然后,需要注册这个拦截器:
package com.example.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private SkyWalkingTagInterceptor skyWalkingTagInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(skyWalkingTagInterceptor);
}
}
添加必要的依赖
确保在你的pom.xml
中添加SkyWalking的相关依赖:
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>8.8.0</version>
</dependency>
依赖配置说明:
项目依赖结构:
└── pom.xml
└── dependencies
├── spring-boot-starter-web
├── spring-boot-starter-aop
└── apm-toolkit-trace (SkyWalking工具包)
实现效果
成功配置后,你将在SkyWalking UI中看到每个追踪都带有自定义标签:
追踪详情示例:
+-----------------------------------------------+
| 追踪详情 |
+-----------------------------------------------+
| 追踪ID: 7a6cc3df-8f9a-4b9c-a1b2-1a2b3c4d5e6f |
| 开始时间: 2023-05-20 14:30:45.123 |
| 持续时间: 157ms |
+-----------------------------------------------+
| 标签: |
| ├─ userid: user_123456 |
| ├─ url: http://api.example.com/users/info |
| └─ ip: 192.168.1.100 |
+-----------------------------------------------+
| 组件: |
| ├─ HTTP GET |
| ├─ Controller.getUserInfo |
| └─ Database Query |
+-----------------------------------------------+
注意事项
getUserIdFromRequest
方法需要根据你的认证机制进行实现- 确保SkyWalking agent已正确配置并与你的应用一起启动
- 过滤器和拦截器两种方案选择一种即可,根据你的项目结构选择更合适的方式
- IP提取逻辑处理了各种代理头信息,以获取真实的客户端IP
总结
通过简单的几步配置,我们成功地为SkyWalking追踪添加了用户ID、URL和IP这三个关键标签,大大增强了应用监控的能力。这些自定义标签不仅可以帮助我们更快地定位问题,还能为业务分析提供有价值的数据支持。
你还可以根据业务需求,添加更多自定义标签,例如设备信息、操作类型等,进一步丰富你的追踪数据。
实现架构图:
希望本文对你有所帮助,让你的微服务监控更上一层楼!
© 版权声明
THE END