命令和查询责任隔离(CQRS)模式

设计模式 同时被 2 个专栏收录
37 篇文章 0 订阅
6 篇文章 0 订阅

【博文目录>>>】


命令和查询责任隔离(CQRS)模式

使用单独的接口将读取数据的操作与更新数据的操作隔离开来。这种模式可以最大限度地提高性能、可伸缩性和安全性;通过更高的灵活性支持系统随时间的发展;并防止更新命令在域级别造成合并冲突。

背景与问题

在传统的数据管理系统中,命令(对数据的更新)和查询(对数据的请求)都针对单个数据存储库中的同一组实体执行。这些实体可以是关系数据库(例如SQL Server)中一个或多个表中行的子集。

通常,在这些系统中,所有创建、读取、更新和删除(CRUD)操作都应用于实体的相同表示形式。例如,数据访问层(DAL)从数据存储中检索表示客户的数据传输对象(DTO),并显示在屏幕上。用户更新DTO的某些字段(可能通过数据绑定),然后DTO被DAL保存回数据存储中。相同的DTO用于读写操作,如图1所示。

在这里插入图片描述

图1-传统CRUD体系结构

当应用于数据操作的业务逻辑有限时,传统的CRUD设计工作良好。开发工具提供的脚手架机制可以非常快速地创建数据访问代码,然后可以根据需要定制这些代码。

然而,传统的CRUD方法有一些缺点:

  • 它通常意味着数据的读和写表示之间不匹配,例如,即使操作中不需要它们,也必须正确更新其他列或属性。
  • 当数据存储中锁定记录时,可能会遇到协作域中的数据争用(多个参与者在同一组数据上并行操作),或者在使用乐观锁定时由并发更新引起的更新冲突。这些风险随着系统的复杂性和吞吐量的增加而增加。此外,由于数据存储和数据访问层的负载以及检索信息所需查询的复杂性,传统方法也会对性能产生负面影响。
  • 它会使管理安全性和权限变得更麻烦,因为每个实体都要同时执行读和写操作,这可能会无意中暴露错误上下文中的数据。


要更深入地了解CRUD方法的局限性,请参阅MSDN上的"CRUD,只有在您能够负担的情况下"在MSDN上。

解决方案

命令和查询责任隔离(CQRS)是一种模式,它通过使用单独的接口将读取数据(查询)的操作与更新数据(命令)的操作隔离开来。这意味着用于查询和更新的数据模型是不同的。然后可以隔离模型,如图2所示,尽管这不是绝对的需求。

在这里插入图片描述

图2-基本的CQRS体系结构

与基于CRUD的系统中固有的数据模型(开发人员从中构建自己的概念模型)相比,对基于CQRS的系统中的数据使用单独的查询和更新模型大大简化了设计和实现。但是,一个缺点是,与CRUD设计不同,CQRS代码不能通过使用脚手架机制自动生成。

用于读取数据的查询模型和用于写入数据的更新模型可以访问相同的物理存储,可以使用SQL视图或动态生成投影。但是,通常将数据分成不同的物理存储以最大化性能,可伸缩性和安全性。如图3所示。

在这里插入图片描述

图3-具有单独读写存储的CQRS体系结构

读存储可以是写存储的只读副本,或者读和写存储可能具有完全不同的结构。使用读取存储的多个只读副本可以显著提高查询性能和应用程序UI响应能力,特别是在分布场景中,其中只读副本位于接近应用程序实例的位置。一些数据库系统(如SQL Server)提供了其他功能,如故障转移副本,以最大限度地提高可用性。

读和写存储的分离也允许每个存储被适当地缩放以匹配负载。例如,读存储通常会遇到比写入存储高得多的负载。

当查询/读取模型包含非规范化信息时(请参见物化视图模式),在为应用程序中的每个视图读取数据或查询系统中的数据时,性能都会最大化。

有关CQRS模式及其实现的更多信息,请参见以下资源:

问题和思考

在决定如何实现此模式时,请考虑以下几点:

  • 将数据存储划分为单独的物理存储进行读和写操作可以提高系统的性能和安全性,但它可以在弹性和最终一致性方面增加相当大的复杂性。必须更新读取模型存储,以反映对写入模型存储的更改,并且可能难以检测用户何时基于过时的读取数据发出了请求,这意味着操作无法完成。


