服务,微服务和面向批处理的编程

许多程序员听说,有时应将代码分配给单独的库,以供进一步重用。 但是,应将哪种类型的代码选为一个单独的实体的问题使许多开发人员感到困惑。 在阅读有关该主题的文章/对话时,通常会提起过早泛化的问题。

经验丰富的程序员通常有自己的规则,遵循这些规则,他们可以理解代码是否应区分为可重用。 例如,如果在三个或更多个地方使用了此类(或非常相似的)代码。 但是,我有机会与这个话题交流的每个人都同意,必须存在这样一个可重用的代码,它的创建是一种祝福,值得您花时间。

我想在创建面向服务的微服务体系结构的上下文中提出代码重用的主题。

什么是可重用代码?


可重用代码是将代码隔离在一个单独的实体中,用不同的语言(库,程序包,依赖项等)不同地调用。 通常,此类代码存储在单独的存储库中,并且有用于连接和使用此代码的文档(README.md)。 此外,该代码可能包含测试内容,可能有进行更改的说明(CONTRIBUTING.md),并且可能配置了CI。 描述中附带的各种标志仅能改善给定实体成熟度的视觉表示,并且分配的星级数将指示此解决方案的受欢迎程度。 您无需花太多时间进行示例-只需使用自己喜欢的语言打开任何流行框架的github页面,例如vue.js。 通常,图书馆的高质量设计方法是旅行车和小型手推车。

服务和微服务


在本文中,服务是一个完整的实体,可以在其职责范围内执行一组特定的特定任务,并提供一个交互接口。 从架构的角度来看,本文中的服务或微服务可以是相同的概念,问题仅在规模上。 服务可以由实现其业务逻辑部门的一组微服务组成,也可以是一个引以为傲的微服务。

面向服务的体系结构假定每个服务之间的连接最少。 但是,不排除服务间交互,而是仅假定应将其最小化。 为了接收请求,服务通常实现一些标准化的API。 它可以是任何东西-REST,SOAP,JSONRPC或新的GraphQL。

按照惯例,服务可以分为基础设施和杂货店。 产品服务是那些实现客户产品逻辑的服务。 例如,他们使用应用程序进行连接,或者在客户的整个生命周期内组织对该产品的支持。 基础结构服务更多地是关于公司(或项目)的基本功能,例如,包含客户信息的服务或存储有关某些订单信息的服务。 此外,基础结构服务包括实现辅助功能的服务,例如,客户信息服务(发送推送消息或SMS)或用于与dadata交互的服务。

一点幻想


假设有一个假设的在线商店,它建立在面向服务的体系结构上。 这个工程奇迹的开发人员能够在彼此之间达成共识,并得出结论,例如,使用jsonrpc协议,他们的所有服务都将充当API。 但是,由于在线商店很大,它并没有停滞不前,而是在积极地发展,那里有几个开发小组,所以要有两个以上的开发小组-两个设计小组,一个伴随着已经编写的内容。 另外,为了增强效果,所有团队都在同一堆栈上编写。

假设的在线商店的架构:



只有Internet上的API服务可以访问所有前端系统-在线商店的Web界面以及移动应用程序。

客户信息服务存储有关客户的信息,知道如何启动客户,授权和发布有关客户的必要信息。

产品信息服务存储有关产品,其余额和可订购性的信息,还提供了方便地获取必要信息的方法。

订单服务与订单一起运行。 这是订单形成,确认,选择付款方式和收货地址等的逻辑。

客户信息服务可以发送PUSH / SMS /电子邮件。 例如,通信类型取决于特定客户端的设置,并且客户端还可以设置接收通知的所需时间。

这些服务是有条件的基础设施,因为没有它们,在线商店将无法正常运行。

项目团队应该在不久的将来开发促销,报价和摘要的服务。 这些服务是有条件的杂货店。

显然,无论如何,任何新产品服务都必须与基础设施服务交互才能存在-它很可能必须接收有关客户的信息或需要发送通知。

