当前位置: 首页 > news >正文

徐州网站开发设计公司电话网站开发设计心得及体会

徐州网站开发设计公司电话,网站开发设计心得及体会,嘉定集团网站建设,青岛做公司网站注册的多吗在 Java 项目中实现分布式追踪系统时#xff0c;traceId 的传递机制可以通过以下图示来说明#xff1a; 1. 分布式追踪系统架构图 [用户请求]│▼ [API网关] → 生成全局 traceId│▼ [服务A] → 接收 traceId → 日志记录 → 调用服务B│ ▲│ …在 Java 项目中实现分布式追踪系统时traceId 的传递机制可以通过以下图示来说明 1. 分布式追踪系统架构图 [用户请求]│▼ [API网关] → 生成全局 traceId│▼ [服务A] → 接收 traceId → 日志记录 → 调用服务B│                     ▲│                     │ 传递 traceId▼                     │ [服务B] → 接收 traceId → 日志记录 → 调用数据库│                     ▲│                     │ 传递 traceId▼                     │ [数据库] → 记录 traceId 到 SQL 日志│▼ [消息队列] → 传递 traceId│▼ [服务C] → 处理消息并记录 traceId 2. traceId 传递机制图解 2.1 HTTP 请求中的传递   [客户端] → GET /api/dataHeader: X-Trace-Id: abc123│▼ [服务A] → 从 Header 获取 traceId│▼ [服务A] → 调用服务B: POST /internal/dataHeader: X-Trace-Id: abc123 (保持相同) 2.2 RPC 调用中的传递   [服务A] → Dubbo RPC 调用服务B┌───────────────────────────┐│ Invocation                ││   - method: getData       ││   - attachments:          ││        traceId abc123 │└───────────────────────────┘│▼ [服务B] → 从 attachments 获取 traceId 2.3 消息队列中的传递 [服务A] → 发送消息到 RabbitMQ/Kafka    ┌───────────────────────────┐    │ Message Properties        │    │   headers:                │    │     traceId abc123    │    └───────────────────────────┘           │           ▼ [服务C] → 从消息属性获取 traceId 3. 线程上下文管理 3.1 同步请求中的上下文 ┌──────────────────────┐ │ ThreadLocal          │ │   traceId abc123 │ │ MDC (日志上下文)      │ └──────────────────────┘ 3.2 异步线程中的上下文传递 主线程 → 提交任务到线程池 ┌──────────────────────┐    ┌──────────────────────┐ │ TransmittableThread  │ →  │ 线程池线程            │ │   traceId abc123 │    │   traceId abc123 │ └──────────────────────┘    └──────────────────────┘        任务执行前复制                任务执行时使用 4. 日志系统中的 traceId 集成 2023-08-15 10:30:25 [http-nio-8080-exec-1] [traceId:abc123] INFO  c.e.s.ServiceA - 处理请求 2023-08-15 10:30:26 [http-nio-8080-exec-1] [traceId:abc123] DEBUG c.e.s.ServiceA - 调用服务B 2023-08-15 10:30:27 [http-nio-8080-exec-3] [traceId:abc123] INFO  c.e.s.ServiceB - 接收请求 2023-08-15 10:30:28 [task-pool-1] [traceId:abc123] INFO  c.e.s.AsyncService - 异步任务开始 5. 全链路追踪示意图 ┌────────────┐     ┌────────────┐     ┌────────────┐     ┌──────────┐ │  网关       │     │  服务A      │     │  服务B      │     │  数据库   │ │ traceId生成 │ ⇒⇒⇒ │ 记录日志    │ ⇒⇒⇒ │ 记录日志    │ ⇒⇒⇒ │ SQL日志  │ │ abc123     │     │ [abc123]    │     │ [abc123]    │     │ [abc123] │ └────────────┘     └────────────┘     └──────┬──────┘     └──────────┘                                ⇓              ⇓                              ┌────────────┐  │  ┌────────────┐                              │  消息队列    │⇐═⇘  │  服务C      │                              │ [abc123]    │     │ [abc123]    │                              └────────────┘     └────────────┘ 关键组件说明 1. traceId 生成器 ◦ 在系统入口网关或第一个服务生成唯一 ID ◦ 格式[应用标识]-[时间戳]-[随机数]例APP1-1692081025-7d3f 2. 上下文传播器 ◦ HTTP通过 HeaderX-Trace-Id ◦ RPC通过调用附件Attachment ◦ MQ通过消息属性Properties ◦ 线程通过 ThreadLocal MDC 3. 日志集成 ◦ 日志框架配置中添加 %X{traceId} ◦ 所有日志自动包含当前 traceId 4. 异步支持 ◦ 使用 TransmittableThreadLocal 解决线程池上下文传递 ◦ 配合 TaskDecorator 包装 Runnable 5. 监控集成 ◦ 将 traceId 传递给监控系统如 Zipkin ◦ 实现全链路追踪可视化 这种设计确保了在分布式系统中从一个请求进入系统开始到经过多个服务、数据库操作、异步任务处理再到最终响应整个过程中的所有日志和操作都能通过同一个 traceId 关联起来极大地方便了问题排查和系统监控。 在 Java 项目中实现统一的 traceId请求追踪 ID是分布式系统追踪的关键以下是几种常用且可靠的实现方案 方案一Servlet Filter MDC推荐 // TraceId 工具类 public class TraceIdUtil {public static final String TRACE_ID traceId;public static String generateTraceId() {// 使用 UUID 时间戳确保唯一性return TRC- System.currentTimeMillis() - UUID.randomUUID().toString().substring(0, 8);} }或者 import java.util.UUID;public class TraceIdGenerator {// 生成标准UUID格式的TraceIdpublic static String generateUUIDTraceId() {return UUID.randomUUID().toString().replace(-, );}// 生成更短的UUID变种(32位)public static String generateShortUUIDTraceId() {return UUID.randomUUID().toString().replace(-, );}// 生成带前缀的TraceIdpublic static String generatePrefixedTraceId(String prefix) {return prefix - generateShortUUIDTraceId();} }// 过滤器实现 WebFilter(/*) public class TraceIdFilter implements Filter {Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {try {// 1. 生成/传递 traceIdHttpServletRequest httpRequest (HttpServletRequest) request;String traceId Optional.ofNullable(httpRequest.getHeader(X-Trace-Id)).orElseGet(TraceIdUtil::generateTraceId);// 2. 存入 MDC日志上下文MDC.put(TraceIdUtil.TRACE_ID, traceId);// 3. 设置到请求属性供业务代码使用httpRequest.setAttribute(TRACE_ID_ATTRIBUTE, traceId);// 4. 传递给下游设置响应头HttpServletResponse httpResponse (HttpServletResponse) response;httpResponse.setHeader(X-Trace-Id, traceId);chain.doFilter(request, response);} finally {// 5. 请求结束后清除 MDCMDC.clear();}} } 日志配置logback.xml appender nameSTDOUT classch.qos.logback.core.ConsoleAppenderencoder!-- 添加 %X{traceId} 输出 --pattern%d{yyyy-MM-dd HH:mm:ss} [%thread] [%X{traceId}] %-5level %logger{36} - %msg%n/pattern/encoder /appender 方案二Spring Interceptor ThreadLocal // ThreadLocal 上下文 public class TraceContext {private static final ThreadLocalString traceIdHolder new ThreadLocal();public static void setTraceId(String traceId) {traceIdHolder.set(traceId);}public static String getTraceId() {return traceIdHolder.get();}public static void clear() {traceIdHolder.remove();} }// 拦截器实现 Component public class TraceInterceptor implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {String traceId request.getHeader(X-Trace-Id);if (traceId null) {traceId TraceIdUtil.generateTraceId();}TraceContext.setTraceId(traceId);response.setHeader(X-Trace-Id, traceId);return true;}Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {TraceContext.clear(); // 清除ThreadLocal} } 注册拦截器 Configuration public class WebConfig implements WebMvcConfigurer {Autowired private TraceInterceptor traceInterceptor;Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(traceInterceptor);} } 方案三Spring Cloud Sleuth微服务专用 !-- pom.xml 添加依赖 -- dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-sleuth/artifactId /dependency 自动实现 自动生成 traceId格式application-[traceId]-[spanId]通过 HTTP Headers 传递X-B3-TraceId, X-B3-SpanId集成日志框架MDC 自动注入支持 OpenZipkin 分布式追踪 方案四异步线程支持关键扩展 使用 TransmittableThreadLocal 解决线程池 traceId 传递问题 // 增强版 ThreadLocal public class AsyncTraceContext {private static final TransmittableThreadLocalString traceIdHolder new TransmittableThreadLocal();// 方法同方案二... }// 线程池包装器 Bean public Executor asyncExecutor() {ThreadPoolTaskExecutor executor new ThreadPoolTaskExecutor();executor.setTaskDecorator(runnable - TtlRunnable.get(() - {// 传递 traceId 到子线程AsyncTraceContext.setTraceId(TraceContext.getTraceId());runnable.run();}));return executor; } 方案五RPC 调用传递 1. HTTP 客户端RestTemplate Bean public RestTemplate restTemplate() {RestTemplate restTemplate new RestTemplate();restTemplate.getInterceptors().add((request, body, execution) - {// 将当前 traceId 设置到请求头request.getHeaders().add(X-Trace-Id, TraceContext.getTraceId());return execution.execute(request, body);});return restTemplate; } 2. Dubbo 调用 // 消费者过滤器 public class DubboTraceConsumerFilter implements Filter {Overridepublic Result invoke(Invoker? invoker, Invocation invocation) {invocation.setAttachment(traceId, TraceContext.getTraceId());return invoker.invoke(invocation);} }// 提供者过滤器 public class DubboTraceProviderFilter implements Filter {Overridepublic Result invoke(Invoker? invoker, Invocation invocation) {String traceId invocation.getAttachment(traceId);if (traceId ! null) {TraceContext.setTraceId(traceId);}return invoker.invoke(invocation);} } 最佳实践总结 入口生成在请求入口Filter/Interceptor生成 traceId全链路传递 HTTP通过 Header 传递X-Trace-IdRPC通过调用附件传递MQ通过消息头传递 存储位置 同步请求使用 MDC ThreadLocal异步线程使用 TransmittableThreadLocal 日志集成在日志模板中添加 %X{traceId}异常处理确保在 finally 块中清理上下文ID 生成规则 // 示例服务前缀 时间戳 随机数 SVC- System.currentTimeMillis() - ThreadLocalRandom.current().nextInt(10000) 验证方式 查看日志输出是否包含 traceId跨服务调用检查 Header 传递异步任务验证 traceId 一致性 Async public void asyncTask() {log.info(Async task traceId: {}, MDC.get(traceId)); // 应非空 } 选择方案时 单体应用 → 方案一Spring MVC → 方案二微服务架构 → 方案三复杂异步场景 → 方案四 traceId实践 生成traceIdimport com.alibaba.ttl.TransmittableThreadLocal; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.UUID;/***/ Component Slf4j public class LogInterceptor extends HandlerInterceptorAdapter {private final static ThreadLocalLong timeThreadLocal new ThreadLocal();public final static TransmittableThreadLocalString requestIdThreadLocal new TransmittableThreadLocal();Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {timeThreadLocal.set(System.currentTimeMillis());// 将当前 traceId 放入请求头String traceId request.getHeader(X-Trace-Id);if (traceId null) {traceId UUID.randomUUID().toString();}request.setAttribute(performanceRequestId, traceId);requestIdThreadLocal.set(traceId);String path request.getServletPath();log.info( 调用开始 访问服务uri:{}, path);return true;}Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {try {long startTime timeThreadLocal.get();long endTime System.currentTimeMillis();log.info( 调用结束 uri:{} 耗时 {} ms, request.getServletPath(), endTime - startTime);}finally {timeThreadLocal.remove();requestIdThreadLocal.remove();}}}对应转换类import ch.qos.logback.classic.pattern.ClassicConverter; import ch.qos.logback.classic.spi.ILoggingEvent;/***/ public class MyLogBackConverter extends ClassicConverter {Overridepublic String convert(ILoggingEvent event) {// 获取你的参数例如从 MDC 或者其他上下文中 // String myParam event.getMDCPropertyMap().get(myParam);String myParam LogInterceptor.requestIdThreadLocal.get();return myParam ! null ? myParam : TraceID;} }对应logback: configurationproperty nameLOG_HOME valuelogs/xxxx-service /conversionRule conversionWordmyParam converterClasscom.xxx.config.MyLogBackConverter /appender nameSTDOUT classch.qos.logback.core.ConsoleAppenderfilter classch.qos.logback.classic.filter.ThresholdFilter!-- 只接受INFO级别的日志 --levelINFO/level/filterencoderpattern%d{yyyy-MM-dd HH:mm:ss} [%thread] [%myParam] %-5level %logger{36} - %msg %n/pattern/encoder/appenderappender nameSTDOUT_ERROR classch.qos.logback.core.ConsoleAppenderfilter classch.qos.logback.classic.filter.ThresholdFilter!-- 只接受INFO级别的日志 --levelERROR/level/filterencoderpattern%d{yyyy-MM-dd HH:mm:ss} [%thread] [%myParam] %-5level %logger{36} - %msg %n/pattern/encoder/appenderroot levelINFOappender-ref refSTDOUT /appender-ref refSTDOUT_ERROR //root/configuration
http://www.hkea.cn/news/14589307/

