草庐IT

当微服务是个坏主意时

PetterLiu 2023-03-28 原文

当微服务是个坏主意时

      这篇文章可能是给大家泼冷水,请各位理性看待。从书面上看,微服务听起来很好。它们是模块化、可扩展和容错的。很多公司使用这种模式取得了巨大的成功,所以微服务可能自然而然地成为卓越的架构和启动新应用程序的最佳方式。然而,大多数利用微服务取得成功的公司并不是从微服务开始的。考虑一下Airbnb和Twitter的例子,它们在超越了它们的单体后走了微服务路线,现在正在与它的复杂性作斗争。即使是使用微服务的成功公司,似乎也仍在摸索使其发挥作用的最佳方式。很明显,微服务有其自身的权衡因素。 从单体迁移到微服务也不是一件简单的事情,而创建一个未经测试的产品作为一个新的微服务则更加复杂。只有在评估了其他路径之后,才应该认真考虑微服务。

微服务只对成熟的产品可行
      关于从微服务设计开始的话题,Martin Fowler洞察:

1. 几乎所有成功的微服务故事都是从一个单体开始的,这个单体变得太大,被分解了。

2. 几乎所有的案例都是以微服务系统的形式从头开始构建的,最后都陷入了严重的麻烦。

这种模式导致很多人认为,你不应该用微服务开始一个新的项目,即使你确信你的应用会足够大,使它值得。

     第一个设计很少是完全优化的。任何新产品的前几次迭代都是在寻找用户真正需要的东西。因此,成功的关键在于保持敏捷,并且能够快速地改进、重新设计和重构。在这一点上,微服务显然比单体差。如果你没有搞定最初的设计,你就会有一个艰难的开始,因为重构一个微服务比重构一个单体要难得多。

你是一个初创企业还是在做一个新建项目?
      作为一个初创企业(在这种经济环境下不太可能),你已经在与时间赛跑,在下一个坏事发生之前寻找突破口。你现在不需要可扩展性(可能在几年内也不需要),那么为什么要使用复杂的架构模型来忽视你的客户呢?

      在从事新建项目时,也可以提出类似的论点,因为新建项目不受早期工作的限制,因此没有任何决策的依据。《构建微服务:Designing Fine-Grained Systems》一书的作者Sam Newman表示,用微服务来构建一个新建项目是非常困难的。

      仍然相信,对现有的 "新 "系统进行分区要比对一个新的、新系统进行分区容易得多。你有更多的工作可以做。你有可以检查的代码,你可以与使用和维护该系统的人交谈。你也知道 "好 "是什么样子的--你有一个可以改变的工作系统,使你更容易知道什么时候你可能弄错了什么,或者在决策过程中过于激进。

微服务并不适合在企业内部使用
      由于所有的移动部件,微服务部署需要强大的自动化。在正常情况下,我们可以依靠持续部署管道来完成工作--开发人员部署微服务,客户只需在线使用应用程序。这对于内部部署的应用程序来说是不可行的,因为开发人员会发布一个包,而客户则需要在他们的私有系统上手动部署和配置一切。微服务使所有这些任务变得特别有挑战性,所以这是一个与微服务架构不相称的发布模式。说白了,开发一个内部微服务应用程序是完全可行的。。然而,正如我们一路走来所意识到的,有几个挑战需要克服。在决定采用内部部署的微服务之前,请考虑以下几点:

1.企业内部微服务的版本管理规则更为严格。你必须跟踪参与发布的每个单独的微服务。
2.你必须进行彻底的集成和端到端测试,因为你不能在生产中测试。
3.如果不能直接进入生产环境,微服务应用程序的故障排除就会变得更加困难。

你的单体可能还有生命力
      每个软件都有一个生命周期。你可能会因为一个单体的老旧和它的并发症而想把它废掉。但是扔掉一个正在工作的产品是一种浪费。只要稍加努力,你也许能从你目前的系统中再挤出几年好时光。

有两个时刻,似乎微服务是唯一的出路:

1. 纠结的代码库:很难在不破坏其他功能的情况下进行修改和添加功能。
2. 性能:你在扩展单体方面有困难。

模块化的单体
      开发人员希望避免使用单体的一个常见原因是,单体有恶化成代码纠结的倾向。当我们走到这一步的时候,增加新的功能是很有挑战性的,因为所有的东西都是相互联系的。

