Jul 14, 2009

Apache ActiveMQ Out Of Memory!

Apache ActiveMQ is adaptable and configurable. A large part of its popularity is due to its flexibility. However, it comes with a default activemq.xml configuration file that cannot possibly suit everybody's needs. The default configuration is a compromise between memory utilisation, low latency and high throughput, with a smattering of feature demonstrations. In all, it is probably too much for one configuration file, but that is another issue that is in part addressed in version 5.3.0.

With the current defaults, it is relatively easy to push the broker's heap memory utilization past the -Xmx512m heap limit passed to the JVM in the start script. When that happens the broker begins to fail in various places with java.lang.OutOfMemoryError: unable to create new native thread or java.lang.OutOfMemoryError: Java heap space.

What to do?
Well Google is your friend but there is also the ActiveMQ FAQ and particularly the entry that deals with the likely causes and relevant configuration that can alleviate ActiveMQ OutOfMemoryError Exceptions.

In short, the answer is nearly always configuration and the intent is that the OutOfMemory FAQ entry will provide a comprehensive reference for the relevant options. Let it be your first port of call.

Jan 9, 2009

Building activemq from source with m2eclipse on Mac OsX

On Mac OsX, when building activemq from source using the neat m2eclipse import maven project feature, the activemq-fileserver module fails with error:
'Access restriction: The type HttpURLConnection is not accessible due to restriction on required library /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Classes/classes.jar'.

This is in fact, a reasonable error. It is not desirable to have a dependency on a sun internal class. When using a sun jdk it is not really an issue but the default eclipse java builder on OsX is using the Apple JVM and the java builder is correctly configured to consider this sort of reference an error. To get a clean build this error needs to be reduced to a warning.

The option to disable is at:
Eclipse -> Preferences -> Java ->
Compiler ->
Errors/Warnings ->
Deprecated and restricted API ->
Forbidden reference (access rules)
Change the drop down selection from Error to Warning.

Should this be fixed? Yeah, we should probably depend on commons http client instead. I will need to dig a little further to understand why access to the implementation class is needed in the first place.
Short term, suppressing this error allows the build to proceed.

activemq systemUsage xml configuration and sendFailIfNoSpace ...

I was caught out with this twice in 24hrs. The systemUsage sendFailIfNoSpace attribute must be configured on the XBean element content, not on the element wrapper.
The use case is to limit the pending message length by memory usage and to fail the producer with an exception when the memory limit (or 70% of the memory limit) is reached. The limit can be reached very easily with a fast producer and slow (or no) consumer.

In activemq XML configuration use:
<systemUsage>
 <systemUsage sendFailIfNoSpace="true">
   <memoryUsage>
     <memoryUsage limit="20 mb">
   </memoryUsage>
 </systemUsage>
</systemUsage>
If the attribute is incorrectly added to the top level element, it is ignored and the result is that a producer will experience the default "wait for space to become available" behaviour and will hang.
Note to self, be sure to double check where XBean attributes are specified!

Jan 2, 2009

Speaking at IJTC 2008 - Choosing a JMS

I will be presenting at IJTC 2008 next week. The focus of my talk will be on choosing a java messaging solution with an emphasis on making a decision in context. Trying to make all the goodness of the web and community work for you. It should be fun.

Nov 21, 2008

Apache ActiveMQ 5.2.0 Release

The Apache ActiveMQ 5.2.0 release goes a long way towards hardening the broker. There has been a particular emphasis on use cases involving large scale networks with high message volumes. The Kaha message store resilience has improved and the remaining issues around slow restart recovery will be addressed for 6.0.

The behavior or the broker and subscriptions in the event of slow or unreliable networks has also seen numerous improvements. One upshot is that failover in now included in the default brokerURL.

The resolved issue count has topped 200, so this release was a little overdue, but I think it will be worth the wait.

Oct 29, 2008

Open Source and Open Standards; Crtl & Esc

Open Source gives the Ctrl; you can see what is going on through the source. You are free to modify and extend it. You can make it better to make your solution better. Given sufficient effort (and time), it is mailable.

Open Standards give the Esc; once due care is given to the use of standard apis, the escape hatch is always open. If a better implementation comes along you are free to go, you are free to switch-out an implementation.

The combination of open source and open standards is a perfect match. While the proprietary extensions will still exist, the good extensions are eventually subsumed or become de facto standards in themselves.

Access to the source provides the ultimate freedom to protect one's investment and influence the future direction of a project. Patch the source and if you get it right, there is a good chance that the patch will filter through to the user community. It may even eventually make its way to the standard.

Note: With FOSS, there is also intrinsic Esc; at least in the early stages. The barrier to entry is so low, the barrier to exit is no more than the cost of the experience. We are all entitled to change our opinions as we learn.

Oct 17, 2008

Testing: simulating a network failure

Figuring out how distributed software behaves in the event of a network failure or partition can be difficult. It requires testing that involves multiple machines, multiple networks and many hands!.
Virtualisation helps, but for really simple testability, a single VM environment is what you need. What follows, with some context, is a simple solution that may help.

Recently I was trying to track down an issue with Apache ActiveMQ network support. The test scenario required a bunch of VMWare images, dual network cards and periodic manual network disabling.
In order to understand the scenario I tried to reduce it to something more manageable. The iptables firewall in Linux meant I did not have to yank out any network cables. With iptables, and a good tutorial, it is relatively easy to simulate a network failure or temporary network outage by instructing iptables to drop network packets that originate from, or are destined for, an individual port.
For my test, I had a simple network of two embedded brokers, a producer on one broker and a consumer on the other. Both the producer and consumer used the vm protocol, leaving the tcp connector free for the networking calls. The connector was using port: 61616. To simulate a network failure, by dropping all tcp packets to and from port 61616, the following iptables rules do the trick:
$ sudo iptables -I INPUT 1 -p tcp --sport 61616 -j DROP;sudo iptables -I INPUT 2 -p tcp --dport 61616 -j DROP
In order to enable communication again, the two rules added above need to be deleted (for simplicity I just delete the first rule twice):
$ sudo iptables -D INPUT 1;sudo iptables -D INPUT 1
This works fine because I have control over the Linux box and I don't typically run any iptables rules. But this will not always be the case and this will not hold on other platforms or on shared Linux work stations. In addition it requires some manual intervention so it cannot be easily automated.

What I needed I thought, was a simple java socket proxy that could sit as an intermediary between the two ends of the network and which I could control through code. Something that will let traffic pass through until it is instructed not to do so. A quick google did not produce any obvious candidate for reuse so I coded a simple solution that worked for me and built a test case around it. The resulting SocketProxy is uses in BrokerQueueNetworkWithDisconnectTest. The usage pattern is based around replacing required tcp URIs with a proxy URL:

socketProxy = new SocketProxy(remoteURI);
DiscoveryNetworkConnector connector = new DiscoveryNetworkConnector(new URI("static:(" + socketProxy.getUrl() + ")"));
The proxy takes the target URI, sets up a listener and forwarder to the target and through getUrl() returns the proxy URL. To simulate a network failure, socketProxy.stop() is called during the test execution. socketProxy.resume() allows a network reconnect such that recovery can be validated. It made my life a little easier and meant I could produce a reliable and portable test case using a single JVM. I know I will use it again :-)

Note: There is also the option to pause/resume the proxy. This keeps the sockets open but does not allow any traffic to pass through. Pausing allows the simulation of a slow network which was handy for exercising the ActiveMQ inactivity monitor.