写点什么

如何处理分布式系统中的紧急情况?

2021 年 5 月 01 日

如何处理分布式系统中的紧急情况?

本文最初发表于 gitconnected 博客,经原作者 Gregory Pabian 授权,InfoQ 中文站翻译并分享。


由于发生意外或遭受攻击,任何分布式系统都可能会遇到紧急情况。即便是像执行脚本这样看似无害的操作,也可能会对整个平台造成严重破坏,最终导致用户无法使用。本文作者分享了软件开发者在紧急情况发生之前为系统做好准备的一些方法。

 

免责声明:我不是软件安全专家,而是一名全栈软件开发者,本文中的所有信息都源于我的开发经验。我希望讨论主要的可能性以准备和处理紧急情况,但我不打算就正确和错误的做法提出看法。至于如何设计一个安全的分布式系统,这可能需要用到资深安全工程师的专业知识。

应急预案

 

我相信系统设计者可能会考虑准备一个应急预案,至少要知道如何保护一个分布式系统不受内外威胁。我从各种 OWASP(即 Open Web Application Security Project,开放式 Web 应用程序安全项目,是一个在线社区,在 Web 应用安全领域提供免费的文章、方法、文档、工具和技术。)资源中学到了很多关于网络应用安全的知识。

 

在我看来,应急预案至少应该包括对下列问题的回答:

 

  • 谁可以启动应急预案,以及有哪些权利;

  • 应急预案实施期间将发生什么情况,在哪里发生;

  • 如何才能有人启动应急预案,将会持续多久。

 

本文假定系统管理员可以使用 CLI 以系统上的最高权限启动应急预案,该措施的调用将无限限制多个后台的某些功能。

时间框架

 

这个应急预案可在这两个时间框架下生效:

 

  • 过去和未来:系统会根据指定的过去和所有未来事件改变其行为;

  • 未来:系统会根据所有未来事件改变其行为。

 

当然,并非所有的分布式系统都支持逆行性行为变更。在使用长时间运行事务的系统中,遵守这样的转换要求执行补偿性事务,这样才能明显消除原始过去事务的影响。

解决方案

 

我将所有可能的解决方案分为三组:无状态协议(如 HTTP)中阻止访问的方案、基于消息的系统(如 Kafka)中阻止访问的方案,以及回滚事务的方案。只要它们在所设计的系统中实际发挥作用,系统架构师就可以选择应用这些解决方案中的一些,甚至是并行的。

无状态协议中阻止访问

 

阻止特定的访问令牌(例如 JWT)可以说是通过限制特定用户对资源的访问来解决紧急情况的最精确的方法。若攻击者已获得访问令牌,并且可能将其用于非法用途,则系统可应用此解决方案。根据暴露程度的不同,此解决方案可以影响到一个或多个后端。

 

系统也可以组织访问特定的访问方法(例如 HTTP 端点或 RPC)。如果系统管理员不知道特定攻击者的访问令牌,或者由于最新的部署,端点无法正常工作,那么他们可能会选择此解决方案。在选择用这种方法解决问题之前,我认为人们应该考虑一下锁定整个功能的后果,以及如何与最终用户沟通这个选择。

 

在阻止某些服务中的某些访问方法无效的情况下,可以考虑关闭该服务。在分布式系统中,这相当于禁止在相关服务实例中向负载均衡器转发请求,或者终止所有以上实例。不管选择哪种解决方案,都会对系统造成严重的影响,因为很多功能已经不能工作了。

 

最后,系统管理员可以决定关闭整个系统(或者至少所有后端)。关闭分布式系统的精确算法在很大程度上取决于其基础设施和使用的冗余。若有人考虑到这一可能性,则应考虑到后果,因为除了某些可能在离线模式下工作的前端功能外,系统将会停止工作。

基于消息的系统中阻止访问


系统管理员可以禁止在基于消息的系统内共享特定的消息。有些情况下,消息代理可以应用此类策略,而有些情况下,这一工作属于后端。这样的规则,读者可以将其视为判定函数,它接受一个参数、一条消息,然后返回一个布尔值。

 

另外,人们可以选择阻止特定的主题或通道分发消息。它会间接地影响依赖这种通信方式的后端。此外,人们也可以禁止某种服务通过某一主题或通道收发消息。

 

