Masterclass

Cracking Microservices practices

BilginIbryam
hawt1

Learn how the Apache Camel framework can assist you in creating microservice style applications in Java with just a few lines of code.

 

This article is also featured in this month’s JAX
Magazine. For more tutorials like this, click here to get your free
download going.

I‘ve been using microservice architectures
before I knew they were called so. I used to create
pipeline 
applications
made up of isolated modules which interacted with each other
through queues. Since then, a number of (ex)ThoughtWorks gurus have
talked about microservices. Fred George[1], then James Lewis[2] and
finally Martin Fowler[3] have all blogged about microservices, all
of them helping to make it the next buzzword ­ and now every
company wants to have few microservices.

Nowadays there are #hashtags, endorsements,
likes, trainings, even two day conferences [4] about it. The more I
read and listen about microservice architectures, the more I
realize how Apache Camel (and the accompanying projects around it)
fits perfectly with this style of applications. In this post we
will see how the Apache Camel framework can help us create
microservice style applications in Java with few lines of
code.

Microservices Practices

There is nothing new in microservices. Many
similar applications have been designed and implemented as such for
a long time. Microservices is just a new term that describes a
style of software systems that have certain characteristics and
follow certain principles. It is an architectural style where an
application or software system is composed of individual standalone
services communicating using lightweight protocols in event based
manner. In the same way as TDD helps us to create decoupled single
responsibility classes, microservices principles guide us to create
simple applications at system level.

Here, we will not discuss the principles and
characteristics of such architectures or argue whether it is a way
of implementing SOA or a totally new approach to application
design, but rather look at the most common practices used for
implementing microservices and how Apache Camel can helps us
accomplish that in practice. There is not a definitive list (yet)
but if you read around or watch the videos posted above, you will
notice that the following are quite common practices for creating
microservices:

1. Small in size. The very
fundamental principle of microservices says that each application
is small in size and it only does one thing and does it well. It is
debatable what constitutes small or large, the number varies from
10 LOC to 1000 but personally, I like the idea that it should be
small enough to fit in your head. There are people with big heads,
so even that is debatable ;) but I think that as long as an
application does one thing and does it well so that it is not
considered a nanoservice[5], that is a good size.

Camel applications are inherently small in size.
A CamelContext with couple of routes with error handling and helper
beans is approximately 100 LOC. Thanks to Camel DSLs and URIs for
abstracting endpoints, receiving an event either through HTTP or
JMS, unmarshaling it, persisting and sending a response back is
around 50 LOC. That is small enough to be understood end­to­end
easily, rewritten and even thrown away without feeling any
remorse.

2. Having transaction
boundaries.
An application consisting of multiple
microservices forms an eventually consistent system of systems
where the state of the whole system is not known at any given time.
This on its own creates a barrier for understanding and adopting
microservices in teams who are not used to work with this kind of
distributed applications. Even though the state of the whole system
is not fixed, it is important to have transaction boundaries that
define where a message currently belongs.

Ensuring transactional behaviour across
heterogeneous systems is not an easy task, but Camel has great
transactional capabilities. Camel has endpoints that can
participate in transactions, transacted routes and error handlers,
idempotent consumers and compensating actions, all of which help
developers easily create services with transactional
behavior.

3. Self monitoring. This is one
of my favorite areas of microservices. Services should expose
information that describes the state of various resources it
depends on and the service itself. These are statistics such as
average, min, max time to process a message, number of successful
and failed messages, being able to track a message, memory usage
and so forth.

This is something you get OOTB with Camel
without any effort. Each Camel application gathers JMX

statistics by default for the whole application,
individual routes, endpoints and custom beans. It will tell you how
many messages have completed successfully, how many failed, where
they failed, etc. This is not read only API, JMX allows also
updating and tuning the application at run time, so based on these
statistics, using the same API you can tune the application
accordingly. Also the information can be accessed with tools such
as jConsole, VisualVM, Hyperic HQ, exposed over HTTP using Jolokia
or feed into a great web UI called Hawtio[6].

Figure 1: Hawtio

If the functionality that is available with OOTB
doesn’t fit your custom requirements, there are
multiple 
extension points such as the nagios,
jmx, amazon cloudwatch components and Interceptors for
custom 
events.

Logging in messaging applications is another
challenge, but Camel’s MDC logging combined
with 
Throughput logger makes it easy to track
individual messages or get aggregated statistics as part of
the 
logging output.

5. Designed for failure. Each
of the microservices can be down or unresponsive for some time but
that should not bring the whole system down. Thus microservices
should be fault tolerant and be able to recover when that is
possible.