但是,单体不一定是一团糟。以Shopify为例:他们拥有超过300万行的代码,是世界上最大的Rails单体之一。有一次,该系统发展得如此之大,给开发人员带来了很多麻烦。

该应用程序非常脆弱,新的代码会产生意想不到的影响。一个看似无害的改变可能会引发一连串不相关的测试失败。例如,如果计算运费的代码被调用到计算税率的代码中,那么改变我们计算税率的方式可能会影响运费计算的结果,但可能并不明显。这是高度耦合和缺乏边界的结果,这也导致了测试难以编写,而且在CI上运行非常缓慢。

Shopify没有将他们的整个单体重写为微服务,而是选择了模块化作为解决方案:

     模块化有助于设计更好的单体和微服务。如果没有精心定义的模块,我们要么落入传统的分层单体(大泥球),要么更糟糕,成为分布式单体,结合了单体和微服务的最糟糕的特征。

     模块化是一项大量的工作,这是事实。但它也增加了大量的价值,因为它使开发更直接。新的开发人员不必在开始修改之前了解整个应用程序。他们一次只需要熟悉一个模块。模块化使一个大的单体感觉很小。

     模块化是过渡到微服务前的一个必要步骤,它可能是比微服务更好的解决方案。模块化单体与微服务中一样,通过将代码分割成独立的模块,解决了纠结的代码库问题。与微服务不同的是,微服务的通信是通过网络进行的,而单体中的模块则是通过内部API调用进行通信。

     分层与模块化的单体。模块化单体与微服务架构的许多特征相同,但没有最困难的挑战

单体可以扩展
      关于单体的另一个误解是它们不能扩展。如果你遇到了性能问题,并认为微服务是唯一的出路,请再想想。Shopify已经向我们展示了健壮的工程可以使单体在一个令人难以置信的规模上工作。

架构和技术栈将决定如何优化单体;这个过程几乎无一例外地从模块化开始,并可以利用云技术进行扩展。

部署单体的多个实例,并使用负载均衡来分配流量。
使用CDN分布静态资产和前端代码。
使用缓存来减少数据库的负载。
用边缘计算或无服务器功能实现高需求的功能。

如果它在工作,就不要修复它
       如果我们用随着时间推移实现的增值功能的数量来衡量生产力,那么在生产力很强的情况下,转换架构就没有什么意义。

       由于维护开销的原因,微服务最初是生产力较低的架构。随着单体的增长,它变得更加复杂,而且更难增加新的功能。微服务只有在线路交叉后才会有回报。
诚然,有些东西最终将不得不改变。但那可能是多年以后的事了,到那时,需求可能已经改变了--谁知道在此期间会出现什么新的架构模式呢?

布鲁克定律和开发人员的生产力
      在《人月神话》(1975年)中,小弗雷德-布鲁克说:"为一个延期的软件项目增加人力会使它变得更延迟"。这种情况的发生是因为新的开发人员必须先接受指导,才能在复杂的代码库上工作。另外,随着团队的壮大,沟通的开销也在增加。更加难以组织和做出决定。

     适用于复杂软件开发的布鲁克定律指出,在一个延期的软件项目中增加更多的开发人员只会使其花费更长的时间。微服务是减少布鲁克定律影响的一种方法。然而,这种影响只有在复杂而庞大的代码库中才能看到,因为在这种情况下,我们不能把开发分成不连续的任务。
     在使用微服务之前,你必须确定布鲁克定律是否会影响你的单体。过早地切换到微服务,不会增加多少价值。

你准备好过渡了吗?
在你开始使用微服务之前,必须满足一些条件。在准备好你的单体的同时,你还需要:

1.建立持续集成和持续交付以实现自动部署。
2.实施快速配置,按需构建基础设施。
3.了解云原生技术栈,包括容器、Kubernetes和无服务器。
4.熟悉领域驱动设计、测试驱动开发和行为驱动开发。
5.重组团队,使之成为跨职能的团队,消除孤岛,扁平化层次,以便于创新。
6.培养一种DevOps文化,使开发人员和运营工作之间的界限变得模糊。
7.改变一个组织的文化可能需要几年时间。学习所有的知识需要几个月的时间。如果没有准备,向微服务的过渡是不可能成功的。

