beyond horizontal scalability: concurrency and messaging using spring

46
Beyond Horizontal Scalability: Concurrency & Messaging Using Spring Bruce Snyder, Senior Software Engineer, SpringSource/VMware Friday, July 8, 2011

Upload: bruce-snyder

Post on 07-Nov-2014

3.746 views

Category:

Technology


0 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Beyond Horizontal Scalability: Concurrency & Messaging Using Spring

Bruce Snyder, Senior Software Engineer, SpringSource/VMware

Friday, July 8, 2011

Page 2: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Problem Statement

• Software systems are growing larger than ever before – Virtual Machines – Physical Machines– More CPUs– Multi-core CPUs– More requests– More data

• With so many hardware changes, shouldn’t our software practices change too?

Friday, July 8, 2011

Page 3: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Typical Application Layers

3

Friday, July 8, 2011

Page 4: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Typical Code Construction

• Command-and-control scheme– One method calls another– Blocking calls

• Assumptions – One task takes place at a time – The order of operations in known – The provider of a particular function is known – All execution happens in a single JVM

4

Friday, July 8, 2011

Page 5: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Typical Component Interaction

• Single memory space • Using the call stack • Sequential execution

• Assumptions – No separation between:

• Knowing what needs to happen next • Knowing which method to invoke

– Interactions are always known at compile time

5

Friday, July 8, 2011

Page 6: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Typical Assumptions

• All work must take place in a single call stack • Example:

– Receive request– Verify data– Save data – Query data– Generate PDF– Send email – Render response

6

Friday, July 8, 2011

Page 7: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

• The higher the number of assumptions, the more tightly coupled the system

7

Friday, July 8, 2011

Page 8: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Typical Client Request

8

Friday, July 8, 2011

Page 9: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Typical Request Growth

9

Friday, July 8, 2011

Page 10: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Typical Strategy For Horizontal Scaling

10

Friday, July 8, 2011

Page 11: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Typical Assumptions

• All work must take place on a single machine • Example:

– Receive request– Verify data– Save data – Query data– Generate PDF– Send email – Render response

11

Friday, July 8, 2011

Page 12: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Treating the Symptoms

• Horizontal scale is good to a point – Treat the symptoms instead of fixing the cause of the illness

• Throughput of functions should not equal response time!

• This is not the case at forward-thinking companies – Amazon.com

12

Friday, July 8, 2011

Page 13: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

The Problem With Distributed Systems

• Most developers don’t understand them – Call stack provides specific interaction style – Most object-oriented systems focus on structure vs.

interaction

• Interaction becomes more important than structure – Mediator pattern - encapsulates how objects interact – Observer pattern - notifies dependent objects of state change

• The real point of service-orientated design – Composition rules are rather simple – Loosely coupled interaction becomes very important

13

Friday, July 8, 2011

Page 14: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Is There a Better Solution?

• Insert a level of indirection – Remove direct interaction between components – Extract the interaction into a separate element – Enterprise Integration Patterns (EIP)

• http://enterpriseintegrationpatterns.com/

• Simplify the rules of component interaction – Remove the coordination and continuation style of interaction– Just send data

14

Friday, July 8, 2011

Page 15: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Concurrency

• Concurrency is a style of asynchronous execution

15

Friday, July 8, 2011

Page 16: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Concurrency With Spring

• Spring provides the TaskExecutor interface – Abstracts the execution of a Runnable, i.e., asynchronous work– SimpleAsyncTaskExecutor

• Creates a new thread for each task – ThreadPoolTaskExecutor

• Uses a JDK 1.5 ThreadPoolExecutor to create a pool of threads– org.springframework.scheduling.concurrent package

• Many scheduling related utility classes – WorkManagerTaskExecutor

• Delegates to a JCA 1.5 CommonJ WorkManager

16

Friday, July 8, 2011

Page 17: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

JDK ExecutorService

17

ExecutorService executorService = Executors.newSingleThreadExecutor();executorService.execute(task);executorService.shutdown();

executorService = Executors.newFixedThreadPool(10);executorService.execute(task);executorService.shutdown();

int corePoolSize = 5;int maxPoolSize = 10;long keepAliveTime = 5000;executorService = new ThreadPoolExecutor(corePoolSize, maxPoolSize,

keepAliveTime, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());

