成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

發件箱模式:打造微服務可靠消息傳輸

開發 系統
本文介紹了在微服務系統中實現可靠消息傳遞以及分布式事務的發件箱模式,該設計模式實現了消息生產者和消費者的解耦,了解這一模式可以幫助我們設計出容錯性、可靠性更高的系統。

開發微服務以及其他分布式系統都不容易,任何問題都有可能發生,甚至還有關于這方面的研究論文

作為工程師,減少出錯的可能性也應該是你的目標之一,本文將嘗試使用發件箱模式(Outbox pattern) 來實現這一點。

如何在分布式系統中實現組件之間的可靠通信?

發件箱模式是此類問題的一種優雅解決方案,該方案讓我們能夠實現事務性保證,并至少向外部系統傳遞一次消息。

讓我們看看發件箱模式如何解決這個問題,以及如何實現。

發件箱模式解決了什么問題?

當然,要理解發件箱模式解決了什么問題,我們先給出一個問題。

下面是一個用戶注冊流程的示例,有幾件事正在發生:

  • 將 User 保存到數據庫
  • 向 User 發生歡迎郵件
  • 向消息總線發布 UserRegisteredEvent
public async Task RegisterUserAsync(User user, CancellationToken token)
{
    _userRepository.Insert(user);

    await _unitOfWork.SaveChangesAsync(token);

    await _emailService.SendWelcomeEmailAsync(user, token);

    await _eventBus.PublishAsync(new UserRegisteredEvent(user.Id), token);
}

所有操作都在常規路徑中按序完成,沒有任何問題,一切都很好。

但如果其中任何一個操作失敗了怎么辦?

  • 數據庫不可用,保存 User 失敗
  • 郵件服務中斷,無法發送郵件
  • 向服務總線發布事件沒有成功

另外,想象一下這種情況:你已經將 User 保存到數據庫中,并向他發送了歡迎郵件,但未能成功發布 UserRegisteredEvent 來通知其他服務。怎么才能從這種情況中恢復過來?

發件箱模式可以幫你自動更新數據庫并將消息發送到消息總線。

實現發件箱模式

首先在數據庫中引入一個表示發件箱(Outbox) 的新表,可以將這個表稱為 OutboxMessages,用于存儲需要傳遞的所有消息。現在,我們不再直接向外部服務發出請求,而是簡單的將消息作為新行存儲在發件箱表中,消息通常以 JSON 格式存儲。

然后引入后臺進程,定期輪詢 OutboxMessages 表。如果發現有未處理的消息,就發布該消息并標記為已發送。如果由于某種原因造成消息發布失敗,就在下一次執行時重試。

注意,通過重試,現在實現了至少一次消息傳遞(at-least-once message delivery)。對于常規路徑,消息只發布一次,而在重試的情況下,則會發布多次。

我們現在可以基于發件箱模式重寫上面的 RegisterUserAsync 方法:

public async Task RegisterUserAsync(User user, CancellationToken token)
{
    _userRepository.Insert(user);

    _outbox.Insert(new UserRegisteredEvent(user.Id));

    await _unitOfWork.SaveChangesAsync(token);
}

發件箱與工作單元在同一個事務中,因此可以將 User 自動保存到數據庫中,并持久化 OutboxMessage。如果保存到數據庫失敗,則回滾整個事務,并且不會向消息總線發送任何消息。

由于現在將 UserRegisteredEvent 的發布轉移到了工作進程,因此需要添加一個處理程序,以便向用戶發送歡迎郵件。下面是 SendWelcomeEmailHandler 類的一個例子:

public classSendWelcomeEmailHandler : IHandle<UserRegisteredEvent>
{
    privatereadonly IUserRepository _userRepository;
    privatereadonly IEmailService _emailService;

    public SendWelcomeEmailHandler(
        IUserRepository userRepository,
        IEmailService emailService)
    {
        _userRepository = userRepository;
        _emailService = emailService;
    }

    public async Task Handle(UserRegisteredEvent message)
    {
        var user = await _userRepository.GetByIdAsync(message.UserId);

        await _emailService.SendWelcomeEmailAsync(user);
    }
}

發件箱模式架構圖

下面是引入發件箱后的系統架構圖,可以在數據庫中看到 Outbox 表,因此可以將消息與相關實體一起通過同一事物存儲到 Outbox 表中。

延伸閱讀

通過本文,你應該對發件箱模式以及它解決的問題有了很好的理解。如果需要在分布式系統中實現可靠消息傳遞,那么發件箱模式是一個很好的解決方案。

如果需要了解發件箱模式的更多實現細節,可以觀看以下油管視頻:

責任編輯:趙寧寧 來源: DeepNoMind
相關推薦

2023-01-07 10:17:06

微服務架構模式

2025-06-04 08:10:00

發件箱模式.NET數據庫

2021-05-06 10:12:14

鴻蒙HarmonyOS應用

2019-07-26 08:00:00

微服務架構

2016-09-23 10:51:23

騰訊云

2021-06-16 08:33:02

分布式事務ACID

2022-07-21 06:54:28

微服務系統RocketMQ

2023-07-25 09:52:00

本地事務宕機

2023-09-07 23:25:34

微服務服務發現

2023-09-02 20:51:09

微服務業務服務

2024-10-10 08:34:34

事務外包模式

2009-11-05 09:51:14

WCF基礎

2022-07-13 13:34:30

微服務邊車SideCar

2017-08-10 15:38:02

互聯網

2012-05-24 13:39:11

Python

2009-01-03 11:07:06

AJAXASP.NET.NET

2009-01-03 16:29:45

AJAXASP.NET.NET

2018-12-11 22:13:28

黑少

2015-05-04 14:12:43

2010-07-02 09:24:22

云計算
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 色就是色欧美 | 欧美视频第三页 | 国产亚洲精品久久午夜玫瑰园 | 国产一区精品 | 97久久精品午夜一区二区 | 欧美一级做性受免费大片免费 | 色婷婷综合成人av | 成人三区四区 | 精品欧美在线观看 | 6080亚洲精品一区二区 | 二区av| 欧美网址在线观看 | 亚洲精品一区二区三区蜜桃久 | 啪啪免费网| 在线91| 国产欧美一区二区三区久久人妖 | 91偷拍精品一区二区三区 | 欧美视频在线看 | 7777在线视频免费播放 | 久久99深爱久久99精品 | 久婷婷 | 欧美日韩在线一区 | 久久精品国产一区二区三区不卡 | 欧美亚洲综合久久 | 蜜桃视频在线观看免费视频网站www | 国产一区三区视频 | 久久久成人免费视频 | 日日操日日舔 | 一区二区三区在线播放 | 亚洲精品综合 | 91九色在线观看 | 国产精品国产三级国产aⅴ原创 | 麻豆天堂| 蜜桃在线视频 | 99爱在线视频 | 午夜精品一区二区三区在线观看 | 成人精品免费视频 | 黄色网一级片 | 精品二区| 国产高清视频在线观看 | 亚州av|