在上述示例中,故意隐藏了每个服务的实现细节。 例如,客户信息服务可能具有延迟的代码执行机制(例如执行队列),并且产品信息服务可以具有自己的管理面板以方便进行商品管理,而前端系统的api可能具有多个副本。 而且,所描述的体系结构可能不是最佳的;它只是从头上考虑的。

在所提议的体系结构的上下文中,立即变得很清楚,现成的库对于快速产品开发至关重要。 因此,重要的是要有一个现成的jsonrpc服务器及其客户端的实现,因为这是组织服务间交互的主要协议。 同样在此示例中,记录API的问题也逐渐发挥出来。 显然,为了形成文档,团队还应该拥有现成的工具。 如果我们假设仍然有现成的工具可以为jsonrpc服务器生成smd方案,那么开发新服务的速度可能会进一步提高。 因此,理想情况下,在公司内部,应该有一组现成的库,所有团队都可以使用这些库来执行典型任务。 这些库可以是专有库,也可以是开源库,主要是它们可以很好地执行任务。 显然,在常规堆栈中使用现成库编写服务的团队比不断循环的团队更有效。 我将所有项目团队中使用的单个框架和单个库数据库的存在称为单个生态系统。

那大公司呢?


在大型公司中,存在更多的基础结构服务以及所使用的交互协议。 完成的库的数量可以达到数十甚至数百。 在此处突出显示可重用的代码更为重要。

碰巧,我在一家拥有200名开发人员的公司中工作,他们使用不同的语言(java,c#,php,python,go,js等)进行编写。令人惊讶的是,在单个堆栈中,常见的生态系统是远非所有开发团队拥有和使用。 似乎显而易见的事情-准备可重用的代码,正确地格式化它并使用它-远非显而易见。 当然,开发团队可以解决他们的问题。 有人使用服务模板-组成每个新服务核心的一组代码,从中抛出所有不必要的内容,并添加必要的内容。

其他开发团队使用他们自己的自行车,在项目之间复制和粘贴它们,而不在乎记录和测试它们。 通常,在一家公司的同一堆栈中使用的工具和方法存在很多不统一之处。 而且,地理位置位于一个城市。

单一生态系统的好处


形成一个单一的生态系统可以解决许多难题,并且对于提高大公司的生产力具有巨大的潜力。 实际上,这种做法来自开放源代码社区-他们所在领域的最佳解决方案得以生存,并且最受欢迎。 现在就可以打开任何依赖项管理器,并且对所提议的解决方案足够多感到惊讶。 但是可以在公司内部实施这种方法。 实施新服务时,此方法的优点如下:

  • 高稳定性-使用经过测试覆盖并有据可查的库可以提高整个服务的稳定性;
  • 团队之间同事的轻松轮换-如果所有团队都在同一个生态系统中,那么从一个团队迁移到另一个团队时,开发人员将不必花费大量时间来了解所使用的工具,因为他已经知道它们了;
  • 专注于业务逻辑-实际上,开发新服务归结为需要加强解决所有基础结构任务并仅编写业务逻辑的必要依赖关系的需要;
  • 加速开发-无需循环,一切准备就绪,除了业务逻辑;
  • 简化测试-因为库已经过测试,所以只需要测试业务逻辑;

美中不足


显然,为了实现此方法,应遵循一些实践,即使用语义版本控制开发库,注意文档和测试并配置ci。 这不仅是开发团队的成熟度指标,还是整个公司开发人员的成熟度指标。

聚苯乙烯


面向包的方法仅仅是因为我堆栈上的可重用代码称为包。 好吧,听起来很有趣。 最近,我与一位同事进行了一次对话,促使我写这篇文章:
-同事:您五分钱成为收银员
-我:意思?)
-同事:很快您会问:“您需要包装吗?”
我:请打开思路。 我不明白
-同事:恩,您有无数次现成的包裹可以解决我的问题

问题在于,在公司内部的开发人员社区中,大约有20个现成的程序包,而创建新服务将转化为提取必要的依赖关系以及编写业务逻辑。 就编写代码而言,捆绑的成本几乎为零。

Source: https://habr.com/ru/post/zh-CN466455/


All Articles