Camel has lots of helpful tools and patterns to
cope with these scenarios too. Dead Letter Channel can make sure
messages are not lost in case of failure ­ the retry policy can
send a message a couple of times for certain error conditions using
custom backoff method and collision avoidance. Patterns such as
Load balancer which supports Circuit breaker[7], Failover and other
policies, Throttler to make sure certain endpoints do not get
overloaded, Detour, Sampler, are all needed in various failure
scenarios. So why not use them rather than reinventing the wheel in
each service?

6. Highly Configurable. It
should be easy to configure the same application for high
availability, scale it for reliability or throughput, or said
another way: have different degrees of freedom through
configuration. When creating a Camel application using the DSLs,
all we do is to define the message flow and configure various
endpoints and other characteristics of the application. So Camel
applications are highly configurable by design. When all the
various options are externalized using properties component, it is
possible to configure an application for different expectations and
redeploy without touching the actual source code at all. Camel is
so configurable that you can change an endpoint with another
one(for example replace HTTP endpoint with JMS) without changing
the application code at all which we will cover next.

7. With smart endpoints. Micro
services favour RESTish protocols and lightweight messaging rather
than Web Services. Camel favors anything. It has HTTP support as no
other framework.It has components for Asynchronous HTTP, GAE URL
fetch service, Apache HTTP Client, Jetty, Netty, Servlet, Restlet,
CXF and multiple data formats for serializing/deserializing
messages. As for the queuing support, OOTB there are connectors for
JMS, ActiveMQ, ZeroMQ, Amazon SQS, Amazon SNS, AMQP, Kestrel,
Kafka, Stomp, you name it.

8. Testable. There is no common
view on this characteristic. Some favor no testing at all and
relying on business metrics. Some cannot afford to have bad
business metrics ever. I like TDD and for me having the ability to
test my business POJOs in isolation from the actual message flow,
then test the flow separately by mocking some of the external
endpoints is invaluable. Camel testing support can intercept and
mock endpoints, simulate events, verify expectations with ease.
Having a well tested individual microservice is the only guarantee
to have the whole system to work as expected.

9. Provisioned individually.
The most important characteristics of microservices is that they
run in isolation from other services most commonly as standalone
Java applications. Camel can be embedded in Spring, OSGI or web
containers. Camel can also run as a standalone Java application
with embedded Jetty endpoints easily. But managing multiple
processes, all running in isolation without a centralized tool is a
hard job. This is what Fabric8[8] is made for. Fabric8 is developed
by the same guys who developed Camel and supported by Red Hat
JBoss. It is a poly Java application provisioning and management
tool that can deploy and manage a variety of Java containers and
standalone processes. To find out more about Fabric8, here is [9]
nice post by Christian Posta.

10. Language neutral. Having
small and independently deployed applications allow developers to
choose thebest suited languagage for the given task. Camel has XML,
Java, Scala, Groovy and few other DSLs with similar syntax and
capabilities .But if you don’t want to you use Camel at all for a
specific micro service, you can still use Fabric8 do deploy and
manage applications written in other languages and run them as
native processes [10].

In summary: Microservices are
not strictly defined and that’s the beauty. It is a lightweight
style of implementing SOA that works. So is Apache Camel. It is not
a full featured ESB, but it can be as part of JBoss Fuse. It is not
a strictly defined specification driven project, but a lightweight
tool that works and developers love it.

References

[1] Micro­Service Architecture, by Fred George
(video) https://www.youtube.com/watch?v=2rKEveL55TY

[2] Micro­Services ­ Java, the UNIX way, by
James lewis (video)

http://jz13.java.no/presentation.html?id=2a7b489a

[3] Microservices, by Martin Fowler

http://martinfowler.com/articles/microservices.html

[4] μCon: The Microservices Conference

https://skillsmatter.com/conferences/6312­mucon

[5} Nanoservices

http://arnon.me/wp­content/uploads/2010/10/Nanoservices.pdf

[6] Hawtio http://hawt.io/

[7] Circuit Breaker Pattern in Apache Camel by
Bilgin Ibryam

http://www.ofbizian.com/2014/04/circuit­breaker­pattern-in­apache­camel.html

[8] Fabric8 http://fabric8.io/

[9] Meet Fabric8: An open­source integration
platform by Christian Posta

http://www.christianposta.com/blog/?p=376

[10] Micro Services the easy way with Fabric8 by
James Strachan

http://macstrac.blogspot.co.uk/2014/05/micro-services­with­fabric8.html

 

 

 

 

Author
BilginIbryam
Bilgin Ibryam (Twitter: @bibryam) is a JBoss Fuse consultant currently working for Red Hat in London. He is interested in message oriented middleware and distributed applications. He is also the author of "Instant Apache Camel Message Routing" book, an open source enthusiast, Apache OFBiz, and Apache Camel committer. In his spare time, he enjoys contributing to open source projects and blogging at http://ofbizian.com.
Comments
comments powered by Disqus