I am completely new to Azure and I have a function which is triggered by a service bus queue, the message is a JSON string. Now I want to check if after 3 minutes of receiving the message another arrived.
how do I achieve this?
You may want to use the concept of "Timers in Durable Functions".
https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-timers?tabs=csharp
Are you using "azure functions" or do you want to have a function in azure e.g. in a webservice? I am not so sure ;)
In short no! You would have to poll the servicebus message queue yourself to control that behaviour.
https://stackoverflow.com/a/48899686/12040634
What is the scenario that would require you to check for a subsequent message after 3 minutes?
I have a function which is triggered by a service bus queue… I want to check if after 3 minutes of receiving the message another arrived.
Azure Service bus can schedule or defer a message. The two are not the same. Deferring means you need to keep a message and retrieve it at some point yourself. Scheduling, requires creating a new message. But, the two could be combined. Upon receiving of the message (message A), it could be deferred and a new message scheduled (message B), with its payload being the sequence number of the message A. When the message’s B time comes, it will be received by your code and you can request the deferred message B.
This is rather straightforward but you’ll need a few changes to the default Function behaviour. You’ll need to specify that your function needs to be injected with the receiver to be able to defer the incoming message A, and create a sender to post a scheduled message. Also, the function code will now have to distinguish between “data” messages (A) and control messages (B). And that all will only work with the in-process Functions SDK as the newer, Isolated Worker SDK doesn’t support Service Bus SDK types.
But, there are alternatives. You could use Durable Functions to build your mini workflow. Or you could use one of the middleware abstractions for messaging to simplify the implementation with function. MassTransit and NServiceBus with SendLocal()would do.
And good luck with conquering Azure. There are many ways to tackle any problem. Especially with cloud providers.
Related
I have multiple microservices. They communicate through message broker as currently, I am using Masstransit rabbitmq. Things are working fine.
Now, I have a case where one service A publishes a message and another service B consumes it. Service B sends a number of emails which takes some time. If it fails, it invokes a new event where I want to send a negative acknowledgment and want service A to republish again after some delay. I know I can through an exception in service B consume method but this is not possible here. Send email runs in an independent way. How can I republish the message from service A to B?
The answer to your question has nothing to do with MassTransit, or any other library, which you can use to support the flow. You need to design the message flow according to your needs.
It is not very clear, why sending an email takes some time, and why it can fail, so the following is purely based on assumptions.
If service B sends a batch of emails by consuming a single message, it is not transactional. If it sends 100 emails and fails on 101, what would happen? If you have a message retry policy, it will send the first 100 emails again.
I would definitely try to limit a single message scope to handle a single transaction. Split each email send operation to its own message and handle those (potentially thousands) of messages, it's totally fine. At least, in case of a retry, it will retry one operation only. Each individual operation is confirmed, not the whole batch. It is fine for service A to command service B to send a number of emails. It is the responsibility of service B to split the number of emails it needs to send to a number of individual messages. Service B can perfectly send messages to itself.
How you handle errors is your own decision. For all the cases when I had to deal with sending emails, it was like this:
Each email is a separate message
If it fails, I check what the reason is. Usually, you don't get a failure from the mail provider immediately, unless the email address is obviously incorrect, or the provider itself is down.
Prevent sending a message to wrong emails in the first place, you don't need to overload the system with such obvious errors.
If the email provider is down, engage the message retry policy accordingly. Ensure to have a circuit breaker in place to manage the backpressure from the provider if you hammer it too hard and get rate-limited. You can also rate-limit your own consumers. All of those are built-in middleware in MassTransit.
Only retry transient errors. If the error is permanent, there's no need to retry.
If all the retries suddenly fail, you can still engage the redelivery. It's built-in to MassTransit. Still, ask yourself a question why can it even happen?
Sending a NACK message from service A to service B is trivial. If the error happens, instead of throwing, publish or send another message for service A. I don't see any issue with that.
You can always check if your retry or redelivery count is depleting by looking at the consumer context metadata. You can decide to only send a NACK message to service A if all the retries have failed.
There's nothing wrong with throwing per se, as you get the retry and redelivery middleware there to help you handling transient failures. Service A can always listen to Fault events if those policies exhaust their retry counts and the message will land in the poison queue. The poison queue is valuable as it allows you to analyse the nature of the failiure.
Again, it's not a technical issue. You need to decide how you want to handle this workflow. MassTransit would help you to implement it in the way you want it, but you first need to decide what you want.
I'm trying to understand the difference between a queue trigger and a service bus queue trigger and which one I need!
I have a asp.net mvc site that is for creating and scheduling classes, which will be represented as a row in a db table. When a class is over I want to send an email to all students asking them to rate their teacher
As far as I'm aware the best way to do this is to create a Azure function that will create and send the emails, but where I'm lost is how to trigger that function at a specific date and time?
Do I use a queue trigger or a service bus queue trigger? What's the difference between the two and which one would be the best for my scenario?
I need to be able to cancel the message in the queue if the class is canceled.
If cancelling scheduled messages is a hard requirement, only Service Bus allows doing that, see this blog.
However, it might be more practical to just add a check whether the class was cancelled at the beginning of your Azure Function, and quit if so.
For the rest of your scenarios, the services will both fit.
Generally, Service Bus has more advanced capabilities and guarantees, but costs more money if you send lots of messages. I usually pick Storage Queues unless I need any of those more advanced features.
I have the following message transport scenarios
Client -> Calls SignalR -> Calls NServiceBus -> Process Message internally -> Calls NServiceBus Gateway service with Result -> Calls SignalR Hub -> Updates the client with result.
In choosing whether to use SignalR vs. long polling, I need to know if SignalR is scaleable. So in doing my homework I came across SignalR on Azure Service Bus. The setup is done on the Global.asax application start.
Ultimately I need to be able to do this, from inside an NServiceBus handler:
var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
context.Clients.Group(group).addMessage(message);
The question is if context will be jacked up, because I'm (potentially) calling it from another machine than the one the client was connected to?
Also what is the sharding schema that the SignalR implementation uses to seed the topics? I know I can configure it to use N-number of topics, but how is it actually determining which message goes to which topics and if it's relevant from an external caller PoV.
You should be able to use GlobalHost.ConnectionManager.GetHubContext in any application where you have registered ServiceBusMessageBus as your IMessageBus via SignalR's GlobalHost.DepenencyResolver. This is done for you if you call GlobalHost.DepenencyResolver.UseServiceBus(...) in the application.
If you do this, a message will be published to Azure Service Bus for each call to addMessage or any other hub method on the IHubContext returned from GetHubContext. If there are subscribed clients connected to other nodes in the web farm, the other nodes will pick up the message from Service Bus and relay it to the subscribed clients.
Which topic a message goes to should not be relevant from the PoV of an external caller. You can use multiple topics to improve throughput, but for most use cases one should be sufficient.
If you choose to use more than one topic, you can think about the topic a message goes to as being essentially random. The only thing that is guaranteed is that messages from the same sender will go to the same topic. This allows SignalR to keep messages from the same sender in order.
Caveat emptor: SignalR has not yet had an official release supporting scale out. The 1.1 version will be the first release to support scale out officially.
I am fixing a .net app written on top of nServiceBus and have a few questions:
The app is configured AsA_Publisher and when it starts it waits for incoming
connections on a socket, do you know why it might have been implemented like so?
Why sockets? This socket is created during the Run method of a class which implements class IWantToRunAtStartup.
Once a message arrives, the message is written to a queue (Q1). The message
is then read from the queue(Q1). The format of the message is changed and then
inserted into yet another queue (Q2). The message is then read from the queue
(Q2) and sent to another application by calling a web service. The whole idea is
to change the message format and send it off to the final destination. If
nServiceBus is built on top of MSMQ, then why is the application creating more
queues and managing them?
I see absolutely nothing about Publish or Subscribe anywhere in the project. I guess it is relying on the socket to receive messages and if so then it is not really taking advantage of nServiceBus's queuing facility? Or am I lost...
If queues are needed and if I was to build this I will have one app writing to
the queue (Q1), another app reading from the queue (Q1) and changing the format
and inserting to another queue (Q2) and finally a third app reading from the
(Q2) and sending it off to the web service. What do you think?
Thanks,
I see nothing wrong with opening a socket in Run in an IWantToRunAtStartup. It must somehow be required that the service can be reached through some custom protocol implemented on top of sockets.
Processing the incoming socket messages by immediately bus.Sending a message is also the way to go - the greatest degree of reliability is achieved by immediately doing the safest thing possible: sending a durable message.
Performing the message translation in a handler and bus.Sending the result in another message is ALSO the way to go - especially if the translation is somehow expensive and it makes sense to be able to pick up processing at this point if e.g. the web service call fails.
Making a web service call in a message handler is also be the way to go - especially if the web service call is idempotent, so it doesn't break anything if the message ever gets retried.
In other words, it sounds like the service correctly bridges a socket-based interface to a web service-based interface.
It sounds weird, however, that the service employs multiple queues to achieve this. With NServiceBus it would be entirely sufficient with one single queue: the service's input queue.
Looking for some ideas/pattern to solve a design problem for a system I will be starting work on soon. There is no question that I will need to use some sort of messaging (probably MSMQ) to communicate between certain areas of the system. I don't want to reinvent the wheel, but at the same time I want to make sure I am using the right tool for the job. I have been tinkering with and reading up on NServiceBus, and I'm very impressed with what it does--however I'm not sure it's intended for what I'm trying to achieve.
Here is a (hopefully) very simple and conceptual description of what the system needs to do:
I have a service that clients can send messages to. The service is "Fire and Forget"--the most the client would get back is something that may say success or failure (success being that the message was received).
The handling/processing of each message is non-trivial, and may take up significant system resources. For this reason only X messages can be handled concurrently, where X is a configurable value (based on system specs, etc.). Incoming messages will be stored in queue until it's "their turn" to be handled.
For each client, messages must be handled in order (FIFO). However, some clients may send many messages in succession (thousands or more), for example if they lost connectivity for a period of time. For this reason, messages must be handled in a round-robin fashion across clients--no client is allowed to gorge and no client is allowed to starve. So the system will either have to be able to query the queue for a specific client, or create separate queues per client (automatically, since the clients won't be known at compile time) and pull from them in rotation.
My current thinking is that I really just need to use vanilla MSMQ, create a service to accept messages and write them to one or more queues, then create a process to read messages from the queue(s) and handle/process them. However, the reliability, auditing, scaleability, and ease of configuration you get with something like NServicebus looks very appealing.
Is an ESB the wrong tool for the job? Is there some other technology or pattern I should be looking at?
Update
A few clarifications.
Regarding processing messages "in order"--in the context of a single client, the messages absolutely need to be processed in the order they are received. It's complicated to explain the exact reasons why, but this is a firm requirement. I neglected to mention that only one message per client would ever be processed concurrently. So even if there were 10 worker threads and only one client had messages waiting to be processed, only one of those messages would be processed at a time--there would be no worry of a race condition.
I believe this is generally possible with vanilla MSMQ--that you can have a list of messages in a queue and always take the oldest one first.
I also wanted to clarify a use case for the round robin ordering. In this example, I have two clients (A and B) who send messages, and only one worker thread. All queues are empty. Client A has lost connectivity overnight, so at 8am sends 1000 messages to the service. These messages get queued up and the worker thread takes the oldest one and starts processing it. As this first message is being processed, client B sends a message into the service, which gets queued up (as noted, probably in a separate queue). When Client A's first message completes processing, the logic should check whether client B has a message (it's client B's "turn"), and since it finds one, process it next.
If client B hadn't sent a message during that time, the worker would continue processing client A's messages one at a time, always checking after processing to see if other client queues contained waiting messages to ensure that no client was being starved.
Where I still feel there may be a mismatch between an ESB and this problem is that an ESB is designed to facilitate communication between services; what I am trying to achieve is a combination of messaging/communication and a selective queuing system.
So the system will either have to be
able to query the queue for a specific client,
Searching through an MSMQ queue for a message from a particular client using cursors can be inefficient and doesn't scale.
or create separate queues per client (automatically, since the
clients won't be known at compile time) and pull from them in rotation.
MSMQ cannot create queues automatically. All messages have to be sent to a known queue first. Your own custom dispatcher service, though, could then create new queues on demand and put copies of the messages in them.
[[I avoid saying "move" messages as you can't do that with application code; you can only read a message and create a new message using the original data. This distinction is important when you are using Source Journaling, for example.]]
Cheers
John Breakwell
Using an ESB like NServiceBus seems like a good solution to your problem. But based on your conceptual description, there's some things to consider. Let's go through your requirements step-by-step, using NServiceBus as a possible ESB solution:
I have a service that clients can send messages to. The service is "Fire and Forget"--the most the client would get back is something that may say success or failure (success being that the message was received).
This is easily done with NServiceBus. You can Bus.Send(Message) from the client. If your client requires an answer, you can use Bus.Return(ErrorCode). You mention that "success being that the message was received". If you use an ESB like NServiceBus, it's up to the messaging platform the deliver the message. So, if your Bus.Send doesn't throw an exception, you can be sure that the message has been sent properly. Because of this you don't probably have to send success / failure messages back to the client.
The handling/processing of each message is non-trivial, and may take up significant system resources. For this reason only X messages can be handled concurrently, where X is a configurable value (based on system specs, etc.). Incoming messages will be stored in queue until it's "their turn" to be handled.
When using NServiceBus, you can configure the the number of worker threads by setting the "NumberOfWorkerThreads" option. If your server has multiple cores / cpus, you can use this setting to balance the work load.
For each client, messages must be handled in order (FIFO).
This is something that may cause problems depending on your requirements. ESBs in general don't promise to process the messages in-order, if they have many threads working on the messages. In a case of NServiceBus, you can send an array of messages from the client into the bus and these will be processed in-order. Also, you can solve some of the in-order messaging problems by using Sagas.
However, some clients may send many messages in succession (thousands or more), for example if they lost connectivity for a period of time
When using an ESB solution, your server doesn't have to be up for the client to work. Clients can still send messages and the server will start processing them as soon as it's back online. Here's a small introduction on this.
For this reason, messages must be handled in a round-robin fashion across clients--no client is allowed to gorge and no client is allowed to starve.
This isn't a problem because you've decided to use messages :)
So the system will either have to be able to query the queue for a specific client, or create separate queues per client (automatically, since the clients won't be known at compile time) and pull from them in rotation.
Could you expand on this? I'm not sure of your design on this one.