Upload
espen-ekvang
View
859
Download
4
Embed Size (px)
DESCRIPTION
Workshop given @ BEKK Fagdag March 1st 2013 together with Tomas Jansson
Citation preview
NSERVICEBUS
Inspired by: The course authored by Udi Dahan
Oslo/Fagdag
Espen Ekvang/Tomas Jansson
01/03/2013
AGENDA 2
• Intro
• Messaging and queues
• Testing
• SOA
• Saga
INTRO 3
• Fallacies of distributed computing
• Why NServiceBus?
• Bus vs. Broker
• Service orientation
• Excercises
FALLACIES OF DISTRIBUTED COMPUTING 4
1. The network is reliable
2. Latency isn’t a problem
3. Bandwidth isn’t a problem
4. The network is secure
5. The topology won’t change
6. The administrator will know what to do
7. Transport cost isn’t a problem
8. The network is homogeneous
Cant’ assume WHEN the message will arrive,
IF AT ALL
WHY NSERVICEBUS 5
1. The network is reliable
2. Latency isn’t a problem
3. Bandwidth isn’t a problem
4. The network is secure
5. The topology won’t change
6. The administrator will know what to do
7. Transport cost isn’t a problem
8. The network is homogeneous
NServiceBus addresses the first five directly
The most developer-friendly service bus for SOA on .NET
BUS VS. BROKER 6
Buss.dll
App
Buss.dll
App
Buss.dll
App
App
App App
Broker
• Bus is not necessarily physically separate
• Simpler; no routing or service fail over
• No single point of failure
TENETS OF SERVICE ORIENTATION 7
• Services are autonomous
• Share contract & schema, not class or type
• Boundaries are explicit
• Compatibitility is base on Policy
LAYERS & COUPLING 8
UI
BL
DAL
DB
Sales Shipping CRM
Tight coupling
Loose coupling
Referential Integrity
Reintroduces coupling
WHEN CAN I WRITE SOME CODE? 9
• Getting started
• New class library
• Install-Package NServiceBus.Host
• Logging
• NServiceBus uses log4net, you can configure logging in app.config
• Default output is console
EXERCISES 10
HELLO WORLD LOGGING
MESSAGING AND QUEUES 11
• Store & forward
• Dangers of store & forward
• Request/Response
• Messaging and NServiceBus
• Exercises
SERVER
STORE & FORWARD 12
MSMQ
OUTGOING INCOMING
CLIENT
MSMQ
OUTGOING INCOMING
Store & Forward writes to disk
Resilient in the face of failures
DANGERS OF STORE & FORWARD 13
• If target is offline for an extended period of timemessages can fill up the disk
• Can cause a server to crash
• Especially problematic in B2B integration
• 1 MB/message, 100 message/sec = 6GB/minute
• Solution – discard messages after a while
• Use [TimeToBeReceived("00:01:00")] on the message definition
REQUEST/RESPONSE 14
SERVER
MSMQ
OUTGOING INCOMING
CLIENT
MSMQ
OUTGOING INCOMING
Client can’t assume when a response will arrive, if at all
Equivalent to 2 one-way messages
REQUEST/RESPONSE 15
• Message is sent from the server to the client’s queue If the client is offline, message sits in the server machine’s outgoing queue
• Client is not blocked until response arrives
• If two requests were sent, responses may arrive out of order
WARNING! THIS IS NOT RPC 16
• Do NOT try to implement regular request/response patterns on top of messaging
• The client should be designed so that it can continue operating if a response never comes
Differences from RPC
• RPC is easy to code
• After invoking a web service
• Next line of code assumes we’ve got a response
• RPC problems
• Can’t reason about the time between one line of code and another
• Messaging makes this all explicit
MESSAGING AND NSERVICEBUS 17
SERVER
MSMQ
OUTGOING INCOMING
CLIENT
MSMQ
OUTGOING INCOMING
Transaction
DEFINE A MESSAGE 18
• Preferably inherit from IEvent or ICommand
• Use IMessage when replying using Bus.Reply()
• Also possible to define your own convention
• Configure.DefiningMessagesAs(t=>MyOwnConvention(t))
• Add properties like a regular class/interface
• Keep contract definintions in their own assembly/project
public class MyEvent: IEvent {}
INSTANTIATE A MESSAGE 19
• var myMessage = new MyMessage();
• var myMessage = Bus.CreateInstance<MyMessage>();
SEND A MESSAGE 20
Bus.Send(messageObject);
Can instantiate and send together (useful for interfaces):
Bus.Send<IMessage>((message) =>
{
message.Prop1 = value1;
message.Prop2 = value2;
});
SPECIFY DESTINATION 21
1. Bus.Send(destination, messages); Requires that application manages routing
2. Configure destination for message type. In <UnicastBusConfig>, under <MessageEndpointMappings> specify one of the following: - <add Messages="assembly" Endpoint="destination"/> - <add Messages="type" Endpoint="destination"/>
3. Specify destination using - QueueName@ServerName , or - Just QueueName for the same machine
HANDLE A MESSAGE 22
Write a class that implements IHandleMessages<T> where T is a message type
public class MyHandler : IHandleMessages<MyMessage>
{
public void Handle(MyMessage message)
{
}
}
Remember to specify in <UnicastBusConfig>, under <MessageEndpointMappings> one of the following: - <add Messages="assembly" Endpoint="source"/> - <add Messages="type" Endpoint="source"/>
CONFIGURING AN ENDPOINT 23
When configuring an endpoint inherit from
1. Using AsA_Client will
- use non-transactional MsmqTransport - purge its queue of messages on startup - processes messages using its own permissions, not those of the message sender
2. Using AsA_Server will - use transactional MsmqTransport - not purge its queue of messages on startup, hence fault-tolerant - processes messages using the permissions of the sender (impersonation)
3. Using AsA_Publisher will
- extends AsA_Server
- indicates to the infrastructure that a storage for subscription request is to be set up
EXERCISES 24
ONE-WAY MESSAGING (CLIENT) PROCESSING MESSAGES (SERVER) EXCEPTIONS
UNIT TESTING MESSAGE HANDLERS 25
Available from NuGet using
Install-Package NServiceBus.Testing
Provides the ability to set expectations around how message handlers handle messages
• Expect: Send, Reply, Publish, etc...
Test.Initialize();
Test.Handler<MyHandler>()
.ExpectPublish<MyMessage>(message => message.Prop1 == value1)
.OnMessage<SomeEvent>(someEvent =>
{
someEvent.Prop1 = inputValue1;
});
EXERCISE 26
UNIT TESTING
SAGA 27
• Definition
• Saga declaration
• Saga ending
• Saga testing
• Exercise
SAGA - DEFINITION 28
A Saga:
• Is a pattern for implementing long-lived transaction by using a series of shorter transactions
• Holds relevant state to needed to process mulitple messages in a ”saga entity”
• Are initiated by a message (event/command)
SAGA - DECLARATION 29
public class MyPolicy : Saga<MyPolicyData>,
IAmStartedByMessages<MyMessage1>,
IHandleMessages<MyMessage2>
{
public void Handle(MyMessage1 order)
public void Handle(MyMessage2 order)
}
• Methods are like regular message handling logic
• Sagas can be started by multiple messages (IAmStartedByMessages<T>)
• First messages should start saga, following messages should be processed by the same one
SAGA – DECLARATION CONT. 30
public class MyPolicyData : ISagaEntity
{
public Guid Id { get; set; }
public string Originator { get; set; }
public string OriginalMessageId { get; set; }
}
ENDING A SAGA 31
MarkAsComplete();
• Can call this from any method
• Causes the saga to be deleted
• Any data that you want retained should be sent on (or published) via a message
UNIT TESTING A SAGA 32
Test.Saga<MyPolicy>()
.ExpectPublish<Message1>(/* check values */)
.ExpectSend<Message2>(/* check values */)
.ExpectReplyToOriginator<Message3>(/* check values */)
.When(saga => saga.Handle(myMessage));
/* check values */
message => return(message.Data == someValue);
EXERCISE - SAGAS ROCK 33
EXTRA EXERCISES 34
TIMEOUT CUSTOM XML NAMESPACE CONFIGURABLE ROUTING DEPENDENCY INJECTION WEB-APP HOSTING FULL DUPLEX DISTRIBUTION GROUP EXERCISE