背景

公司目前的服务设计大部分满足 design for failure 理念。随着业务复杂度的提升,我们很难再保证对系统故障的容错性。我们需要工具来验证服务的容错性,基于这个需求我们使用了 tc 工具,并开发了chaosmonkey工具。本文主要围绕这两个工具进行讲述。

TC流控

基本概念

Netem 是 Linux 2.6 及以上内核版本提供的一个网络模拟功能模块。该功能模块可以模拟出局域网诸如低带宽、传输延迟、丢包、乱序、重复等情况。

基本原理

包从进入tc开始,分为多个qd(qdisc)。每个qd可以包含多个子qd,qd彼此连接形成一颗树。每个qd上可以附加filter,选择进入哪个child。流量控制控发不控收。

基本操作

# 网络延迟
# sudo tc qdisc add dev eth0 root netem delay 100ms
# 网络丢包
# sudo tc qdisc add dev eth0 root netem loss 1%
# 基于filter
# 192.168.33.1被延迟,其他地址无效果
# sudo tc qdisc add dev eth0 root handle 1: prio
# sudo tc qdisc add dev eth0 parent 1:1 handle 10: netem delay 1s loss 2%
# sudo tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dst 192.168.33.1 flowid 1:1
# 删除规则
# sudo tc qdisc del dev eth0 root

缺点

tc 工具在配置时比较繁琐,不能模拟一段时间内的故障,不能作为一个服务定期演练。自己开发的chaosmonkey可以满足以上条件。

chaosmonkey

功能

chaosmonkey基于golang开发,它包含三个功能:网络故障模拟、服务重定向、资源限制。如图。

网络故障模拟

用户向服务发送http请求,服务解析参数,模拟丢包、延迟,其中主要使用的package是 netlink 。部分代码如下:

// 用户提交的参数
type addNetwork struct {
Duration uint32
Limit *network.LinkLimit
}
type LinkLimit struct {
Latency uint32
Jitter uint32
Loss float32
Corruption float32
} //设置丢包、延迟
func (l *Link) AddLimit(limit LinkLimit) error {
netemQdiscAttrs := netlink.NetemQdiscAttrs{
Latency: limit.Latency,
Jitter: limit.Jitter,
Loss: limit.Loss,
CorruptProb: limit.Corruption,
}
qdiscAttrs := netlink.QdiscAttrs{
Parent: netlink.HANDLE_ROOT,
LinkIndex: l.Attrs().Index,
}
netem := netlink.NewNetem(qdiscAttrs, netemQdiscAttrs)
if err := netlink.QdiscAdd(netem); err != nil {
return fmt.Errorf("qdisc add %v: %v", netem, err)
}
log.Infof("AddLimit finish with %v", netem)
return nil
}

服务重定向

服务主要使用exec包执行iptables命令,部分代码如下:

// 用户提交的参数
type startRedirect struct {
Duration uint32
Redirectors []redirector.Redirector
Name string
}
type Redirector struct {
Protocol string `json:"protocol"`
Destination string `json:"destination"`
Dport string `json:"dport"`
Target string `json:"target"`
} //增加iptables规则
for _, r := range redirectors {
if err := ipt.Append("nat", "OUTPUT", "-p", r.Protocol, "-d", r.Destination, "--dport", r.Dport, "-j", "DNAT", "--to", r.Target); err != nil {
return fmt.Errorf("append tables %v: %v", r, err)
}
log.Infof("append iptables rule finish: %v", r)
...
} func (ipt *IPtables) Append(table string, chain string, rulespec ...string) error {
cmd := append([]string{"-t", table, "-A", chain}, rulespec...)
return ipt.run(cmd...)
} func (ipt *IPtables) runWithOutput(args []string, stdout io.Writer) error {
args = append([]string{ipt.path}, args...)
var stderr bytes.Buffer
cmd := exec.Cmd{
Path: ipt.path,
Args: args,
Stdout: stdout,
Stderr: &stderr,
}
err := cmd.Run()
if err != nil {
return &Error{*(err.(*exec.ExitError)), stderr.String()}
}
return nil
}

资源限制

主要使用的packge是 fs 和 configs 。代码如下:

type addResources struct {
Pids []int
Pattern string
Duration uint32
Limit resources.Limit
}
type Limit struct {
Cpu int64
Memory int64
BlkioReadBPS uint64 `json:"blkio_read_bps"`
BlkioReadIOPS uint64 `json:"blkio_read_iops"`
BlkioWriteBPS uint64 `json:"blkio_write_bps"`
BlkioWriteIOPS uint64 `json:"blkio_write_iops"`
} // 设置cgroup
config := limit.toConfig()
monkey, err := factory.CreateManager(config)
...
for _, pid := range pids {
if manager, err := factory.GetManager(pid); err != nil {
return fmt.Errorf("get manager for pid %d: %v", pid, err)
} else {
p := &process{manager: manager, pid: pid, monkey: monkey, wait: r.wait}
if err := p.start(duration); err != nil {
return fmt.Errorf("process apply monkey: %v", err)
} else {
r.processes = append(r.processes, p)
}
}
} if err := monkey.Set(config); err != nil {
return fmt.Errorf("set monkey config: %v", err)
} else {
log.Infof("set monkey %v for pids %v", limit, pids)
}

参考文档

linux高级流控 netlink cgroups

