JMS性能调优

FUSE Message Broker Performance Tuning Guide

<!-- Root decorator: this is a layer of abstraction that Confluence doesn't need. It will be removed eventually. -->
<!-- wiki content -->

The FUSE Message Broker is based on Apache ActiveMQ, which offers numerous options for perofmance optimization. There are various things which affect the performance of Apache ActiveMQ and there are many ways you can use to make it go faster depending on your exact requirements.

Choose the right Quality of Service

Using persistent messaging is quite a bit slower than non-persistent messaging. Many things are a tradeoff in IT between performance and quality of service.

With non-persistent messaging, things are reliable - unless the broker is killed in which case any messages in the broker are lost. Persistent messaging avoids this by ensuring by default that every message is written to disk before the MessageProducer.send() method returns.

Even if you need persistent messaging there are various things you can do to speed things up - such as do you really need to block the sender to wait until the message is physically on disk on the broker before being able to send another message? There now follows a number of options you can consider if you need the extra safety of persistent messaging.

Use Transactions

If you are using persistent messaging and you don't want to use Async Sends then you should use JMS transactions to batch up many operations inside a single transaction.

Even if you have to pay the performance cost of XA transactions - using batching (processing and sending many messages in a single transaction (JMS or XA) will boost performance considerably. This is because you share the synchrony cost (the waiting for things to be written and sync'd to disk) across many many messages.

Use asynchronous sending

If you enable Async Sends then you will reduce the blocking in senders which increases throughput.

Increase the prefetch size

ActiveMQ uses a prefetch size to determine how many messages are streamed to a JMS consumer. The higher this number then typically the higher the throughput of the consumers as it typically means under heavy message load then the consumer always has more messages available immediately in RAM for processing - rather than having to wait for messages to be read and parsed from a socket.

Use Session.DUPS_OK_ACKNOWLEDGE

For transient messages (non persistent) or where performance is more critical than QOS, use Session.DUPS_OK_ACKNOWLEDGE on message consumers. The message consumer can lazily acknowledge and batch receipt of messages to the broker - which will dramatically improve performance. However, if you use Session.DUPS_OK_ACKNOWLEDGE with durable topic or Queue consumers for persistent messages, duplicate messages can be received if a consumer terminates abnormally (is killed without closing).

Other flags

If you look at javadoc of ActiveMQConnection you will see a number of properties you can use.

For example if you enable the following flags

  • optimizedAcknowledge
  • optimizedMessageDispatch
  • useAsyncSend
  • asyncDispatch

You will generally make ActiveMQ go faster, acknowledge messages in batches and use asynchronous sending

You can set these properties on the Connection object using Java code or using the connection URI String such as for Async Sends

Reduce latency using embedded brokers

If you send a message from a producer to a consumer then there are 2 network hops; one to get to the broker then from the broker to the consumer.

You can reduce one network hop by deploying an embedded broker in either the producer or consumer. Then there is no network hop on one end which typically reduces latency.

Avoid TCP for embedded brokers

If you are using an embedded broker then using the VM Transport is much more efficient than using the TCP Transport as objects can be passed by reference rather than being marshalled onto/off of a socket..

For more details see How to Run a Broker

Avoid message copy

If you know you are not going to reuse the Message object after sending then disable copyMessageOnSend flag on the ActiveMQConnection (via Java code or the connection URI)

Avoid unnecessary object serialization

If you are using the VM Transport with an embedded broker and using ObjectMessage intances then you can optimise the use of serialization (assuming that the producer and consumer are using the same classpath to avoid classloader issues).

To do this enable the objectMessageSerializeDefered flag which will avoid doing unnecessary serialisation of the Java objects inside the ObjectMessage instances.

Reduce CPU Usage: Use OpenWire loose encoding

By default ActiveMQ uses tight encoding with ActiveMQ. This encoding method uses more CPU but produces smaller packets. In most enviroments this works well. In some other enviroments where bandwith is not an issue and CPU usage is the constraint, switching to loose encoding should help reduce CPU usage.

For more assistance

The FUSE forum is available for any questions you may have.

你可能感兴趣的:(apache,socket,jms,activemq,performance)