您当前的位置: 首页 >  微服务

凌云时刻

暂无认证

  • 0浏览

    0关注

    1437博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

微服务世界里的遭遇

凌云时刻 发布时间:2021-06-03 19:00:00 ,浏览量:0

凌云时刻

记得Martin Fowler在2014年发表关于微服务的文章时,我所在的团队已经在构建面向服务的架构了。当时,这篇文章和随后的炒作几乎影响了世界上所有的软件团队。“Netflix OSS stack”是当时最酷的东西,全世界的工程师都可以在分布式系统中借鉴Netflix的经验。六年多过去了,如果我们现在看看软件工程工作,大多数都在谈论微服务的架构。 

在2010年初,许多组织都在他们的软件开发周期方面遇到了挑战。一起工作的工程师们在开发环境、繁重的QA流程和编程部署中苦苦挣扎。Martin Fowler的《持续交付》一书揭示了许多这样的团队,他们开始意识到他们的宏伟计划给他们带来了组织问题。因此,微服务对软件工程师很有吸引力。其实在一个大项目中引入持续交付或部署更具挑战性。

目前软件团队大多数使用“JSON over HTTP”,进行组件之间的远程调用。人们对HTTP协议很熟悉,而且它是一种相对简单的方式,可以将庞然大物转换成更小的部分。这样,团队可以在不到15分钟的时间内将代码部署到生产环境中。

但是,大多数工程师可能忘记了,在软件体系结构级别上解决组织问题的同时,他们也引入了许多复杂性。分布式系统的弊端变得越来越明显,并开始越来越令人头疼。即使是那些已经在现有的基础上进行客户/服务器架构的公司,这种情况也会愈演愈烈。

但现实却反唇相讥

进行重大的架构变更并不是免费的。团队开始意识到不仅面临共享数据库,而且最终的一致性是一个大问题。如果正在提取数据的服务宕机了怎么办?问题的数量开始堆积起来。高速开发的承诺被寻找错误、事件、数据一致性等问题胜过。不仅如此,工程师需要集中的日志和可观察性的解决方案,跨越数十个服务来发现和纠正这些缺陷。

服务太小

每天创造新服务的能力伴随着开发者创造力的爆发。一个新特性?启动一项服务!这意味着每人不止一项服务! 一般来说,由20名工程师组成的团队要维护50项服务。而维护每项服务都是要付出代价的。试想一下,假设你在系统中对一个库升级,其中的服务是在不同的时间点启动的,具有不同的体系结构,业务逻辑和所使用的框架之间存在一些关联,你会做何感想!当然,有一些方法可以解决这些问题,不过也要花费很多时间。

当有人告诉我,在服务a中部署一个新功能的同时也需要在服务b中部署。该怎么做呢? 一些团队正遭受服务的困扰。更糟糕的是,它在发展过程中产生了许多问题。人们不是只在IDE中查看一个项目,而是需要同时打开多个项目才能理解所有的逻辑。

开发环境

我已经记不清有多少次他们跟我说:“嘿!你有时间吗?我们需要修复我们的开发环境! ”人们总是抱怨他们,这是行不通的!

在跨分布式系统的开发环境中存在几个问题,特别是在规模上:

  1. 在一个云供应商中运行200个服务要花多少钱?你能做到吗?你还能启动运行它们所需的基础设施吗?

  2. 这样做要花费多少时间?如果一个工程师在给定版本中开发完成一个功能时,有十个新版本要部署到生产中,那又会怎样呢?

  3. 那么测试数据呢?你有所有服务的测试数据吗?它是否贯穿整个服务,以便用户和其他实体匹配?

  4. 如果您正在开发一个多用户、多区域的应用程序,那么如何配置和标志呢?你如何与生产保持同步?如果违约或发生变化怎么办?

这只是冰山一角。我们可以考虑在这些问题上投入工程力量,而且我认为大多数组织都有足够的规模来做这件事。这可能会奏效,但是正确地做这件事是非常棘手和昂贵的。

端到端测试

可以想象,端到端测试与开发环境有类似的问题。以前,使用虚拟机或容器创建一个新的开发环境相对容易。在微服务之后,即使我们可以通过设置环境来解决上述所有问题,我们也不能再声明一个系统正在工作。最多,我们可以声明一个具有特定版本的服务运行和配置系统在特定时间点工作。这是一个巨大的区别!

