热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

“自主设计与实施的故障注入微服务Sidecar,欢迎大佬批评指正!”

“故障注入Sidecar“——为您的微服务注入故障以验证集群性能!由于导师和实验室师兄们的科研需要,本人专门以Sidecar的模式设计了一个用于错误注入的微服务模块。该模块可以与任

“故障注入 Sidecar“——为您的微服务注入故障以验证集群性能! 由于导师和实验室师兄们的科研需要,本人专门以 Sidecar

的模式设计了一个用于错误注入的微服务模块。该模块可以与任何微服务应用共同部署运行,为其模拟cpu、内存等错误。 本项目的 Github

地址:
https://github.com/iscas-micr…

我的联系方式: leontian1024@gmail.com || 或直接留言 欢迎您提出问题批评指点!

项目背景

目前,本人正在中科院软件所的微服务研究组从事部分研究工作。由于本人所在科研小组的研究内容( 微服务自动扩缩容相关 ),需要经常使微服务应用处于”高 CPU 利用率” 和 “高内存使用”的状态。因此,为了方便导师和实验室的各位师兄进行实验,本人特地开发了一个可以注入进 Pod 中的错误注入容器,来模拟上述的高负载状态。

导师和师兄们使用后对我的工作给予了肯定,因此我准备将开发过程和简单使用方法写成文章做个记录( 也就是本文 ),一来方便自己日后工作学习,二来也方便有类似实验需求的其他同仁们使用这个小项目,为大家的研究节省时间。更具体的安装和使用方法,可以移步本项目 Github 的代码仓库,其中有非常详细的说明。

知识储备

什么是微服务中的”Sidecar 运行模式?”

《“故障注入 Sidecar”——自己设计并实现的“故障注入微服务”,非常欢迎各位大佬批评指正!》

上图: 以 Sidecar 模式部署并运行的微服务单元

Sidecar 运行模式是最近两年比较火的一种微服务部署和运行方法,它由目前流行的 ServiceMesh(服务网格) 架构推广而来。

具体而言,Sidecar 运行模式是一种”将不属于业务应用的功能以独立的容器运行于业务容器旁边”,在 K8s 中表现出的样子就是将具有不同功能的模块封装成不同的镜像,并以不同的容器运行在同一个 Pod 中。这种说法非常形象,因为 Sidecar 这个单词的本意就是三轮摩托侧面的”跨斗”,这里形容独立于业务应用但又与业务应用部署在一起非常合适。

《“故障注入 Sidecar”——自己设计并实现的“故障注入微服务”,非常欢迎各位大佬批评指正!》

上图: Sidecar ,中文意思为摩托车的跨斗,不由赞叹命名的非常生动

主要设计思想

架构设计

本项目的错误注入模块也采用了 Sidecar 这种设计思想,将用于模拟 CPU、内存等故障的模块独立封装成一个镜像,并在 Pod 启动时以 Sidecar 的形式运行在主业务容器旁边。这样,不用它时他就会安安静静地当个美男子,完全不用担心它会影响到正常业务的运行;一旦需要它模拟错误产生,由于与业务容器同处于一个 Pod 之中(而 K8s 又以 Pod 为基本单元),因此他模拟出的错误亦被 K8s 集群视为业务应用所在 Pod 产生而被监测到。

《“故障注入 Sidecar”——自己设计并实现的“故障注入微服务”,非常欢迎各位大佬批评指正!》

上图: Pod 中的每个容器都有自己的端口映射到外部主机,因此不会相互影响

注入方式设计

本项目在设计之初是采用“在容器内修改环境变量”的方式对容器注入故障的,但事实证明这种方法太low,而且非常麻烦。因此在后续设计和实现中采用了目前较为流行的通过 REST API 传递 POST 请求的方式使容器模拟错误,这样就极大地方便了师兄们展开实验,而且也可以模拟出“微服务间调用而产生错误”的场景( 上游服务调用错误注入的 API 而模拟下游服务产生错误 )。