有关最终一致性的说明,请参见"数据一致性入门"

  • 考虑将CQRS应用于系统中最有价值的有限部分,并从中吸取经验教训。
  • 实现最终一致性的一种典型方法是将事件源与CQRS结合使用,这样写模型就是由命令执行驱动的仅附加的事件流。这些事件用于更新作为读取模型的物化视图。有关更多信息,请参见事件源和CQRS。

何时使用此模式

这种模式非常适合于:

  • 在同一数据上并行执行多个操作的协作域。CQRS允许您定义具有足够粒度的命令,以尽量减少域级别的合并冲突(或任何确实出现的冲突都可以由命令合并),即使在更新看起来是相同类型的数据时也是如此。
  • 与基于任务的用户界面(其中,通过一系列步骤指导用户完成一个复杂的过程),复杂的域模型以及已经熟悉域驱动设计(DDD)技术的团队一起使用写入模型具有完整的命令处理堆栈,其中包含业务逻辑,输入验证和业务验证,以确保每个聚合始终保持一致(每个关联对象的群集都被视为一个单元,以进行数据更改)。读取模型没有业务逻辑或验证堆栈,仅返回DTO以在视图模型中使用。读取模型最终与写入模型一致。
  • 数据读取的性能必须与数据写入的性能分开微调的场景,特别是当读写比很高时,以及当需要水平缩放时。例如,在许多系统中,读取操作的数量比写入操作的数量大几个数量级。为此,请考虑扩展读取模型,但仅在一个或几个实例上运行写入模型。少量的写模型实例还有助于最大程度地减少合并冲突的发生。
  • 一个团队的开发人员可以专注于作为写模型部分的复杂域模型,而另一组经验不足的团队可以专注于读模型和用户界面的场景。
  • 预计系统会随着时间而发展并且可能包含模型的多个版本,或者业务规则会定期更改的场景。
  • 与其他系统的集成,特别是与事件源的组合,其中一个子系统的时间故障不会影响其他子系统的可用性。

这种模式可能不适用于以下情况:

  • 领域或业务规则很简单的地方。
  • 简单的CRUD风格的用户界面和相关的数据访问操作就足够了。
  • 用于整个系统的实施。总体数据管理方案中有一些特定的组件,在这些组件中CQRS可能有用,但是在实际上不需要的情况下,它可能会增加相当多的不必要的复杂性。

事件源与CQRS

CQRS模式通常与事件源模式一起使用。基于CQRS的系统使用独立的读写数据模型,每个模型都是根据相关任务量身定做的,并且通常位于物理上独立的存储区。当与事件源一起使用时,事件的存储是写模型,这是信息的权威来源。基于CQRS的系统的读取模型提供数据的物化视图,通常是高度非规范化的视图。这些视图是根据应用程序的接口和显示需求定制的,这有助于最大限度地提高显示和查询性能。

使用事件流作为写存储而不是某个时间点的实际数据,可以避免在单个聚合上发生更新冲突,并最大限度地提高性能和可伸缩性。这些事件可用于异步生成用于填充读取存储的数据的物化视图。

因为事件存储是信息的权威来源,所以可以在系统演进或必须更改读取模型时删除实例化视图并重播所有过去的事件,以创建当前状态的新表示形式。物化视图实际上是数据的持久只读缓存。。

当使用CQRS与事件源模式相结合时,请考虑以下几点:

  • 与任何读写存储分离的系统一样,基于这种模式的系统最终只能是最终一致的。在生成的事件与保存由这些事件更新的操作结果的数据存储之间会有一些延迟。。
  • 该模式带来了额外的复杂性,因为必须创建代码来初始化和处理事件,以及组装或更新查询或读取模型所需的适当视图或对象。当将CQRS模式与事件源结合使用时,其固有的复杂性会使成功实施变得更加困难,并且需要重新学习一些概念和设计系统的不同方法。但是,由于保留了数据更改的意图,因此事件源可以使对域的建模更加容易,并且可以更轻松地重建视图或创建新视图。
  • 通过重放和处理特定实体或实体集合的事件来生成物化视图以用于读取的模型或数据的投影,可能需要大量的处理时间和资源使用,尤其是在需要长时间汇总或分析值的情况下,因为可能需要检查所有相关事件。通过按计划的时间间隔实施数据快照(例如已发生的特定操作的总数或实体的当前状态),可以部分解决此问题。