executorService.execute(task);executorService.shutdown();

Friday, July 8, 2011

Page 18: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Spring TaskExecutor

18

<bean id="myTask" class="org.bsnyder.spring.concurrency.MyTask" />

<bean id="springConcurrencyExample" class="org.bsnyder.spring.concurrency.SpringConcurrencyExample" /> <bean id="simpleAsyncTaskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor" p:daemon="false" />

<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" p:corePoolSize="5" p:maxPoolSize="10" p:queueCapacity="30" />

Friday, July 8, 2011

Page 19: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Spring TaskExecutor

19

public class SpringConcurrencyExample {! @Autowired! private Runnable task;! @Autowired! private SimpleAsyncTaskExecutor simpleAsyncTaskExecutor;! @Autowired! private ThreadPoolTaskExecutor threadPoolTaskExecutor;!! public void runExamples() {! ! simpleAsyncTaskExecutor.execute(task);! ! threadPoolTaskExecutor.execute(task);! }!! public static void main(String[] args) {! ! ApplicationContext context = ! ! ! new ClassPathXmlApplicationContext("/META-INF/spring/executor-context.xml",

SpringConcurrencyExample.class);! ! SpringConcurrencyExample example =

context.getBean(SpringConcurrencyExample.class);! ! example.runExamples();! }}

Friday, July 8, 2011

Page 20: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Messaging

• Messaging is a style of communication • Often used for integration purposes

20

Friday, July 8, 2011

Page 21: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Messaging With Spring

• JMS Support – JmsTemplate for sync send and receive – DefaultMessageListenerContainer and

SimpleMessageListenerContainer for async receive • javax.jms.MessageListener• org.springframework.jms.listener.SessionAwareMessageListener• org.springframework.jms.listener.adapter.MessageListenerAdapter

• AMQP Support – RabbitTemplate for sync send and receive – SimpleMessageListenerContainer for async receive

• org.springframework.amqp.core.MessageListener• org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter

21

Friday, July 8, 2011

Page 22: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Spring JmsTemplate

22

<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory" p:brokerURL="tcp://localhost:61616" /> <bean id="destination" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg value="FOO.TEST" /> </bean> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate" p:connectionFactory-ref="connectionFactory" p:defaultDestination-ref="destination" />

<bean id="messageProducer" class="org.bsnyder.spring.jms.producer.SimpleMessageProducer" p:jmsTemplate-ref="jmsTemplate" />

Synchronous

Friday, July 8, 2011

Page 23: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Spring JmsTemplate

23

// Use the default destination jmsTemplate.convertAndSend("Hello World!");

// Use a different destinationjmsTemplate.convertAndSend(“TEST.BAR”, “Hello World!”);

// Use a different destinationString textMessage1 = (String) jmsTemplate.receiveAndConvert();

// Use a different destinationString textMessage2 = (String) jmsTemplate.receiveAndConvert(“TEST.BAR”);

Synchronous

Friday, July 8, 2011

Page 24: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

DefaultMessageListenerContainer

• XML configuration

24

<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory" p:brokerURL="tcp://localhost:61616" />

<bean id="messageListener" class="org.bsnyder.spring.jms.listener.SimpleMessageListener" />

<jms:listener-container concurrency="5-10"> <jms:listener destination="FOO.TEST" ref="messageListener"/> </jms:listener-container>

Asynchronous

Friday, July 8, 2011

Page 25: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Spring RabbitTemplate

25

<bean id="rabbitAdmin" class="org.springframework.amqp.rabbit.core.RabbitAdmin"> <constructor-arg ref="connectionFactory"/> </bean> <bean id="connectionFactory" class="org.springframework.amqp.rabbit.connection.SingleConnectionFactory" p:host="localhost" p:port="5672" p:username="guest" p:password="guest"/>

<bean id="rabbitTemplate" class="org.springframework.amqp.rabbit.core.RabbitTemplate" p:connectionFactory-ref="connectionFactory" p:routingKey="TEST.FOO" p:queue="TEST.FOO" />

<bean id="messageProducer" class="org.bsnyder.spring.amqp.producer.SimpleMessageProducer" p:rabbitAdmin-ref="rabbitAdmin" p:rabbitTemplate-ref="rabbitTemplate"/>

