应用 Strangler 模式将遗留系统分解为微服务

许多来源在一般情况下提供了微服务的解释,但缺乏特定领域的示例。新来者或不确定从哪里开始的人可能会发现掌握如何将遗留系统过渡到微服务架构具有挑战性。本指南主要面向那些正在努力启动迁移工作的个人,它提供了特定于业务的示例来帮助理解该过程。

我想谈谈另一种模式 - Strangler模式 - 这是一种迁移模式,用于逐步从旧系统过渡到新系统,同时最大限度地降低风险。

让我们以传统杂货计费系统为例。现在是时候升级到微服务架构以利用其优势了。

Strangler 是一种逐步退役旧系统,同时逐步开发新系统的模式。这样,用户可以更快地开始使用新系统,而不是等待整个系统迁移完成。

在第一篇文章中,我将重点关注杂货店所需的微服务。例如,考虑这样一个场景:您当前有一个杂货店的遗留系统,并且您有兴趣将其升级到微服务架构并将其迁移到云。

杂货店遗留系统概述

首先,在线杂货店可能具有的模块是:

  1. 购物车服务

  2. 退款处理服务

  3. 库存管理服务:商品销售时减去商品数量,订单退款时加回商品数量。

根据 Strangler 模式,您应该能够用新的微服务替换一个模块,同时继续使用其他模块,直到更新的服务准备就绪。

在这里,您可以先用更新的服务替换购物车。由于购物车服务依赖于支付处理服务,因此您也需要开发该服务。

假设我们将逐步开发这些服务。出于演示目的,我将仅关注上述三个服务。但在现实场景中,您可能需要如下所示的其他服务来完成杂货店的整个电子商务网站:


public class Product
{public Guid Id { get; set; }public string Name { get; set; }public decimal Price { get; set; }public int StockQuantity { get; set; }public Category ProductCategory { get; set; }
}public class Category
{public Guid Id { get; set; }public string Name { get; set; }
}public class ShoppingCartItem
{public Product Product { get; set; }public int Quantity { get; set; }
}public class ShoppingCart
{public Guid Id { get; set; }public List<ShoppingCartItem> Items { get; set; }public Customer Customer { get; set; }public DateTime CreatedAt { get; set; }
}public class Order
{public Guid Id { get; set; }public List<ShoppingCartItem> Items { get; set; }public Customer Customer { get; set; }public decimal TotalAmount { get; set; }public DateTime CreatedAt { get; set; }
}

图片

现在让我们考虑每个服务所需的基本模型类和操作。

对于购物车服务,您需要以下模型类和操作:产品、产品类别、添加到购物车的商品、购物车和订单。它的结构如下:

购物车服务


public class Product
{public Guid Id { get; set; }public string Name { get; set; }public decimal Price { get; set; }public int StockQuantity { get; set; }public Category ProductCategory { get; set; }
}public class Category
{public Guid Id { get; set; }public string Name { get; set; }
}public class ShoppingCartItem
{public Product Product { get; set; }public int Quantity { get; set; }
}public class ShoppingCart
{public Guid Id { get; set; }public List<ShoppingCartItem> Items { get; set; }public Customer Customer { get; set; }public DateTime CreatedAt { get; set; }
}public class Order
{public Guid Id { get; set; }public List<ShoppingCartItem> Items { get; set; }public Customer Customer { get; set; }public decimal TotalAmount { get; set; }public DateTime CreatedAt { get; set; }
}

理想情况下,您应该创建一个共享项目来容纳所有模型和接口。首先必须确定必要的模型和操作。

在考虑客户可以在购物车中执行的操作时,通常只涉及一个主要操作,CreateOrder,即向购物车添加商品。然而,其他操作,例如支付处理、退款和库存调整,应作为单独的微服务来实现。这种模块化方法可以在管理业务流程的不同方面提供更大的灵活性和可扩展性。