结论
      我们可以用一句话来总结关于向微服务过渡的整个讨论:除非你有充分的理由,否则不要这样做。那些在没有准备和没有坚实设计的情况下开始微服务之旅的公司将有一个非常艰难的过程。在考虑将微服务作为一种选择之前,你需要实现关键的工程文化和伸缩特性。同时,如果你的系统表现良好,而且你还在以适当的速度开发功能,为什么要改变呢?



今天先到这儿,希望对云原生,技术领导力, 企业管理,系统架构设计与评估,团队管理, 项目管理, 产品管理,团队建设 有参考作用 , 您可能感兴趣的文章:
领导人怎样带领好团队
构建创业公司突击小团队
国际化环境下系统架构演化
微服务架构设计
视频直播平台的系统架构演化
微服务与Docker介绍
Docker与CI持续集成/CD
互联网电商购物车架构演变案例
互联网业务场景下消息队列架构
互联网高效研发团队管理演进之一
消息系统架构设计演进
互联网电商搜索架构演化之一
企业信息化与软件工程的迷思
企业项目化管理介绍
软件项目成功之要素
人际沟通风格介绍一
精益IT组织与分享式领导
学习型组织与企业
企业创新文化与等级观念
组织目标与个人目标
初创公司人才招聘与管理
人才公司环境与企业文化
企业文化、团队文化与知识共享
高效能的团队建设
项目管理沟通计划
构建高效的研发与自动化运维
某大型电商云平台实践
互联网数据库架构设计思路
IT基础架构规划方案一(网络系统规划)
餐饮行业解决方案之客户分析流程
餐饮行业解决方案之采购战略制定与实施流程
餐饮行业解决方案之业务设计流程
供应链需求调研CheckList
企业应用之性能实时度量系统演变
Openshift与Kubernetes的区别

如有想了解更多软件设计与架构, 系统IT,企业信息化, 团队管理 资讯,请关注我的微信订阅号:

作者:Petter Liu
出处:http://www.cnblogs.com/wintersun/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 该文章也同时发布在我的独立博客中-Petter Liu Blog。