Synchronous

Friday, July 8, 2011

Page 26: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Spring RabbitTemplate

26

// Use the default destination rabbitTemplate.convertAndSend("Hello World!");

// Use a different destinationrabbitTemplate.send(“TEST.FOO”, “TEST.FOO”, message);

// Use a different destinationMessage message1 = rabbitTemplate.receiveAndConvert();

// Use a different destinationString textMessage2 = (String) rabbitTemplate.receive(“TEST.FOO”);

Synchronous

Friday, July 8, 2011

Page 27: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

SimpleMessageListenerContainer

27

<bean id="connectionFactory" class="org.springframework.amqp.rabbit.connection.SingleConnectionFactory" p:host="localhost" p:port="5672" p:username="guest" p:password="guest"/>

<bean id="rabbitAdmin" class="org.springframework.amqp.rabbit.core.RabbitAdmin"> <constructor-arg ref="connectionFactory"/> </bean>

<bean id="rabbitTemplate" class="org.springframework.amqp.rabbit.core.RabbitTemplate" p:connectionFactory-ref="connectionFactory" p:routingKey="TEST.FOO" p:queue="TEST.FOO" />

<bean id="messageListener" class="org.bsnyder.spring.amqp.listener.SimpleMessageListener" p:rabbitTemplate-ref="rabbitTemplate"/> <bean id="listenerContainer" class="org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer" p:connectionFactory-ref="connectionFactory" p:queueName="TEST.FOO" p:concurrentConsumers="5" p:listener="messageListener" />

Asynchronous

Friday, July 8, 2011

Page 28: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Best of Both Worlds

• What if concurrency and messaging was provided together?

28

Friday, July 8, 2011

Page 29: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Spring Integration

• A framework for integration

• Styles of integration – Intra-application integration – Inter-application integration – External system integration

29

Friday, July 8, 2011

Page 30: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Enterprise Integration Patterns (EIP)

30

http://enterpriseintegrationpatterns.com/

Friday, July 8, 2011

Page 31: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Spring Integration

• Provides both concurrency and messaging– Message Endpoints

• Connections between services – Channel Adapters

• Adapter between application and message broker – Messaging Gateways

• Provides uni-directional or bi-directional messaging – Service Activators

• Invokes a services based on an incoming message – Routers

• Determines where to dispatch a message – Splitters and Aggregators

• Breaks up a message and reassembles it after processing

31

Friday, July 8, 2011

Page 32: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Spring Integration

• Supports – AMQP– Email– File system – Gemfire– JMS– JMX– MongoDB– Redis– Spring Batch – Testing – Web Services

32

Friday, July 8, 2011

Page 33: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Spring Integration

33

Friday, July 8, 2011

Page 34: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Spring Integration

34

Friday, July 8, 2011

Page 35: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Spring Integration

35

Friday, July 8, 2011

Page 36: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Spring Integration

36

Friday, July 8, 2011

Page 37: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Spring Integration

37

Friday, July 8, 2011

Page 38: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Spring Integration

38

Friday, July 8, 2011

Page 39: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Spring Integration

39

Friday, July 8, 2011

Page 40: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Spring Integration

40

Friday, July 8, 2011

Page 41: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Spring Integration

41

Friday, July 8, 2011

Page 42: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Spring Integration

42

Friday, July 8, 2011

Page 43: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Your Coffee Shop Does Not Use 2PC

• Order is accepted • Cup is labeled and placed in the queue • Money is exchanged• Coffee drink is processed

• Multiple baristas = competing consumers • Drinks are processed out of order = correlation id (label)• Cannot pay for drink = discard (write-off) • Erroneous drink = retry • Drink machine fails = compensating action (refund, etc.)

43

Friday, July 8, 2011

Page 44: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Conversation Pattern

• Interaction between two parties – Short synchronous interaction – Longer asynchronous interaction

• Other examples – Amazon.com

44

Friday, July 8, 2011

Page 45: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Cafe Demo

45

Friday, July 8, 2011

Page 46: Beyond Horizontal Scalability: Concurrency and Messaging Using Spring

Q&A

Thank You!

Friday, July 8, 2011