构建投资组合洞察:来自事件驱动 .NET 微服务仪表盘的经验教训

发布: (2025年12月16日 GMT+8 23:59)
8 min read
原文: Dev.to

Source: Dev.to

请提供您希望翻译的具体文本内容(除代码块和 URL 之外),我将为您翻译成简体中文并保持原有的 Markdown 格式。

投资组合洞察 – 个人理财仪表盘

使用 .NET 8、RabbitMQ、gRPC、Docker 构建(微服务架构)

概览

Portfolio Insights 是一个 演示,展示基于 .NET 8 微服务的个人理财与分析平台。它在我之前的 E‑Commerce Microservices 项目中探索的架构模式之上构建,并将其应用于以数字为驱动、聚焦分析的领域。

该应用让用户能够:

  • 管理 投资组合(资产和数量)
  • 检索 模拟的市场价格
  • 异步计算 投资组合分析
  • 接收 分析刷新时的通知

所有服务均已容器化,并通过 Docker Compose 编排,展示了一个真实的端到端分布式系统。

我的收获

  • 事件驱动的微服务
  • gRPC 与 HTTP 通信
  • CQRS 与分层架构
  • 基于消息的分析管道
  • 垂直切片与清洁架构
  • 使用 Docker 的容器编排
  • 横切关注点(验证、日志、健康检查、自定义异常处理)

解决方案架构

该解决方案由 八个项目 组成,全部位于同一级目录下:

ServiceResponsibilityData Store
Market Data Service模拟并发布市场价格SQLite / Redis / In‑memory
Portfolio Service管理用户的投资组合和资产PostgreSQL (Marten)
Analytics Service根据投资组合和市场事件计算指标SQL Server (layered architecture)
Notification Service响应分析结果并存储通知SQLite
YARP API Gateway所有客户端流量的单一入口点
Razor Pages Web Client通过网关使用系统的 UI
(Other supporting projects)基础设施、契约等

高层流程

  1. 用户 在其投资组合中添加/更新资产。
  2. Portfolio Service 发布 PortfolioUpdatedEvent
  3. Analytics Service 消费该事件,将其与最新的市场价格关联,并计算指标。
  4. Analytics Service 发布 AnalyticsComputedEvent
  5. Notification Service 响应并存储用户通知。
  6. 客户端在数据准备好后查询 Analytics 或 Notification 接口。

通信方式

  • gRPC – 低延迟的请求/响应交互(例如,Portfolio Service → Market Data Service 获取当前价格)。
  • RabbitMQ + MassTransit – 基于事件的工作流(投资组合更新、市场价格变动、分析计算)。

设计洞察

首先绘制图表

在编写代码之前,我先绘制了:

  • 每个服务的数据所有权
  • 同步 vs. 异步 交互
  • 跨系统的状态变更传播

这一步的前期工作避免了代价高昂的重新设计,并澄清了端点合约。

异步 UI 考虑

由于分析在后台计算,Razor Pages 客户端必须:

  • 触发启动后台工作流的命令
  • 在等待时显示已计算的数据
  • 在下游服务处理事件后刷新视图

在设计 UI 时,我必须仔细思考 何时 请求数据以及 哪个 服务应提供数据。

服务特定存储

ServiceStorage ChoiceRationale
PortfolioPostgreSQL (Marten)文档存储语义,适用于灵活的投资组合结构
AnalyticsSQL Server关系查询,适用于复杂的指标计算
Market DataSQLite / Redis / In‑memory轻量持久化,用于模拟价格推送
NotificationSQLite简单、持久的用户提醒存储

关键原则:所有权清晰 优于服务之间的严格一致性。

运行项目

# Clone the repository
git clone https://github.com/yourusername/Portfolio-Insights.git
cd Portfolio-Insights

# Start all services with Docker Compose
docker compose up --build

网关可通过 http://localhost:5000 访问,Razor Pages UI 可通过 http://localhost:5000/ui 访问。

最后思考

Portfolio Insights 是一个 学习和作品集 项目,但它代表了我对现代 .NET 微服务理解的一个重要进步:

  • 在事件驱动系统中,清晰的边界和明确的契约至关重要。
  • 及早绘制工作流图可节省时间并降低耦合。
  • 前端设计必须反映异步处理的实际情况。
  • Docker Compose 为整体思考分布式系统提供了极佳的沙盒环境。

欢迎探索代码,启动容器,并尝试该架构!

微服务、异步通信与系统级设计

如果你正在探索类似的架构,我最大的建议很简单:在编码之前先设计流程。在事件驱动系统中,这种清晰度决定了一切。

接下来怎么办?

如果本文让你更清晰地了解了事件驱动微服务架构在真实 .NET 应用中的实现方式,以下是几种继续探索的途径:

  • 📁 探索 GitHub 仓库 – 查看完整源码,了解服务、消息流、API 网关以及 Razor Pages 客户端是如何协同工作的。边看代码边对照架构图是巩固同步与异步通信实际运作方式的最佳方法。
  • 💡 分享架构 – 如果你认识正在学习 .NET 微服务、消息系统或分布式系统的人,可以把这个项目分享给他们。通过具体的端到端示例往往更容易理解这些概念。
  • 🖥 实验并扩展 – 克隆项目并尝试对其进行演进。添加新事件、引入额外的分析功能,或调整客户端对异步工作流的响应。小幅改动是深化对事件驱动设计理解的好办法。
  • 👍 给仓库加星 – 如果你觉得该项目有用,考虑给仓库点星。这有助于其他人发现该项目,并支持我们持续分享实用的架构示例。

通过这样的项目实践,你会培养超越单一框架的直觉,帮助你设计既能应对日益复杂又保持可理解性的系统。

Back to Blog

相关文章

阅读更多 »

gRPC - 为什么使用 Mock Server?

为什么需要 Mock Server 来进行 gRPC?gRPC 提供紧凑的消息、基于 HTTP/2 的高效二进制传输,并对多种通信模式提供一流的支持……