最后,有人可能会决定阻止整个消息管道。与关闭整个系统一样,这种解决方案对系统内的通信产生巨大影响,并可能导致多个功能失效。软件开发者在出现这种情况之前,应该弄清楚哪些功能可能会崩溃。

回滚事务


在后端向关系数据库提交某些事务之前,系统可能会回滚它们。这类规则的应用要求对后端架构进行有效性检查,并确保后端能够及时接收策略变更信息。此解决方案可以作为取消已启动事务的示例。

 

对于使用依赖注入的后端,一个基于紧急情况的限制列表可以驻留在所有请求或消息处理程序重用的组件中。人们可以使用全局变量实现类似的结果,但是我不赞成这种方法。


处理程序可以运行一个检查函数,以验证对于当前评估的请求是否存在某些限制。当系统使用紧急编排时,接受紧急通告的后端需要与系统的其他部分通过无状态请求或消息管道共享信息。若后端无法执行此操作,则将阻止应急响应的传播。系统设计者应该找到避免这个障碍的方法,例如,让前一个服务等待下一个服务确认信息处理,然后继续进行处理。

总结

 

在本文的开头,我已经指出,由于不同的系统使用不同的模式进行后端到后端的通信,所以在分布式系统中处理紧急情况的方法多种多样。我认为,尝试将危机应对措施融入开发中的系统中,或许可以为系统设计提供许多参考。

 

作者介绍:

 

Gregory Pabian,全栈软件开发者,热爱构建产品。

 

原文链接:

 

https://levelup.gitconnected.com/emergencies-in-distributed-systems-9f93c6d75600

2021 年 5 月 01 日 10:101175

评论

发布
暂无评论
发现更多内容

在培训机构花了好几万学Java,当了程序员还常被鄙视,这是招谁惹谁了?

四猿外

Java 学习 程序员 个人成长 转行程序员

不懂送女朋友什么牌子的口红?没关系!Python 数据分析告诉你。

JackTian

Python 程序员 数据分析 python 爬虫 口红

安装R语言编译器:

唯爱

纯CSS“返回顶部”特效

寇云

CSS css3

写给产品经理的信(5):谈谈项目管理(青铜-王者)

夜来妖

产品 极客时间,项目管理 项目管理 产品经理 项目

Java 学习笔记(三)数据类型

杜朋

控制 Pod 内容器的启动顺序

张晓辉

Kubernetes

解决版权难题,“豪横”字体自己做

zhoo299

设计 CG

自定义列表样式

寇云

CSS css3

Vol.9 Web前端发展历程及前端工程化

pyfn2030

前端 前端工程

ARTS|Week 1 第一次使用LeetCode

Puran

LeetCode ARTS活动

时序数据库

pydata

机器学习项目是如何开发和部署的?

陆道峰

人工智能 学习

金灿灿的季节 - Apache DolphinScheduler收获5位新Committer

海豚调度

珍藏已久的 OS 学习网站拿出来分享给大家

cxuan

操作系统

Vol.8 云栖小镇游记

pyfn2030

阿里云 随笔 数字化转型

Rust 遇上 C/C++(二):函数传参

Coding Fatty

c c++ rust 编程语言

《中国互联网简史》系列笔记之P2P

dongh11

读书笔记

认识数据产品经理(四 与互联网产品经理的区别)

马踏飞机747

大数据 互联网 产品经理 职业规划

MySQL死锁系列-常见加锁场景分析

程序员历小冰

MySQL

磁盘挂载

唯爱

Eureka 实例注册状态保持 STARTING 的问题排查

张晓辉

spring Spring Cloud netflix

只用CSS实现响应式Full-Width img 2种方法

寇云

CSS css3

如何通过样本数据推断其分布

张利东

Python

【写作群星榜】5.22~5.28写作平台优秀作者&文章排名

InfoQ写作平台官方

写作平台 排行榜

深入浅出Mysql索引的那些事儿

猿人谷

MySQL 性能优化 索引

XSKY发布XMotion纳管热迁移技术,OpenStack集群迁移效率提升超10倍

XSKY融合存储

Vol.7 聊聊我热爱的陕西省图书馆

pyfn2030

记录 生活,随想

避免争执

孙苏勇

职场 随笔杂谈

前端工程化之创建项目

春生

前端 前端工程 前端架构 全栈工程师

超简单入门MyBatis,看了就会了~

程序员的时光

mybatis

如何处理分布式系统中的紧急情况?-InfoQ