-
Notifications
You must be signed in to change notification settings - Fork 337
Outbound请求匹配
hueng edited this page Apr 29, 2020
·
2 revisions
Mock Server有个非常重要的工作,就是匹配Outbound请求,这直接决定着回放的精确度和成功率。
理论上来说,一个程序执行的过程中时间顺序是确定的,通过录制的时序就可以做回放。但是在现实的场景中,这种实现非常脆弱且不满足需求。因为大部分重构都需要调整调用顺序,如果回放完全基于调用顺序,则无法满足重构的功能回归的需求。
为此,Mock Server使用类似全文检索的模式,通过 分词+打分,实现如下匹配算法:
- n-gram 分词:n 取值是 16 个 byte
- 按 phrase 模式进行分词后的匹配打分
- 分词后的首个 chunk 进行加权匹配,因为 http 头部的 url 最有区分度
- 首个 chunk 要求是连续16个 readable bytes,过滤掉了二进制内容。主要是匹配 thrift 请求过滤到 size 的差异引起的问题
- 优先按顺序向后搜索(阈值 0.85),如果第一轮匹配不上则回到头部从头搜索(阈值0.1)
下面简化下匹配算法核心步骤:
a) 匹配当前请求时,若上一次匹配成功,则从上一次匹配成功的请求(lastMatchedIndex)的下一个请求开始匹配,否则就从第一个请求开始匹配;
b) 将请求切分成长度为16字节的数组,依次取16字节与所有Outbound请求进行匹配,若请求里包含该16字节数组,则权重加1;
c) 判断权重最高的Outbound请求是否达标(权重是否超过阈值)。达标则匹配成功,否则匹配失败。
在实践过程中,发现 对于相似Outbound请求比较多的流量,匹配重复率较高。因为当中间一个请求匹配失败后,后面所有的请求都会重头开始匹配。最终导致多个线下请求匹配同一个线上请求,进而导致剩余的线上请求报missing错误。
因此,基于上面的匹配算法,增如下两点优化:
- 新增一个全局游标MaxMatchedIndex,记录当前已匹配请求的最大下标,当新请求到来时,优先从该游标之后的线上请求选择匹配:如果游标前后同时出现权重最高的线上请求,则选择游标之后的线上请求作为算法的匹配结果。
- 新增一个降权系数,当线上请求已被之前的请求匹配过之后,在本次请求的匹配过程中,它的匹配权重会降低为:权重*降权系数。
在实际使用过程中,降权系数选择为90%时,匹配效果非常好,成功率相当高。