1.新建專案

利用idea創建一個父專案,三個子專案,其中一個專案為生產者,一個專案為消費者,一個為介面等公共服務專案,生產者和消費者需要有web依賴,可以作為tomcat容器啟動,
2.專案依賴
<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專案中新建介面

4.撰寫生產者
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 撰寫生產者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
這里代碼的目的是將從消費端傳來的執行緒名稱設定為執行緒名稱
在resources目錄下新建META-INF/dubbo/com.alibaba.dubbo.rpc.Filter 檔案
即新增目錄META-INF/dubbo和檔案 com.alibaba.dubbo.rpc.Filter
在檔案中增加,等號后面為實作dubbo filter的實作類路徑
providerFilter=com.dubbo.spring.provider.filter.ProviderFilter
4.3撰寫dubbo生產者實作類
@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.撰寫消費者
5.1撰寫消費者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,后續使用dubbo請求生產者時,會把attachment給到生產者,故在生產中中可以通過key ThreadName來獲取消費者端的執行緒名稱
在resources目錄下新建META-INF/dubbo/com.alibaba.dubbo.rpc.Filter 檔案
即新增目錄META-INF/dubbo和檔案 com.alibaba.dubbo.rpc.Filter
在檔案中增加,等號后面為實作dubbo filter的實作類路徑
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端回傳到頁面統一物件
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是在請求進入時給執行緒設定名稱,為隨機生成的uuid
2.around是環繞通知,在執行完之后,在回傳的結果中將執行緒名稱設定進去,便于以后例外追蹤
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;
}
}
請求結果

此處為postman回應的,index 為1ca55cb7a17148879923265b89102ccf
生產者執行緒名稱:

消費者執行緒名稱:

可以看到從web頁面到生產者,消費者,都有一個全域唯一id進行貫穿,如果在web頁面提示有例外時,可以通過這個uuid進行日志追蹤
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/193486.html
標籤:其他
上一篇:其實你也可以使用SpringBoot自定義starter
下一篇:【演算法-Java實作】組合總和
