Showing posts with label ActiveMQ in Action. Show all posts
Showing posts with label ActiveMQ in Action. Show all posts

25.12.11

ActiveMQ in Action–KahaDB

  • Since 5.3
  • File based
  • Combined with a transactional journal
    • Reliable message storage
    • Recovery
  • Good performance
  • Good Scalability

File based

  • No prerequisite for a third-party database.
    • Easy to use
    • Allowing ActiveMQ to be downloaded and running in literally minutes.
  • The structure of the KahaDB store has been streamlined especially for the requirements of a message broker.

I am interested to take a look at the design of the KahaDB structure to see how it tries to meet the requirements of a message broker. Before that, maybe I need to understand the requirements of a message broker.

 

  • The KahaDB message store uses a transactional log for its indexes and only uses one index file for all its destinations.
  • The configurability of the KahaDB store means that it can be tuned for most usage scenarios, from high throughput applications (for example, trading platform), to storing large amounts of messages (for example, GPS tracking).
  • <persistenceAdapter>

ActiveMQ in Action–How are message stored by ActiveMQ?

  • Messages sent to queues and topics are stored differently, because there are some storage optimizations that can be made with topics that don’t make sense with queues.
  • Queues
    • Straightforward
      • FIFO
      • Only when that message has been consumed and acknowledged can it be deleted from the broker’s message store.
  • Topics
    • Durable subscribers to a topic.
      • Each consumer gets a copy of the message.
    • Only one copy of message is stored by the broker
    • A durable subscriber object in the store maintains a pointer to its next stored message and dispatches a copy of its consumer.
    • A message can’t be deleted from the store until it’s been successfully delivered to every interested durable subscriber.

ActiveMQ–Discovery

  • From the book
    • Discovery
      • is a process of detecting remote broker services.
    • Clients usually want to discover all available brokers.
    • Brokers usually want to find other available brokers so that they can establish a network of brokers.

Apache ActiveMQ ™ – Discovery

This document is a little bit old, because it was using maven 1.

  • Discovery Agents
    • ActiveMQ uses an abstraction called a Discovery Agent to detect remote services such as remote brokers. We can use discovery for JMS clients to auto-detect a Message Broker to connect to, or to provide Networks of Brokers
  • Two kinds of discovery agent
    • Multicast
    • Zeroconfig
    • LDAP Discovery
  • Trying out discovery

