网页
综合
更新时间 2026-11-14 15:58:52
Blog • Particular Software
自动蜘蛛
particular.net
正文约 6000 字
The question I find myself asking more than any other is “Why?”…
Unfortunately, when the “why” behind decisions goes undocumented, it doesn’t just gracefully fade away—it comes back to haunt you.
Or these days, was it an AI hallucination nobody caught?
Have you ever used a green screen application backed by an IBM mainframe? Or watched a store clerk try to navigate a green-screen point-of-sale system? One of us authors (we’ll never admit who!) remembers almost taking down an entire call center on one of those systems, but that’s another story. 1
Those apps and systems are about as far away from “modern” as you can get, but they run real business: they move orders, settle payments, and sync inventory. Companies that can’t afford downtime depend on them all day, every day. They carry decades of business rules that are hard to replace and risky to rewrite. So most teams don’t get the luxury of choosing between “old” and “new.” They’re trying to keep mission-critical systems in place while giving developers a better way to build with and around them.
Our new IBM MQ message transport bridges the old and the new. IBM MQ keeps doing what it’s always done well: durable, reliable message delivery. NServiceBus adds a modern programming model and operational tooling that many teams would otherwise have to build by hand: handlers instead of receive loops, built-in recoverability, and visibility across service boundaries.
OK fine, you clicked, you asked for it! I was a young, enthusiastic software developer maintaining software that told call center operators which company a caller was trying to reach. My colleagues uploaded files from the command line, but I installed WS_FTP, one of the first FTP clients for Windows (It was great, look it up!) on Windows 3.11 and proudly clicked through the mainframe's folders instead. Then I accidentally dragged one folder into another. Whoops. I had no idea which folder I'd moved, so I did the only natural thing I could do: I told no one. The mainframe slowed and slowed until someone investigated and found the misplaced folder. The machine needed a restart, which took four hours. Calls kept coming in the whole time, but with the software down, operators had to answer the phone without knowing which company they were representing.
For a good primer on these two problems, check out our blog post Banish ghost messages and zombie records from your web tier that describes our transactional session feature that you can also use with the IBM MQ transport.
When it comes to developing distributed systems, anyone can spin up a handful of containers. The part that causes us to bang our foreheads on the table is getting the dozen or so settings configured correctly across all of them. This means using the same transport, mapping queue names, and configuring the correct URLs between ServicePulse and each ServiceControl instance. Now, AddParticularPlatform quietly does all of it for you.
Leave your forehead out of it.
Azure Functions makes it easy to deploy multiple triggers side by side. With support for multiple NServiceBus endpoints in a single process, the new Functions integration brings that same flexibility to message processing: related endpoints can run in one Functions app without sharing handlers, configuration, or dependency injection registrations.
You can now make deployment much easier while preserving endpoint boundaries. HTTP and timer triggers can also send messages through named send-only endpoints without requiring a companion host.
That sounds like a party to me! Plus, each endpoint arrives with a “plus one”: the Service Bus trigger that feeds it messages. Here’s how we made room for them all in one Azure Functions app.
…which included the name "Worker" because the "isolated worker" model replaced the earlier "in-process" hosting model that has been retired by Microsoft. Creating a new package also allowed us to unify the naming around Functions now that the distinction between in-process and isolated worker is no longer necessary.
One day, we believe ahead-of-time compilation will be a killer feature for Azure Functions hosting, as serverless environments start instances on demand, so cold start time and total memory footprint are key. The thing is that the Azure Functions SDK doesn't support trimming or native AOT yet.
In the previous post, we talked about how NServiceBus version 10.2 can now host multiple endpoints within the same host process.
Since we’re already talking about removing constraints and limitations from the past, why don’t we talk about another long-standing NServiceBus requirement…
What if you didn’t need IHandleMessages<T>?
By the way, some people really love this, but there are others that really hate it. It doesn't exactly rise to the level of tabs vs. spaces, but feelings on both sides are very strong.
We already had to do that once in NServiceBus 6 to support async/await. We were forced to change from synchronous void Handle(TMessage) to Task Handle(TMessage, IMessageHandlerContext), and it was so painful we never want to force that kind of change on our users again if we can help it.
That was already a gargantuan project that required changes to nearly every single async method in every one of our repos.
A separate diagnostic NSB0025 does the same for sagas.
I just realized how old I am getting when I recalled that Visual Studio didn't always do that. You needed to get ReSharper for even that simple refactoring.
It even adds the required namespaces!
Oh my gosh, please don't, refactor that mess!
Throughout the history of NServiceBus, there has been a fairly standard practice:
1 endpoint == 1 queue == 1 process
The endpoint owned everything within the process boundary and used assembly scanning to find and wire up all the things that make up that endpoint. While you could use “satellites”, you really couldn’t put more than one full endpoint inside a process boundary.
But… what if it didn’t have to be that way?
…because there are a lo
本页为82搜索生成的网页快照,内容来自站内索引;演示数据的原文链接仅作示例。