有关更多信息,请参见在MSDN上事件源模式物化视图模式,以及模式和实践指南CQRS旅程。特别是你应该阅读这一章。事件源简介以充分探讨该模式及其如何在CQRS中使用,以及本章CQRS与ES深度历险了解更多–包括如何在MicrosoftAzure中与CQRS一起使用聚合分区。

示例

下面的代码显示了CQRS实现示例中的一些摘录,CQRS实现对读和写模型使用了不同的定义。模型接口并不规定底层数据存储的任何特性,它们可以独立地进化和调整,因为这些接口是分开的。

下面的代码显示了读取模型定义。

// Query 
interface namespace ReadModel { 
    public interface ProductsDao { 
        ProductDisplay FindById(int productId); 
        IEnumerable<ProductDisplay> FindByName(string name); IEnumerable<ProductInventory> FindOutOfStockProducts(); IEnumerable<ProductDisplay> 
        FindRelatedProducts(int productId); 
    } 
    
    public class ProductDisplay { 
        public int ID { get; set; } 
        public string Name { get; set; } 
        public string Description { get; set; } 
        public decimal UnitPrice { get; set; } 
        public bool IsOutOfStock { get; set; } 
        public double UserRating { get; set; } 
    } 
    public class ProductInventory { 
        public int ID { get; set; } 
        public string Name { get; set; } 
        public int CurrentStock { get; set; } 
    } 
}

该系统允许用户对产品进行评分。应用程序代码通过使用以下代码中显示的RateProduct命令来执行此操作。

public interface Icommand{  
    Guid Id { get; }
}

public class RateProduct : Icommand{  
    public RateProduct()  { this.Id = Guid.NewGuid(); }  
    public Guid Id { get; set; }  
    public int ProductId { get; set; }  
    public int rating { get; set; }  
    public int UserId {get; set; }
}

系统使用ProductsCommandHandler类来处理应用程序发送的命令。 客户端通常通过消息系统(例如队列)将命令发送到域。 命令处理程序接受这些命令并调用域接口的方法。 每个命令的粒度旨在减轻冲突请求的机会。 以下代码显示了ProductsCommandHandler类的概述。

public class ProductsCommandHandler : 
        ICommandHandler<AddNewProduct>, ICommandHandler<RateProduct>,    ICommandHandler<AddToInventory>,ICommandHandler<ConfirmItemShipped>,    ICommandHandler<UpdateStockFromInventoryRecount> { 
    private readonly IRepository<Product> repository;  
    public ProductsCommandHandler (IRepository<Product> repository)  {
        this.repository = repository;  
    }  
    void Handle (AddNewProduct command){ ... }  
    void Handle (RateProduct command)  {    
        var product = repository.Find(command.ProductId);    
        if (product != null)    {      
            product.RateProuct(command.UserId, command.rating);      repository.Save(product);    
        }  
    }  
    
    void Handle (AddToInventory command)  { ... } 
    void Handle (ConfirmItemsShipped command)  { ... }  
    void Handle (UpdateStockFromInventoryRecount command)  { ... }
}

以下代码显示了写入模型中的ProductsDoman接口。

public interface ProductsDomain {
    void AddNewProduct(int id, string name, string description, decimal price);
    void RateProduct(int userId int rating);
    void AddToInventory(int productId, int quantity);
    void ConfirmItemsShipped(int productId, int quantity);
    void UpdateStockFromInventoryRecount(int productId, int updatedQuantity);
}

还要注意ProductsDomain接口如何包含在域中具有意义的方法。通常,在CRUD环境中,这些方法将具有通用名称(如“Save”或“Update”),并且将DTO作为唯一参数。可以更好地定制CQRS方法,以适合该组织执行业务和库存管理的方式。

相关模式和指导

在实施这一模式时,下列模式和指导也可能相关:

  • 数据一致性入门。本指南介绍了使用CQRS模式时由于读写数据存储之间最终的一致性而通常遇到的问题,以及如何解决这些问题。
  • 数据分区指南。本指南介绍了如何将CQRS模式中使用的读写数据存储区划分为多个单独的分区,这些分区可以分别进行管理和访问,以提高可伸缩性,减少争用并优化性能。
  • 事件源模式。此模式更详细地描述了如何将事件源与CQRS模式一起使用以简化复杂域中的任务。改善性能,可伸缩性和响应能力;提供交易数据的一致性;并保持完整的审计追踪和历史记录,以支持采取补偿措施。
  • 物化视图模式。CQRS实现的读取模型可以包含写入模型数据的实例化视图,或者读取模型可以用于生成实例化视图。

