
GoReportCard
Chaos Monkey 随机终止生产环境中运行的虚拟机实例和容器。通过让工程师更频繁地面对故障,激励他们构建更具弹性的服务。
# 获取 Chaos Monkey 二进制文件
go get github.com/netflix/chaosmonkey/cmd/chaosmonkeyChaos Monkey 会在以下路径查找 chaosmonkey.toml 配置文件:
./apps/chaosmonkey/etc/etc/chaosmonkey详细部署和配置说明请参考官方文档。
# 查看版本
chaosmonkey --version
# 安装 Chaos Monkey(设置 cron、应用数据库迁移)
chaosmonkey install
# 生成终止调度计划
chaosmonkey schedule
# 手动终止指定组中的实例
chaosmonkey terminate --app=myapp --account=prod --region=us-east-1
# 从 API 获取并安装调度计划
chaosmonkey fetch-schedule
# 检查是否有正在进行的故障
chaosmonkey outage
# 查看可终止的实例列表(测试用)
chaosmonkey eligible --app=myapp --account=prod
# 应用数据库迁移
chaosmonkey migrate
# 导出应用配置
chaosmonkey config --app=myapp
# 导出 Chaos Monkey 全局配置
chaosmonkey config# chaosmonkey.toml 配置示例
[chaos]
enabled = true
leashed = false # true 表示模拟终止,false 表示实际终止
accounts = ["prod", "staging"]
start_hour = 9 # 开始时间(本地时间)
end_hour = 17 # 结束时间(本地时间)
location = "America/Los_Angeles" # 时区
max_apps = 50 # 单次调度最大应用数通过 Spinnaker 为每个应用配置 Chaos Monkey:
{
"name": "myapp",
"attributes": {
"chaosMonkey": {
"enabled": true,
"meanTimeBetweenKillsInWorkDays": 5,
"minTimeBetweenKillsInWorkDays": 1,
"grouping": "cluster",
"regionsAreIndependent": false,
"exceptions": [
{
"account": "prod",
"stack": "*",
"cluster": "*",
"region": "us-west-2"
}
]
}
}
}// main.go - Chaos Monkey 主入口
package main
import (
"github.com/Netflix/chaosmonkey/v2/command"
// 匿名导入以注册相关模块
_ "github.com/Netflix/chaosmonkey/v2/constrainer"
_ "github.com/Netflix/chaosmonkey/v2/decryptor"
_ "github.com/Netflix/chaosmonkey/v2/env"
_ "github.com/Netflix/chaosmonkey/v2/errorcounter"
_ "github.com/Netflix/chaosmonkey/v2/outage"
_ "github.com/Netflix/chaosmonkey/v2/tracker"
)
func main() {
command.Execute()
}// schedule.go - 生成每日终止调度计划
func do(d deploy.Deployment, g chaosmonkey.AppConfigGetter,
ss schedstore.SchedStore, cfg *config.Monkey,
cons schedule.Constrainer, apps []string) error {
// 创建新的调度计划
s := schedule.New()
// 填充应用实例
err := s.Populate(d, g, cfg, apps)
if err != nil {
return fmt.Errorf("failed to populate schedule: %v", err)
}
// 应用约束条件过滤
sched := cons.Filter(*s)
// 部署调度计划到 API 和本地 cron
err = deploySchedule(&sched, ss, cfg)
if err != nil {
return fmt.Errorf("failed to deploy schedule: %v", err)
}
return nil
}// term.go - 核心终止逻辑
func Terminate(d deps.Deps, app string, account string,
region string, stack string, cluster string) error {
// 检查 Chaos Monkey 是否启用
enabled, err := d.MonkeyCfg.Enabled()
if !enabled {
log.Println("not terminating: enabled=false")
return nil
}
// 检查是否有故障正在进行
problem, err := d.Ou.Outage()
if err != nil {
return errors.Wrap(err, "could not check for outage")
}
if problem {
log.Println("not terminating: currently in an outage")
return nil
}
// 获取符合条件的实例列表
group := grp.New(app, account, region, stack, cluster)
instances, err := eligible.Instances(group, cfg.Exceptions, d.Dep)
if err != nil {
return err
}
// 随机选择一个实例并终止
selected := instances[rand.Intn(len(instances))]
termination := chaosmonkey.Termination{
Instance: selected,
Time: time.Now(),
}
return d.T.Execute(termination)
}// spinnaker.go - 从 Spinnaker API 获取应用配置
func (s Spinnaker) Get(app string) (*chaosmonkey.AppConfig, error) {
url := s.appURL(app) + "?expand=false"
resp, err := s.client.Get(url)
if err != nil {
return nil, errors.Wrapf(err, "http get failed at %s", url)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, errors.Errorf("unexpected response code (%d)", resp.StatusCode)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, errors.Wrapf(err, "body read failed")
}
return fromJSON(body)
}// cal/cal.go - 工作日判断逻辑
func IsWorkday(t time.Time) bool {
return isWeekday(t)
}
func isWeekday(t time.Time) bool {
switch t.Weekday() {
case time.Monday, time.Tuesday, time.Wednesday,
time.Thursday, time.Friday:
return true
case time.Saturday, time.Sunday:
return false
}
panic(fmt.Sprintf("Unknown weekday: %s", t.Weekday()))
}// chaosmonkey/chaosmonkey.go - 核心数据结构
type AppConfig struct {
Enabled bool // 是否启用
RegionsAreIndependent bool // 区域是否独立
MeanTimeBetweenKillsInWorkDays int // 平均终止间隔(工作日)
MinTimeBetweenKillsInWorkDays int // 最小终止间隔(工作日)
Grouping Group // 分组策略
Exceptions []Exception // 异常规则
Whitelist *[]Exception // 白名单
}
type Exception struct {
Account string // 账户名称
Stack string // 堆栈名称(* 表示所有)
Detail string // 详细信息
// ... 其他字段
}原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。