多进程模拟故障产生

此外,原本该项目的实现是单进程的,故每注入一个错误都要等待错误结束后才能获得应答并注入下一个错误,这十分不利于实验的进行。因此在后面我们改为了多进程运行,即每当一个错误产生时,程序都会建立一个子进程用于运行错误故障,而原来的进程则立刻产生注入是否成功的应答并继续监听相应的服务端口,从而满足应答实时汇报和多种错误同时注入的功能需求。

《“故障注入 Sidecar”——自己设计并实现的“故障注入微服务”,非常欢迎各位大佬批评指正!》

上图: 该程序的主要运行流程-以 “A 进程监听服务端口”的状态为起点

使用说明( 故障注入的方法 )

启动服务

本应用以 Web 服务的方式运行,并封装为镜像保存于 DockerHub 上。因此使用之前需要先以容器的形式运行镜像。以 docker 命令运行本应用的参考命令如下所示:

# 使用 docker 命令简单测试该应用( 测试版本为 docker 18.03-ce )
docker run --rm -it -d --name fault-injection-server -p 5000:5000 xinyaotian/micro-fault-injection:1.0.0

待容器就绪后,访问您启动该容器的主机 IP 的 5000 号端口,如果出现了使用指引界面,就表明您的服务启动成功,可以参考使用说明进行错误注入了。

《“故障注入 Sidecar”——自己设计并实现的“故障注入微服务”,非常欢迎各位大佬批评指正!》

上图: 为了方便师兄们和大家的使用, 特地在服务首页制作了简易的使用方法指引, 为大家节省查 Github 文档的时间

错误注入

本项目主要支持四种故障类型: cpu、内存、磁盘和网络,均通过 POST 请求向 /fault-inject 搭配相应参数进行注入。具体的注入方法如下所示( 注意更改 IP 和端口号 ):

1.注入 CPU 故障

# fault_type=cpu 指定错误故障类型(此处为 cpu 类型)
# thread_num=4 触发该错误的线程数(此处为 4 个线程)
# duration=15 故障持续时间,单位为秒(此处为 15 秒)
curl -X POST -d 'fault_type=cpu&thread_num=4&duration=15' http://localhost:5000/fault-inject

2. 注入内存故障

# fault_type=mem 指定错误故障类型(此处为 mem 类型)
# mem_size=120M 指定内存泄露的数值(此处为 120M ,注意 M 不能省略)
# thread_num=4 触发该错误的线程数(此处为 4 个线程)
# duration=15 故障持续时间,单位为秒(此处为 15 秒)
curl -X POST -d 'fault_type=mem&mem_size=120M&thread_num=4&duration=15' http://localhost:5000/fault-inject

3.注入磁盘故障

# fault_type=disk 指定错误故障类型(此处为 disk 类型)
# io_times=4
# duration=15 故障持续时间,单位为秒(此处为 15 秒)
curl -X POST -d 'fault_type=disk&io_times=4&duration=15' http://localhost:5000/fault-inject

4.注入网络故障

# fault_type=net 指定错误故障类型(此处为 net 类型)
# net_port=100
curl -X POST -d 'fault_type=net&net_port=100' http://localhost:5000/fault-inject
在 K8s 或 Istio 上运行( 基于 yaml )

本项目的镜像将作为原本微服务应用的 Sidecar 独立部署运行, 因此在 K8s 环境中其应该与业务应用部署于同一个 Pod 之中。

您可以利用 yaml 启动一个单独的 Pod 来初步体验一下这个应用。快读启动的 yaml 如下所示( Istio 同样可以这样写, K8s 版本为 1.13.1, Istio 版本为 1.0.6 ):

