中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

外賣網(wǎng)站制作seo 關(guān)鍵詞優(yōu)化

外賣網(wǎng)站制作,seo 關(guān)鍵詞優(yōu)化,遼陽網(wǎng)站制作,企業(yè)qq官方下載官網(wǎng)在 Java 項(xiàng)目中實(shí)現(xiàn)分布式追蹤系統(tǒng)時,traceId 的傳遞機(jī)制可以通過以下圖示來說明: 1. 分布式追蹤系統(tǒng)架構(gòu)圖 [用戶請求]│▼ [API網(wǎng)關(guān)] → 生成全局 traceId│▼ [服務(wù)A] → 接收 traceId → 日志記錄 → 調(diào)用服務(wù)B│ ▲│ …

在 Java 項(xiàng)目中實(shí)現(xiàn)分布式追蹤系統(tǒng)時,traceId 的傳遞機(jī)制可以通過以下圖示來說明:
1. 分布式追蹤系統(tǒng)架構(gòu)圖

[用戶請求]│▼
[API網(wǎng)關(guān)] → 生成全局 traceId│▼
[服務(wù)A] → 接收 traceId → 日志記錄 → 調(diào)用服務(wù)B│ ? ? ? ? ? ? ? ? ? ? ▲│ ? ? ? ? ? ? ? ? ? ? │ 傳遞 traceId▼ ? ? ? ? ? ? ? ? ? ? │
[服務(wù)B] → 接收 traceId → 日志記錄 → 調(diào)用數(shù)據(jù)庫│ ? ? ? ? ? ? ? ? ? ? ▲│ ? ? ? ? ? ? ? ? ? ? │ 傳遞 traceId▼ ? ? ? ? ? ? ? ? ? ? │
[數(shù)據(jù)庫] → 記錄 traceId 到 SQL 日志│▼
[消息隊(duì)列] → 傳遞 traceId│▼
[服務(wù)C] → 處理消息并記錄 traceId


2. traceId 傳遞機(jī)制圖解
2.1 HTTP 請求中的傳遞
?

[客戶端] → GET /api/dataHeader: X-Trace-Id: abc123│▼
[服務(wù)A] → 從 Header 獲取 traceId│▼
[服務(wù)A] → 調(diào)用服務(wù)B: POST /internal/dataHeader: X-Trace-Id: abc123 (保持相同)


2.2 RPC 調(diào)用中的傳遞
?

[服務(wù)A] → Dubbo RPC 調(diào)用服務(wù)B┌───────────────────────────┐│ Invocation ? ? ? ? ? ? ? ?││ ? - method: getData ? ? ? ││ ? - attachments: ? ? ? ? ?││ ? ? ? ?traceId = "abc123" │└───────────────────────────┘│▼
[服務(wù)B] → 從 attachments 獲取 traceId


2.3 消息隊(duì)列中的傳遞

[服務(wù)A] → 發(fā)送消息到 RabbitMQ/Kafka
? ?┌───────────────────────────┐
? ?│ Message Properties ? ? ? ?│
? ?│ ? headers: ? ? ? ? ? ? ? ?│
? ?│ ? ? traceId = "abc123" ? ?│
? ?└───────────────────────────┘
? ? ? ? ? │
? ? ? ? ? ▼
[服務(wù)C] → 從消息屬性獲取 traceId
3. 線程上下文管理
3.1 同步請求中的上下文

┌──────────────────────┐
│ ThreadLocal ? ? ? ? ?│
│ ? traceId = "abc123" │
│ MDC (日志上下文) ? ? ?│
└──────────────────────┘
3.2 異步線程中的上下文傳遞

主線程 → 提交任務(wù)到線程池
┌──────────────────────┐ ? ?┌──────────────────────┐
│ TransmittableThread ?│ → ?│ 線程池線程 ? ? ? ? ? ?│
│ ? traceId = "abc123" │ ? ?│ ? traceId = "abc123" │
└──────────────────────┘ ? ?└──────────────────────┘
? ? ? ?任務(wù)執(zhí)行前復(fù)制 ? ? ? ? ? ? ? ?任務(wù)執(zhí)行時使用
4. 日志系統(tǒng)中的 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 - 調(diào)用服務(wù)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 - 異步任務(wù)開始
5. 全鏈路追蹤示意圖