更多信息

原文链接

https://docs.microsoft.com/en-us/previous-versions/msp-n-p/dn568103%28v%3dpandp.10%29

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
<p style="font-size:16px;color:#666666;"> <img src="https://img-bss.csdn.net/202001311426171105.png" alt="" /> </p> <p style="font-size:16px;color:#666666;"> <strong><span style="font-size:20px;">课程目标</span></strong> </p> <p style="font-size:16px;color:#666666;"> 《从零开始学Scrapy网络爬虫》从零开始,循序渐进地介绍了目前流行的网络爬虫框架Scrapy。即使你没有任何编程基础,学习起来也不会有压力,因为我们有针对性地介绍了Python编程技术。另外,《从零开始学Scrapy网络爬虫》在讲解过程中以案例为导向,通过对案例的不断迭代、优化,让读者加深对知识的理解,并通过14个项目案例,提高学习者解决实际问题的能力。 </p> <p style="font-size:16px;color:#666666;"> <br /> </p> <p style="font-size:16px;color:#666666;"> <strong><span style="font-size:20px;">适合对象</span></strong> </p> <p style="font-size:16px;color:#666666;"> 爬虫初学者、爬虫爱好者、高校相关专业的学生、数据爬虫工程师。 </p> <p style="font-size:16px;color:#666666;"> <br /> </p> <p style="font-size:16px;color:#666666;"> <span style="font-size:20px;"><strong>课程介绍</strong></span> </p> <p style="font-size:16px;color:#666666;"> 《从零开始学Scrapy网络爬虫》共13章。其中,第1~4章为基础篇,介绍了Python基础、网络爬虫基础、Scrapy框架及基本的爬虫功能。第5~10章为进阶篇,介绍了如何将爬虫数据存储于MySQL、MongoDB和Redis数据库中;如何实现异步AJAX数据的爬取;如何使用Selenium和Splash实现动态网站的爬取;如何实现模拟登录功能;如何突破反爬虫技术,以及如何实现文件和图片的下载。第11~13章为高级篇,介绍了使用Scrapy-Redis实现分布式爬虫;使用Scrapyd和Docker部署分布式爬虫;使用Gerapy管理分布式爬虫,并实现了一个抢票软件的综合项目。 </p> <p style="font-size:16px;color:#666666;"> <span style="color:#FF0000;">      由于目标网站可能会对页面进行改版或者升级反爬虫措施,如果发现视频中的方法无法成功爬取数据,敬请按照页面实际情况修改XPath的路径表达式。视频教程主要提供理论、方法支撑。我们也会在第一时间更新源代码,谢谢!</span> </p> <p style="font-size:16px;color:#666666;"> <img src="https://img-bss.csdn.net/202001311426306665.png" alt="" /> </p> <p style="font-size:16px;color:#666666;"> <strong><span style="font-size:20px;">课程特色</span></strong> </p> <p style="font-size:16px;"> <img src="https://img-bss.csdn.net/202001311426415123.png" alt="" /> </p> <div> <br /> </div>
<div style="color:rgba(0,0,0,.75);"> <span style="color:#4d4d4d;"> </span> <div style="color:rgba(0,0,0,.75);"> <span style="color:#4d4d4d;"> </span> <div style="color:rgba(0,0,0,.75);"> <div style="color:rgba(0,0,0,.75);"> <span style="color:#4d4d4d;">当前课程中商城项目的实战源码是我发布在 GitHub 上的开源项目 newbee-mall (新蜂商城),目前已有 6300 多个 star,</span><span style="color:#4d4d4d;">本课程是一个 Spring Boot 技术栈的实战类课程,课程共分为 3 大部分,前面两个部分为基础环境准备和相关概念介绍,第三个部分是 Spring Boot 商城项目功能的讲解,让大家实际操作并实践上手一个大型的线上商城项目,并学习到一定的开发经验以及其中的开发技巧。<br /> 商城项目所涉及的功能结构图整理如下:<br /> </span> </div> <div style="color:rgba(0,0,0,.75);">   </div> <div style="color:rgba(0,0,0,.75);"> <p style="color:#4d4d4d;"> <img alt="modules" src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9uZXdiZWUtbWFsbC5vc3MtY24tYmVpamluZy5hbGl5dW5jcy5jb20vcG9zdGVyL3N0b3JlL25ld2JlZS1tYWxsLXMucG5n?x-oss-process=image/format,png" /> </p> </div> <p style="color:rgba(0,0,0,.75);"> <strong><span style="color:#e53333;">课程特色</span></strong> </p> <p style="color:rgba(0,0,0,.75);">   </p> <div style="color:rgba(0,0,0,.75);">   </div> <div style="color:rgba(0,0,0,.75);"> <ul> <li> 对新手开发者十分友好,无需复杂的操作步骤,仅需 2 秒就可以启动这个完整的商城项目 </li> <li> 最终的实战项目是一个企业级别的 Spring Boot 大型项目,对于各个阶段的 Java 开发者都是极佳的选择 </li> <li> 实践项目页面美观且实用,交互效果完美 </li> <li> 教程详细开发教程详细完整、文档资源齐全 </li> <li> 代码+讲解+演示网站全方位保证,向 Hello World 教程说拜拜 </li> <li> 技术栈新颖且知识点丰富,学习后可以提升大家对于知识的理解和掌握,可以进一步提升你的市场竞争力 </li> </ul> </div> <p style="color:rgba(0,0,0,.75);">   </p> <p style="color:rgba(0,0,0,.75);"> <span style="color:#e53333;">课程预览</span> </p> <p style="color:rgba(0,0,0,.75);">   </p> <div style="color:rgba(0,0,0,.75);">   </div> <div style="color:rgba(0,0,0,.75);"> <p style="color:#4d4d4d;"> 以下为商城项目的页面和功能展示,分别为: </p> </div> <div style="color:rgba(0,0,0,.75);"> <ul> <li> 商城首页 1<br /> <img alt="" src="https://img-bss.csdnimg.cn/202103050347585499.gif" /> </li> <li> 商城首页 2<br /> <img alt="" src="https://img-bss.csdn.net/202005181054413605.png" /> </li> <li>   </li> <li> 购物车<br /> <img alt="cart" src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9uZXdiZWUtbWFsbC5vc3MtY24tYmVpamluZy5hbGl5dW5jcy5jb20vcG9zdGVyL3Byb2R1Y3QvY2FydC5wbmc?x-oss-process=image/format,png" /> </li> <li> 订单结算<br /> <img alt="settle" src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9uZXdiZWUtbWFsbC5vc3MtY24tYmVpamluZy5hbGl5dW5jcy5jb20vcG9zdGVyL3Byb2R1Y3Qvc2V0dGxlLnBuZw?x-oss-process=image/format,png" /> </li> <li> 订单列表<br /> <img alt="orders" src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9uZXdiZWUtbWFsbC5vc3MtY24tYmVpamluZy5hbGl5dW5jcy5jb20vcG9zdGVyL3Byb2R1Y3Qvb3JkZXJzLnBuZw?x-oss-process=image/format,png" /> </li> <li> 支付页面<br /> <img alt="" src="https://img-bss.csdn.net/201909280301493716.jpg" /> </li> <li> 后台管理系统登录页<br /> <img alt="login" src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9uZXdiZWUtbWFsbC5vc3MtY24tYmVpamluZy5hbGl5dW5jcy5jb20vcG9zdGVyL3Byb2R1Y3QvbWFuYWdlLWxvZ2luLnBuZw?x-oss-process=image/format,png" /> </li> <li> 商品管理<br /> <img alt="goods" src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9uZXdiZWUtbWFsbC5vc3MtY24tYmVpamluZy5hbGl5dW5jcy5jb20vcG9zdGVyL3Byb2R1Y3QvbWFuYWdlLWdvb2RzLnBuZw?x-oss-process=image/format,png" /> </li> <li> 商品编辑<br /> <img alt="" src="https://img-bss.csdnimg.cn/202103050348242799.png" /> </li> </ul> </div> </div> </div> </div>
<p style="color:#333333;"> <strong> </strong> </p> <p style="font-family:"color:#222226;font-size:14px;background-color:#FFFFFF;"> <strong><span style="color:#337FE5;">[为什么要学习Spring Cloud微服务]</span> </strong> </p> <p style="font-family:"color:#222226;font-size:14px;background-color:#FFFFFF;"> <strong><span style="color:#4D555D;"></span> </strong> </p> <p class="ql-long-24357476" style="font-family:"color:#222226;font-size:14px;background-color:#FFFFFF;"> <strong><span style="font-family:"background-color:#FFFFFF;">SpringCloud作为主流微服务框架,<span style="color:#4D555D;">已成为各互联网公司的首选框架,国内外企业占有率持续攀升,</span>是Java工程师的必备技能。</span><span style="font-family:"background-color:#FFFFFF;">就连大名鼎鼎的阿里巴巴</span><span style="font-family:"background-color:#FFFFFF;">dubbo</span><span style="font-family:"background-color:#FFFFFF;">也正式更名为</span><span style="font-family:"background-color:#FFFFFF;">Spring Cloud Alibaba</span><span style="font-family:"background-color:#FFFFFF;">,成为了</span><span style="font-family:"background-color:#FFFFFF;">Spring Cloud </span><span style="font-family:"background-color:#FFFFFF;">微服务中的一个子模块。</span><span style="font-family:"background-color:#FFFFFF;"></span><span style="font-family:"background-color:#FFFFFF;">Spring Cloud是企业架构转型、个人能力提升、架构师进阶的不二选择。</span> </strong> </p> <p style="color:#333333;"> <strong><strong><br /> </strong> </strong> </p> <strong><span style="font-family:"color:#337FE5;font-size:14px;background-color:#FFFFFF;">【推荐你学习这门课的理由】</span><br /> </strong> <p> <br /> </p> <p> <span>1、</span><span style="color:#222226;font-family:"font-size:14px;background-color:#FFFFFF;">本课程总计</span><span style="background-color:#FFFFFF;">29</span><span style="color:#222226;font-family:"font-size:14px;background-color:#FFFFFF;">课时,<span style="color:#333333;">从微服务是什么、能够做什么开始讲起,绝对的零基础入门</span></span><span></span> </p> <p> <span style="background-color:#FFFFFF;">2、<span style="color:#333333;">课程附带全部26个项目源码,230页高清PDF正版课件</span><span style="color:#333333;"></span></span> </p> <p> <span style="background-color:#FFFFFF;"><b><br /> </b></span> </p> <p> <span style="background-color:#FFFFFF;"><b><span style="color:#337FE5;">【课程知识梳理】</span></b></span> </p> <p> <span style="background-color:#FFFFFF;"><b>1、</b></span><span style="color:#333333;">先讲解了什么是单体架构、什么是微服务架构、他们之间有什么区别和联系,各自有什么优缺点。</span> </p> <p> <span style="color:#333333;">2、</span><span style="color:#333333;">从本质入手,使用最简单的Spring Boot搭建微服务,让你认清微服务是一种思想和解决问题的手段,而不是新兴技术。</span> </p> <p style="color:#333333;"> 3、讲解Spring Boot 与Spring Cloud 微服务架构之间的联系,原生的RestTemplate工具,以及Actuator监控端点的使用。 </p> <p style="color:#333333;"> 4、带着微服务所带来的各种优缺点,为大家引入服务发现与注册的概念和原理,从而引入我们的第一个注册中心服务Eureka。 </p> <p style="color:#333333;"> 5、引入负载均衡的理念,区分什么是服务端负载均衡,什么是客户端负载均衡,进而引入Ribbon负载均衡组件的详细使用。 </p> <p style="color:#333333;"> 6、为了解决微服务之间复杂的调用,降低代码的复杂度,我们引入了Feign声明式客户端,让你几行代码搞定服务的远程调用。 </p> <p style="color:#333333;"> 7、最后为大家介绍了整个微服务体系应该包含什么,学习路线是什么,应该学习什么。 </p> <p style="color:#333333;"> <strong><br /> </strong> </p> <p style="color:#333333;"> <strong><span style="color:#337FE5;">【</span><strong><span style="color:#337FE5;">学习方法</span></strong><span style="color:#337FE5;"></span><span style="color:#337FE5;">】</span></strong> </p> <p style="color:#333333;"> 每一节课程均有代码,最好的方式是静下心来,用一天的时间,或者两个半天时间来学习。 </p> <p style="color:#333333;"> 一边听我的讲解,一边使用我提供的项目代码进行观察和运行。 </p> <p style="color:#333333;"> 只要你能跟住我的节奏,你就可以搞定微服务。 </p> <br />
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值