rattler
项目简介
每个服务都有属于自身的核心特性。我们将服务的核心特性进行抽象,并使用核心链路这个概念来具象化核心特性。说的更直白一些,核心链路覆盖了核心服务绝大部分功能(超过80%),例如某服务为交易服务,那么下单链路、付款链路、退单链路、退款链路都属于核心链路。
在进行迭代开发的过程中,新增或者修改的代码对核心链路的影响一直都有RD评估后给出,缺乏量化的标准。比如现在对交易服务中的某个公共service做了修改,那么这个service的变动会影响那些核心链路呢?这部分目前没有数据支撑。
rattler是一个侵入式的核心链路信息收集工具,通过CoreChainClass注解以及CoreChainMethod注解来收集服务的链路信息,然后将链路信息上送到指定的服务器,目前仅支持http上送。
代码的变更最后反馈到核心链路的变更,这样就有了一个量化的数据来衡量本次需求对原有核心链路的影响.
需要注意的是:这里核心链路的概念并非指的是多个微服务之间通过HTTP或者RPC组成的调用链路,而是指在单个微服务本身中函数之间的链路调用关系。本工具更加适用于偏底层的核心服务,比如支付的记账管理、搜索引擎的广告检索、金融对账结算等类似场景。
链路信息采集方式对比
目前链路采集方式,目前主要有两种方式:一种手动采集、手动记录,以文本文档的方式存储(xml,yml,xmind,xls),一种为注解方式,现在就主要的收集方式做一下对比:
记录方式 | 优势 | 不足 |
以注解形式内嵌在代码中 |
|
|
文本文档的方式存储(xml,yml,xmind,etc) |
|
|
核心原理
1、 定义CoreChainClass、CoreChainMethod注解,使用注解在服务工程中进行标注(侵入式)
2、 利用Reflections的反射机制,静态扫描指定package的标注类或者标注方法
3、 将扫描得到的核心链路数据上送到指定的服务,目前仅支持HTTP
使用方法
由于rattler进行链路信息采集,所以需要在项目中集成该项目SDK,通过jar包引入。
java包引入
在使用之前需要事先通过pom引入jar文件,可以使用本开源的jar包,也可以自行编译上传到私有maven仓库,示例:
<dependency>
<groupId>com.github.airfer</groupId>
<artifactId>rattler</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
注解引入
注解引入,有两种引入方式。可以通过CoreChainClass注解和CoreChainMethod注解引入。由于目前是侵入式收集,会直接修改代码,所以最好和RD一起来做这个事情。 由于链路收集的收集采用静态扫描方式,所以理论上不会对注入服务造成性能影响。为了避免对线上服务造成潜在影响,可以在线上环境可以关闭链路信息收集以及信息上送服务,如何关闭请参见配置说明部分。
由于CoreChain通过Component引入,所以在注解引入后需要在ComponentScan配置中添加rattler所在的包名,示例如下所示。如果对本项目重新打包并变更包名则可省去扫描包添加的步骤。当前对注解标注的权重信息留在下一期支持
- CoreChainClass注解引入
@CoreChainClass(coreChainName="查询链路",weightEnum=MethodWeightEnum.LOW)
public class QueryService{
/**
* 通过Class方式引入,所有在class中的方法都将被标注相同的链路名称,以及链路权重
*/
}
- CoreChainMethod注解引入
@Serivice
public class QueryService{
/**
* 通过Method方式引入,只有该Method会被标注,其他方法不会被标注
*/
@Autowired
private CommonService commonService;
@CoreChainMethod(coreChainName="查询链路",weightEnum=MethodWeightEnum.LOW)
private String queryOrderNum(){
try{
return commonService.queryOrderInfo();
}catch (RuntimeException re){
log.error("runtime error");
}
}
}
- ComponentScan扫描包添加
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,MongoAutoConfiguration.class,MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})
@ComponentScan(basePackages = {"com.airfer.rattler"})
public class Application {
}
配置文件使用
服务引入jar包,并添加链路注解后,需要添加rattler配置文件。添加方式为在resource目录下新增rattler.properties文件,内容示例如下:
#链路上报开关,true开启,false关闭。在线上环境可以选择关闭【必填】
chain_capture_switch=true
#链路信息的上送接口,采用post方式进行上送【选填】|【链路开关打开必填】
#upload_url=-1 表示不进行上送
upload_url=http://upload.domain.info.com/chain/test
#待扫描的服务package名称,目前不支持多package配置【必填】|【链路开关打开必填】
package_name=com.airfer.rattler.data
#在链路开关开启且后端服务启动后,rattler会按照指定的刷新频率刷新收集,单位秒【选填】|【链路开关打开必填】
# refresh_interval=-1 表示不启动定时刷新
refresh_interval=-1
#server_id唯一标识一个服务,和美团的appkey是同一个概念【选填】|【链路开关打开必填】
server_id=airfer_rattler_test
rattler-func-detection
rattler-func-detetion 是一个基于Git Patch文件的开源代码分析工具(仅限java服务),主要用于函数变动探测,目前支持python2.x以及python3.x版本。通过以下命令:
git diff feature/* master >result.patch
获取patch文件后,解析patch文件,获取变动的函数列表,并将函数列表信息上送到指定服务器,目前仅支持Http协议
主要用途
- 基于git patch文件分析函数变动,进行服务核心链路冲撞率(collision rate)计算,评估影响面大小
- 统计核心链路的变更频率,为服务的重构以及优化提供数据支持
安装方法
通过pip安装
如果不需要对代码进行查看或者二次开发,可以使用pip来进行安装,支持python2.x以及python3.x,命令如下:
pip install rattler-func-detection
通过源码安装
- 下载源代码,使用python setup.py install进行安装
- 使用rattler-func-detection 命令运行,可通过 --help命令查看可选项
命令行信息详解
Usage: rattler-func-detection [OPTIONS]
:param rootPath: 扫描根路径 :param diffFilePath: :return:
Options:
--root_path TEXT 扫描根路径,git clone代码后根目录
--diff_path TEXT git diff文件路径
--server_id TEXT server_id,服务唯一标识
--upload_url TEXT 数据上送地址
--help Show this message and exit.
链路碰撞分析
假设我们现在有两个核心链路A和A1(单个服务内部函数之间的链路调用关系,非微服务之间的调用,A-G、A1-G1皆为函数),两条链路中的所有调用函数都可通过CoreChain类注解进行收集。而需求迭代所造成的代码变动可通过rattler-func-detection进行收集,链路碰撞示意图如下所示:
结果预览
拿到链路数据之后,就可以计算每条链路中有多少函数处于被影响的范围。虽然在进行链路信息标注时设置了权重值,但是目前权重值还没有被应用于计算,预计下期项目提供支持
{
u'data': u'{
"all": "0.36", // 整体冲撞率
"A" : "0.57", // 消费链路冲撞率
"A1" : "0.23" // 开户链路冲撞率
}',
u'resCode': u'00'
}
使用限制
- rattler基于JDK8开发,使用了很多新特性,比如stream,对于基于低于JDK8的服务版本暂不支持
- 目前rattler仅适用于JAVA后端服务,对于非JAVA服务以及前端暂不支持
排期计划
- 方法权重值纳入链路冲撞分析范围 预计2019/11