慣性聚合 高效追讀感興趣之博客、新聞、科技資訊
閱原文 以慣性聚合開啟

推薦訂閱源

博客园 - 司徒正美
V
V2EX
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
aimingoo的专栏
aimingoo的专栏
Apple Machine Learning Research
Apple Machine Learning Research
IT之家
IT之家
Blog — PlanetScale
Blog — PlanetScale
A
About on SuperTechFans
月光博客
月光博客
T
The Blog of Author Tim Ferriss
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
博客园 - 聂微东
The GitHub Blog
The GitHub Blog
V
Visual Studio Blog
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python)
CTO之反馈,吾遂精进.NET之序管。此乃其终焉之状也。
Aftab Bashir · 2026-05-24 · via DEV Community

数周前,吾撰文记一事,乃于.NET中所建之事件驱动订单流水也。有CTO名Andrew Tan者,留评指吾之出箱模式存隙——轮询间隔以延迟易数据库负载,且无御多轮询实例相践之策。

吾于后续之文,已弥缝发箱之隙。然安德鲁复指二事,亦当理会。此乃经手诸事之后,管路之状也。

吾始所行之境

原管道有运作之出盒模式。订单与出盒记录,同书于 PostgreSQL 之交易。一后台服务,每五秒轮询,而发布于 Kafka。消息既成发布,则标为已处理。

是事可行。然安德鲁察得三隙:

  1. 无保护于横向扩展——二轮询实例,或取同消息。
  2. 卡夫卡宕机时无后备机制——唯五秒一重试
  3. 无死信队列——屡败之讯永滞原地

修一——FOR UPDATE SKIP LOCKED

旧询但取未处之讯。若启二例此务,俱揽同讯,欲发之再

其治乃生SQL询,具FOR UPDATE SKIP LOCKED

SELECT * FROM "OutboxMessages"
WHERE "Processed" = false AND "RetryCount" < 3
ORDER BY "CreatedAt"
FOR UPDATE SKIP LOCKED

进入全屏模式 退出全屏模式

FOR UPDATE锁定行于事务期间。SKIP LOCKED意味着其他轮询实例将跳过已锁定的行,而非等待。两实例并行运行,永无争抢同一消息之虞。随心所欲横向扩展。

交易横贯取用、处理、存贮之全周期而未尝阖。惟及讯息既标为已处理,交易亦既成,锁钥乃释。

修二——对卡夫卡失事施以指数退避

旧式服务,无论何事,每五秒必复试。卡夫卡若陷,则恒率频击经纪,求连之试。

新设之务,察其发布或败,遂调其待时之度:

if (anyKafkaFailure)
{
    _logger.LogWarning("Kafka publish failed. Backing off for {Seconds}s", _currentBackoff);
    await Task.Delay(TimeSpan.FromSeconds(_currentBackoff), stoppingToken);
    _currentBackoff = Math.Min(_currentBackoff * 2, MaxBackoffSeconds);
}
else
{
    _currentBackoff = BaseBackoffSeconds;
    await Task.Delay(TimeSpan.FromSeconds(BaseBackoffSeconds), stoppingToken);
}

入全屏模式 出全屏模式

初败,待五秒,继而十,再二十,终限于六十。凡成者,复归五秒。当Kafka困顿之际,此务能从容退避,不致加剧其弊。

不良之负载若未能反序列化,则增重试之数,然不启回退——惟 Kafka 之连接失败者方为之。此别有深意,盖不欲一腐之讯迟滞其余之处理也。

修正三——死信之路

原实作止重试于三度,而置讯于待发之匣,任其滞留。RetryCount = 3,其形虽寂,而不可见也。

今若信息至而重试之限已竭,则移于DeadLetterMessages之表:

if (message.RetryCount >= MaxRetries)
{
    var deadLetter = new DeadLetterMessage
    {
        OrderId = message.OrderId,
        EventType = message.EventType,
        Payload = message.Payload,
        OriginalCreatedAt = message.CreatedAt,
        DeadLetteredAt = DateTime.UtcNow,
        FailureReason = message.Error ?? "Max retries exceeded",
        RetryCount = message.RetryCount
    };

    context.DeadLetterMessages.Add(deadLetter);
    context.OutboxMessages.Remove(message);

    _logger.LogWarning(
        "Message {MessageId} for order {OrderId} moved to dead letter after {RetryCount} retries",
        message.Id, message.OrderId, message.RetryCount);
}

全屏模式入 全屏模式出

发箱则净。死讯有所可见。复有GET /api/deadletters之端,使司者得察其败因,而无需直触数据库。

现今全貌何如

今之发件处理器已能净理四境:

吉途 - 消息既取,播于Kafka,标为已理。五秒后复询。

Kafka倾颓 - 播失,重试计增,延数倍。服务渐待久时,Kafka复振则再试。

多实例 - 更新跳过锁定,确保每讯必属一例。无复本之刊行.

恒久之败 - 三次重试之后,讯移于死信。发信箱洁净无瑕。司者可察而手复.

诚之映照

无安德鲁之评,此诸善皆不可成。原实之施,试之则效。三缺仅现于特制之产境——横扩之时,中继之败,恒久之恶讯是也。

此乃公码评审之重也。新目之观者,尝遇此困者,其值胜独审之量。

源码:github.com/aftabkh4n/order-pipeline

若尔构建事件驱动之系统,此篇当与原文并读。出箱模式乃其根基。此三者,方使其堪于生产。