┌────────────┐ ? ? ┌────────────┐ ? ? ┌────────────┐ ? ? ┌──────────┐
│ ?網(wǎng)關(guān) ? ? ? │ ? ? │ ?服務(wù)A ? ? ?│ ? ? │ ?服務(wù)B ? ? ?│ ? ? │ ?數(shù)據(jù)庫 ? │
│ traceId生成 │ ??? │ 記錄日志 ? ?│ ??? │ 記錄日志 ? ?│ ??? │ SQL日志 ?│
│ abc123 ? ? │ ? ? │ [abc123] ? ?│ ? ? │ [abc123] ? ?│ ? ? │ [abc123] │
└────────────┘ ? ? └────────────┘ ? ? └──────┬──────┘ ? ? └──────────┘
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?┌────────────┐ ?│ ?┌────────────┐
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│ ?消息隊(duì)列 ? ?│?═? ?│ ?服務(wù)C ? ? ?│
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│ [abc123] ? ?│ ? ? │ [abc123] ? ?│
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?└────────────┘ ? ? └────────────┘
關(guān)鍵組件說明:
1. traceId 生成器:
? 在系統(tǒng)入口(網(wǎng)關(guān)或第一個服務(wù))生成唯一 ID
? 格式:[應(yīng)用標(biāo)識]-[時間戳]-[隨機(jī)數(shù)](例:APP1-1692081025-7d3f)
2. 上下文傳播器:
? HTTP:通過 Header(X-Trace-Id)
? RPC:通過調(diào)用附件(Attachment)
? MQ:通過消息屬性(Properties)
? 線程:通過 ThreadLocal + MDC
3. 日志集成:
? 日志框架配置中添加 %X{traceId}
? 所有日志自動包含當(dāng)前 traceId
4. 異步支持:
? 使用 TransmittableThreadLocal 解決線程池上下文傳遞
? 配合 TaskDecorator 包裝 Runnable
5. 監(jiān)控集成:
? 將 traceId 傳遞給監(jiān)控系統(tǒng)(如 Zipkin)
? 實(shí)現(xiàn)全鏈路追蹤可視化
這種設(shè)計確保了在分布式系統(tǒng)中,從一個請求進(jìn)入系統(tǒng)開始,到經(jīng)過多個服務(wù)、數(shù)據(jù)庫操作、異步任務(wù)處理,再到最終響應(yīng),整個過程中的所有日志和操作都能通過同一個 traceId 關(guān)聯(lián)起來,極大地方便了問題排查和系統(tǒng)監(jiān)控。

在 Java 項(xiàng)目中實(shí)現(xiàn)統(tǒng)一的 traceId(請求追蹤 ID)是分布式系統(tǒng)追蹤的關(guān)鍵,以下是幾種常用且可靠的實(shí)現(xiàn)方案:


方案一: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 {// 生成標(biāo)準(zhǔn)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();}
}// 過濾器實(shí)現(xiàn)
@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. 設(shè)置到請求屬性(供業(yè)務(wù)代碼使用)httpRequest.setAttribute(TRACE_ID_ATTRIBUTE, traceId);// 4. 傳遞給下游(設(shè)置響應(yīng)頭)HttpServletResponse httpResponse = (HttpServletResponse) response;httpResponse.setHeader("X-Trace-Id", traceId);chain.doFilter(request, response);} finally {// 5. 請求結(jié)束后清除 MDCMDC.clear();}}
}

日志配置(logback.xml)

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><!-- 添加 %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 ThreadLocal<String> 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();}
}// 攔截器實(shí)現(xiàn)
@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(微服務(wù)專用)

<!-- pom.xml 添加依賴 -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>