---
# 为 fault injection 创建 service 分配端口 #
---
apiVersion: v1
kind: Service
metadata:
name: single-fault-injection
namespace: default
spec:
selector:
# deployment identifier
# 这个标签要与 deployment 中相对应
app: fault-injection
ports:
- protocol: TCP
port: 5000 # 容器内端口为 5000
nodePort: 30050 # 映射至主机的 30050 端口
type: NodePort # 映射方式为 NodePort
---
# 将该模块作为一个独立的 Pod 在 K8s 上进行部署 #
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: single-fault-injection
namespace: default
spec:
replicas: 1
template:
metadata:
labels:
# svc identifier
# 这个标签要与 service 中相对应
app: fault-injection
spec:
containers:
# 错误注入模块的 container
- name: fault-injection-container
image: xinyaotian/micro-fault-injection:1.0.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 5000
# 该容器的资源限制, 错误注入可使其达到峰值 #
resources:
limits:
cpu: "0.4"
memory: 128Mi

如果您希望以 Sidecar 的形式将本应用部署在其他微服务的 Pod 之中同样可行,这也是本项目的设计初衷。在 K8s 环境下部署和启动的 yaml 如下所示意( Istio 同样可以这样写, K8s 版本为 1.13.1, Istio 版本为 1.0.6 ):

---
# 为 fault injection 创建 service 分配端口 #
---
apiVersion: v1
kind: Service
metadata:
name: your-microapp-with-faultinjection
namespace: default
spec:
selector:
# deployment identifier
# 这个标签要与 deployment 中相对应
app: sidecar-fault-injection
ports:
- protocol: TCP
port: 5000
nodePort: 30050
type: NodePort
---
# 相应的 deployment 配置( 与原应用配置在一起 )
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: your-microapp-with-faultinjection
namespace: default
spec:
replicas: 1
template:
metadata:
labels:
# svc identifier
# 这个标签要与 service 中相对应
app: sidecar-fault-injection
spec:
containers:
# 你原来应用的 container 信息
- name: your-micro-app
image: your-docker-name/project:1.0
imagePullPolicy: IfNotPresent
env:
- name: PATH_VALUE
value: "example"
ports:
- containerPort: 80
# ------------------- #
# Sidecar 错误注入模块的 container
- name: fault-injection-sidecar
image: xinyaotian/micro-fault-injection:1.0.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 5000
# ------------------- #
---

在我自己的实验集群上,利用 Istio 启动该服务,并对其注入内存故障后,可以在 Grafana 监控面板上清晰地看到微服务 Pod 的内存忽高忽低,非常有趣。 错误注入的结果如下图所示。
《“故障注入 Sidecar”——自己设计并实现的“故障注入微服务”,非常欢迎各位大佬批评指正!》

上图: 注入内存故障后, 我自己的 Istio 集群监测微服务资源面板的可视化展现

后续版本开发展望

项目到这里已经满足了实验室内师兄们绝大部分的科研需求。在之后的迭代中预计还会加入故障的产生速率( 例如 CPU 使用率会呈线性或指数上涨等 ),相应的 API 也会采用向前兼容的形式进行扩充( 添加更多的可选参数,不填则设置为默认值 ),以确保这个版本或之前版本使用者的代码无需改变而可继续使用后续版本。

此外,简单的用户控制面板也会在后续版本中开发。通过提供的用户界面,使用者可以在界面上输入参数并通过按钮进行错误注入,而不再仅仅通过发送 POST 请求( 虽然底层原理还是本地请求 )。相信用户界面会在汇报演示时为导师和师兄们带来诸多便利。

小结

本项目主要以 Sidecar 的方式开发了一个用于错误注入的实验镜像,并通过在 docker 和 k8s 上运行从而达到对微服务单元注入故障的目标,为研究集群自动扩缩容、微服务自动扩缩容等课题提供了前提保障和研究条件。

致谢

感谢您的阅读,如果您对这个项目有什么更好的建议,或指出哪里设计有问题,我都会非常欢迎,洗耳恭听。非常希望于读完本文的您进行交流,欢迎您在下方留言。

如果您的科研团队也有类似需求,也非常欢迎与我们进行合作,并对针对本项目提出宝贵的改进意见。


