beyond horizontal scalability: concurrency and messaging using spring

Post on 07-Nov-2014

3.748 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

 

TRANSCRIPT

Beyond Horizontal Scalability: Concurrency & Messaging Using Spring

Bruce Snyder, Senior Software Engineer, SpringSource/VMware

Friday, July 8, 2011

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

Typical Application Layers

3

Friday, July 8, 2011

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

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

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

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

7

Friday, July 8, 2011

Typical Client Request

8

Friday, July 8, 2011

Typical Request Growth

9

Friday, July 8, 2011

Typical Strategy For Horizontal Scaling

10

Friday, July 8, 2011

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

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

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

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

Concurrency

• Concurrency is a style of asynchronous execution

15

Friday, July 8, 2011

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

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

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

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

Messaging

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

20

Friday, July 8, 2011

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

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

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

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

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

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

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

Best of Both Worlds

• What if concurrency and messaging was provided together?

28

Friday, July 8, 2011

Spring Integration

• A framework for integration

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

29

Friday, July 8, 2011

Enterprise Integration Patterns (EIP)

30

http://enterpriseintegrationpatterns.com/

Friday, July 8, 2011

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

Spring Integration

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

32

Friday, July 8, 2011

Spring Integration

33

Friday, July 8, 2011

Spring Integration

34

Friday, July 8, 2011

Spring Integration

35

Friday, July 8, 2011

Spring Integration

36

Friday, July 8, 2011

Spring Integration

37

Friday, July 8, 2011

Spring Integration

38

Friday, July 8, 2011

Spring Integration

39

Friday, July 8, 2011

Spring Integration

40

Friday, July 8, 2011

Spring Integration

41

Friday, July 8, 2011

Spring Integration

42

Friday, July 8, 2011

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

Conversation Pattern

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

• Other examples – Amazon.com

44

Friday, July 8, 2011

Cafe Demo

45

Friday, July 8, 2011

Q&A

Thank You!

Friday, July 8, 2011

top related