Apache ActiveMQ ™ -- Discovery Transport Reference

  • The Discovery transport works just like the Failover transport, except that it uses a discovery agent to locate the list of uri to connect to.
  • The Discovery transport is also used by the Fanout transport for discovering brokers to send a fanout message to.
  • Note that to be able to use Discovery to find brokers, the brokers need to have the multicast discovery agent enabled on the broker.
    • <transportConnector … discoveryUri=”multicast://default” />
  • discovery:(discoveryAgentURI)?transportOptions
  • discovery:discoveryAgentURI
  • Example URI:
    • discovery:(multicast://default)?initialReconnnectDelay=100
Transport Options
Option Name Default Value Description
reconnectDelay 10 How long to wait for discovery
initialReconnectDelay 10 How long to wait before the first reconnect attempt to a discovered url
maxReconnectDelay 30000 The maximum amount of time we ever wait between reconnect attempts
useExponentialBackOff true Should an exponential backoff be used btween reconnect attempts
backOffMultiplier 2 The exponent used in the exponential backoff attempts
maxReconnectAttempts 0 If not 0, then this is the maximum number of reconnect attempts before an error is sent back to the client
group default an identifier for the group to partition multi cast traffic among collaborating peers; the group forms part of the shared identity of a discovery datagram (since 5.2)

ActiveMQ in Action–Network Connectors

  • A network of brokers
    • Creates a cluster composed of multiple ActiveMQ instances that are interconnected to meet more advanced messaging scenarios.
    • Apache ActiveMQ ™ -- Networks of Brokers
      • To provide massive scalability of a large messaging fabric you typically want to allow many brokers to be connected together into a network so that you can have as many clients as you wish all logically connected together - and running as many message brokers as you need based on your number of clients and network topology.
      • It is about horizontally scaling.
  • Chapter 10: Deploying ActiveMQ in the enterprise:
    • Topologies for broker networks
    • Purpose of the cluster
    • Configuration details
  • Network connectors
    • Broker-to-broker communications
    • Are channels that are configured between brokers so that those brokers can communicate with one another.
    • Unidirectional channels by default.
      • A given broker communicates in on direction by only forwarding messages it receives to the brokers on the other side of the connection.
      • forwarding bridge
    • Bidirectional communication channels
      • Channels that communicate not only outward to the brokers on the other side, but also receives message from other brokers on the same channel.
      • duplex connector.

ActiveMQ in Action–When not to choose VM broker?

  • If too many Java applications that use embedded brokers exists, maintenance problems may arise when trying to consistently configure each broker as well as back up the data.
  • In such situation, it’s always easier to create a small cluster of standalone brokers instead of using embedded brokers.

It looks like the requirements of embedded database or the centralized DB center.

ActiveMQ in Action – VM Connector

Apache ActiveMQ ™ -- URI Protocols

  • Protocol:
    • VM
  • Example:
    • vm://host:port
  • Description
    • Client connect to each other within the same JVM. This does use an asynchronous channel and a separate worker thread. You can enable sync sending using a query parameter, such as
    • vm://localhost?async=false
  • Server?
    • Yes

The “Server?” column above indicates whether or not a protocol can be used in an ActiveMQ broker transport connector.

  • useEmbeddedBroker property
    • When connecting to an ActiveMQ broker, this could reside locally inside your JVM or be remote on another machine somewhere.
    • If you want to enable the deployment of the ActiveMQ inside your JVM you can enable the useEmbeddedBroker property on the ActiveMQConnectionFactory.

Apache ActiveMQ ™ -- VM Protocol

I think this doc page is very old, because it use the package “org.codehaus.activemq”.

  • The VM protocol allows clients to connect to each other inside the VM without the overhead of the network communication.
  • The connection used is not a socket connection but some kind of virtual connection that allows an embedded messaging system.
  • It is to be noted that objects inside JMS ObjectMessage instances are transferred using serialization and not by reference. This may sound surprising but there are very good reasons for that.
    • Isolated classloader hierarchies and a shared references will lead to a ClassCastException. (OSGi has a difference solution on this.)
    • TCK tests will exactly test whether your message could be modified before sending it.

Apache ActiveMQ ™ -- VM Transport Reference

  • The VM transport allows clients to connect to each other inside the VM without the overhead of the network communication.
  • The connection used is not a socket connection but use direct method invocations which enables a high performance embedded messaging system.
  • The first client to use the VM connection will boot an embedded broker. Subsequent connections will attach that the same broker. Once all VM connections to the broker have been closed, the embedded broker will automatically shutdown.

Simple Broker Configuration Syntax

  • Normal syntax
    • Simple
    • Only a limited amount of configuration
    • vm://brokerName?transportOptions
Option Name Default Value Description
marshal false If true, forces each command sent over the transport to be marshalled and unmarshalled using a WireFormat
wireFormat default The name of the WireFormat to use
wireFormat.*   All the properties with this prefix are used to configure the wireFormat
create true If the broker should be created on demand if it does not already exist. Only supported in ActiveMQ 4.1
waitForStart -1 If > 0, indicates the timeout in milliseconds to wait for a broker to start. Only supported in ActiveMQ 5.2
broker.*   All the properties with this prefix are used to configure the broker. See Configuring Wire Formats for more information
  • Example URI:
    • vm://broker1?marshal=false&broker.persistent=false
  • Be careful
    • If you are using the VM transport and wish to explicitly configure an Embedded Broker there is a chance that you could create the JMS connections first before the broker starts up.
    • Apache ActiveMQ ™ -- The vm transport starts a broker before my configured broker starts
    • Currently ActiveMQ will auto-create a broker if you use the VM transport and there is not one already configured. (In 5.2 it is possible to use the waitForStart and create=false options for the connection uri).
    • Spring work around -
      • depends-on attribute, so that your JMS ConnectionFactory depends on the embedded broker to avoid this happening.
      • <bean id=”broker” …”>…</broker>
      • <bean id=”connFactory” depends-on=”broker” …>…</bean>

Advanced Broker Configuration Syntax

  • It allows you configure the broker more extensively using a Broker Configuration URI.
  • Apache ActiveMQ ™ -- Broker Configuration URI
  • vm:(broker:(tcp://localhost)?brokerOptions)?transportOptions
  • vm:broker:(tcp://localhost)?brokerOptions

Transport Options

Option Name Default Value Description
marshal false If true, forces each command sent over the transport to be marshalled and unmarshalled using a WireFormat
wireFormat default The name of the WireFormat to use
wireFormat.*   All the properties with this prefix are used to configure the wireFormat

More Options

Example URI:

  • vm:(broker:(tcp://localhost:6000)?persistent=false)?marshal=false

External Config

  • vm://localhost?brokerConfig=xbean:activemq.xml

Apache ActiveMQ ™ -- How should I use the VM transport

  • SEDA:
    • SEDA - Architecture for Highly-Concurrent Server Applications
    • A robust, high-performance platform for Internet services.
    • The goal is to build a system capable of supporting massive concurrency (on the order of tens of thousands of simultaneous client connections) and avoid the pitfalls which arise with traditional thread and event-based approaches.
    • SEDA : Staged Event-Driven Architecture
      • To decomposes a complex, event-driven application into a set of stages connected by queues.
    • This design avoids
      • the high overhead associated with thread-based concurrency models, and
      • decouples event and thread scheduling from application logic.
    • Key technologies
      • Admission control on each event queue
        • The service can be well-conditioned to load
        • Preventing resources from being overcommitted when demand exceeds service capacity.
      • Dynamic control to automatically tune runtime parameters, such as
        • The scheduling parameters of each stage.
      • Manage load, for example
        • By performing adaptive load scedding.
      • Decomposing services into a set of stages
        • enables modularity and code reuse
      • Debugging tools for complex event-driven applications.
  • Passing by Reference
    • One thing to note with the VM transport is that messages are passed by reference. (This is different from the very old doc page.)
    • One slight exception to this is the JMS ObjectMessage. (see below for details on how to disable it in ActiveMQ 4.x)
  • copyMessageOnSend
    • Further optimising.
    • Avoiding making a copy of the ObjectMessage to send.
    • Assuming that you don’t try and reuse the ObjectMessage instance; you just create it once and send it once and don’t try and change the body of the message after sending it.
    • Be careful of ClassLoaders
      • Compatible class loader
  • Disabling Object serialization with ObjectMessage for ActiveMQ 4.x
    • The JMS specification dictates that the body of an ObjectMessage must be serialized when you call send() to avoid the object changing under your feet affecting what view the consumer sees of the object.
    • objectMessageSerializationDeferred flag
      • factory.setObjectMessageSerializationDefered(true);

Apache ActiveMQ ™ -- The vm transport starts a broker before my configured broker starts

  • Dependency issue. Mostly likely.
  • Different broker name. Need to be careful.
  • waitForStart=’timeout’. Coupled with the “create=false” option, it is possible to ensure that a single embedded broker is auto-started.

Apache ActiveMQ ™ -- Message Cursors

  • Running out of RAM buffer
    • Apache ActiveMQ ™ -- My producer blocks
    • What can I do if my producer blocks sending a message?
      • Producer Flow Control: http://activemq.apache.org/producer-flow-control.html
      • ActiveMQ 4.x
        • Flow control was implemented using TCP flow control.
        • The underlying network connection of throttled consumers was suspended to enforce flow control limits.
        • This strategy is very efficient but can lead to deadlocks if there are multiple producers and consumers sharing the same connection.
      • ActiveMQ 5.0,
        • Individually flow control each producer on a shared connection without having to suspend the entire connection.
        • By 'flow control' we mean that if the broker detects that
          • the memory limit for the destination, or
          • the temp- or file-store limits for the broker,
        • have been exceeded, then the flow of messages can be slowed down.
        • The producer will be either blocked until resources are available or will receive a JMSException: this behaviour is configurable and described in the section below on <systemUsage>.
      • Default <systemUsage> settings
        • Will cause the producer to block when the memoryLimit or <systemUsage> limits are reached.
        • This blocking behaviour is sometimes misinterpreted as a “hung producer”, when in fact the producer is simply diligently waiting until space is available.
    • Active 4.x
      • All in transit messages are held in memory.
        • Slow consumer
        • ActiveMQ has a configurable limit of how many in transit messages it will hold.
        • Once it is reached, producers will be slowed down / blocked.
      • Quick fix
      • An alternative approach
        • Set individual usageManager limits on different destinations and for producers versus consumers.
      • JMX support or Web Console to look at what destinations are being used and what producers & consumers you have to see what’s going on.
    • ActiveMQ 5.x and Later
      • Message Cursors
        • By default: moving messages out of memory and onto disk.
      • This problem will not be seen unless you fill up the max allocated disk space for message storage which typically is an order of magnitude larger.
  • A new memory model
    • Begin with ActiveMQ 5.0.0
    • Allows messages to be pages in from storage when space is available (using Store cursors for persistent messages)
  • A Typical Approach for messaging systems dispatching persistent message
    • Pulling the persistent messages in batches from long term storage when a client is ready to consume them.
    • Using a cusor to maintain the next to dispatch position.
    • Benefits:
      • Robust
      • Very scalable
    • Drawbacks:
      • Not the most performant for cases when the consumer(s) CAN keep up with the producers(s) of messages.
  • A hybrid approach
    • Allowing messages to pass from producer to consumer directly (after the messages have been persisted)
    • But switches back to using cursors if the consumer(s) fall behind.

  • Types of Cursors
    • VM Cursor
    • File based Cursor

Apache ActiveMQ ™ -- Spring Support

  • Efficient Lightweight JMS with Spring and ActiveMQ « CodeDependents
  • Using VM Transport
    • Note that in ActiveMQ 4.x or later if you configure the ActiveMQConnectionFactory with the vm: transport then you do not have to configure an embedded broker explicitly – one will be auto-created for you – unless you wish to explicitly configure the transports and persistence options used on the embedded broker.

24.12.11

ActiveMQ in Action–NIO

  • The most prominent features of NIO are selectors and nonblocking I/O programming, allowing developers to use the same resources to handle more network clients and generally heavier loads on their servers.

Situations:

  • A large number of clients connecting to the broker.
    • Generally, the number of clients that can connect to the broker is limited by the number of threads supported by the operating system.
    • NIO => fewer threads per client.
  • A heavy network traffic to the broker.
    • The NIO connector generally offers better performance than the TCP connector.

ActiveMQ in Actionve–Transport Connectors

  • In order to exchange messages, producers and consumers (clients) need to connect to the broker. This client-to-broker communication is performed through transport connectors.

Unfortunately, when I tried to search “Transport Connectors” from the Internet, I didn’t find a similar definition for it.

There is a class, TransportConnector, implemented in ActiveMQ. Anything I found about transport connectors, they are related to the broker configuration.

  • From the broker’s perspective, the transport connector is a mechanism used to accept and listen to connections from clients.

This makes sense to me. So, from the JMS client’s perspective, Transport Connectors are used for connecting to the brokers, while from the broker’s perspective, configuring the Transport Connectors is configuring the binding address for providing services for the clients.

  • <transportConnectors><transportConnector>…</transportConnector></transportConnectors>
  • <transportConnector name=”openwire” uri=”tcp://localhost:61616” discoveryUri=”multicase://default” />
    • name: The configuration for a connector must uniquely define the name.
    • uri: The configuration for a connector must uniquely define the URI attributes.
      • Network protocol
      • optional parameters
    • discoveryUri
      • Is Optional
  • <transportConnector name=”ssl” uri=”ssl://localhost:61617” />
  • <transportConnector name=”stomp” uri=”stomp://localhost:61613” />
  • <transportConnector name=”xmpp” uri=”xmpp://localhost:61222” />

XMPP is not supported by activemq-core.
SSL connector need certificate configuration.

  • From the client’s perspective, the Transport Connector URI is used to create a connection to the broker in order to send and receive messages.
  • ActiveMQConnectionFactory factory
    • = new ActiveMQConnectionFactory(“tcp://localhost:61616”);

Recently, I made a very stupid mistake for the transport connector concept. Now I won’t have that problem any more.

ActiveMQ–Implementation of Failover Transport

  • FailoverTransport
  • FailoverTransportFactory

 

FailoverTransport

ActiveMQ in Action–Chapter 4 - Connector URI/URI Protocols

Apache ActiveMQ ™ -- URI Protocols

  • Low-level connectors: ActiveMQ connectors using this kind of simple hierarchical URI pattern are sometimes referred to as low-level connectors and are used to implement basic network communication protocols.
    • I tried to search “low-level connectors” via Google but rarely find anything.
  • Composite URIs and automatic reconnection:
    • Apache ActiveMQ ™ -- Failover Transport Reference
      • This is the dedicated page for failover:// scheme.
      • The Failover transport layers reconnect logic on top of any of the other transports. (We used to call this transport the Reliable transport in ActiveMQ 3).
      • The Failover configuration syntax allows you to specify any number of composite uris. The Failover transport randomly chooses one of the composite URI and attempts to establish a connection to it. If it does not succeed or if it subsequently fails, a new connection is established to one of the other uris in the list.
    • But what “Understanding connector URIs” says about “failover transport” is about composite URIs using static:// scheme.
      • Apache ActiveMQ ™ -- Static Transport Reference
      • The static transport provides a hard coded mechanism to discover other connections using a list of URIs. A connection using this discovery mechanism will attempt to connect to all URIs in the list until it is successful.
      • As the static transport protocol is for broker discovery, it should not be used by client programs. Clients wishing to failover to a static list of broker instances, should use the failover:// transport instead.
  • White spaces:
    • Apache ActiveMQ ™ -- Configuring Transports
    • Be careful about whitespace
      All of the following URI configurations are based on the java.net.URI class which does not allow whitespace to be used. So if you are using failover: or static: URIs, do not put any whitespace around the , symbol.

ActiveMQ in Action–Chapter 4–Connecting to ActiveMQ

  • ActiveMQ provides connectors
    • A connectivity mechanism that provides client-to-broker communications
      • Using transport connectors
    • As well as broker-to-broker communications
      • Using network connectors.
  • Protocols are general-purpose concepts and connectors are ActiveMQ-specific mechanism.
    • But every ActiveMQ connectors implements a specific protocol and is named after it.

23.12.11

ActiveMQ in Action–CEP

Complex Event Processing (CEP)

Complex event processing (CEP) consists of processing many events happening across all the layers of an organization, identifying the most meaningful events within the event cloud, analyzing their impact, and taking subsequent action in real time.

Complex event processing refers to process states, the changes of state exceeding a defined threshold of level, time, or value increment or just of a count as the event. It requires the respective event monitoring, event reporting, event recording and event filtering. An event may be observed as a change of state with any physical or logical or otherwise discriminated condition of and in a technical or economical system, each state information with an attached time stamp defining the order of occurrence and a topology mark defining the location of occurrence.

Within the Book:

  • Each service fulfills a discrete function and only that function.
  • Then applications are built through the composition of these services, and the  communication among services is achieved using  asynchronous  messaging  and  eventual  consistency. 
  • This  style  of  application design makes it possible to introduce such concepts as complex event processing  (CEP ).

Further Analysis

  • Using  CEP , the interactions among the components in a system are
    tracked for further analysis.
  • Such  possibilities are  truly endless when  you consider  that  asynchronous  messaging  is  simply  adding  a  level  of  indirection between components in a system.

ActiveMQ in Action–Asynchronous Processes in Amazon

  • The  order  placement  process  that’s  employed  by  Amazon  is  a  good
    example of the first stage in a much larger set of asynchronous processes.
    • Each stage  of  the  order  is  handled  discretely by  a  separate  service. 
    • When  the  user places the order, there’s a synchronous call to submit the order,
    • but the entire order process doesn’t take place behind a synchronous call via the web browser.
    • Instead, the order is accepted and acknowledged immediately.
    • The rest of the steps  in  the  process  are  handled  asynchronously.
    • If  a  problem  occurs  that prevents the process from proceeding, the user is notified via email.

Users would be notified via emails when something bad happens will create some inconvenience. However, that’s the way we trade off for high scaling.

ActiveMQ in Action–Chapter 1 - When

  • Not  only  will  a change to one component in the system not ripple across the entire system, but component  interaction  is  also  dramatically  simplified.

I truly doubt it. Smile It may be true for component interaction per se, but not for system architecture design.

Loosely coupling and asynchronous communication approach add a lot of complexity into architecture design. At least, it is very much against the traditional way of designing the system, so that system architects need to learn how to design the system using Message Queuing approach, instead of using direct communication approaches.

  • EDA
    • Instead  of  using  a  synchronous scheme for component interaction (where one method calls another and  the  caller  waits  for  a  response  from  the  callee),  components  utilize  asynchronous communications (where they simply send a message without waiting
      for a response—also known as  fire-and-forget ). Such loose coupling throughout a system can lead to what’s known as an  event-driven architecture  (EDA).
    • Event-driven architecture - Wikipedia, the free encyclopedia

First of all, system architects from old schools with a bunch of developers from ancient would probably design a system in a synchronous scheme for component interaction with Message Queuing support. That’s not EDA at all.

On the other hand, EDA is one of the essential architecture skills you must have before you can fully make use of Message Queuing.

  • The decoupled, asynchronous style of architecture described in the previous point allows the broker itself to scale much  further  and  handle  considerably  more  clients  via  tuning,  additional memory allocation, and so on (known as vertical scalability) instead of only relying upon the ability of the number of broker nodes to be increased to handle many more clients (known as horizontal scalability).

Scalability - Wikipedia, the free encyclopedia

  • Horizontal Scaling
    • Scale horizontally (scale out)
    • To scale horizontally (or scale out) means to add more nodes to a system, such as adding a new computer to a distributed software application.
    • Brokers are distributed software components/nodes. Adding a broker is a kind of scaling out or horizontal scaling.
  • Vertical Scaling
    • Scale vertically (scale up)
    • To scale vertically (or scale up) means to add resources to a single node in a system, typically involving the addition of CPUs or memory to a single computer.
    • Such vertical scaling of existing systems also enables them to use virtualization technology more effectively, as it provides more resources for the hosted set of operating system and application modules to share.
    • So adding memory is a kind of vertical scaling.
    • When doing system tuning by adding more memory or more CPUs or more CPU cores, we are doing vertical scaling.

ActiveMQ in Action - Part 1



  • Not only is messaging a style of communication between applications, it’s also a style of integration
    • Notification
    • Inter-operation
I don't really understand this. But I guess the relationship is:
  • Communication <=> Notification
  • Integration <=> Inter-operation
Although it doesn't make much sense to me.


22.12.11

ActiveMQ in Action - About this book


  • Four parts
    • Part 1 provides an introduction to ActiveMQ, a high-level overview of JMS, and a brief discussion of the examples used throughout the book.
    • Part 2 focuses on the three standard components in ActiveMQ including connectivity into the message broker, message persistence, and message broker security.
    • Part 3 is using ActiveMQ to build application using technologies such as the Spring Framework, leading open source application servers, and numerous applications beyond just Java.
    • Part 4 discusses advanced features in ActiveMQ such as high availability, scalability, many advanced broker and client features, performance tuning, and administration of ActiveMQ.

  • Part 1
    • Chapter 1, Introduces ActiveMQ at a high level and discusses why and when to use ActiveMQ.
    • Chapter 2, Introduces enterprise messaging, message-oriented middleware (MOM) and the JMS specification.
    • Chapter 3, Introduces the examples to be used throughout ActiveMQ in Action.
  • Part 2
    • Chapter 4, Covers all the connectivity options for ActiveMQ.
      • URIs
      • The transport connectors
        • Client to broker
        • Broker to Broker
      • TCP
      • NIO
      • STOMIP
      • failover
      • SSL
      • HTTP/S
    • Chapter 5, Discusses message persistence in ActiveMQ
      • For Queue
      • For Topics
      • Four styles of message stores
      • Message caching
    • Chapter 6, Introduces and elaborates on security in ActiveMQ.
      • Authentication
      • Authorization
      • Certificate-based security
      • How to create a custom security plug-in
  • Part 3
    • Chapter 7, Deals with creating Java applications using ActiveMQ
    • Chapter 8, Is all about integrating ActiveMQ with some popular open source application servers.
      • Tomcat
      • Jetty
      • Geronimo
      • JBoss
      • client-side JNDI support
    • Chapter 9, Discusses messaging with ActiveMQ using languages other than Java
  • Part 4
    • Chapter 10, Discusses concepts around deploying ActiveMQ for production systems.
      • HA
      • Scalability
    • Chapter 11, Presents advanced features provided by ActiveMQ
      • Wildcards and composite destinations
      • Advisory messages
      • Virtual topics
      • ActiveMQ plugins
      • Message routing with Apache Camel
    • Chapter 12, Covers advanced ActiveMQ client features
      • Exclusive consumers
      • Message groups
      • ActiveMQ streams
      • Large objects
      • Failover transport
      • Message scheduling
    • Chapter 13, Deals with performance tuning
      • Persistent versus non-persistent messages
      • Transactions
      • Embedded brokers
      • Tuning the wire level protocol
      • Tuning the TCP transport
      • Optimizations for message producers and message consumers.
    • Chapter 14, Finishes up by discussing the administration and monitoring of ActiveMQ.
      • JMX
      • JConsole
      • Command-line tools
        • XMPP
        • JConsole
        • Web console
      • Broker- and client-level logging.