There's lots of heated debate of late on micro services and what they are. From our perspective its simply about about creating separate (JVM) processes using the Java Container for each service so that each service is self contained, isolated, managed and has a minimal footprint.
You just choose whatever jars go onto the static flat classpath; just enough to function well but not necessarily including a whole Application Server (though you are free to embed whatever libraries and frameworks you need including embedding whatever parts of, say, Apache Tomcat, Apache Karaf or WildFly you wish to use).
From our perspective the main benefits of Micro Services are:
With Micro Services you specify the exact list of jars to be on the classpath; thats it. No magic Class Loaders; no complex graph of Class Loader trees to understand or complex OSGi package level versioned import/export statements.
A simple, flat classpath (jars in a lib directory) thats very simple to understand.
No more fighting with ClassCastException because you have 2 versions of a given class in different parts of the class loader tree, or ClassNotFoundException if one branch of your Class Loader tree can't see another branch. No fighting with Application Server internals or clashes with jaxb or logging libraries included in the Application Server. You just pick the jars you need.
Wondering whats on your classpath? Just look in the lib directory. The easiest Application Server to work with in the world is literally a flat class path :). Simples!
Only include the exact list of jars you need to implement the Micro Service. Be as minimal as you want or need to be :)
That way your JVM uses the least amount of memory, threads, file descriptors and IO. This also leads to the fastest possible startup of your service.
Rather than running all your services in the same JVM; you run separate JVM processes for each micro service. This has many benefits:
It must be said that using more processes can use more memory and resources but we feel the benefits greatly outweigh the costs; particularly as memory and disk getting cheaper while people's time remains a scarce commodity and agility is of the essence. Using more processes are harder to manage in theory; though fabric8 helps make that easy via its use of profiles and containers.
To implement Micro Services in Fabric8 we use the Java Container to run each service as a completely separate and isolated JVM process. This lets us start, stop and perform rolling upgrades to service instances without affecting other services.
We create a Profile for each Micro Service so that its easy to view the entire fabric and all its containers; grouping them by profile (or service).
To help auto-scale individual micro services we can then use the Profile Requirements to define the sizing requirements and automatically scale up and down using the JMX API calls on Fabric8 in an operational management tool's alerting mechanism like JBoss RHQ