003_饿了么chaosmonkey实现的更多相关文章

  1. 解析ListView联动的实现--仿饿了么点餐界面

    一.博客的由来 大神王丰蛋哥 之前一篇博客仿饿了点餐界面2个ListView联动(http://www.cnblogs.com/wangfengdange/p/5886064.html) 主要实现了2 ...

  2. IOS-小项目(饿了么 网络部分 简单实现)

    在介绍小项目之前,在此说明一下此代码并非本人所写,我只是随笔的整理者. 在介绍之前先展现一下效果图. 看过效果图大家应该很熟悉了,就是饿了么的一个界面而已,值得注意的是,实现时并没有采用本地连接,而是 ...

  3. 饿了么基于Vue2.0的通用组件开发之路(分享会记录)

    Element:一套通用组件库的开发之路 Element 是由饿了么UED设计.饿了么大前端开发的一套基于 Vue 2.0 的桌面端组件库.今天我们要分享的就是开发 Element 的一些心得. 官网 ...

  4. 用vue2 +vue-router2 + es6 +webpack 高仿饿了么app(干货满满)

    #高仿饿了么app商家详情 (vue2 +vue-router2 + es6 +webpack )   ##demo [demo 地址](http://liangxiaojuan.github.io/ ...

  5. java中的单例模式(懒汉式+饿汉式)

    什么是单例模式: 单例模式既只能在自己本类中创建有且唯一的一个实例(姑且不考虑映射的情况)通过方法将该实例对外公开 第一种:单例模式-懒汉式 既调用getInstance()方法返回实例之前判断有没有 ...

  6. 仿饿了点餐界面2个ListView联动

    如图是效果图 是仿饿了的点餐界面 1.点击左侧的ListView,通过在在适配器中设置Item来改变颜色,再通过notifyDataSetInvalidated来刷新并用lv_home.setSele ...

  7. C++的单例模式与线程安全单例模式(懒汉/饿汉)

    1 教科书里的单例模式 我们都很清楚一个简单的单例模式该怎样去实现:构造函数声明为private或protect防止被外部函数实例化,内部保存一个private static的类指针保存唯一的实例,实 ...

  8. 这交互炸了:饿了么是怎么让Image变成详情页的

    这交互炸了:饿了么是怎么让Image变成详情页的 晚上叫外卖,打开饿了么,发现推了一个版本,更新以后,点开了个鸡腿,哇,交互炫炸了. 本文同步自wing的地方酒馆 不过还是有槽点.我是无意中才发现可以 ...

  9. (转)Singleton 单例模式(懒汉方式和饿汉方式)

    原文地址:http://www.cnblogs.com/kkgreen/archive/2011/09/05/2166868.html 单例模式的概念: 单例模式的意思就是只有一个实例.单例模式确保某 ...

随机推荐

  1. bash执行命令分别输出正常日志和错误日志

    0. 说明 执行bash命令的定时任务时候,希望能把正常的日志输出到一个文件里面,同时如果执行的过程发生异常则把异常日志输出到另一个不同的文件中.方便今后异常排查,极大有利于快速定位出错位置. 需要了 ...

  2. A1061. Dating

    Sherlock Holmes received a note with some strange strings: "Let's date! 3485djDkxh4hhGE 2984akD ...

  3. C++中const关键字的使用方法,烦透了一遍一遍的搜,总结一下,加深印象!!!

    之前一直在学习C/C++,关于const的使用,这里出现一点,那里出现一点.知识用时方恨少,这一段时间正好各种笔试题,其中关于const的用法也是层出不穷,所以疲于在书本上各种翻,这里汇总一下,加深自 ...

  4. STM32 CAN

    STM32普通型芯片的 CAN 有14组过滤器组(互联型有28组过滤器组) ,用以对接收到的帧进行过滤.每组过滤器包括了2个可配置的32位寄存器:CAN_FxR0和 CAN_FxR1.对于过滤器组, ...

  5. P4891 序列

    P4891 序列 题目描述 给定两个长度为 n 的序列 A 和 B,定义序列 \(C_i=\max\limits_{j=1}^i A_j\) 定义当前的价值是 $\prod\limits_{i=1}^ ...

  6. HDFS集群PB级数据迁移方案-DistCp生产环境实操篇

    HDFS集群PB级数据迁移方案-DistCp生产环境实操篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 用了接近2个星期的时间,终于把公司的需要的大数据组建部署完毕了,当然,在部 ...

  7. xen 配置vm 跟随xen server一起启动

    查看Xen Server 信息 (1)查看pool信息 [root@xenserver-243 ~]# xe pool-list uuid ( RO) : e29037aa-0dca-f95a-193 ...

  8. golang数组排序算法

    冒泡排序 图 https://www.cnblogs.com/onepixel/articles/7674659.html package main import ( "fmt" ...

  9. golang锁

    golang锁包:https://studygolang.com/pkgdoc sync.Mutex是一个互斥锁 var lock sync.Mutex 加锁段在中 lock.lock() lock. ...

  10. Java之Jacob调用COM接口DLL-----------------------------------dm。dll

    用Java控制windows了,嗯,低层次按键模拟,可控制游戏,内存也不在话下. 一.环境介绍 1.myeclipse8.5 2.著名按键插件dm.dll  32bit.此插件实现COM接口,百度百科 ...