正文
借助流量复制分发服务进行功能和系统级别的测试,以达到:
故障演练
如果要演练故障,首先要模拟故障(我们不可能真跑去机房把服务器炸了)。自动化的故障模拟系统业界已有实践,如Netflix的SimianAmy,阿里的MonkeyKing等。
美团点评内部也有类似的工具,casekiller等等。
SimianAmy和casekiller设计思路相仿,都是通过Linux的一些“tc”、“iptables”等工具,模拟制造网络延时、中断等故障。这些工具都是需要root权限才可以执行。美团点评的服务器都需要使用非root用户来启动进程,所以这种思路暂不可行。
这些工具都有一定要求,比如root权限,比如需要用Hystrix来包装一下外部依赖。比如我想制造一个表的慢查询、想制造Redis的某个操作网络异常,就有些麻烦。
所以我们准备自己造个轮子 :)
需求:业务方低成本接入,流量以最低成本进行故障的“制造”和“恢复”,无需发布、对代码无侵入就可以在后台界面上进行故障的场景配置、开启与停止。
基于以上,我们开发了故障演练系统。它是一个可以针对集群级别(AppKey级别)的所有机器,随意启停“故障”的故障演练平台。可以在无需root权限的前提下,构造任意method级别的延时或者异常类故障。
我们的设计思路是:
-
复制线上流量到影子集群。
-
通过对同样配置影子集群的压测,获得系统抗压极值。
-
制造针对外部接口/DB/Cache/MQ等方面的故障,在影子集群上测试降级方案、进行演练。
流量复制系统
架构设计中参考了
DubboCopy
的系统设计,增加了一个SDK,解除了对TCPCopy的依赖。
形成以下的流程:
① 需要压测方先依赖我们的SDK包,在需要压测的具体实现方法上打上注解@Copy,并注明采样率simplingRate(默认采样率为100%)。
@Copy(attribute = CopyMethodAttribute.READ_METHOD, simplingRate = 1.0f)
public Result toCopiedMethod() {
}
② 正式流量来时,异步将流量发往copy-server。
③ copy-server根据流量中的信息(interface、method、serverAppKey)来获取压测配置(影子集群的AppKey,需要放大几倍)。
④ 根据压测配置,对影子集群按照放大倍数开始发包。
协议分析
Thrift原生协议情况下,如果你没有IDL(或者注解式的定义),你根本无法知道这条消息的长度是多少,自然做不到在没有IDL的情况下,对报文进行解析转发。感谢基础组件同学做的统一协议方面的努力,让ThriftCopy这个事情有了可行性 :)
除了公网RPC接口使用HTTP协议以外,美团点评内部RPC协议都统一为一种兼容原生Thrift协议的“统一协议”。
total length指定其后消息的总长度,包含2B的header length+消息头的长度+消息体的长度+可能的4B的校验码的长度。header length指定其后消息头的长度。
header里的内容有
TraceInfo
和RequestInfo等信息,里面有clientAppKey、interfaceName、methodName等我们需要的信息。
client功能
应用启动时
-
客户端启动时,首先获取copyServer的IP list(异步起定时任务不断刷新这些IP列表)。
-
建立相应的连接池。
-
初始化对@Copy做切面的AOP类。
RPC请求到来时
-
命中切面,先同步处理业务逻辑。
-
异步处理下面的逻辑:
以上,便可进行流量的复制与分发,在服务设计上,Client端尽量做到轻量高效,对接入方的影响最小,接入成本低,并且在整个流量复制的过程中安全可控。另外,在Client,当前针对美团点评使用的Thrift协议,进行: