messaging for the cloud and microservices
TRANSCRIPT
Messaging for the Cloud and Microservices
Rob Davies2015
RED HAT | Fabric8 Rocks!2
Rob Davies
• Director of Middleware Engineering for xPaaS
• Over 20 years experience of developing large scale solutions for telcos and finance
• Creator of ActiveMQ and ServiceMix• Committer on open source projects,
including fabric8, Apache Camel and other stuff …
RED HAT | Fabric8 Rocks!3
All singing, all dancing scalable messaging for the
cloud
AND …
Messaging for Microservices
RED HAT | Fabric8 Rocks!4
Why do we use messaging ?
• Robustness to change• Time independence• Hide latency• Event driven• Platform and language
independenceBroker
Message in
Message out after enrichment by Process B
Process C
Process B
Process AQueue:Foo
Queue:Bar
RED HAT | Fabric8 Rocks!5
Traditional Enterprise Message brokers
• Designed to support many different messaging patterns
• highly available• Support clustering• Support store and
forward• But – are usually
very static in nature
RED HAT | Fabric8 Rocks!6
Core Messaging Patterns …
RED HAT | Fabric8 Rocks!7
Requestor
Core Message Pattern: Request/Reply
Service
RED HAT | Fabric8 Rocks!8
Producer
Core Message Pattern: Queue
Consumer
Consumer
Consumer
RED HAT | Fabric8 Rocks!9
Core Message Pattern: Publish/Subscribe
Consumer
Consumer
Consumer
Producer
RED HAT | Fabric8 Rocks!10
Message Channels and Filters
RED HAT | Fabric8 Rocks!11
Message Routing: Selectors
Producer Destination
ConsumerColor = red
ConsumerColor =
blue
RED HAT | Fabric8 Rocks!12
Message Routing: Destination Wildcards
• * matches a subject• > matches sub-tree
Topic:BAR.BEER.WHITE
Topic:BAR.WINE.WHITE
Producer
ConsumerTopic:BAR.WINE.WHITE
ConsumerTopic:BAR.BEER.WHITE
ConsumerTopic:BAR.*.WHITE
ConsumerTopic:BAR.>
RED HAT | Fabric8 Rocks!13
Message Groups
Producer
Consumer
Consumer
Consumer
Queue:Prices
Message message = session.createTextMessage(“Hi DWP”);message.setStringProperty("JMSXGroupID", ”JavaRocks");producer.send(message);
RED HAT | Fabric8 Rocks!14
Scaling Messaging – the traditional way …
RED HAT | Fabric8 Rocks!15
Client Scaling:
Message Bus
RED HAT | Fabric8 Rocks!16
Client Scaling:
Message Bus
RED HAT | Fabric8 Rocks!17
Broker Scaling:
Message BusMessage throughput requirement exceeds broker capacity
RED HAT | Fabric8 Rocks!18
Broker Scaling:
Message Bus Message Bus
RED HAT | Fabric8 Rocks!19
Broker Scaling:
Message Bus Message Bus
RED HAT | Fabric8 Rocks!20
Broker Scaling:
Message Bus Message Bus
Message BusMessage Bus
RED HAT | Fabric8 Rocks!21
Broker Scaling: Problems
Message Bus Message Bus
Message BusMessage Bus• Diminished
returns • Focused
Overload• Stranded
Capacity
RED HAT | Fabric8 Rocks!22
How do we scale Messaging for the Cloud ?
RED HAT | Fabric8 Rocks!23
Requirements for Messaging as a Service
• Needs to support many thousands of clients• Flexible, brokers need to be spun up and down,
based on demand• Client connections may need to be multiplexed,
to decrease the load on individual message brokers
• Popular messaging protocols support• Flexible routing needs to be supported
RED HAT | Fabric8 Rocks!24
What contenders are already out there ?
RED HAT | Fabric8 Rocks!25
ActiveMQHornetQ
RabbitMQProprietary Enterprise
Messaging
RED HAT | Fabric8 Rocks!26
Apache Kafka
• Publish/Subscribe messaging – rethought as a distributed commit log
• Designed for fast data ingestion of logs• Scalable – designed to allow a single cluster to act as a
messaging platform, allowing for elastic expansion with no downtime
• Messages are persisted to disk, and replicated to prevent data loss
• Allows partitioning of data streams across cluster of machines
• Created at Linkedin – donated to the ASF
RED HAT | Fabric8 Rocks!27
Apache Kafka Architecture
ZooKeeper BrokerBrokerBroker Broker
Producer Producer
Consumer Consumer
RED HAT | Fabric8 Rocks!28
Apache Kafka Performance
https://cwiki.apache.org/confluence/display/KAFKA/Kafka+papers+and+presentations
From: Kafka: A distributed Messaging System for log processing, Jun Rao
RED HAT | Fabric8 Rocks!29
Apache Kafka – Differences with a Message Broker
• Distributed commit log – broker maintains no state• Niche – so works really well for a particular set of use
cases• Proprietary • Written in Scala• Consumers have to maintain state
RED HAT | Fabric8 Rocks!30
Kubernetes Helps
RED HAT | Fabric8 Rocks!31
Fabric8 MQ – not a message broker – but a scalable messaging system
Many concurrent connections, one out
FlexibleProtocols
Mul
tiple
xConnections
Vert.x Core
Embedded Camel,Integration with APIMan
OpenWire,STOMPMQTTAMQPWebSockets – all done asynchronously
Scaling ConnectionsNOT a problem
Destination Sharding
RED HAT | Fabric8 Rocks!32
Fabric8 MQ Independently scalable:
Node
Pod
ActiveMQ Broker
AMQ Replication Controller
Node
Pod
ActiveMQ Broker
Node
Pod
ActiveMQ Broker
Fabric8MQ Replication Controller
Vert.xVert.x
Vert.x
MultiplexerMultiplexer
MultiplexerFabric8MQ
Vert.xVert.x
Vert.x
MultiplexerMultiplexer
MultiplexerFabric8MQ
Vert.xVert.x
Vert.x
MultiplexerMultiplexer
MultiplexerFabric8MQ
RED HAT | Fabric8 Rocks!33
Fabric8 MQ Message Flow:
Protocol Conversion
Camel Routing
API Management Multiplexer
Destination Sharding
Broker Control
RED HAT | Fabric8 Rocks!34
Qpid Dispatch Router
BrokerBrokerBroker Broker
Producer ProducerConsumer Consumer
Router Router Router Router
AMQP 1.0
RED HAT | Fabric8 Rocks!35
Multiplexing
• Brokers performs better the lower the number of connections – less contention
• IoT applications have long lived connections, but small amount of traffic
• All configurable – you can decide how fine or coarse grained you want multiplexing
• Dispatch Router does this automatically
RED HAT | Fabric8 Rocks!36
Destination Sharding: Benefits
• There is an overhead associated with a Destination – restrict the number of Destinations per Broker to improve performance
• Co-locate producers and consumers of a Destination to the same broker reduces latency and improves overall performance
• Increased scalability for your messaging solution
• Dispatch Router does this automatically
RED HAT | Fabric8 Rocks!37
Red Hat Messaging – how we plan to tackle messaging for
the cloud …
RED HAT | Fabric8 Rocks!38
What we have today Separate clients tied to
broker- specific protocols
Limitedintegration between brokers& overlapping capabilities
MRG-M (Apache Qpid C++ broker)•AMQP, high performance, routing, HA•No longer sold but actively supported
M. MQ 6.x (Apache ActiveMQ 5.x Java broker)
• Multi-protocol JMS-oriented broker• Large user community, rich feature set
EAP HornetQ JMS Messaging Broker (HornetQ GitHub project)•Multi-protocol JMS-oriented broker•JMS 2.0, best-in-class SpecJMS performance
MRG-M 3.1
A-MQ6.x
HornetQ EAP6
RED HAT | Fabric8 Rocks!39
Clients
A-MQ
Where we’re going
• Consolidate to a single messaging product, known as A-MQ
• Consists of three components: Broker, Interconnect & Clients
• Developed in open, community-based, upstream projects and
leveraging open, standards-based protocols
Broker
Interconnect
RED HAT | Fabric8 Rocks!40
Where we’re going
M. MQ Broker• Full-featured, high-performance, multi-protocol
enterprise broker• HA through replication and failover
M. MQ Interconnect Router• Large-scale, secure, reliable, and manageable
messaging networks• Use with or without broker. HA through redundant
routing.
M. MQ Clients• Ubiquitous, standards-based messaging clients for all
common platforms and programming languagesA-MQA-MQ
Broker
Interconnect
Clients
RED HAT | Fabric8 Rocks!41
Where we’re going
• AMQP (Advanced Message Queuing Protocol)
• Rich semantics, multiplexing, flow control, extensible
• International standard – ISO/IEC ISO 19464
• MQTT (Message Queuing Telemetry Transport)
• Lightweight “first mile” telemetry• OASIS Standard; International
standardization in progress
• STOMP (Simple Text-Oriented Messaging Protocol)
• WebSocket encapsulationA-MQ
Broker
Interconnect
Clients
RED HAT | Fabric8 Rocks!42
Messaging for Microservices
RED HAT | Fabric8 Rocks!43
Reliable, Fast Communication between Services
RED HAT | Fabric8 Rocks!44
Functional Decomposition
RED HAT | Fabric8 Rocks!45
Micromessaging
• Whilst external services should often be http – internal services do not need to be.
• Using a messaging system can improve performance and scalability
• Standards are important – immutable infrastructure leads to disposable infrastructure. Apply that all assets in your design.
RED HAT | Fabric8 Rocks!46
Micromessaging: inter-service communications
Broker
Service AService A
Service AService C
Service AService B
Service AService F
Service AService E
Service AService Drequest
reply
subscribe
subscribe
publishpublish
RED HAT | Fabric8 Rocks!47
Micromessaging: Control Plane
BrokerController
Service AService F
Service AService A
subscribe
subscribe
publish
{Start Processing}
{Stop Processing}
RED HAT | Fabric8 Rocks!48
Micromessaging: Stream Processing
Brokerpublish
Event ListenerSMS
Event Listener
Event ListenerHTTP Post
Event ListenerHTTP Post
Event ListenerHTTP Post
Event ListenerHTTP Post
Event ListenerHTTP Post
SMTP
publish
publish
EventProcessing
Engine
RED HAT | Fabric8 Rocks!49
Micromessaging anti-patterns
• Any pattern that is transactional in nature
e.g. Transactional Client• Any pattern that relies on Message Persistence
Durable Subscriber, Guaranteed Delivery• Any pattern where the message system inspects, or
selectively routes messages Message Filter, Content Based Routing, Content Enricher
RED HAT | Fabric8 Rocks!50
Micromessaging: what to use ?
Qpid Dispatch Router
RED HAT | Fabric8 Rocks!51
RED HAT | Fabric8 Rocks!52
Demo:Variance
Collector
Compare Interprocess communication:HTTP vs Messaging
RED HAT | Fabric8 Rocks!53
Standard Deviation Processor:
public void process(Exchange exchange) throws Exception {
String message = exchange.getIn().getBody(String.class); ObjectMapper objectMapper = new ObjectMapper();
TypeFactory typeFactory = objectMapper.getTypeFactory();
List<Double> values = objectMapper.readValue(message, typeFactory.constructCollectionType(List.class, Double.class));
SummaryStatistics summaryStatistics = new SummaryStatistics();
List<Double> list = new ObjectMapper().readValue(message, List.class); for (Double value : list) { summaryStatistics.addValue(value); } String stdDev = Double.toString(summaryStatistics.getStandardDeviation()); exchange.getOut().setBody(stdDev);}
RED HAT | Fabric8 Rocks!54
Standard Deviation Route:
@ContextName("stddevCamel")public class StdDevHTTP extends RouteBuilder {
@Inject StdDevProcessor processor;
@Override public void configure() throws Exception { from("jetty:http://0.0.0.0:8183/std-dev").doTry() .process(processor) .doCatch(Throwable.class) .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(500)) .setBody(constant("{\"error\" : \"Service failed\"}")) .end(); }}
RED HAT | Fabric8 Rocks!55
HTTP Calculator
@Override
public void configure() throws Exception { onException(Throwable.class).maximumRedeliveries(-1).delay(5000); from("direct:start") .multicast() .parallelProcessing().timeout(10000).to(stdDevService, varianceService) .end().setHeader("name", constant("HTTP")).to(collectorService);
}
RED HAT | Fabric8 Rocks!56
HTTP Calculator
@Inject
@Uri("netty4-http:http://{{service:collector-http:localhost:8184}}/results/http")private Endpoint collectorService;
@Inject@Uri("netty4-http:http://{{service:variance-http:localhost:8182}}/variance")private Endpoint varianceService;
@Inject@Uri("netty4-http:http://{{service:std-dev-http:localhost:8183}}/std-dev")private Endpoint stdDevService
RED HAT | Fabric8 Rocks!57
Messaging Calculator
Endpoint jmsSender = getContext().getEndpoint("jms:topic:" + CALCULATION_TOPIC + "?preserveMessageQos=true" + "&replyTo=" + RESULT_QUEUE +"&replyToType=Exclusive" + "&asyncConsumer=true" + "&asyncStartListener=true" + "&concurrentConsumers=10");
RED HAT | Fabric8 Rocks!58
Messaging Calculator
from("jms:queue:”+RESULT_QUEUE).aggregate(header(CORRELATION_HEADER), new AggregationStrategy() { @Override public Exchange aggregate(Exchange oldExchange, Exchange newExchange) { if (oldExchange == null) { return newExchange; }
String oldBody = oldExchange.getIn().getBody(String.class); String newBody = newExchange.getIn().getBody(String.class); oldExchange.getIn().setBody(oldBody + "+" + newBody); return oldExchange; }}).completionSize(NUMBER_OF_SERVICES).completionTimeout(2000) .setHeader("name", constant("MSG")).to(collectorService);
RED HAT | Fabric8 Rocks!59
The Collector:
@ContextName("collectorCamel")public class CollectorHTTP extends RouteBuilder {
@Override public void configure() throws Exception { getContext().addRoutePolicyFactory(new MetricsRoutePolicyFactory());
from("jetty:http://0.0.0.0:8184/results/http”).setId("HTTP");
from("jetty:http://0.0.0.0:8184/results/msg”).setId("MSG"); }}
RED HAT | Fabric8 Rocks!60
Links:Links:
http://camel.apache.orghttp://camel.apache.orghttp://fabric8.iohttp://fabric8.iohttps://github.com/rajdavies/microservices-https://github.com/rajdavies/microservices-examplesexamples