相关文章:

  • 亚马逊网站网址wordpress 脚本
  • 如何在自己的网站上做友情链接html导入wordpress
  • 快速提升网站关键词排名网站建设前的分析第一小节内容
  • 备案号 网站软文营销的概念
  • 电子商务网站建设与规划案例做网站送推广
  • wordpress代码高亮主题淄博网站制作定制优化
  • wordpress站点使用期限插件网站外链可以在哪些平台上做外链
  • 校园门户网站系统建设关键技术天津建设网站安管人员成绩查询
  • 洛阳网站设计公司如何做国外销售网站
  • 郑州网站建设中国建设建设银行wordpress 内存溢出
  • 音乐类网站模板培训课程网站
  • 厦门市建设局网站首页阿里云 企业网站选哪种
  • 潍坊网站关键词推广展示类网站开发费用
  • 北京建设数字网站wordpress rest 授权
  • 礼叮当 一家做创意礼品定制的网站网站分类导航代码
  • 中小企业网站制作模板企业市场营销
  • 漳州市龙文区建设局网站网站做优化好还是推广好
  • 局域网如何做视频网站建设外贸流程及详细步骤
  • 微商城网站建设市场图书馆网站建设工作
  • 口碑好的扬中网站建设沈阳沈河区网站建设
  • 如何用服务器搭建自己的网站怎么查网站备案域名备案
  • 网站建设岗位职责怎么写百度识图网页版 在线
  • 网站搭建app制作网站参考
  • 珲春建设局网站怎么做福利视频网站
  • 做网站一定要有服务器吗仿团购网站模板
  • 沧州企业网站建设05网学霸
  • 许昌网站制作公司闵行网络推广
  • 网站建设收获互联网公司排名完整
  • 手把手教你学网站建设做网站不懂行情 怎么收费
  • 哪类公司做网站的最多濮阳房产网