springboot整合dubbo設(shè)置全局唯一ID進(jìn)行日志追蹤的示例代碼
1.新建項(xiàng)目
利用idea創(chuàng)建一個(gè)父項(xiàng)目,三個(gè)子項(xiàng)目,其中一個(gè)項(xiàng)目為生產(chǎn)者,一個(gè)項(xiàng)目為消費(fèi)者,一個(gè)為接口等公共服務(wù)項(xiàng)目,生產(chǎn)者和消費(fèi)者需要有web依賴,可以作為tomcat容器啟動。
2.項(xiàng)目依賴
<dependencies> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.6</version> </dependency> <!-- zk的依賴 --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-dependencies-zookeeper</artifactId> <version>2.7.6</version> <type>pom</type> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> </dependency>
3.在facade項(xiàng)目中新建接口
4.編寫生產(chǎn)者
4.1 增加dubbo配置
server.port=8081 dubbo.registry.address=zookeeper://localhost:2181 dubbo.protocol.name=dubbo dubbo.protocol.port=20880 dubbo.registry.timeout=30000 dubbo.application.name=dubbo-provider-ll
4.2 編寫生產(chǎn)者dubbo filter
public class ProviderFilter implements Filter { @Override public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { Object threadName= invocation.getAttachment("ThreadName"); if(null!=threadName){ Thread thread = Thread.currentThread(); thread.setName(threadName.toString()); } return invoker.invoke(invocation); } }
注意:此處Filter 是dubbo的filter,不是servlet的filter
這里代碼的目的是將從消費(fèi)端傳來的線程名稱設(shè)置為線程名稱
在resources目錄下新建META-INF/dubbo/com.alibaba.dubbo.rpc.Filter 文件
即新增目錄META-INF/dubbo和文件 com.alibaba.dubbo.rpc.Filter
在文件中增加,等號后面為實(shí)現(xiàn)dubbo filter的實(shí)現(xiàn)類路徑
providerFilter=com.dubbo.spring.provider.filter.ProviderFilter
4.3編寫dubbo生產(chǎn)者實(shí)現(xiàn)類
@Service(filter = {"providerFilter"}) public class DemoServiceImpl implements IDemoService { public Logger LOGGER= LoggerFactory.getLogger(DemoServiceImpl.class); @Override public String getName() { LOGGER.info("provider ThreadName : "+Thread.currentThread().getName()); return "dubbo-test"; } }
5.編寫消費(fèi)者
5.1編寫消費(fèi)者filter
public class DubboFilter implements Filter { @Override public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { String name = Thread.currentThread().getName(); invocation.setAttachment("ThreadName",name); return invoker.invoke(invocation); } }
此處是將線程名稱放入到attachment中,attachment底層是hashmap,后續(xù)使用dubbo請求生產(chǎn)者時(shí),會把a(bǔ)ttachment給到生產(chǎn)者,故在生產(chǎn)中中可以通過key ThreadName來獲取消費(fèi)者端的線程名稱
在resources目錄下新建META-INF/dubbo/com.alibaba.dubbo.rpc.Filter 文件
即新增目錄META-INF/dubbo和文件 com.alibaba.dubbo.rpc.Filter
在文件中增加,等號后面為實(shí)現(xiàn)dubbo filter的實(shí)現(xiàn)類路徑
consumerFilter=com.dubbo.spring.consumer.filter.DubboFilter
5.2 編寫response對象
public class Response implements Serializable { private static final long serialVersionUID = -3186818832535757509L; private String code; private String message; private Object result; private String index; public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public Object getResult() { return result; } public void setResult(Object result) { this.result = result; } public String getIndex() { return index; } public void setIndex(String index) { this.index = index; } }
此response為web端返回到頁面統(tǒng)一對象
5.3 編寫aop切面
@Aspect @Component public class AopContext { @Before("execution(* com.dubbo.spring..*.*(..))") public void before(){ Thread thread = Thread.currentThread(); thread.setName(UUIDUtil.getUUID()); } @Around("execution(* com.dubbo.spring..*.*(..))") public Object around(ProceedingJoinPoint pjp){ Response response=new Response(); try { Object proceed = pjp.proceed(); if(proceed instanceof Response){ response=(Response) proceed; response.setIndex(Thread.currentThread().getName()); } } catch (Throwable throwable) { throwable.printStackTrace(); } return response; } }
1.before是在請求進(jìn)入時(shí)給線程設(shè)置名稱,為隨機(jī)生成的uuid
2.around是環(huán)繞通知,在執(zhí)行完之后,在返回的結(jié)果中將線程名稱設(shè)置進(jìn)去,便于以后異常追蹤
5.4 編寫web
@RestController public class WebController { private Logger LOGGER= LoggerFactory.getLogger(WebController.class); @Reference(filter = {"consumerFilter"}) private IDemoService iDemoService; @GetMapping("/getName") public Response getName(){ LOGGER.info("consumer ThreadName : "+Thread.currentThread().getName()); String name = iDemoService.getName(); Response response=new Response(); response.setResult(name); response.setCode("1001"); response.setMessage("success"); return response; } }
請求結(jié)果
此處為postman響應(yīng)的,index 為1ca55cb7a17148879923265b89102ccf
生產(chǎn)者線程名稱:
消費(fèi)者線程名稱:
可以看到從web頁面到生產(chǎn)者,消費(fèi)者,都有一個(gè)全局唯一id進(jìn)行貫穿,如果在web頁面提示有異常時(shí),可以通過這個(gè)uuid進(jìn)行日志追蹤
到此這篇關(guān)于springboot整合dubbo設(shè)置全局唯一ID進(jìn)行日志追蹤的文章就介紹到這了,更多相關(guān)springboot整合dubbo內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java時(shí)間戳與日期相互轉(zhuǎn)換工具詳解
這篇文章主要為大家詳細(xì)介紹了java各種時(shí)間戳與日期之間相互轉(zhuǎn)換的工具,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12springboot中如何實(shí)現(xiàn)kafa指定offset消費(fèi)
這篇文章主要介紹了springboot中如何實(shí)現(xiàn)kafa指定offset消費(fèi),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12SpringBoot如何實(shí)現(xiàn)starter原理詳解
這篇文章主要介紹了SpringBoot如何實(shí)現(xiàn)starter原理詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06SpringBoot實(shí)現(xiàn)防止XSS攻擊的示例詳解
這篇文章主要為大家詳細(xì)介紹了SpringBoot如何實(shí)現(xiàn)防止XSS攻擊,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03java實(shí)現(xiàn)的n*n矩陣求值及求逆矩陣算法示例
這篇文章主要介紹了java實(shí)現(xiàn)的n*n矩陣求值及求逆矩陣算法,結(jié)合具體實(shí)例形式分析了java基于數(shù)組的矩陣定義、遍歷、運(yùn)算等相關(guān)操作技巧,需要的朋友可以參考下2017-09-09idea中導(dǎo)入別人的springboot項(xiàng)目的方法(圖文)
這篇文章主要介紹了idea中導(dǎo)入別人的springboot項(xiàng)目的方法(圖文),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09Spring JdbcTemplate實(shí)現(xiàn)添加與查詢方法詳解
JdbcTemplate是Spring框架自帶的對JDBC操作的封裝,目的是提供統(tǒng)一的模板方法使對數(shù)據(jù)庫的操作更加方便、友好,效率也不錯(cuò),這篇文章主要介紹了Spring?JdbcTemplate執(zhí)行數(shù)據(jù)庫操作,需要的朋友可以參考下2022-11-11Spring中的Schedule動態(tài)添加修改定時(shí)任務(wù)詳解
這篇文章主要介紹了Spring中的Schedule動態(tài)添加修改定時(shí)任務(wù)詳解,可能有人會問,為啥不用Quartz,Quartz自然是非常方便強(qiáng)大的,但不是本篇要講的內(nèi)容,本篇就偏要使用SpringSchedule來實(shí)現(xiàn)動態(tài)的cron表達(dá)式任務(wù),需要的朋友可以參考下2023-11-11