Java microservices vs Go microservices, who is stronger! ?

Preface

Can Java microservices be as fast as Go microservices? This is a question I have been thinking about recently.

At the Oracle Groundbreakers Tour 2020 LATAM conference in August last year, Mark Nelson and Peter Nagy did a series of basic tests for comparison. Next, let me introduce you.

The following content and opinions are mainly derived from: https://medium.com/helidon/can-java-microservices-be-as-fast-as-go-5ceb9a45d673

In programmer circles, the common belief is that Java is old, slow, and boring  , while Go is fast, new, and cool.

In order to conduct a relatively fair test as much as possible, they used a very simple microservice, no external dependencies (such as a database), a very short code path (just manipulating strings), and used a small, lightweight Framework (Helidon for Java and Go Toolkit for Go), experimented with different versions of Java and different jvms.

Duel

Let's first look at the players on both sides of the ring:

  • The player in the dark uniform is JAVA

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

Let's take a look at the problem of JAVA. It is generally believed that its biggest problem is its slow speed, which is so slow that it is no longer reasonable, but more historical. But over the years, Java has produced many different garbage collection algorithms to speed up its operation.

Oracle Labs has recently developed a new Java virtual machine GraalVM, which has a new compiler and some exciting new features, such as the ability to convert Java bytecode into a native image, which can be used without javavm Run under circumstances, etc.

  • And its opponent is the young and energetic GO

GO was created by Google’s Robert Grimmer, Rob Pike, and Ken Thomson. They have made significant contributions to UNIX, B, C, Plan9, UNIX window system, etc. GO is open source, released version 1.0 in 2012 (16 years later than 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 multiple languages ​​such as C, Python, JavaScript and C++. Designed to be the best language for high-performance networking and multiprocessing.

StackOverflow has 27872 questions with "Go", while Java has only 1,702,730. It shows that the waves behind the Yangtze River push the waves forward.

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

Pre-match comparison

Personally speaking, compared to JAVA, Go has the following advantages:

  • Go is easier to implement functional modes such as composite, pure function, and invariant state.

  • Go is in the early stages of its life cycle, so it does not have a heavy burden of backward compatibility-Go can still easily break certain limitations to improve.

  • Go is compiled into a native statically linked binary file-there is no virtual machine layer-the binary file has everything needed to run the program, which is great for a "from scratch" container.

  • Go is small in size, fast to start, and fast to execute (currently yes)

  • Go has no OOP, inheritance, generics, assertions, pointer arithmetic

  • Fewer parentheses in Go

  • Go has no circular dependencies, no unused variables or imports, and no implicit type conversion mandatory

  • Go has much less boilerplate code

weakness is:

  • The Go tool ecosystem is still immature, especially dependency management-there are several options, none of which is perfect, especially for non-open source development; there are still compatibility challenges.

  • Building code with new/updated dependencies is very slow (such as Maven’s famous "Download Internet" problem)

  • Importing binds code to the repository, which makes moving code in the repository a nightmare.

  • Debugging, evaluation, etc. are still a challenge

  • Pointers used

  • Need to implement some basic algorithms

  • No dynamic link

  • There are not too many knobs to tune execution or garbage collection, profile execution or optimize algorithms.

Game start

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, track the native memory.

Before the measurement, 1000 service calls are used to warm up the application.

The source code of the application itself and the definition of the load test are all in this GitHub repository: https://github.com/markxnelson/go-java-go

first round

In the first round of testing, the test was performed on a "small" machine, a 2.5GHz dual-core Intel core i7 laptop with 16GB of RAM running macOS. The test ran 100 threads, each with 10,000 loops, and a rise time of 10 seconds. Java applications run on JDK11 and Helidon2.0.1. Go application compiled with Go 1.13.3.

The results are as follows:

It can be seen that Go won the first round!

JAVA takes up too much memory; warm-up has a great impact on JVM-we know that JVM will be optimized at runtime, so this makes sense

On the basis of the first round, the GraalVM image was introduced to make the execution environment of Java applications closer to the environment of Go applications, and the GraalVM image test was added (the native machine built with GraalVM EE 20.1.1-JDK 11). The result of the image) is:

By using the GraalVM image to run the application on the JVM, we did not see any substantial improvement in throughput or response time, but the memory footprint did become smaller.

Below is a graph of response time for some tests:

second round

In the second round of testing, the test was run on a larger machine. A machine with 36 cores (two threads per core), 256GB of memory, and oraclelinux 7.8.

Similar to the first round, 100 threads were used, each thread used 10,000 cycles, a 10 second acceleration time, and the same version of Go, Java, Helidon and GraalVM.

The results are as follows:

This round is the GraalVM image won!

Below is a graph of response time for some tests:

In this test, the Java variant performed much better, and its performance greatly exceeded Go without using Java logging. Java seems to be more able to use the multi-core and execution threads provided by hardware (compared to Go).

The best performance in this round comes from the GraalVM native image. The average response time is 0.25 milliseconds, and the number of transactions per second is 82,426. The best result of Go is 1.59 milliseconds and 39227 tps, but this is two orders of magnitude more. At the cost of memory!

The GraalVM image is about 30–40% faster than the same application running on the jvm!

Third round

This time, the competition runs these applications in a Kubernetes cluster, which is a more natural microservice runtime environment.

This time a Kubernetes 1.16.8 cluster is used, which has three worker nodes, each with two cores (each core has two execution threads), 14GB of RAM and oraclelinux7.8.

Application access is performed through the Traefik ingress controller. JMeter runs outside the Kubernetes cluster for some tests, while for other tests, ClusterIP is used and JMeter is run in the cluster.

As in the previous test, 100 threads were used, each thread used 10,000 cycles, and a 10 second acceleration time.

Here are the sizes of various different containers:

  • Go 11.6MB 11.6 MB

  • Java/Helidon 1.41GB 1.41 GB

  • Java / Helidon JLinked 150MB 150mb

  • Native image 25.2MB 25.2 MB

The results are as follows:

Below is a graph of response time for some tests:

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

Java seems to be better at using all available cores/threads than Go-I have seen better CPU utilization in Java tests. Java performance is better on machines with more cores and memory, and Go performance is better on smaller/less powerful machines. On a "production-scale" machine, Java is easily as fast as Go, or faster

At last

There will be more test matches next to see who is better!

 

 

Guess you like

Origin blog.csdn.net/j3T9Z7H/article/details/112597585