零度新版框架搭建系列视频教程
朋友们,零度新一代框架开始搭建。我们非常激动地宣布,新一代基架起名为 HelloShop 项目, 这个基架将演示新一代 .NET 技术栈开发架构,目标是提供细粒度的微服务架构和最佳实践,让您可以自行组合各种技术,统一的身份认证和授权系统,服务发现,负载均衡,容错,分布式跟踪,分布式缓存,分布式事务,分布式消息,分布式日志,分布式配置,分布式定时任务等。此外,我们还提供了界面,包括基于 Blazor 的 Web 应用和基于 MAUI 的混合应用,可以在不同的平台上运行,包括桌面应用,安卓应用和 IOS 应用。
共 61 项内容
本分类内容
构建可靠的事务性发件箱模式
事务性发件箱模式确保将事件保存在数据存储中,然后再最终推送到消息代理。 如果业务对象和相应的事件保存在同一数据库事务中,则保证不会丢失任何数据。 所有内容都将被提交,或在出错时所有内容回滚。 为了最终发布事件,其他服务或工作进程会在发件箱表中查询未处理项,发布这些事件,并将其标记为已处理。 此模式可确保创建或修改业务对象后不会丢失事件。
自动迁移和数据库初始化
EF Core中数据库迁移与初始化的核心概念与实用技巧。内容包括生成与应用迁移脚本、EnsureCreatedAsync与MigrateAsync的使用及冲突解决、通过内部服务实现优雅的自动迁移、EF Core 9.0推荐的异步种子数据初始化方法,以及利用IHostedService或BackgroundService实现耗时操作的异步数据库初始化。通过本课程,开发者将掌握高效管理数据库生命周期的最佳实践,提升项目开发效率与质量。
重构代码并抽取基础构建库
本次重构优化了事件总线架构,提升了系统的扩展性和灵活性。新增支持包和多个项目,增强了事件处理能力。通过实现基于 Dapr 和 RabbitMQ 的事件总线,改进了消息传递效率。加入了分布式锁功能,确保并发场景下的数据一致性。
在 Aspire 中集成 PostgreSQL 数据库
在 Host 项目中添加 PostgreSQL 数据库,在最终的应用中引用 PostgreSQL 数据库,添加 PostgreSQL pgAdmin 资源,添加 PostgreSQL pgWeb 资源。
关于 Aspire 应用宿主的编排
配置显式资源启动,等待资源启动和完成,自定义容器的启动参数,配置容器资源生存期,配置外部参数,外部连接字符串,终结点引用,在 Redis 上启用图形管理扩展,注册生命周期钩子,网络模型和多副本启动。
引入 CPM 中心包管理
管理单个项目的依赖项很容易,随着多项目解决方案在规模和复杂性上逐渐增加,管理其依赖项可能会变得困难,在管理许多不同项目的常见依赖项的情况下,可以利用中央包管理 CPM 功能从单个位置轻松完成所有包版本的管理。
使用 TimeProvider 类注入时间
在零度框架中使用 TimeProvider 类型,System.TimeProvider 是一种时间抽象,它以 DateTimeOffset 类型的形式提供时间点。 通过使用 TimeProvider,可确保代码可测试且可预测。 TimeProvider 已在 .NET 8 中引入。
重构单元测试和集成测试
重构单元测试,使用 DistributedApplicationFactory 重构分布式测试通用主机,针对不通过测试的代码进行重构,关于内存数据库的共享模式。
零度框架升级到 Aspire 9.0 版本
将零度框架升级到 Aspire 9.0 版本,包括升级 Visual Studio 开发工具和非 Visual Studio 开发环境的步骤。文章涵盖了安装 .NET Core SDK 9.0、升级 Aspire 工作负载、修改项目文件以支持新版本,以及使用工具简化升级过程。此外,还介绍了服务发现支持 https+http 的新写法。
数据库对象命名约定
不同数据库对象的命名约定不同,EF Core 为了适配不同数据库,提供了一些命名约定的配置选项,可使用 Humanizr 库将字符串转换为不同的命名风格,社区对单数和复数表名的争论一直存在,没有统一的标准,但零度推荐使用单数形式,使用自动化命名约定器,规范化迁移历史表。
使用改进后的资源浏览器
在最新版的 Visual Studio 中,资源浏览器的体验得到了显著提升,为开发人员带来了更加赏心悦目的界面,使得资源管理的工作流程更为高效。通过对比新旧两种体验,不难发现,我们不仅弥补了以往体验的不足,还引入了众多令人愉悦的新功能,旨在进一步提升您的工作效率。现在,让我们一同开启这段更加现代、便捷的资源管理之旅吧!
使用分布式事件总线异步通信
使用分布式事件总线在多个微服务之间进行异步通信,订单微服务通知购物车微服务清空用户购物车,产品宽限期校验辅助角色自动任务,订单微服务通知产品微服务进行库存确认,产品微服务通知订单微服务库存确认结果,订单微服务处理库存确认结果。
使用分布式锁解决并发问题
开源 DistributedLock 是一个 .NET 库,它基于各种底层技术提供强大且易于使用的分布式互斥锁、读写器锁和信号量,零度框架中提供分布式锁的基本抽象,并基于 Dapr 实现了分布式锁。
PostgreSQL 高可用性和读写分离
数据库逻辑复制使用发布和订阅模型, 其中一个或多个订阅者订阅发布者节点上的一个或多个发布,订阅者从他们订阅的发布中提取数据,流复制是一种物理复制方法,它通过将 WAL 记录从一个服务器传输到另一个服务器来复制数据。
实现 CQRS 中的 Query 模式
在 CQRS 模式的全程是 Command Query Responsibility Segregation,即命令查询职责分离。在 CQRS 模式中,命令和查询是分开实现的,命令负责写操作,查询负责读操作,这样可以更好地实现单一职责原则,同时也可以更好地实现性能优化。
使用 Aspire 启动分布式微服务
使用 Aspire 启动分布式微服务,包括配置 PostgreSQL 数据库的时间类型为 UTC 时间,删除不优雅的时间转换设置,并推荐使用 TimeProvider 抽象类获取当前时间,以便在测试时更方便地模拟时间。
Aspire 集成 Dapr 和 RabbitMQ
在 Aspire 构建的云原生应用程序中的启动 RabbitMQ 分布式队列,使用 Aspire 启动 Dapr 边车,使用基于环境变量的密钥存储组件配置 Dapr 组件。
使用 Dpar 发布订阅配置分布式事件
Dapr 是一个可移植的、事件驱动的运行时,它使任何开发人员能够轻松构建出弹性的、无状态和有状态的应用程序,并可运行在云平台或边缘计算中,它同时也支持多种编程语言和开发框架。使用 Bundle 离线初始化 Dapr 运行时。
实现事务性发件箱模式
在分布式系统中,不同的组件需要相互通信,通常通过异步消息传递。发件箱模式提供了一种可靠的方法来处理这些消息。它确保即使系统在执行本地事务之后但在发送消息之前发生故障,消息也不会丢失。相反,它会暂时存储在发件箱中,并在系统恢复时检索和发送。
使用分布式事件实现订单支付库存通知
使用自动任务模拟订单支付成功和失败,使用分布式事件实现订单库存变更,发布和订阅模块使微服务能够使用事件驱动架构的消息相互通信。
使用 Dapr 实现分布式事件总线
Dapr 是一个开源的分布式应用程序运行时,发布和订阅模块使微服务能够使用事件驱动架构的消息相互通信,Dapr 提供了一个事件总线的实现,使用 Dapr 发布事件,提供 Dapr 订阅终结点,将消息路由到不同的事件处理程序。
分布式事件的设计与抽象
分布式事件总线提供了一种在不同的微服务进程之间消息通信的机制,设计分布式事件总线接口,抽象分布式事件,抽象分布式事件处理程序,分布式事件处理程序的依赖注入,基于 Keyed 服务的依赖注入,使用 JsonExtensionDataAttribute 处理溢出的属性。
本地事件的设计与实现
"本地事件总线是一个轻量级的事件总线,用于在应用程序内部的组件之间传递事件,它是一个简单的观察者模式的实现,用于解耦组件之间的依赖关系, 使得组件之间的通信更加简单,在订单创建处理程序中引发事件,使用不同的处理程序处理订单创建事件。"
订单创建命令处理程序
实现创建命令处理程序,订单相关实体数据存储,使用中间件管道进行事务上下文管理,使用执行策略进行事务失败重试,连接复原能力会自动重试失败的数据库命令。
订单的取消和发货命令
实现订单的取消命令,订单取消 WebApi 实现,实现订单的发货命令,订单发货 WebApi 实现,对命令进行规则验证,依赖注入验证器和映射器。
订单接口和命令映射验证管道
实现创建订单 WebApi 接口,构建命令,发送命令,命令去重,请求和命令映射器,请求和命令验证,验证错误封装,使用管道中间件验证命令,命令日志自动记录。
命令模式和消息幂等去重
CQRS 是命令和查询责任分离的英文缩写,它是一种将读取操作和更新操作分离的模式,查询返回结果,不改变系统的状态,没有副作用。命令执行更改系统状态,幂等性是指相同的命令多次执行,结果是一样的,不会有副作用。
订单微服务实体类型设计
订单微服务实体类型设计,未来可使用 Keyed services 方式注入不同连接字符串的同类型 DbContext 类,实现主从数据库的读写分离,实体类型配置,重构代码,提高代码的可维护性和可扩展性。
使用 Azure Data Studio 管理数据库
Azure Data Studio 是一个轻量级的跨平台开源的数据库工具,提供了一个现代化的用户界面,可以帮助用户更轻松地管理各种不同的数据库。
订单微服务架构概述
订单部分使用了很多技术点,这包括 CQRS 模式、本地命令分发、本地事件处理、分布式事件的抽象和实现、发件箱模式、分布式锁等技术。
使用缓存提高系统性能
私有专用缓存,分布式共享缓存,使用 Redis 分布式缓存,使用微软 Garnet 分布式缓存,使用 Window Service 运行 Garnet 缓存,购物车服务使用分布式缓存,高可用性分布式缓存集群,缓存最佳实践,缓存技术点,分布式缓存监控工具,使用 Aspire 分布式缓存组件。
测试 gRPC 购物车服务
使用测试工具生成测试代码,使用 AI 人工智能生成测试代码,单元测试直接从单元测试库测试 gRPC 服务方法,集成测试则需要启动一个测试服务器,然后通过客户端调用服务,使用拦截器模拟身份验证令牌。
使用 gRPC 实现购物车服务
gRPC 是一种与语言无关的高性能远程过程调用,使用消息协定来创建高性能的实时服务,gRPC JSON 转码是为 gRPC 服务创建 RESTful JSON API 的扩展,配置转码后,应用可以使用熟悉的 HTTP 概念调用 gRPC 服务,关于 gRPC 的身份认证授权,模型映射和模型验证。
多租户应用程序设计
多租户应用程序是一种软件架构设计,允许单个实例的软件服务多个客户,每个客户被称为一个租户,租户之间的数据自动隔离的,租户之间的数据不会相互影响。
负载测试和压力测试
负载测试应用在特定情况下处理指定的用户负载能够满足响应目标,压力测试在极端条件下测试应用的稳定性,测试会对应用施加高用户负载,关于 JMeter 测试工具,基准测试用于确定应用程序的性能基准,以便在应用程序的生命周期中进行性能优化。
集成测试最佳实践
集成测试也称为功能测试,与单元测试的不同之处在于,它试验两个或更多软件组件一同工作集成能力。这些测试在更广泛范围的受测系统上运行,而单元测试则侧重于单个组件函数,通常,集成测试会包括对基础结构问题的测试,例如数据库、文件系统和网络资源的交互。
单元测试最佳实践
使用自动测试是确保应用程序代码按作者期望执行操作的一种绝佳方式,零度框架中提供单元测试、集成测试和负载测试,单元测试是一种试验单个软件组件或方法的测试,单元测试仅应测试开发人员控件内的代码,它们不测试基础结构问题,基础结构问题包括与数据库、文件系统和网络资源的交互。
零度框架升级 8.0 稳定版
随着微软 Aspire 正式版的发布,零度框架正式也发布了,之前,零度框架使用的是 Aspire 的多个预览版,导致了一些不稳定的问题,现在,零度框架和所有依赖包都升级到了最新稳定版,不再引用任何预览包,能够更好的部署到生产平台。
聚合 API 网关
使用网关可将多个单独请求聚合成一个请求。 当客户端必须向不同的后端系统发出多个调用来执行某项操作时,此模式非常有用。在某些情况下,客户端需要向多个后端系统发出多个请求。 例如,客户端可能需要从多个服务中检索数据,然后将这些数据聚合到一个响应中。 在这种情况下,客户端必须发出多个请求,这可能会导致性能问题。 此外,客户端还必须处理多个响应,这可能会导致复杂性问题。
聚合 OpenApi 文档
每个微服务都有自己的 OpenApi 文档,但是在实际开发中,我们更希望能够将所有微服务的 OpenApi 文档聚合到一起,以便于查看和调试,微服务都是基于 Aspire 框架开发的,所以我们可以使用 Aspire 框架提供的服务发现功能来自动聚合所有微服务的 OpenApi 文档。
网关和服务发现
API 网关是一个服务器,它是客户端和后端服务之间的中介。它接收来自客户端的请求,然后将这些请求转发到后端服务。基于 BFF(后端用于前端)模式,当客户端请求数据时,API 网关可以调用多个服务来获取数据,然后将数据聚合到一个响应中返回给客户端,以减少客户端与后端服务之间的通信次数,从而提高性能。服务发现是一种用于发现和定位服务的机制,它可以帮助客户端找到服务的位置和地址。服务发现可以用于构建和设计微服务架构中的 API 网关,以便客户端可以通过 API 网关访问后端服务。
实现产品管理微服务
使用基础构建块构建产品管理微服务、创建实体、实体配置、创建模型、自动映射、验证器、控制器、多语言,权限定义等、演示数据生成、模型属性本地化等。
全球化与本地化
全球化 (G11N)使应用支持不同语言和区域的过程。 缩写来自第一个和最后一个字母以及它们之间的字母数,本地化 (L10N)针对特定语言和区域自定义全球化应用的过程,国际化 (I18N)包括全球化和本地化,区域性是一种语言或区域,非特定区域性,具有指定语言但不具有区域的区域性,特定区域性,具有指定语言但和区域的区域性。
分页排序和多条件查询
排序和分页模型设计,生成排序表达式树,实现自动分页和排序方法,扩展 IQueryable 以便通过属性名称排序,扩展 IQueryable 以便搜索和排序,在 API 控制器中使用扩展方法,实现灵活的复杂查询,基于 OData 或者 GraphQL 来实现更复杂的查询。
模型自动验证机制
模型验证可以帮助我们验证用户输入的数据是否符合预期,优雅的使用基于数据注解的验证和基于链式调用的验证规则,提供一个简单、清晰的 API 逻辑,同时还能支持复杂的验证规则,异步验证器,在验证器中依赖注入服务,自定义通用验证错误消息,自动验证器和手动验证器,错误消息的多语言实现。
自动映射实体和模型
AutoMapper 是一个对象映射工具,可以自动映射实体对象和模型对象,减少手动映射的工作量,提高开发效率,除此之外 Mapster 也是一个高性能的对象映射工具,支持源生成代码,性能更好。AutoMapper 比 Mapster 更加流行,更加成熟,更加稳定,更加易用,更加灵活,更加强大,更加全面,更加受欢迎。AutoMapper 是 .NET Foundation 的一部分,是一个开源项目,是一个非常优秀的对象映射工具。
模型绑定最佳实践
实体对象是 EF 中的概念, 每个实体对象对应数据库中的一张表。模型对象是 MVC 中的概念,是 HTTP 请求和响应的数据结构。HTTP 请求中通过 URL 参数、表单、标头、 JSON 数据等方式传递数据,这些数据最终会被绑定为模型对象中,模型经过转换为实体对象后,被持久化到数据库中。
基于资源授权的最佳实践
重构 Identity Service 权限检查端点,重构远程权限检查器,重新实现权限处理程序,取消缓存以便测试,可读性重构,资源信息描述重构,全面测试权限系统。
基于策略和资源的授权机制
ASP.NET Core 中的授权系统是基于策略的授权系统,可以通过声明式的方式来定义授权策略。授权策略可以基于角色,也可以基于资源,也可以基于其他的条件。授权策略可以通过声明式的方式来定义,也可以通过代码的方式来定义。
实现权限访问控制列表
主体、资源、操作。 例如:用户(主体)对文件(资源)的读写(操作)。主体、资源、操作三者之间的关系称为授权关系,基于这种关系,我们可以将授权关系抽象为一个三元组(主体,资源,操作),这个三元组就是授权的基本单位。
设计权限定义和权限提供者
每个微服务是自治的,权限定义也是每个微服务的职责,各自定义自己的权限,权限管理器会自动合并权限定义,权限定义上下文是微服务内的权限定义和全局权限定义的合集,权限提供者会根据权限定义上下文提供权限数据,权限分组是为了方便权限定义的管理,权限分组是权限定义的一部分,权限提供者自动注入到容器,提供权限查询端点。
使用 JwtBearer 令牌进行身份验证
"JwtBearer 令牌身份验证是一种基于 JSON Web 令牌的身份验证方法, 用于验证用户的身份, 它是一种无状态的身份验证方法, 适用于 Web API 和 Web 应用程序。"
Identity 身份认证和授权终结点
Identity 提供了用户管理、角色管理、声明管理、密码管理、登录管理、外部登录管理、双重身份认证、电子邮件确认、手机号码确认、安全令牌管理、用户锁定、用户解锁、用户注销、用户删除、用户恢复等功能,使用 Identity Api Endpoints 快速构建基于令牌的身份认证授权系统。
使用 OpenAPI 规范生成 API 文档
将 OpenAPI 抽象到一个单独的库中,可以使得 API 项目更加简洁,同时也可以更好地遵循单一职责原则,使得 API 项目更加容易维护。
在项目中添加文件头注释
文件头注释是一种用于说明文件版权和许可的注释。它通常包括版权声明、许可证信息、作者信息和其他相关信息,文件头注释是一种很好的实践,可以帮助开发人员了解文件的版权和许可信息。
用于生成初始数据的提供程序
数据播种是使用一组初始数据填充数据库的过程,通常在数据库首次创建时执行,这些数据通常是静态的,不会随时间变化,数据播种通常用于填充一些基本数据,例如用户、角色、权限、商品、分类等。
使用 PostgreSQL 数据库存储数据
在 Docker 中 启动 PostgreSQL 数据库,使用 PgAdmin 连接 PostgreSQL 数据库,EfCore 使用 PostgreSQL 数据库,命名约定,使用脚本迁移,列迁移排序,时间自动转换配置。
更新 .NET 8.0 到 .NET 9.0
安装更新 Visual Studio 最新预览版,安装 .NET 9.0 SDK,更新所有 NuGet 包到最新版本,更新 Aspire 和 MAUI 工作负载,将 Tab 自动补全添加到适用于 .NET CLI 的 PowerShell 命令行工具。
创建解决方案和项目结构
使用 .NET Aspire 构建分布式应用程序,包含了一系列的库、框架、工具和命令行实用程序,用于构建和管理可扩展的分布式应用程序,它还包括一组可扩展的基于微服务的框架,用于构建可靠的、可扩展的、事件驱动的微服务,这些微服务运行在 Docker 容器中,使用 Blazor 开发的前端应用程序,使用 MAUI 开发跨平台的移动应用程序,可以快速的进行开发,提高开发效率。
制作动态流程图和架构图
学习开源的画图工具,分享一些画图经验和技巧,容器图,图形和连接线,浮动连接和固定连接的区别,自带样式,矢量图和位图,嵌入图像和在线图像,使用第三方开源图标库中的素材,如何优雅地画流程图和架构图,添加连接线动画,更复杂的动态架构图制作方法。
零度新版框架搭建概况
朋友们,零度新一代基架今日正式开始搭建。我们非常激动地宣布,新一代基架起名为 HelloShop 项目, 演示新一代 .NET 技术栈开发架构,之所以起名为 HelloShop 是以为简单的商店应用能够演示出一个系统的所有技术,当然,这个商城系统也可以是其它系统,只要你能够理解这个基架的设计思想,你就能够快速搭建一个系统。