人们很难相信,我们最多只能做几次这样的测试。然而,在持续集成流中,它们应该连续运行,并且应该在生产中测试。

共享数据库

保持数据一致性的一种简单方法是继续使用共享数据库。它不会增加操作负载,而且便于将大的事情分为小的部分。然而,它也有很大的缺点。除了明显的单点故障、违背面向服务的体系结构的一些原则之外,还有更多:您是否为每个服务创建一个用户?您是否拥有足够的权限,以便服务A只能从特定的表读取或写入?如果有人无意中删除了一个索引怎么办?您如何知道有多少服务正在使用不同的表?

理清这一切本身就是一个全新的问题。从技术上讲,数据库往往比软件更“长寿”,考虑使用数据复制来解决这个问题——不管是Kafka、AWS DMS还是其他什么——你的开发团队都需要了解数据库的细节,以及如何处理重复事件等等。

API网关

API网关是面向服务体系结构中的典型模式。它们有助于将后端用户与前端用户分离开来。在跨系统实现端点聚合、速率限制或身份验证时,它们也很有用。最近,该行业一直倾向于backend-for-frontend (服务于前端的后端)架构,这些网关被部署到每个前端消费者——iOS、Android、web或桌面应用程序——使它们的发展彼此分离。

与世界上的任何新事物一样,人们开始对它发挥创造性的用例。有时,让移动应用程序向后兼容是一个小技巧。可能突然之间,您的“API网关”就变成了单点故障——因为人们发现在单个地方处理身份验证更容易——并且在其中包含一些意想不到的业务逻辑。工程师们很快意识到这是一个错误,但由于有许多定制,有时他们无法用无状态、规模友好的定制来替代这部分。

API网关灾难的罪魁祸首是当它使用没有分页的端点或返回大量响应时,或者当您在没有后备机制的情况下进行聚合时,使一个API调用烧毁了您的网关。

超时、重试

分布式系统经常处于局部故障模式。当服务A无法联系服务B时,会发生什么?我们可以重新请求,对吧?但这很快就把我们带进了兔子洞。我见过一些团队使用断路器,然后增加对下游服务的HTTP调用的超时。虽然这给我们解决了问题,但它会产生二阶效应。如果流量增加,将有越来越多的请求排队,导致出现比预期更糟糕的情况。我见过工程师们努力理解排队理论,以及为什么会出现超时。当团队开始为他们的HTTP客户端讨论线程池之类的事情时,也会发生同样的问题。虽然配置这些参数本身就是一门艺术,但根据直觉设置值可能会导致重大停机。

当系统恢复过来时,一个棘手的问题是,不是所有的停机都是幂等的。我们可能期望我们的消费者在某些情况下是幂等的。但这意味着我们应该主动决定在每个失败场景中做什么。消费者是幂等的吗?许多工程师忽略了这些,因为这属于“边缘情况”,后来才意识到这是一个巨大的数据完整性问题。

重试比所有这些更棘手,即使您设置了回退机制。假设你的手机应用中有500万用户,而更新用户偏好的消息总线暂时停止工作。您为这种情况设置了一个回退机制,该机制通过HTTP API调用用户的首选项服务。现在,这项服务突然出现了巨大的流量高峰,它可能无法应付所有的流量。更糟糕的是:您的服务可能获得所有这些新请求,但如果重试机制没有实现指数退避抖动,您可能会遇到来自移动应用程序的分布式拒绝服务。

如此遭遇,你还爱分布式系统吗?

如果我告诉你这只是所遇到的一小部分呢?分布式系统很难掌握,直到最近大多数软件工程师才不断地接触到它们。

好消息是,上述的很多问题都得到了很好的回答,行业已经创造了更好的工具,让组织能够更好的解决这些问题。

我仍然喜欢分布式系统,我仍然认为微服务是组织问题的一个很好的解决方案。然而,当我们认为“边缘情况”永远不会发生在自己身上时,可能问题就来了。这些边缘事件在一定程度上会成为新常态,我们应该予以应对。

原文链接:https://world.hey.com/joaoqalves/disasters-i-ve-seen-in-a-microservices-world-a9137a51

来源|CSDN

END

长按扫描二维码关注凌云时刻

每日收获前沿技术与科技洞见

投稿及合作请联系邮箱:lingyunshike@163.com

关注
打赏
1663816507
查看更多评论
立即登录/注册

微信扫码登录

0.0452s