本文的目标是改进dubbo,在各个dubbo服务之间透传traceId,实现服务跟踪
一、关于RPC
在大型系统中,一个对外http服务的背后往往隐匿了多个内部服务之间的相互调用。因为性能、开发成本层面的考量,http协议并不适合内部服务之间的调用,为此产生了thrift、dubbo 等优秀RPC框架。
thrift 的由facebook 开发,跨语言支持丰富是其最大的亮点,thrift定义了一种接口定于语言,通过自动化工具,生成client 端和server端代码。
dubbo 是由一个由阿里开发的开源分布式服务框架,相对于于thrift,dubbo实现了完善的服务治理功能,包括:服务发现、路由规则、配置规则、服务降级、负载均衡等。
二、关于服务跟踪
在微服务的趋势下,一次调用产生的日志分布在不同的机器上,虽然可以使用ELK的技术,将所有服务的日志灌入es中,但是如何将这写日志“穿起来”是一个关键问题。
一般的做法是在系统的边界生成一个traceId,向调用链上的后继服务传递traceId,后继服务使用traceId 打印相应日志,并再向后继服务传递traceId。简称“traceId透传”。
在使用http协议作为服务协议的系统里,可以统一使用一个封装好的http client做traceId透传。但是dubbo实现traceId透传就稍微复杂些了。
三、dubbo traceId 透传测试
首先抛开实现,看一下实现透传成功的测试case
评价指标:
(1) 调用链上的所有dubbo服务都有一个同样的traceId
(2) 对业务代码无侵入,来的业务代码无需修改升级
(3) 对性能无太大的影响
测试用例:
/**
* 测试Service
* Created by WuMingzhi on 2017/3/19.
*/
public interface GiftService {
int getPrice(int giftId);
}
/**
* provider端
* Created by WuMingzhi on 2017/3/19.
*/
public class GiftServiceImpl implements GiftService{
private static Random random = new Random();
@Override
public int getPrice(int i) {
System.out.println("gift provider traceId:" + TraceIdUtil.getTraceId());
int price = random.nextInt(i + 100);
System.out.println("set gift price: " + price);
return price;
}
}
/**
* consumer 端
* Created by WuMingzhi on 2017/3/19.
*/
public