public class BillingService : IBillingService
{public Order CreateOrder(Customer customer, List<ShoppingCartItem> items){return new Order{Id = Guid.NewGuid(), //Create a new order idItems = items,Customer = customer,TotalAmount = CalculateTotalAmount(items),CreatedAt = DateTime.Now};}private decimal CalculateTotalAmount(List<ShoppingCartItem> items){decimal totalAmount = 0;foreach (var item in items){totalAmount += item.Product.Price * item.Quantity;}return totalAmount;}
}

理想情况下,在共享项目中,您必须为 IBillingService 创建一个接口。它应该如下所示:

public interface IBillingService{   public Order CreateOrder(Customer customer, List<ShoppingCartItem> items);}

现在您可以对CreateOrder操作进行单元测试。

在现实世界中,通常的做法是创建IBillingRepository 将订单保存在数据库中。该存储库应包含在数据库中存储订单的方法,或者您可以选择使用下游服务来处理订单创建过程。

我不会解决用户身份验证、安全、托管、监控、代理以及本讨论中的其他相关主题,因为它们是不同的主题。我的主要关注点仍然是根据您的特定需求量身定制的微服务的设计方面。

创建购物车后,下一步涉及客户付款。让我们继续创建支付服务项目及其关联模型。

付款处理服务


public class Payment
{public Guid Id { get; set; }public decimal Amount { get; set; }public PaymentStatus Status { get; set; }public DateTime PaymentDate { get; set; }public PaymentMethod PaymentMethod { get; set; }
}public enum PaymentStatus
{Pending,Approved,Declined,
}
public enum PaymentMethod
{CreditCard,DebitCard,PayPal,
}public class Receipt
{public Guid Id { get; set; }public Order Order { get; set; }public decimal TotalAmount { get; set; }public DateTime IssuedDate { get; set; }
}public class PaymentService : IPaymentService
{private PaymentGateway paymentGateway;public PaymentService(){this.paymentGateway = new PaymentGateway();}public Payment MakePayment(decimal amount, PaymentMethod paymentMethod, string paymentDetails){// In a real system, you would handle the payment details and validation before calling the payment gateway.return paymentGateway.ProcessPayment(amount, paymentMethod, paymentDetails);}
}public class ReceiptService : IReceiptService
{public Receipt GenerateReceipt(Order order){var receipt = new Receipt{Id = Guid.NewGuid(),Order = order,TotalAmount = order.TotalAmount,IssuedDate = DateTime.Now};return receipt;}
}

在此服务项目中,您必须创建并实现以下接口:


public Interface IPaymentService
{public Payment MakePayment(decimal amount, PaymentMethod paymentMethod, string paymentDetails); 
}
public Interface IReceiptService
{public Receipt GenerateReceipt(Order order);
}public Interface IPaymentRepository
{public Payment ProcessPayment(decimal amount, PaymentMethod paymentMethod, string paymentDetails)
} public class PaymentGateway : IPaymentRepository
{public Payment ProcessPayment(decimal amount, PaymentMethod paymentMethod, string paymentDetails){// Simplified payment processing logic for demonstrationvar payment = new Payment{Id = Guid.NewGuid(),Amount = amount,Status = PaymentStatus.Pending,PaymentDate = DateTime.Now,PaymentMethod = paymentMethod};// In a real system, you would connect to a payment gateway and process the payment, updating the payment status accordingly.// For example, you might use an external payment processing library or API to handle the transaction.// Simulating a successful payment here for demonstration purposes.payment.Status = PaymentStatus.Approved;return payment;}
}

创建所有这些服务后,我们可以轻松地使用新系统停用购物车(假设您也有一个并行完成的新用户界面)。

接下来,我们必须解决下订单后的库存管理问题。库存管理服务负责在创建采购订单时补货。该服务项目的结构如下:

库存管理服务

public class Product
{public Guid Id { get; set; }public string Name { get; set; }public decimal Price { get; set; }public int QuantityInStock { get; set; }public Category ProductCategory { get; set; }
}
public class Category
{public Guid Id { get; set; }public string Name { get; set; }
}public class Supplier
{public Guid Id { get; set; }public string Name { get; set; }public string ContactEmail { get; set; }
}
public class PurchaseOrder
{public Guid Id { get; set; }public Supplier Supplier { get; set; }public List<PurchaseOrderItem> Items { get; set; }public DateTime OrderDate { get; set; }public bool IsReceived { get; set; }
}public class PurchaseOrderItem
{public Product Product { get; set; }public int QuantityOrdered { get; set; }public decimal UnitPrice { get; set; }
}public interface IInventoryManagementService
{void ReceivePurchaseOrder(PurchaseOrder purchaseOrder);void SellProduct(Product product, int quantitySold);
}public class InventoryManagementService : IInventoryManagementService
{public void ReceivePurchaseOrder(PurchaseOrder purchaseOrder){if (purchaseOrder.IsReceived){throw new InvalidOperationException("The order is already placed.");}foreach (var item in purchaseOrder.Items){item.Product.QuantityInStock += item.QuantityOrdered;}purchaseOrder.IsReceived = true;}public void SellProduct(Product product, int quantitySold){if (product.QuantityInStock < quantitySold){throw new InvalidOperationException("Item not in stock.");}product.QuantityInStock -= quantitySold;}
}

正如我所提到的,本指南主要面向那些正在努力启动迁移工作的个人,它提供了特定于业务的示例来帮助理解该过程。

我相信本文为如何在微服务架构中启动迁移项目提供了宝贵的见解。如果您正在开发杂货店或任何在线购物车系统,那么此信息对您来说应该特别有用。我希望你能从这里拿走它。在我的下一篇文章中,我将介绍另一个特定于领域的示例,因为您始终可以在其他地方探索有关微服务的更多一般信息。


作者:Somasundaram Kumarasamy

更多技术干货请关注公号【云原生数据库

squids.cn,云数据库RDS,迁移工具DBMotion,云备份DBTwin等数据库生态工具。

irds.cn,多数据库管理平台(私有云)。

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

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

相关文章

Spring Boot学习随笔- 拦截器实现和配置(HandlerInterceptor、addInterceptors)、jar包部署和war包部署

学习视频&#xff1a;【编程不良人】2021年SpringBoot最新最全教程 第十三章、拦截器 拦截器 &#xff1a;Interceptor 拦截 中断 类似于javaweb中的Filter&#xff0c;不过没有Filter那么强大 作用 Spring MVC的拦截器是一种用于在请求处理过程中进行预处理和后处理的机制。拦…

机器学习算法(11)——集成技术(Boosting——梯度提升)

一、说明 在在这篇文章中&#xff0c;我们学习了另一种称为梯度增强的集成技术。这是我在机器学习算法集成技术文章系列中与bagging一起介绍的一种增强技术。我还讨论了随机森林和 AdaBoost 算法。但在这里我们讨论的是梯度提升&#xff0c;在我们深入研究梯度提升之前&#xf…

(1)(1.9) MSP (version 4.2)

文章目录 前言 1 协议概述 2 配置 3 参数说明 前言 ArduPilot 支持 MSP 协议&#xff0c;可通过任何串行端口进行遥测、OSD 和传感器。这样&#xff0c;ArduPilot 就能将遥测数据发送到 MSP 兼容设备&#xff08;如大疆护目镜&#xff09;&#xff0c;用于屏幕显示&#x…

C# SixLabors.ImageSharp.Drawing的多种用途

生成验证码 /// <summary> /// 生成二维码 /// </summary> /// <param name"webRootPath">wwwroot目录</param> /// <param name"verifyCode">验证码</param> /// <param name"width">图片宽度</…

Spring Boot学习随笔- 文件上传和下载(在线打开、附件下载、MultipartFile)

学习视频&#xff1a;【编程不良人】2021年SpringBoot最新最全教程 第十二章、文件上传、下载 文件上传 文件上传是指将文件从客户端计算机传输到服务器的过程。 上传思路 前端的上传页面&#xff1a;提交方式必须为post&#xff0c;enctype属性必须为multipart/form-data开发…

在modelsim中查看断言

方法一&#xff1a;单纯的modelsim环境 &#xff08;1&#xff09;编译verilog代码时按照system verilog进行编译 vlog -sv abc.v 或者使用通配符编译所有的.v或者.sv文件 &#xff08; vlog -sv *.sv *.v&#xff09; &#xff08;2&#xff09;仿真命令加一个-assert…

R语言——基本操作(二)

目录 一、矩阵与数组 二、列表 三、数据框 四、因子 五、缺失数据 六、字符串 七、日期和时间 参考 一、矩阵与数组 matrix&#xff1a;创建矩阵&#xff0c;nrow 和 ncol 可以省略&#xff0c;但其值必须满足分配条件&#xff0c;否则会报错 只写一个值则自动分配&…

基于JAVA的海南旅游景点推荐系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用户端2.2 管理员端 三、系统展示四、核心代码4.1 随机景点推荐4.2 景点评价4.3 协同推荐算法4.4 网站登录4.5 查询景点美食 五、免责说明 一、摘要 1.1 项目介绍 基于VueSpringBootMySQL的海南旅游推荐系统&#xff…

如何选择适合的UI自动化测试工具

随着软件开发项目的复杂性增加&#xff0c;UI自动化测试成为确保应用程序质量的关键步骤之一。然而&#xff0c;在选择UI自动化测试工具时&#xff0c;开发团队需要考虑多个因素&#xff0c;以确保选取的工具适用于项目需求并提供可靠的测试结果。 1. 了解项目需求 在选择UI自动…

百度侯震宇详解:大模型将如何重构云计算?

12月20日&#xff0c;在2023百度云智大会智算大会上&#xff0c;百度集团副总裁侯震宇以“大模型重构云计算”为主题发表演讲。他强调&#xff0c;AI原生时代&#xff0c;面向大模型的基础设施体系需要全面重构&#xff0c;为构建繁荣的AI原生生态筑牢底座。 侯震宇表示&…

Android蓝牙协议栈fluoride(八) - 音乐播放与控制(1)

概述 通常情况下音乐播放与控制这两个profile(即A2DP和AVRCP)都是同时存在的&#xff0c;A2DP分为Sink(SNK)和Source(SRC)两个角色&#xff0c;ACRVP分为Controller(CT)和Target(TG)两个角色。接下来的几篇博客将详细介绍这两个profile。 Sink和Source、CT和TG都是成对出现的。…

智能优化算法应用:基于梯度算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于梯度算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于梯度算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.梯度算法4.实验参数设定5.算法结果6.参考文献7.MA…

vue中最重要的点,双向数据绑定是什么?

一、什么是双向绑定 我们先从单向绑定切入单向绑定非常简单&#xff0c;就是把Model绑定到View&#xff0c;当我们用JavaScript代码更新Model时&#xff0c;View就会自动更新双向绑定就很容易联想到了&#xff0c;在单向绑定的基础上&#xff0c;用户更新了View&#xff0c;Mo…

多维时序 | MATLAB实现BiTCN-Multihead-Attention多头注意力机制多变量时间序列预测

多维时序 | MATLAB实现BiTCN-Multihead-Attention多头注意力机制多变量时间序列预测 目录 多维时序 | MATLAB实现BiTCN-Multihead-Attention多头注意力机制多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 多维时序 | MATLAB实现BiTCN-Multihea…

vp与vs联合开发-串口通信

模拟串口通信 1.配置虚拟串口驱动 winform 实现串口通信 1.模拟串口和winform程序通信 2.模拟串口通信 控制拍照功能

ubuntu保存分辨率失效解决办法

在VM虚拟机中&#xff0c;遇到修改ubuntu分辨率后&#xff0c;重启后又重置的解决办法。 目前我的ubuntu版本是&#xff1a;ubuntu 18.04.6 版本。 1.首先&#xff0c;在你喜欢的目录建立一个.sh 脚本文件。 终端执行命令&#xff1a;sudo vim xrandr.sh 2.按 i 进入编辑状…

【数据结构】五、数组与广义表

目录 一、定义 二、计算数组元素地址 三、稀疏矩阵快速转置 稀疏矩阵的表示 稀疏矩阵快速转置 四、广义表 一、定义 我们所熟知的一维、二维数组的元素是原子类型。广义表中的元素除了原子类型还可以是另一个线性表。当然所有的数据元素仍然属于同一类型。 这里的数组可…

VSCode安装PYQT5

安装PYQT5 pip install PyQt5 -i https://pypi.tuna.tsinghua.edu.cn/simple pip install PyQt5-tools -i https://pypi.tuna.tsinghua.edu.cn/simple 获得Python环境位置 查看函数库安装位置 pip show 函数库名 通过查询函数库&#xff0c;了解到python安装位置为 C:\User…

在 Kubernetes 上部署 Python 3.7、Chrome 和 Chromedriver(版本 114.0.5735.90)的完整指南

一、构建基础镜像 docker build -f /u01/isi/DockerFile . -t thinking_code.com/xhh/crawler_base_image:v1.0.2docker push thinking_code.com/xhh/crawler_base_image:v1.0.2 二、K8s运行Pod 三、DockerFile文件 # 基于镜像基础 FROM python:3.7# 设置代码文件夹工作目录…

泛微e-cology XmlRpcServlet文件读取漏洞复现

漏洞介绍 泛微新一代移动办公平台e-cology不仅组织提供了一体化的协同工作平台,将组织事务逐渐实现全程电子化,改变传统纸质文件、实体签章的方式。泛微OA E-Cology 平台XmRpcServlet接口处存在任意文件读取漏洞&#xff0c;攻击者可通过该漏洞读取系统重要文件 (如数据库配置…