nservicebus alt.net 20100511
DESCRIPTION
TRANSCRIPT
Building enterprise applications with
NServiceBusAndreas Öhlund
onsdag den 12 maj 2010
What is a distributed system?
“A distributed system is one in which the failure of a computer you didn't even know existed can render your own computer unusable”
-Leslie Lamport
onsdag den 12 maj 2010
The first rule of NServiceBus
onsdag den 12 maj 2010
The first rule of NServiceBus
There is NO Service Bus!
onsdag den 12 maj 2010
Well, at least no physical one
onsdag den 12 maj 2010
The second rule of NServiceBus
onsdag den 12 maj 2010
The second rule of NServiceBus
You DO NOT usesynchronous communication
onsdag den 12 maj 2010
The key to robust communication
onsdag den 12 maj 2010
Store and forward
onsdag den 12 maj 2010
Request/Response the NServiceBus way
Fire and forget X 2
onsdag den 12 maj 2010
The effect of tight coupling
TemporalBehavioral
onsdag den 12 maj 2010
Communication and coupling
onsdag den 12 maj 2010
Coupling NServiceBus style
onsdag den 12 maj 2010
Command oriented communication
OnlineSales OrderService
CompleteSaleCommand
onsdag den 12 maj 2010
Sending MessagesIBus.Send()
OnlineSales OrderService
CreateOrderCommandbus.Send(new CompleteSaleCommand
{ProductId = 123,Quantity = 10....
});
onsdag den 12 maj 2010
Receiving and processing of messages
OnlineSales OrderService
CreateOrderCommandpublic class CompleteSaleMessageHandler:
IHandleMessages<CompleteSaleCommand>{
public void Handle(CompleteSaleCommand c){
...}
}
onsdag den 12 maj 2010
Message Contracts
• Versioned by the owner
• Regular .Net Assembly
• Bound to a input queue
• class MyMessage : IMessage
onsdag den 12 maj 2010
Throttling the load• Manage traffic peaks
• Consumer controls the pace
• <MsmqTransportConfig NumberOfWorkerThreads="3" />
onsdag den 12 maj 2010
What happens when the load becomes to heavy for one server?
onsdag den 12 maj 2010
Scaling with the Distributor
onsdag den 12 maj 2010
Building consistent systems
• Do we produce predictable results even under failure conditions?
• What about non transactional sources?
onsdag den 12 maj 2010
Isolate non transactional sources as separate endpoints
public void Handle(CompleteSaleCommand cmd){ var order = ....
orderRepository.Save(order)
smtpClient.Send(new MailMessage{...})}
onsdag den 12 maj 2010
Isolate non transactional sources as separate endpoints
public void Handle(CompleteSaleCommand cmd){ var order = ....
orderRepository.Save(order)
smtpClient.Send(new MailMessage{...})}
public void Handle(CompleteSaleCommand cmd){ var order = ....
orderRepository.Save(order)
bus.Send(new NotifyCustomerRequest { EmailAddress = customer.Email, Body = “Order confirmation” });
}
onsdag den 12 maj 2010
Idempotent
“Idempotent operations are operations that can be applied multiple times without changing the result”
onsdag den 12 maj 2010
When things go wrong
onsdag den 12 maj 2010
Messaging gives you a chance to do better
• No more showing the users a WSOD
• Messages are replayable
• Async communication opens up a crucial windows of time for corrections
onsdag den 12 maj 2010
Event oriented communication
onsdag den 12 maj 2010
Publish and subscribe
• Everyone get’s a copy
• Removes behavioral coupling
onsdag den 12 maj 2010
Business eventsSales
SalesService
Billing
BillingService
Shipping
ShippingService
OrderAcceptedEvent
onsdag den 12 maj 2010
Finally a chance to discuss non functional requirements that business people understand
onsdag den 12 maj 2010
The mechanics of pub/sub
onsdag den 12 maj 2010
The mechanics of pub/sub
onsdag den 12 maj 2010
Becoming a subscriber
bus.Subcribe<IOrderAcceptedEvent>();
onsdag den 12 maj 2010
Publishingbus.Publish<IOrderAcceptedEvent>(x=>
{ProductId = 123,Quantity = 10....
});
onsdag den 12 maj 2010
It’s hard to get it right the first time around
onsdag den 12 maj 2010
Versioning events using interfaces
public interface IOrderAcceptedEvent2 : IOrderAcceptedEvent{
string SomeNewProperty{ get;set; }}
onsdag den 12 maj 2010
Long running transactions
onsdag den 12 maj 2010
Use sagas to model long running transactions
public class MySaga : Saga<MySagaData>, IAmStartedByMessages<Message1>, IHandleMessages<Message2>{ public void Handle(Message1 message) { // code to handle Message1 }
public void Handle(Message2 message) { // code to handle Message2 }}
onsdag den 12 maj 2010
Storing state
public class MySagaData : IContainSagaData{ // the following properties are mandatory public virtual Guid Id { get; set; } public virtual string Originator { get; set; } public virtual string OriginalMessageId { get; set; }}
onsdag den 12 maj 2010
Timeoutspublic void Handle(Message1 message){ this.Data.SomeID = message.SomeID;
RequestTimeout(TimeSpan.FromHours(1), "some state");}
public override void Timeout(object state){ // some business action like: if (!Data.Message2Arrived) ReplyToOriginator(new TiredOfWaitingForMessage2());}
onsdag den 12 maj 2010
Configuration
Developers: use codeAdministrators: use config files
onsdag den 12 maj 2010
Hosting options
• Custom hosting
• Website
• Smartclient
• Commandline
• Generic host
onsdag den 12 maj 2010
Using the Generic Hostpublic class EndpointConfig: IConfigureThisEndpoint, AsA_Publisher
{
}
onsdag den 12 maj 2010
Using profiles to adapt to different environments
onsdag den 12 maj 2010
NServiceBus role in CQRS Style applications
onsdag den 12 maj 2010
NServiceBus is opinionated
onsdag den 12 maj 2010
Why all these opinions?
onsdag den 12 maj 2010
Don’t use messaging for queries
• Queries need to return relatively fast
• No benefit from the robustness that NSB gives
• Use NSB to cache data close and use native apis to get at that data
onsdag den 12 maj 2010
The end
• www.nservicebus.com
• www.udidahan.com/blog
• andreasohlund.blogspot.com
onsdag den 12 maj 2010