preface

Can Java microservices be as fast as Go Microservices?

This is a question I’ve been thinking about lately.

Last August at the Oracle Groundbreakers Tour 2020 LATAM conference, Mark Nelson and Peter Nagy did a series of basic tests to compare this. Next, I’ll introduce it to you.

In the programmer community, the conventional wisdom is that Java is old, slow and boring, and Go is fast, new and cool

To do as fair a test as possible, they used a very simple microservice with no external dependencies (like a database), a very short code path (just manipulating strings), a small, lightweight framework (Helidon for Java and Go toolkit for Go), We experimented with different versions of Java and different JVMS.

Duel pair

Let’s take a look at the players on both sides of the ring:

  • The contestant in the dark suit is JAVA

Java was developed by Sun Microsystems, which was acquired by Oracle. Version 1.0 was released in 1996, and the latest version is Java15 in 2020. The main design goals were Java virtual machine and bytecode portability, and memory management with garbage collection. It is one of the most popular languages in the world and is developed in an open source environment.

Let’s start with JAVA. The biggest problem, by common consent, is that it is slow, so slow that it no longer feels justified, but rather historic. But over the years, Java has developed many different garbage collection algorithms to speed it up.

Oracle LABS has recently developed a new Java virtual machine, GraalVM, with a new compiler and some exciting new features, such as the ability to convert Java bytecode into a native image that can run without JavavM.

  • And its opponent is the young and energetic GO

GO was created by Google’s Robert Grimmer, Rob Peck and Ken Thomson. They made significant contributions to UNIX, B, C, Plan9, UNIX window systems, and more. GO is open source, with version 1.0 released in 2012 (16 years after JAVA) and version 1.15 in 2020. It is growing rapidly, both in terms of adoption and in terms of the language and tool ecosystem itself.

GO is influenced by C, Python, JavaScript, and C++. Designed to be the best language for high performance networking and multiprocessing.

StackOverflow had 27,872 “Go” questions, while Java had 1702,730. It can be seen that in the Yangtze river the waves behind push on those ahead.

Go is a statically typed compiled language. It has lightweight processes called Goroutines (these are not OS threads) that have unique communication channels (typed, FIFO) between them. Go is the preferred language for many CNCF projects, such as Kubernetes, Istio, Prometheus, and Grafana

Before the contrast

In my opinion, Go has the following advantages over JAVA:

  • Go is easier to implement composite, pure function, invariant state and other functional patterns.
  • Go is early in its life cycle, so it doesn’t have the heavy burden of backward compatibility — Go can still easily be improved by breaking certain limitations.
  • Go compiles to a native statically linked binary – there is no virtual machine layer – and the binary has everything you need to run the program, which is great for a “start from scratch” container.
  • Go is small, starts fast, and executes fast (so far)
  • Go has no OOP, inheritance, generics, assertions, pointer algorithms
  • Fewer parentheses in the Go notation
  • Go has no loop dependencies, no unused variables or imports, and no implicit cast coercion
  • Go boilerplate code is much less

The disadvantage is that:

  • The Go tool ecosystem is still immature, especially for dependency management — there are several options, none of them perfect, especially for non-open source development; Compatibility challenges remain.
  • Building code with new/updated dependencies is very slow (such as Maven’s famous “download the Internet” problem)
  • Imports bind code to the repository, which makes moving code around the repository a nightmare.
  • Debugging, profiling, and so on remain a challenge
  • Using a pointer
  • Some basic algorithms need to be implemented
  • No dynamic linking
  • There are not many knobs to tune execution or garbage collection, profile execution or optimization algorithms.

The race had begun

Use JMeter to run load tests. These tests call these services multiple times and collect data on response time, throughput (transactions per second), and memory usage. For Go, collect the resident set size; For Java, trace native memory.

Use 1000 service calls to warm up the application before measuring.

The source code for the application itself, as well as the definition of the load tests, are in this GitHub repository: github.com/markxnelson…

The first round

In the first round of testing, tests were conducted on a “small” machine, a 2.5ghz dual-core Intel Core I7 laptop with 16GB of ram running macOS. The test ran 100 threads with 10,000 loops per thread and a rise time of 10 seconds. The Java application runs on JDK11 and Helidon2.0.1. Go application compiled with Go 1.13.3.

The results are as follows:

You can see that the first round is won by Go!

JAVA takes up too much memory; Warm-up has a big impact on the JVM — we know that the JVM is optimized at run time, so it makes sense

Building on the first round, GraalVM images were added to make the Java application execution environment more similar to that of the Go application, and tests of GraalVM images (native images built with GraalVM EE 20.1.1 * JDK 11) were added, which resulted in:

By using GraalVM images to run the application on the JVM, we didn’t see any real improvement in throughput or response time, but we did see a smaller footprint.

Here are the response times for some of the tests:

The second round

In the second run, the tests were run on a larger machine. 36 cores (two threads per core), 256GB of RAM, and a machine running Oracle Elinux 7.8.

Similar to the first round, 100 threads were used, with 10,000 loops per thread, a 10 second acceleration time, and the same versions of Go, Java, Helidon, and GraalVM.

The results are as follows:

This round is won by GraalVM images!

Here are the response times for some of the tests:

In this test, the Java variant performed much better and significantly outperformed Go without using Java logging. Java seems to make better use of the multi-core and thread of execution hardware provides (compared to Go).

The best performance of this round came from GraalVM Native Image with an average response time of 0.25 ms and 82,426 transactions per second, while the best result of Go was 1.59 ms and 39,227 TPS, however at the cost of two orders of magnitude more memory!

GraalVM images are about 30-40% faster than the same application running on the JVM!

The third round

This time, the competition runs the applications in a Kubernetes cluster, a more natural microservices runtime environment.

This time a Kubernetes 1.16.8 cluster was used with three working nodes with two kernels per node (each kernel has two threads of execution), 14GB of RAM, and Oracle Elinux7.8.

Application access is through the Traefik entry controller, JMeter runs outside the Kubernetes cluster for some tests, and for others, Using ClusterIP and running JMeter in the cluster.

As in the previous tests, we used 100 threads, 10,000 loops per thread, and 10 seconds of acceleration.

Here are the different container sizes:

  • Go 11.6 MB 11.6 MB
  • Java/Helidon 1.41 GB 1.41 GB
  • Java/Helidon JLinked 150MB 150mb
  • Native Image 25.2MB 25.2MB

The results are as follows:

Here are the response times for some of the tests:

In this round, we observed that Go was sometimes faster and GraalVM images were sometimes faster, but the difference between the two was small (usually less than 5%).

Java seems to be better at using all available cores/threads than Go — we saw better CPU utilization in Java testing. Java performance is better on machines with more cores and memory, and Go performance is better on smaller/less capable machines. On a “production scale” machine, Java could easily be as fast or faster than Go

The last

There will be more test matches to see who is better! If you’re interested, you can try it out for yourself and let us know the results!

Reference for this article: medium.com/helidon/can…

Welcome to pay attention to my public account: Program monkey DD, get the exclusive arrangement of learning resources, daily dry goods and welfare gifts.