25.12.11

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.

No comments: