《微服务架构设计模式》第十三章 微服务架构的重构策略

微服务架构的重构策略

    • 一、重构到微服务需要考虑的问题
      • 1、为什么重构
      • 2、重构形式
      • 3、重构策略
    • 二、设计服务与单体的协作方式
    • 三、总结



一、重构到微服务需要考虑的问题

1、为什么重构

单体地狱造成的业务问题:

  1. 交付缓慢
  2. 充满故障的软件交付
  3. 可扩展性差

2、重构形式

1、一步到位

你企图从零开始开发一个全新的基于微服务的应用程序(彻底替换遗留的单体应用)。虽然从头开始并抛弃老代码库听起来很有吸引力,但它的风险极高,很可能以失败告终。你将花费数月甚至数年来复制现有功能,然后才能实现业务今天就需要的功能!此外,无论如何,你都需要开发和维护老的应用程序,这会打乱重写的工作,并意味着你有一个不断变化的目标。更重要的是,你可能会浪费时间重新实现不再需要的功能。正如Martin Fowler所说的那样,“推倒重写的唯一保证,就是彻底搞砸一切”。


2、逐步绞杀

逐步构建一个新的、被称为绞杀者应用程序的应用。绞杀者应用程序由与单体应用程序结合使用的微服务组成。随着时间的推移,单体应用程序实现的功能数量会缩小,直到完全消失或者变成另一个微服务。这种策略类似于以70mph(约110km/h)的速度在高速公路上行驶时为汽车更换轮胎。这很有挑战性,但相比“一步到位,推倒重来”的风险要小得多。

Martin Fowler把这项策略称为绞杀者应用模式。这个名字来自在热带雨林中发现的绞杀者藤蔓


特点:

  1. 尽早且频繁的体现出价值
  2. 尽可能少对单体做出修改
  3. 不需要考虑过多的基础设置,但是需要保证拥有自动化测试的部署流水线



3、重构策略

有三种主要策略可以实现对单体的“绞杀”,并逐步用微服务替换之:

1、将新功能实现为服务

  • API Gateway:将对新功能的请求路由到新服务,并将遗留请求路由到单体。
  • 集成胶水代码:将服务与单体结合。它使服务能够访问单体所拥有的数据,并能够调用单体实现的功能。

2、隔离表现层和后端。

将表现层与业务逻辑和数据访问层分开。典型的企业应用程序包含以下各层:

  1. 表现逻辑层:它由处理HTTP请求的模块组成,并生成实现Web UI的HTML页面。在具有复杂用户界面的应用程序中,表现层通常包含大量代码。
  2. 业务逻辑层:由实现业务规则的模块组成,这些模块在企业应用程序中可能很复杂。
  3. 数据访问逻辑层:包含访问基础设施服务(如数据库和消息代理)的模块。

以这种方式拆分单体应用有两个主要好处。它使你能够彼此独立地开发、部署和扩展这两个应用程序。特别是,它允许表现层开发人员快速迭代用户界面并轻松执行A/B测试,而无须部署后端。这种方法的另一个好处是它公开了业务逻辑的一组远程API,可以被稍后开发的微服务调用。

但这种策略只是部分解决方案。很可能至少有一个或两个最终的应用程序仍然是一个难以管理的单体。你需要使用第三种策略将单体替换为服务。


3、通过将功能提取到服务中来分解单体。

你想要提取到服务中的功能是对单体应用自上而下的一个“垂直切片”。该切片包含以下内容:

  1. 领域逻辑。
  2. 出站适配器,例如数据库访问逻辑。
  3. 单体的数据库模式。

提取服务具有挑战性。你需要确定如何将单体的领域模型分成两个独立的领域模型,其中一个模型成为服务的领域模型。你需要打破对象引用等依赖。你甚至可能需要拆分类,以将功能移动到服务中。你还需要重构数据库。

第一种策略阻止了单体的发展。它通常是一种快速展示微服务价值的方法,有助于让迁移和重构的工作获得公司内部各个层面支持。另外两种策略打破了单体。在重构单体时,你有时可能会使用第二种策略,但你肯定会使用第三种策略,因为它能实现将功能从单体迁移到绞杀者应用程序中。




二、设计服务与单体的协作方式

1、设计集成胶水


2、数据一致性

借助Saga


3、处理身份验证和访问授权




三、总结

  1. 在迁移到微服务架构之前,确保你的软件交付问题是由于业务需求超出单体架构承载能力而导致的。在架构重构之前,你可以通过改进软件开发过程来加速交付。
  2. 通过逐步开发一个绞杀者应用程序来迁移到微服务非常重要。绞杀者应用程序是一个新的应用程序,由围绕现有单体应用构建的微服务组成。你应该尽早并经常证明自己的价值,以确保业务团队支持迁移工作。
  3. 将微服务引入架构的一个好方法是将新功能作为服务实现。这样做可以使你使用现代技术和开发过程快速轻松地开发功能。这是快速展示迁移到微服务价值的好方法。打破单体结构的一种方法是将表现层与后端隔离,这会产生两个较小的单体结构。虽然这不是一个巨大的改进,但它确实意味着你可以独立部署每个单体。例如,这允许用户界面团队更轻松地在用户界面设计上进行迭代,而不会影响后端。
  4. 打破单体的主要方法是逐步将功能从单体转移到服务中。重点是提取提供最大利益的服务。例如,如果提取实现正在积极开发功能的服务,你将加快开发速度。
  5. 新开发的服务几乎总是必须与单体交互。服务通常需要访问单体的数据并调用其功能。单体有时需要访问服务的数据并调用其功能。要实现此协作,需要开发集成胶水,其中包含单体的入站和出站适配器。
  6. 为了防止单体的领域模型污染服务的领域模型,集成胶水应该使用反腐层,这是一个在领域模型之间进行转换的软件层。
    最小化对提取服务的单体结构的影响的一种方法是将移动到服务的数据复制回单体的数据库。由于单体的数据库模式保持不变,因此无须对单体代码库进行潜在的大范围修改。
  7. 开发服务通常需要你实现涉及单体的Saga。但实现可补偿性事务可能具有挑战性,需要对单体进行大范围的修改。因此,有时你需要仔细设计服务的提取顺序,以避免在单体中实现可补偿事务。
  8. 在重构为微服务架构时,你需要同时支持单体应用的现有安全机制,该机制通常基于内存的会话,以及服务使用的基于令牌的安全机制。幸运的是,一个简单的解决方案是修改单体的登录处理程序以生成包含安全令牌的cookie,然后由API Gateway转发给服务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1378.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Visual Studio 向工程中添加现有文件夹

前言: 在创建C#类库(dll)工程后,需要把现有的C#文件添加进工程中 步骤1.将所有文件夹复制到工程中 步骤2. 点击这个图标,显示所有文件夹 工程目录下的所有文件夹都会被显示出来 选中需要添加的文件夹,右…

Linux安装MongoDB数据库,并内网穿透远程连接

文章目录 前言1. 配置Mongodb源2. 安装MongoDB3. 局域网连接测试4. 安装cpolar内网穿透5. 配置公网访问地址6. 公网远程连接7. 固定连接公网地址8. 使用固定地址连接 前言 MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富&…

虚拟化容器化与docker

虚拟化容器化与docker 基本概念虚拟化分类虚拟化实现主机虚拟化实现容器虚拟化实现命名空间namespace空间隔离 控制组群cgroup资源隔离 LXC(Linux Container) docker与虚拟机 基本概念 物理机: 实际的服务器或者计算机。相对于虚拟机而言的对实体计算机的称呼。物理…

初识Redis——Redis概述、安装、基本操作

目录 一、NoSQL介绍 1.1什么是NoSQL 1.2为什么会出现NoSQL技术 1.3NoSQL的类别 1.4传统的ACID是什么 1.5 CAP 1.5.1 经典CAP图 1.5.4 什么是BASE 二、Redis概述 2.1 什么是Redis 2.2 Redis能干什么 2.3 Redis的特点 2.4 Redis与memcached对比 2.5 Redis的安装 2.6 Docker安装 三…

二、学习回归 - 基于广告费预测点击量

山外风雨三尺剑 有事提剑下山去 云中花鸟一屋书 无忧翻书圣贤来 1.设置问题 以Web广告和点击量的关系为例来学习回归。 前提:投入的广告费越多,广告的点击量就越高。 根据以往的经验数据,可以得到下图: 那么假设我要投200块的广…

SeLa:Self Labeling Via Simultaneous Clustering and Representation Learning

方法论 有监督的分类任务实现 给定一个将数据I映射至特征向量 x ∈ R D x ∈ R^D x∈RD 的深度神经网络 Φ Φ Φ ,即 x Φ ( I ) x Φ ( I ) xΦ(I)。使用有N个样本 I 1 , … , I N I_1 , … , I_N I1​,…,IN​, 且具有标签 y 1 , … , y N ∈ { 1 , … , K }…

Office如何通过VSTO进行WORD插件开发?

文章目录 0.引言1.工具准备2.WORD外接程序创建和生成3.外接程序生成并使用 0.引言 VSTO(Visual Studio Tools for Office )是VBA的替代,是一套用于创建自定义Office应用程序的Visual Studio工具包。VSTO可以用Visual Basic 或者Visual C#扩展…