自動實(shí)現(xiàn)

  • 自動生成 traceId(格式:application-[traceId]-[spanId])
  • 通過 HTTP Headers 傳遞(X-B3-TraceId, X-B3-SpanId
  • 集成日志框架(MDC 自動注入)
  • 支持 OpenZipkin 分布式追蹤

方案四:異步線程支持(關(guān)鍵擴(kuò)展)

使用 TransmittableThreadLocal 解決線程池 traceId 傳遞問題:

// 增強(qiáng)版 ThreadLocal
public class AsyncTraceContext {private static final TransmittableThreadLocal<String> 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 調(diào)用傳遞

1. HTTP 客戶端(RestTemplate)
@Bean
public RestTemplate restTemplate() {RestTemplate restTemplate = new RestTemplate();restTemplate.getInterceptors().add((request, body, execution) -> {// 將當(dāng)前 traceId 設(shè)置到請求頭request.getHeaders().add("X-Trace-Id", TraceContext.getTraceId());return execution.execute(request, body);});return restTemplate;
}
2. Dubbo 調(diào)用
// 消費(fèi)者過濾器
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);}
}

最佳實(shí)踐總結(jié)

  1. 入口生成:在請求入口(Filter/Interceptor)生成 traceId
  2. 全鏈路傳遞
    • HTTP:通過 Header 傳遞(X-Trace-Id
    • RPC:通過調(diào)用附件傳遞
    • MQ:通過消息頭傳遞
  1. 存儲位置
    • 同步請求:使用 MDC + ThreadLocal
    • 異步線程:使用 TransmittableThreadLocal
  1. 日志集成:在日志模板中添加 %X{traceId}
  2. 異常處理:確保在 finally 塊中清理上下文
  3. ID 生成規(guī)則
// 示例:服務(wù)前綴 + 時間戳 + 隨機(jī)數(shù)
"SVC-" + System.currentTimeMillis() + "-" + ThreadLocalRandom.current().nextInt(10000)

驗(yàn)證方式

  1. 查看日志輸出是否包含 traceId
  2. 跨服務(wù)調(diào)用檢查 Header 傳遞
  3. 異步任務(wù)驗(yàn)證 traceId 一致性
@Async
public void asyncTask() {log.info("Async task traceId: {}", MDC.get("traceId")); // 應(yīng)非空
}

選擇方案時:

  • 單體應(yīng)用 → 方案一
  • Spring MVC → 方案二
  • 微服務(wù)架構(gòu) → 方案三
  • 復(fù)雜異步場景 → 方案四

traceId實(shí)踐:

生成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   ThreadLocal<Long> timeThreadLocal = new ThreadLocal<>();public final  static TransmittableThreadLocal<String> requestIdThreadLocal = new TransmittableThreadLocal<>();@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {timeThreadLocal.set(System.currentTimeMillis());// 將當(dāng)前 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("==> 調(diào)用開始 訪問服務(wù)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("==> 調(diào)用結(jié)束 uri:{} 耗時 {} ms", request.getServletPath(), endTime - startTime);}finally {timeThreadLocal.remove();requestIdThreadLocal.remove();}}}對應(yīng)轉(zhuǎn)換類:import ch.qos.logback.classic.pattern.ClassicConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;/***/
public class MyLogBackConverter extends ClassicConverter {@Overridepublic String convert(ILoggingEvent event) {// 獲取你的參數(shù),例如從 MDC 或者其他上下文中
//        String myParam = event.getMDCPropertyMap().get("myParam");String myParam = LogInterceptor.requestIdThreadLocal.get();return myParam != null ? myParam : "TraceID";}
}

對應(yīng)logback:

<configuration><property name="LOG_HOME" value="logs/xxxx-service" /><conversionRule conversionWord="myParam" converterClass="com.xxx.config.MyLogBackConverter" /><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><!-- 只接受INFO級別的日志 --><level>INFO</level></filter><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] [%myParam] %-5level %logger{36} - %msg %n</pattern></encoder></appender><appender name="STDOUT_ERROR" class="ch.qos.logback.core.ConsoleAppender"><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><!-- 只接受INFO級別的日志 --><level>ERROR</level></filter><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] [%myParam] %-5level %logger{36} - %msg %n</pattern></encoder></appender><root level="INFO"><appender-ref ref="STDOUT" /><appender-ref ref="STDOUT_ERROR" /></root></configuration>
http://m.risenshineclean.com/news/32043.html

相關(guān)文章:

  • 想做一個部門的網(wǎng)站怎么做頭條熱點(diǎn)新聞
  • 公司手機(jī)網(wǎng)站模板優(yōu)化大師win10下載
  • 手機(jī)如果做網(wǎng)站市場調(diào)研方案怎么寫
  • 網(wǎng)站開發(fā)工程師社交百度代發(fā)收錄
  • 做局域網(wǎng)網(wǎng)站百度圖片識別搜索引擎
  • szfob外貿(mào)論壇網(wǎng)站重慶seo推廣公司
  • 衡水哪有做網(wǎng)站的網(wǎng)站推廣的概念
  • 做考研政治真題的網(wǎng)站免費(fèi)手機(jī)網(wǎng)站建站系統(tǒng)
  • 各種類型網(wǎng)站建設(shè)售后完善免費(fèi)建站的網(wǎng)站哪個好
  • 2008iis網(wǎng)站建設(shè)找客戶的軟件有哪些
  • 眾籌網(wǎng)站建設(shè)廣告推廣圖片
  • 網(wǎng)站建設(shè)經(jīng)費(fèi)放哪個經(jīng)濟(jì)科目企業(yè)網(wǎng)站seo哪里好
  • 正保建設(shè)工程教育網(wǎng)合肥網(wǎng)絡(luò)優(yōu)化推廣公司
  • 廣州網(wǎng)站建設(shè)開發(fā)公司指數(shù)基金有哪些
  • 廈門企業(yè)網(wǎng)站開發(fā)公司2024年新冠第三波癥狀分析
  • 網(wǎng)頁設(shè)計 效果圖亞馬遜seo推廣
  • c語言做網(wǎng)站后臺服務(wù)百度關(guān)鍵詞排名銷售
  • 學(xué)習(xí)網(wǎng)站開發(fā)寧德市房價
  • 域名備案成功怎么做網(wǎng)站免費(fèi)的網(wǎng)絡(luò)推廣渠道
  • 無錫做網(wǎng)站優(yōu)化價格301313龍虎榜
  • 做網(wǎng)站組織架構(gòu)西安高端模板建站
  • 做網(wǎng)站端口無法清除十大經(jīng)典事件營銷案例分析
  • 頂尖網(wǎng)站設(shè)計東莞百度快照優(yōu)化排名
  • 小魚賺錢網(wǎng)站能重復(fù)做任務(wù)嗎電商網(wǎng)站對比表格
  • 大良營銷網(wǎng)站建設(shè)價位在線看crm系統(tǒng)
  • 房山成都網(wǎng)站建設(shè)肇慶seo按天收費(fèi)
  • 西安國內(nèi)做網(wǎng)站的公司有哪些排行榜前十名
  • html5flash設(shè)計開發(fā)|交互設(shè)計|網(wǎng)站建設(shè) 青島樂天seo培訓(xùn)中心
  • 網(wǎng)絡(luò)營銷策略內(nèi)容廈門seo俱樂部
  • 做網(wǎng)站需要什么技術(shù)搜索關(guān)鍵詞站長工具