当前位置: 首页 > 科技观察

避免对微服务的误解

时间:2023-03-21 22:25:09 科技观察

开场白:我是微服务的忠实粉丝。现在的时代,每隔一段时间就会出现一个新概念或新技术,带来希望和炒作,似乎可以拯救世界。但我认为这有一个真正的好处,即新技术是开创性的,可以带来显着的好处。然而,就像生活中的其他事物一样,它也有其局限性。就像我们无法将牛顿定律应用于亚原子粒子,或无法将电视机塞进袜子一样。就像我们不能忽视合同最后的约束条款一样,其后果可能是灾难性的。照片由MollieSivaram提供拆分是一种可选策略。常规的Web应用程序通常只有一个进程来接收和处理所有请求。或许出于负载均衡或者高可用的考虑,我们会复制一个部署,但是在任何一个单一的场景下,所有的实现逻辑都打包成一个包,软件运行起来。使用微服务,我们可以设计多个不同的进程,每个进程可以运行不同的包,每个包只包含自己的代码来处理请求数据的一个子集。这是新的吗?答案是不。事实上,与任何新兴技术一样,微服务模式在被大肆宣传之前已经存在了好几年。它本质上是面向对象编程在更高层次上的应用,即应用程序架构。同时,微服务会经常使用HTTPAPI,尤其是RESTful也是有道理的。RESTfulAPI是在API设计中应用OOP原则的结果。稍微扩展一下面向对象程序设计的过程。在使用面向对象编程创建程序时,通常会分为几个类,每个类代表一个组件,具有特定的作用,并处理相应的数据子集,这是我们熟悉的内容。虽然在这里讨论面向对象编程并不合适,但本文将涉及几个关键方面。如果读者对这些内容不熟悉,我建议参考这方面的在线文档。两条原则——“好裁缝”当我们设计类时,我们必须遵循两条主要原则:低耦合和高内聚。坦率地说,我认为这不仅仅是面向对象项目的指导原则,而应该是每个软件项目的明星指导原则(可能有歧义,不展开)。高内聚:指的是组件的每一部分都具有高度一致的愿景,包括它的数据和方法,都指向一个非常特定的领域、意义或作用。低耦合:指的是每个组件与其他组件的交互尽可能少。它隐藏了底层细节,可以独立运行,只暴露必要的接口。微服务也是如此。良好的面向对象设计将带来最佳的微服务设计。我个人觉得这一点怎么强调都不为过。这也应该足以回答为什么以及何时考虑采用微服务的问题,接下来会继续。一个好的裁缝会用松散的针迹缝制致密的织物。图片来自jeffWadeSplitTiming这与面向对象编程的情况完全相同。即在需要的时候可以遵循高内聚低耦合的原则。如果您知道如何以正确的方式将代码拆分为类。那你为什么要随意拆分你的微服务呢?如果一个糟糕的类图设计不合理,导致功能代码分散在多个文件中,最终难以维护和管理,那么我们可以想象随意拆分微服务应用导致在一个微应用中运行完全不同的进程的困境。拆分应用程序的原因想象一下,两个对象交互是多么容易,只要调用另一个对象的方法,实现起来就非常容易,而且所有代码都在一个程序中。相对于微服务架构,应用程序运行在不同的线程上,甚至可能在不同的机器上,基于网络,使用API??s进行请求通信。这显然增加了复杂性。但这样做必须有充分的理由,既不是为了时尚,也不是为了好玩。我可以保证,如果你随便使用微服务,那么由此产生的管理一点都不好玩。事实上,决定使用API访问的原因与使用微服务的原因是一样的。API将所有实现细节隐藏在接口后面的能力在某些情况下非常重要,它可以带来超出预期的好处。包括:非均匀流量的可扩展性考虑一个超市应用程序,它包含一个仅显示库存商品数量的库存微服务,以及一个使用GPU检测商品中包含的图像的视图微服务。如果某个应用程序在某个时间段内收到来自库存应用程序的数千个API请求,但只有少数来自视图微服务的API请求,则只需要复制多个库存微服务来处理API请求,而无需增加GPU资源。考虑另一种情况,如果所有的代码实现都集中在一台机器或者一个应用上,你还想通过扩展资源来匹配所有的访问请求,那么你就必须整体复制部署,造成明显的不必要的资源浪费。容错弹性假设有一个银行应用程序,其汇款微服务不断崩溃,可能是由于偶尔的错误,或者更糟糕的是,由于新错误导致软件的未经测试版本。是不是因为这个原因,整个银行应用都被关闭了?有些客户并不关心这项业务,他们只是想查看他们的资金或使用他们的卡。单独部署按照上面的场景,如果我们要增加一个新的功能或者需要修复一个bug,微服务可以让我们只部署更新对应的微服务,构建和部署的时间也相应少了很多。此外,微服务可以部署在不同的机器或不同的位置。完全隔离用于需要服务之间完全隔离的需求。可以通过微服务以这种方式使用不同的数据库(SQL和NoSQL)或完全不同的实现技术。具有最大的设计自由度。当然,它在容错、弹性、请求处理等其他方面也有严格的关联要求。差异化需求业务应用是否有重计算需求,比如机器学习,需要GPU资源,或者需要调用大量算法模型库等,可能有些需求用Python实现更好,而有些部分更适合用Java实现发展。或者同一种语言的库可能会部分冲突,迫切需要两个特定的软件版本来处理两个不同的任务。甚至最终需要使用两种不同的云产品服务来托管2个不同的组件。出现上述现象等等的原因有很多,其中有很多是常见的情况。在这些情况下,应用程序拆分可能更容易解决问题。但是我们一定要牢记遵守“两个原则”,做一个“好裁缝”,否则经常会遇到困难,包括微服务之间共享数据等等。巨石再高,也是由石块或原子组成的。图片来源ZoltanTasi以上不适用于您的情况,它就像一个整体如果您的系统是紧密耦合的整体应用程序方法,则它可以称为整体应用程序。您拥有清晰的依赖管理,不需要复杂的编排或分布式系统来跟踪错误、共享数据、收集日志、同步调用、保护网络交互等。那么是不是面向对象编程不适合你的应用架构,RESTful设计和微服务不适合呢?如果应用程序需要使用很长的API请求队列,并且其中一个API还需要调用上一个API的返回结果,那么这种设计并不是一种理想的方式。肯定会有网络延迟之类的问题。而如果应用程序是一个需要用户交互的单一进程,那么这句话本身就意味着它是一个不可分割的程序。如果必须在调用之间共享状态,则每个组件都不是独立的,序列中的一个错误可能会完全阻塞整个请求序列。拆分应用程序没有什么好处。Monolith应用不等于混乱,有不同的理解。有些人认为单体应用程序是一堆错综复杂的代码。他们声称微服务模式是分离和有序构建应用程序的唯一方法。我想表达的是:这种观点是不正确的。因为代码设计不依赖于线程分区,面向对象编程也不依赖。如果能正确拆分代码,层次分明地管理依赖和代码包文件,就可以实现同级内聚和解耦。还有一个秘诀,如果把API分成独立的packages/modules/controllers/blueprints/evencodesegments等等,你可以自由决定是单进程运行,还是在代码构造或运行时拆解.分成微服务运行没有任何限制。结论正如开头所述,我是微服务的超级粉丝。当在正确的上下文中出于正确的原因考虑时,微服务可以解决问题、提高性能或节省资金。但是,请不要将他们理解为救世主,他们也可能是万恶之源。