华为ospf路由协议在局域网中的高级应用案例

关键配置: 1、出口为ospf区域0,下联汇聚依次区域1、2…,非骨干全部为完全nssa区域 2、核心(abr)上对非骨干区域进行路由汇总,用于解决出口两台路由的条目数量 3、ospf静默接口配置在汇聚下联接接入交换机的…

在Microsoft Excel中如何快速将上下两行数据合并为一行?

合并单元格是电子表格初学者最常用的选项之一。当一组单元格、行或列需要标题或标签时,合并单元格是一种常用的技术。 合并单元格时,仅保留区域左上角单元格中的值或公式,并将其显示在合并后的单元格中。将丢弃任何其他值或公式,那么如何在新的空白单元格中将两行数据合并…

基于FPGA的按键消抖

文章目录 基于FPGA的按键消抖一、按键消抖原理二、按键消抖代码三、仿真代码编写四:总结 基于FPGA的按键消抖 一、按键消抖原理 按键抖动:按键抖动通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性…

Makefile学习笔记

Makefile思想: 一个简单的 Makefile 文件包含一系列的“规则”,其样式如下: 目标:依赖 tab命令 例如: test : main.c sub.c sub.h gcc -o test main.c sub.c如果“依赖文件”比“目标文件”更加新,那么执…

如何保证消息的可靠性+延迟队列(TTL+死信队列+延迟队列)

目录 1.如何保证消息的可靠性 1.1.消息的可靠投递 confirm机制 return机制 1.2.如何保证消息在队列中不丢失 1.3.确保消息能可靠的被消费掉 2.延迟队列 2.1.TTL 2.2.死信队列 2.3.延迟队列 3.如何防止消费者重复消费消息 1.如何保证消息的可靠性 1.1.消息的可靠投递…

Ajax详解

文章目录 1. 概述1.1 Ajax工作原理1.2 Ajax的作用1.3 同步异步 2. 原生Ajax3. Axios3.1 Axios的基本使用3.2 Axios快速入门3.3 请求方法的别名 1. 概述 Ajax 是 “Asynchronous JavaScript and XML”(异步 JavaScript 和 XML)的缩写。它是一种在无需重新…

RabbitMQ知识掌握 【进阶篇】

一、如何保证消息的可靠性 🍉 1.保证消息的可靠性投递 🥝 在生产环境中由于一些不明原因,导致 rabbitmq 重启,在 RabbitMQ 重启期间生产者消息投递失败,导致消息丢失,需要手动处理和恢复。于是&#xff0…

微服务Gateway网关(自动定位/自定义过滤器/解决跨域)+nginx反向代理gateway集群

目录 Gateway网关 1.0.为什么需要网关? 1.1.如何使用gateway网关 1.2.网关从注册中心拉取服务 1.3.gateway自动定位 1.4.gateway常见的断言 1.5.gateway内置的过滤器 1.6.自定义过滤器-全局过滤器 1.7.解决跨域问题 2.nginx反向代理gateway集群 2.1.配置…

什么是 TCP 和 UDP?Java 中如何实现 TCP 和 UDP 协议

在计算机网络中,TCP(传输控制协议)和UDP(用户数据报协议)是两种最常用的传输层协议。它们都用于在网络上传输数据,但是它们之间有很多不同之处。本文将介绍TCP和UDP的基本概念,以及在Java中如何…

ubuntu20.04配置vscode

下载: https://az764295.vo.msecnd.net/stable/660393deaaa6d1996740ff4880f1bad43768c814/code_1.80.0-1688479026_amd64.debhttps://az764295.vo.msecnd.net/stable/660393deaaa6d1996740ff4880f1bad43768c814/code_1.80.0-1688479026_amd64.deb 安装&#xff1a…

Ubuntu 放弃了战斗向微软投降

导读这几天看到 Ubuntu 放弃 Unity 和 Mir 开发,转向 Gnome 作为默认桌面环境的新闻,作为一个Linux十几年的老兵和Linux桌面的开发者,内心颇感良多。Ubuntu 做为全世界Linux界的桌面先驱者和创新者,突然宣布放弃自己多年开发的Uni…

回首2023上半年:成长、思考、感恩

文章目录 每日一句正能量前言一、目标达成情况总结二、工作和学习成果总结三、下半年规划总结四、个人想法 后记附录 每日一句正能量 做一个向日葵族,面对阳光,不自艾自怜,每天活出最灿烂的自己。曾经拥有的,不要忘记。不能得到的…

day52

思维导图 比较指令结果的条件码 练习 汇编实现1-100的累加 .text .global _strat _start: mov r0,#0mov r1,#0 add_fun:add r0,r0,#1cmp r0,#100addls r1,r1,r0bls add_fun .end