springboot整合dubbo设置全局唯一ID进行日志追踪的示例代码

网友投稿 391 2022-11-15


springboot整合dubbo设置全局唯一ID进行日志追踪的示例代码

1.新建项目

利用idea创建一个父项目,三个子项目,其中一个项目为生产者,一个项目为消费者,一个为接口等公共服务项目,生产者和消费者需要有web依赖,可以作为tomcat容器启动。

2.项目依赖

org.apache.dubbo

dubbo-spring-boot-starter

2.7.6

org.apache.dubbo

dubbo-dependencies-zookeeper

2.7.6

pom

org.slf4j

slf4j-log4j12

org.springframework.boot

spring-boot-starter-aop

test

org.aspectj

aspectjweaver

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进行日志追踪


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Springmvc返回html页面问题如何解决
下一篇:Mybatis实体类属性与数据库不一致解决方案
相关文章

 发表评论

暂时没有评论,来抢沙发吧~