So firstly, some of you may be aware I've been on a big Kubernetes, Docker, "Right sized services" project. There is a lot of articles coming out on this but I've seen some recent ones that miss some important details from a JVM perspective.
I co-presented on this topic to our local JVM group just last week.
So IMO (and keeping it short):
1) I do believe in the Docker Kubernetes trend. It's a big and growing trend and I personally believe it will become the dominant deployment mechanism for services.
2) JVM developers need to be able to go small with fast startup. We need to be able to get high deployment density on shared hardware and be able to compete with golang here.
3) The JVM can go small with fast startup with some caveats:
- CGroup awareness is vital when going small (Java 8 with +UseCGroupMemoryLimitForHeap)
- Java 10 also made a big jump (measured as halving startup time for one specific case)
- We (very likely) need to use frameworks and libraries that have reduced their use of classpath scanning, reflection and "automatic configuration"
Note: By small I measured at -cpus=0.5 -m100m (That is, half a CPU and 100M total memory so the JVM heap would be ~25M)
4) What works on 8 CPU's and 32G (my laptop) can be very very poor at 0.5 CPU and 100M (e.g. Spring boot)
5) Frameworks (including Ebean) need to think about improving their startup times
What does this mean?
- Lots of libraries and frameworks on the JVM have tended to use a lot of classpath scanning, reflection etc to ease developer experience at the cost of startup CPU consumption and runtime memory.
- JVM developers are going to become more aware of this trade off and I believe there will be a move to use libraries and frameworks that are good in low resource environments (e.g. a 0.5 CPU and 100M total memory type environment).
What does this mean for Ebean?
- We already do lots of stuff better than the competition so we are pretty good already thankfully
- We may encourage the use of build time enhancement (but I suspect the majority are already doing this)
- We should encourage more explicit entity registration over scanning (e.g. serverConfig.addClass() or ServerConfigProvider ) or look to add a mechanism (like APT) to use code generation to do this automatically at compile or build time.
- At some point we could look to profile and speed up our startup using optional code generation. Look to avoid all reflection reads of bean properties, annotations etc and instead use code generation.
What are other projects doing?- We had an interesting discussion on DI. Guice 4 is apparently pretty quick.
micronaut.io has taken the step of doing "dagger like" code generation for DI
- Many "Web frameworks" forgo scanning and reflection and are explicit (which makes them fast and light)
So as I see it, right now we are ok. We are better than the competition and my personal experience to date with low resource environments shows no issue with Ebean startup. However, at some point we need to look to do some profiling and thinking about startup. If there are people struggling with going small / fast startup etc then let us know.
If anyone has a thought or experience in this area then by all means add to the discussion.
Cheers, Rob.