👉 這是一個或許對你有用的社群
《專案實戰(影片)》:從書中學,往事上“練” 《網際網路高頻面試題》:面朝簡歷學習,春暖花開 《架構 x 系統設計》:摧枯拉朽,掌控面試高頻場景題 《精進 Java 學習指南》:系統學習,網際網路主流技術棧 《必讀 Java 原始碼專欄》:知其然,知其所以然

👉這是一個或許對你有用的開源專案國產 Star 破 10w+ 的開源專案,前端包括管理後臺 + 微信小程式,後端支援單體和微服務架構。功能涵蓋 RBAC 許可權、SaaS 多租戶、資料許可權、商城、支付、工作流、大屏報表、微信公眾號、ERP、CRM、AI 大模型等等功能:
Boot 多模組架構:https://gitee.com/zhijiantianya/ruoyi-vue-pro Cloud 微服務架構:https://gitee.com/zhijiantianya/yudao-cloud 影片教程:https://doc.iocoder.cn 【國內首批】支援 JDK 17/21 + SpringBoot 3.3、JDK 8/11 + Spring Boot 2.7 雙版本

背景
基於 Spring Boot + MyBatis Plus + Vue & Element 實現的後臺管理系統 + 使用者小程式,支援 RBAC 動態許可權、多租戶、資料許可權、工作流、三方登入、支付、簡訊、商城等功能
專案地址:https://github.com/YunaiV/ruoyi-vue-pro 影片教程:https://doc.iocoder.cn/video/
方案
一、Rest模組
LogEventPatternConvert
來做,比較簡單:
[%d{yyyy-MM-dd HH:mm:ss.SSS}][%t][%level][%C:%L][%traceId] %m%n
TraceMessage
@Getter
@Setter
publicclassTraceMessageextendsParameterizedMessage
{
private
String traceId;
publicTraceMessage(String traceId, String spanId, String messagePattern, Object... arguments)
{
super
(messagePattern, arguments);
this
.traceId = traceId;
}
}
TraceMessageFactory
繼承Log4j的MessageFactory
工廠類,重寫newMessage
方法publicclassTraceMessageFactoryextendsAbstractMessageFactory
{
publicTraceMessageFactory()
{
}
@Override
public Message newMessage(String message, Object... params)
{
//..這裡透過你的方式獲取從上游傳過來的那個traceId引數, 生成一個自定義的TraceMessage
String traceId =
"..."
returnnew
TraceMessage(traceId, message, params);
}
@Override
public Message newMessage(CharSequence message)
{
return
newMessage(message);
}
@Override
public Message newMessage(Object message)
{
returnsuper
.newMessage(message);
}
@Override
public Message newMessage(String message)
{
return
newMessage(message,
null
);
}
}
Convert
外掛就可以了@Plugin
(name =
"TraceIdPatternConverter"
, category = PatternConverter.CATEGORY)
@ConverterKeys
({
"traceId"
})
publicclassTraceIdPatternConverterextendsLogEventPatternConverter
{
privateTraceIdPatternConverter(String name, String style)
{
super
(name, style);
}
publicstatic TraceIdPatternConverter newInstance()
{
returnnew
TraceIdPatternConverter(
"TraceIdPatternConverter"
,
"TraceIdPatternConverter"
);
}
@Override
publicvoidformat(LogEvent event, StringBuilder toAppendTo)
{
Message message = event.getMessage();
if
(message
instanceof
TraceMessage) {
TraceMessage traceMessage = (TraceMessage) message;
toAppendTo.append(
"["
+ ObjectUtil.defaultIfBlank(traceMessage.getTraceId(),
""
) +
"]"
)
return
;
}
toAppendTo.append(
"~"
);
}
}
二、MQ模組
@Slf
4j
@Aspect
@Component
publicclassLogRocketMQAspect
{
@Pointcut
(
"execution(* org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently.consumeMessage(..))"
)
publicvoidpointCut()
{
}
@Around
(
"pointCut()"
)
public Object injectTraceId(ProceedingJoinPoint proceedingJoinPoint)throws Throwable
{
try
{
if
(proceedingJoinPoint.getSignature().getName().equals(
"consumeMessage"
)) {
List<MessageExt> messageExtList = (List<MessageExt>) proceedingJoinPoint.getArgs()[
0
];
String messageId = messageExtList.stream().map(MessageExt::getMsgId).collect(Collectors.joining(
"-"
));
MDC.put(
"msgId"
, messageId);
}
return
proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
}
finally
{
MDC.clear();
}
}
}
@Plugin
(name =
"TraceIdPatternConverter"
, category = PatternConverter.CATEGORY)
@ConverterKeys
({
"traceId"
})
publicclassTraceIdPatternConverterextendsLogEventPatternConverter
{
privateTraceIdPatternConverter(String name, String style)
{
super
(name, style);
}
publicstatic TraceIdPatternConverter newInstance()
{
returnnew
TraceIdPatternConverter(
"TraceIdPatternConverter"
,
"TraceIdPatternConverter"
);
}
@Override
publicvoidformat(LogEvent event, StringBuilder toAppendTo)
{
Message message = event.getMessage();
if
(message
instanceof
TraceMessage) {
TraceMessage traceMessage = (TraceMessage) message;
toAppendTo.append(StringUtils.isBlank(msgId) ?
"["
+ ObjectUtil.defaultIfBlank(traceMessage.getTraceId(),
""
) +
"]"
:
"["
+ msgId +
"]"
)
return
;
}
toAppendTo.append(
"~"
);
}
}
三、RPC模組
RCPContext
的attachment
裡@Activate
(order =
99
, group = {Constants.PROVIDER_PROTOCOL, Constants.CONSUMER_PROTOCOL})
publicclassLogAttachmentFilterimplementsFilter
{
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation)throws RpcException
{
RpcContext context = RpcContext.getContext();
if
(context.isConsumerSide()) {
//這裡是從上游獲取的已經設定好的traceId,透過你的方式拿到
String traceId =
"..."
;
if
(StringUtils.isBlank(traceId)) {
traceId = UuidUtils.getUuid();
}
context.setAttachment(
"traceId"
, traceId);
}
elseif
(context.isProviderSide()) {
//此處透過LogContext或者MDC都可設定traceId
LogContext.setTraceId(context.getAttachment(
"traceId"
));
}
return
invoker.invoke(invocation);
}
}
基於 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實現的後臺管理系統 + 使用者小程式,支援 RBAC 動態許可權、多租戶、資料許可權、工作流、三方登入、支付、簡訊、商城等功能
專案地址:https://github.com/YunaiV/yudao-cloud 影片教程:https://doc.iocoder.cn/video/
結尾