推荐阅读
  • 离线安装Grafana Cloudera Manager插件并监控CDH集群
    本文详细介绍如何离线安装Cloudera Manager (CM) 插件,并通过Grafana监控CDH集群的健康状况和资源使用情况。该插件利用CM提供的API接口进行数据获取和展示。 ... [详细]
  • 全面解析运维监控:白盒与黑盒监控及四大黄金指标
    本文深入探讨了白盒和黑盒监控的概念,以及它们在系统监控中的应用。通过详细分析基础监控和业务监控的不同采集方法,结合四个黄金指标的解读,帮助读者更好地理解和实施有效的监控策略。 ... [详细]
  • 解决TensorFlow CPU版本安装中的依赖问题
    本文记录了在安装CPU版本的TensorFlow过程中遇到的依赖问题及解决方案,特别是numpy版本不匹配和动态链接库(DLL)错误。通过详细的步骤说明和专业建议,帮助读者顺利安装并使用TensorFlow。 ... [详细]
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
  • 本文探讨了如何在Classic ASP中实现与PHP的hash_hmac('SHA256', $message, pack('H*', $secret))函数等效的哈希生成方法。通过分析不同实现方式及其产生的差异,提供了一种使用Microsoft .NET Framework的解决方案。 ... [详细]
  • 访问一个网页的全过程
    准备:DHCPUDPIP和以太网启动主机,用一根以太网电缆连接到学校的以太网交换机,交换机又与学校的路由器相连.学校的这台路由器与一个ISP链接,此ISP(Intern ... [详细]
  • 在寻找轻量级Ruby Web框架的过程中,您可能会遇到Sinatra和Ramaze。两者都以简洁、轻便著称,但它们之间存在一些关键区别。本文将探讨这些差异,并提供详细的分析,帮助您做出最佳选择。 ... [详细]
  • 解决Spring Boot项目创建失败的问题
    在尝试创建新的Spring Boot项目时遇到了一些问题,具体表现为在项目创建过程中的两个关键步骤出现错误。本文将详细探讨这些问题及其解决方案。 ... [详细]
  • CentOS 7.6环境下Prometheus与Grafana的集成部署指南
    本文旨在提供一套详细的步骤,指导读者如何在CentOS 7.6操作系统上成功安装和配置Prometheus 2.17.1及Grafana 6.7.2-1,实现高效的数据监控与可视化。 ... [详细]
  • 本文深入探讨了SQL数据库中常见的面试问题,包括如何获取自增字段的当前值、防止SQL注入的方法、游标的作用与使用、索引的形式及其优缺点,以及事务和存储过程的概念。通过详细的解答和示例,帮助读者更好地理解和应对这些技术问题。 ... [详细]
  • 本题来自WC2014,题目编号为BZOJ3435、洛谷P3920和UOJ55。该问题描述了一棵不断生长的带权树及其节点上小精灵之间的友谊关系,要求实时计算每次新增节点后树上所有可能的朋友对数。 ... [详细]
  • 本文详细介绍了Java中实现异步调用的多种方式,包括线程创建、Future接口、CompletableFuture类以及Spring框架的@Async注解。通过代码示例和深入解析,帮助读者理解并掌握这些技术。 ... [详细]
  • BreederDAO 一周年:回顾历程,庆祝成就,展望未来
    10月标志着BreederDAO踏入Web3.0领域的起点,开启了元宇宙工厂的建设。自成立以来,BreederDAO始终致力于构建多样化的数字资产工厂。 ... [详细]
  • 本文详细介绍如何通过设置SSH密钥来获取连接GitHub远程仓库的权限,包括生成密钥、添加到GitHub账户以及验证连接等步骤。 ... [详细]
  • 深入解析Hadoop的核心组件与工作原理
    本文详细介绍了Hadoop的三大核心组件:分布式文件系统HDFS、资源管理器YARN和分布式计算框架MapReduce。通过分析这些组件的工作机制,帮助读者更好地理解Hadoop的架构及其在大数据处理中的应用。 ... [详细]
author-avatar
520文雅_293
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有