RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 897637
Accepted
Zufir
Zufir
Asked:2020-10-25 14:45:59 +0000 UTC2020-10-25 14:45:59 +0000 UTC 2020-10-25 14:45:59 +0000 UTC

微服务版本控制

  • 772

有一个微服务(.Net core,但这不是那么重要)。新功能在其中实现,它们在某个地方发生了变化DTO,并且这个实现需要制作一个新版本(v2),同时保持旧功能(v1)。

已提出以下选项:

  1. v1从当前分支创建一个分支master,提交它并将其布置为单独的实例。在更正影响两个分支的逻辑时,请进行cherry-pick适当的提交。
  2. 复制逻辑v1并v2在一个解决方案中,将其分布在不同的命名空间中,实现两个控制器 - forv1和v2.

第一种方法涉及基础设施成本。第二个在代码形式上非常丑陋。
问题:什么重要best practice?也许还有一些我们没有考虑过的第三种(第四、第五)方法?

архитектура
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    StateItPrimitive
    2020-11-05T04:51:48Z2020-11-05T04:51:48Z

    前言

    如您所知,没有“单一”和/或“理想”的方法来解决这个问题,在每个特定案例的上下文中只有最方便和最不方便的方法。我可以提供一个开发团队,在我所处的环境中,通过反复试验得到的。


    一般优惠 (client-side和server-side)

    我建议使用接近您提出的第一个选项的选项,即 根据质量的组合,将您的微服务版本拆分v1为v22 个独立的模块(客户端的 2 个客户端库和服务器端的 2 个文凭单元):

    • 平行发展的可能性
    • 发展独立
    • 选择退出服务版本之间的向后兼容性的可能性

    随着后续版本服务的进一步出现(因为您有第二个版本的服务,那么很可能第三个版本将在稍后出现),遵循类似的策略。

    微服务的介绍feature和bug fix其他改进:

    在开发版本化微服务时,至少应该区分 -versions(major格式minor)${major-version}.${minor-version}:

    • -版本更改minor发生在同一版本的服务中
    • -版本更改major需要分配新版本的服务

    应根据以下规则进行改进:

    • 在服务minor的相同版本的上下文中,通过提高版本进行不破坏向后兼容性的修订major
    • 破坏向后兼容性的修订将需要提高major-version,即创建服务的新版本

    Client-side(为客户端提供)

    提供客户端库以使用您的微服务:

    通常,服务开发人员还提供了一个客户端库来处理他们的微服务,它提供了一个方便的 API 并封装了集成交互的细节:

    • 验证接收对象的字段值的一致性
    • 基于经过验证的对象,它形成并http通过微服务的后端间接发送 -request load balancer,即 进入处理针对相应服务版本的请求的 Web 应用程序
    • 接收对已发送请求的响应,并将http其与来自 API 的用户友好类覆盖,将它们作为返回值提供

    如果您提供一个客户端库来处理您的微服务,那么在目标解决方案中,最方便的是也可以按服务版本拆分它,但需要注意以下几点:

    • major客户端库的 -version 必须与 major与之关联的微服务的 -version 匹配(major-version 是您在问题上下文中简单地称为 version)
    • 库的每个版本都必须在单独的“空间” 中major提供自己的版本API
      • namespace在C#
      • package在Java
      • ...

    解释:

    通过给API每个版本一个单独的“空间”,您可以让用户API在同一模块中同时使用多个版本的代码,这在版本之间的过渡期间尤其需要。

    例如,对于您的服务的消费者而言,当其模块(已经在使用旧版本)的整个转换到服务的新版本时,可能是一项耗时的任务,或者在特殊情况下,不需要完全过渡。


    Server-side(为服务器端提供)

    在服务器端,根据整体质量为每个版本的服务分配单独的文凭单元(独立工件):

    • 平行发展的可能性
    • 开发和交付到应用程序服务器的独立性(因此,站立)
    • 在一个应用服务器的上下文中同时使用第n'th 个服务版本的能力
    • 提供微服务的片/点调试和退役的可能性(包含Endpoint's / Conteoller's 的 Web 应用程序仅在相应版本的服务的上下文中处理请求)
    • 选择退出微服务版本之间的向后兼容性的可能性

    随着后续版本服务的进一步出现(因为您有第二个版本的服务,那么很可能第三个版本将在稍后出现),遵循类似的策略。

    解释:

    对于每个版本的微服务,您分配一个单独的模块/工件,它将作为 Web 应用程序文凭的单独单元交付。这些文凭单元中的每一个都将在微服务版本上下文中的独特上下文中上升:

    • some/web/app/context/v1
    • some/web/app/context/v2
    • ...
    • some/web/app/context/vn

    由于在 Web 应用程序上下文级别进行版本控制,这种解决方案可能看起来不太优雅(不是每个人都会喜欢在 url 中明确指定版本的想法),但值得给出一些理由赞成这个解决方案,使它看起来不那么令人厌恶:

    • 在一台应用服务器(WebSphere/WildFly/Tomcat/Jetty等)的上下文中,会出现以下机会:
      • 同时组合必要的微服务版本
      • 独立调试和停用不同版本的微服务
    • 在每个版本的服务的上下文中,都有一个机会L7 load balancing(OSI / ISOL7网络模型)到运行这些微服务的 Web 应用程序的相应实例,例如,通过: Nginx
      • upstream为每个版本的服务启动一个单独的
      • location为每个版本的服务启动一个单独的
      • 每个location's 将请求代理到相应版本的服务upstream
      • upstream为服务的相应版本之一生成load balancing一个 Web 应用程序(它只处理对某个版本的服务的请求),即使对应于不同版本的微服务的多个 Web 应用程序部署在一个应用程序服务器的上下文中。Load balancing例如,由以下算法之一生成:
        • Round Robin
        • IP-Hash
        • Least connected(在这种情况下,nginx端将需要维护一个最新的活动列表connection,即 http 连接)
        • ...

    数据库使用:

    如果需要使用持久数据存储来正确运行微服务,则可以使用以下方法之一来对数据模式进行版本控制:

    1. 将微服务的一个版本的数据与另一个版本的数据隔离开来
    2. 进化数据库设计

    您可以在链接中阅读有关对数据库模式进行版本控制的第二种方法,因此我将告诉您第一种方法,这是本答案上下文中最合乎逻辑的解决方案。

    作为隔离数据的一种方法,您可以查看最常见的两种:

    1. 各种数据库

      +高水平的数据隔离

      这种情况下,隔离级别将取决于托管不同版本服务数据的数据库的服务器,如果它们不同,那么即使一台服务器也不会影响其数据的服务不存储。

      -一次用于维护多个数据库实例(甚至可能是不同的数据库)的额外的、巨大的服务器资源(CPU、RAM 和 ROM)成本

    2. 通过使用的数据库提供的隔离机制

      -在容错方面缺乏隔离(一个数据库的下降会影响所有版本的服务的运行)

      一般来说,隔离的级别将取决于数据库内部对分区的抵抗力(partition tolerance来自CAP定理)

      +几乎完全没有服务器资源的额外成本

      例如,如果您使用 Oracle DBMS 存储不同版本服务的数据,您可以实现以下方法之一:

      1. 使用不同的数据模式

        • 所有版本服务的表、序列和其他数据库实体都应保留相同的名称,以最大程度地减少版本之间微服务代码的更改量
        • 创建DataSource一个用于处理数据库的包装器,它将请求上下文切换到所需的数据模式 ( ALTER SESSION SET CURRENT_SCHEMA),以避免在对数据库的查询中显式指定数据模式
      2. 使用分区机制(分片)

        • 对每个版本服务的数据使用单独的分区,并在查询以这种方式分区的表时显式指示分区列的值(例如,选择列VERSION),从而隐式指示Oracle DBMS进行搜索仅在某个分区文件中,迫使它忽略其余部分,因为它们保证缺少所请求版本的服务的数据

    在大多数情况下,从成本需求比来看,数据隔离的第二种选择是最合适的。

    值得注意的是,如果你有一些特殊的业务逻辑假设通过更高版本的服务你必须可以访问更低版本的数据,那么没有人禁止写一个周期性启动的(特别是一次性的)从包含较低版本数据的存储到包含较高版本数据的存储的数据转换器。

    例如,在 DBMS 的情况下,Oracle转换器可以写为PL/SQL存储过程


    附言

    我的整个帖子在某种程度上是在术语的上下文中呈现的java enterprise,但我希望以上内容能够以某种方式充分应用于您的.Net应用程序的体系结构。

    • 4
  2. mishamx
    2020-11-01T17:04:00Z2020-11-01T17:04:00Z

    类似的情况引发了许多问题: - 两个版本的开发是否会并行,如果可以,持续多长时间?- 版本有什么v2不同v1?

    如果第一个版本的开发处于错误修复级别,那么第一个选项。

    如果并行开发时间长,版本差异很大,那么也是第一种选择。

    如果并行开发持续了很长时间,版本差异不大,那么可以在旧控制器中添加新方法,名称中带有前缀,并在外部决定请求路由级别,并/v1/<action>在引擎盖controller/action和/v2/<action>引擎盖下controller/v2Action。

    • 2

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5