有关当微服务是个坏主意时的更多相关文章

  1. 通过 MacPorts 的 RubyGems 是个好主意吗? - 2

    从MB升级到新的MBP后,Apple的迁移助手没有移动我的gem。我这次是通过macports安装ruby​​gems,希望在下次升级时避免这种情况。有什么我应该注意的陷阱吗? 最佳答案 如果你想把你的gems安装在你的主目录中(在传输过程中应该复制过来,作为一个附带的好处,会让你以你自己的身份运行geminstall,而不是root),将gemhome:键设置为您在~/.gemrc中的主目录中的路径. 关于通过MacPorts的RubyGems是个好主意吗?,我们在StackOverf

  2. Observability:从零开始创建 Java 微服务并监控它 (二) - 2

    这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/

  3. ruby - 使用 ruby​​ 进行套接字编程是个好主意吗? - 2

    我选择的语言是Ruby,但因为Twitter,我知道Ruby不能处理很多请求。将它用于套接字开发是个好主意吗?或者我应该像Twitter开发人员那样使用像erlang或haskell或scala这样的函数式语言吗? 最佳答案 我工作的公司使用Ruby作为我们的网站。到目前为止,我们已经处理了超过34,000,000,000次点击。我们每天处理大约10,000,000次点击没有问题。每天的点击量峰值已超过40,000,000次。可扩展性取决于很多因素。例如,与读取相比,我们的数据库执行的写入比例高得不成比例。虽然大多数网站执行大约90

  4. ruby-on-rails - 在 Rails 中动态重新加载路由是个坏主意吗? - 2

    我有一个正在编写的应用程序,我允许管理员为页面、类别等添加别名,我想根据别名使用不同的Controller/操作(不重定向,我'我发现render实际上并没有调用该方法。我只是渲染了模板)。我已经尝试了捕获所有路由,但我并不热衷于引发和捕获每次都会抛出的DoubleRender异常。我想出的解决方案是在服务器启动时动态生成路由,并在创建/更新/销毁别名时使用别名模型的回调重新加载路由。这是我的routes.rb中的代码:Alias.find(:all).eachdo|alias_to_add|map.connectalias_to_add.name,:controller=>alias

  5. 【微服务笔记23】使用Spring Cloud微服务组件从0到1搭建一个微服务工程 - 2

    这篇文章,主要介绍如何使用SpringCloud微服务组件从0到1搭建一个微服务工程。目录一、从0到1搭建微服务工程1.1、基础环境说明(1)使用组件(2)微服务依赖1.2、搭建注册中心(1)引入依赖(2)配置文件(3)启动类1.3、搭建配置中心(1)引入依赖(2)配置文件(3)启动类1.4、搭建API网关(1)引入依赖(2)配置文件(3)启动类1.5、搭建服务提供者(1)引入依赖(2)配置文件(3)启动类1.6、搭建服务消费者(1)引入依赖(2)配置文件(3)启动类1.7、运行测试一、从0到1搭建微服务工程1.1、基础环境说明(1)使用组件这里主要是使用的SpringCloudNetflix

  6. ruby - sleep() 对于作业调度应用程序的主循环来说是个好主意吗 - 2

    我正在为我的工作用Ruby编写一个作业调度应用程序(主要是为了以给定的频率使用各种协议(protocol)移动文件)我的主循环是这样的:whiletruedo#somecodetolaunchtheproperjobsleepCONFIG["interval"]end它的工作就像一个魅力,但我不确定它是否足够安全,因为该应用程序可能在运行cpu密集型软件的服务器上运行。是否有另一种方法可以做同样的事情,或者sleep()对我来说是否足够安全? 最佳答案 每当我觉得需要阻塞时,我都会使用事件循环;通常是libev。这是一个Ruby绑定

  7. ruby - 从 'next' 返回值是个坏主意吗? - 2

    应该很简单。我想,从阅读thisblogpost我可以在我的next命令之后立即返回一些东西:如果axis_range=="test",下一个“新值”我真正想做的是在同一行记录下一个原因:next@logger.info('跳过这个项目是为了好玩')unless(elephants.size>0)我在rubydoc上找不到任何关于next用法的讨论。.该代码肯定有效。我意识到我可以用unlessblock来做到这一点,但是那行代码太简洁了。两个问题:有更好的文档吗?next的这种用法是不是有点奇怪而不是“ruby-ish”? 最佳答案

  8. 若依框架解读(微服务版)——2.模块间的调用逻辑(ruoyi-api模块)(OpenFeign)(@innerAuth) - 2

    模块之间的关系我们可以了解到一共有这么多服务,我们先启动这三个服务其中rouyi–api模块是远程调用也就是提取出来的openfeign的接口ruoyi–commom是通用工具模块其他几个都是独立的服务ruoyi-api模块api模块当中有几个提取出来的OpenFeign的接口分别为文件,日志,用户服务我们以RemoteUserService接口为例子:其中contextId="remoteUserService"为bean的名称,value=ServiceNameConstants.SYSTEM_SERVICE为接口的描述,fallbackFactory=RemoteUserFallback

  9. ruby - 在系统范围内安装 RVM 是个坏主意吗? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭9年前。Improvethisquestion我很困惑,在服务器上,您应该以普通用户身份安装RVM还是进行系统范围的安装,如果是后者,您应该如何做bundleinstall不使用sudo。就RVM而言,在运行Rails的服务器上是否有明确的指导方针?乘客和Nginx?在这种类型的环境中,并非所有Ruby进程都在同一用户下运行,所以我认为就RVM和bundler而言,事情变得不清楚。在服务器上完全避免使用RVM并以传统方式安装Ruby和

  10. 【微服务】ES使用实战·黑马旅游(五) - 2

    🚗Es学习·第五站~🚩Es学习起始站:【微服务】Elasticsearch概述&环境搭建(一)🚩本文已收录至专栏:微服务探索之旅👍希望您能有所收获一.引入综合前几站所学,我们已经对Elasticsearch的使用有了一定的了解,接下来让我们一起通过一个综合实战案例来复习前几站所学内容,体会在实际生产中的作用。我们一起实现如下功能:酒店搜索和分页酒店结果过滤我周边的酒店酒店竞价排名数据聚合筛选选项搜索框自动补全酒店数据的同步二.环境搭建按照第一站的学习部署Elasticsearch并启动运行。按照第二站的学习中的如下步骤,初始化测试项目并在Es导入数据。使用Elasticsearch,肯定离不开

随机推荐