Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the advantages of Java microservice

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article focuses on "what are the advantages of Java microservices". Interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn what are the advantages of Java microservices.

1. Background introduction

We hope to know whether the running speed of Java micro-service can reach the level of Go micro-service through experiments. At present, the software industry generally thinks that Java is too old, slow and boring. Go, on the other hand, has become synonymous with being fast, new and cool. Is that true? We want to see if this impression is tenable from a data point of view.

We wanted to establish a fair test, so we created a very simple micro service with no external dependencies (such as a database) and a very short code path (only dealing with strings). We include metrics and logging in it because it seems that all microservices contain them more or less. In addition, we used a small, lightweight framework (Helidon for Java and Go-Kit for Go), and tried Java's pure JAX-RS with two sleeves. We also tried different versions of Java and different JVM. We made basic adjustments to the heap size and garbage collection mechanism, and warmed up the micro-service before the test run.

2. The development history of Java

Java was developed by Sun Microsystems and later acquired by Oracle. Version 1.0 was released in 1996, and the latest version is Java 15 in 2020. The current main design goal of Java is to realize the portability of Java virtual machine and bytecode, as well as a memory management mechanism with garbage collection. Today, Java as an open source language is still one of the most popular language options in the world (according to sources such as StackOverflow and TIOBE).

Let's talk about the "Java problem". People's impression of its slow speed is actually more of an inherent concept than the fact that it is no longer adapted to the present. Today's Java even has a number of performance-sensitive areas, including a storage object data heap, a garbage collector for managing the heap, and a just-in-time (JIT) compiler.

Over the years, Java has used a variety of different garbage collection algorithms, including serial, parallel, concurrent marking / clearing, G1, and the latest ZGC garbage collector. Modern garbage collectors are designed to minimize the pauses caused by garbage collection.

Oracle Labs has developed a Java virtual machine called GraalVM, which is written in Java and has a new compiler plus a series of exciting new features, including the ability to convert Java bytecode into a native image that runs without a Java virtual machine.

3. The development history of Go

The Go language is developed by Google's Robert Griesemer, Rob Pike and Ken Thomson. They are also major contributors to projects such as UNIX, B, C, Plan9 and UNIX Windows. As an open source language, version 1.0 of Go was released in 2012, with the latest version 1.15 in 2020. The ontology, adoption speed and tool ecosystem of Go language are developing rapidly.

Influenced by C, Python, JavaScript and C++, Go has become an ideal high-performance network and multi-processing language.

As of the time of our keynote speech, there were 27872 questions labeled "Go" on StackOverflow and 1702730 on Java.

Go is a statically typed compiled language with a syntax similar to C # and features such as memory security, garbage collection, structured typing, and CSP-style concurrency (communication sequential procedures). Go also uses a lightweight process called goroutine (not an operating system thread), plus a channel for communication between processes (typed, FIFO). The Go language does not provide race condition protection.

Go is the preferred language for many CNCF projects, such as Kubernetes, Istio, Prometheus, and Grafana, all written (or mostly) in the Go language.

Go language emphasizes rapid construction and fast execution in design. Is it two spaces or four spaces? Go language means no trouble, it doesn't matter.

Compared with Java, I have sorted out the advantages of Go language that I have experienced as follows:

It is easier to implement functional patterns, such as composite, pure functions, immutable states, and so on.

There is much less boilerplate code (but still too much objectively).

The Go language is still in its early life cycle, so there is no downward compatibility pressure-the road to improvement is smooth.

Go code can be compiled into native statically linked binaries-- no virtual machine layer-- binaries contain everything the program needs to run, so it is more suitable for "starting from scratch" containers.

The utility model has the advantages of smaller size, faster starting speed and faster execution speed.

No OOP, inheritance, generics, assertions, pointer arithmetic.

There are few parentheses, such as if x > 3 {whatever}.

Enforcement, no circular dependencies, no unused variables or imports, no implicit type conversions.

But Go is certainly not perfect. Compared with Java, I think Go has the following problems:

The tool ecosystem is not yet mature, especially in dependency management, although there are many options, but none of them is perfect. In terms of non-open source development, the Go module has obvious advantages in dependency management, but its adoption rate is still not particularly high because of some compatibility problems.

It is very slow to build code with new / update dependencies (such as Maven's famous "download Internet" problem).

The import binds the code to repo, making it very difficult to move the code.

IDE is very suitable for programming, document search and automatic completion, but it is difficult to debug and analyze. Hands! I thought I could say goodbye to this thing before the 21 century, but there are still in Go! Fortunately, at least there is no pointer algorithm.

There are no try/catch exceptions like Java (you always end up using if err! = nil), and there are no function-style primitives such as lists, mappings, and so on.

Some basic algorithms are still missing, so users often have to write their own. I recently wrote some code that uses sloe to compare and convert two strings (lists). In functional languages, we can use built-in algorithms such as map.

No dynamic links! If you want to use licenses such as GPL in your static link code, it will be inconvenient. There are few options for tuning execution, garbage collection, profiling, or optimizing algorithms. Java has hundreds of garbage collection adjustment options, compared with only one for Go.

4. Load testing method

We use JMeter for load testing. Test multiple calls to the service and collect data on response time, throughput (transactions per second), and memory usage. On the Go side, we mainly collect resident set sizes, while on the Java side, we mainly track native memory.

In several tests, we placed JMeter and the application under test to run on the same computer. By comparison, we found that running JMeter on other machines had little impact on the results. Later, when we deploy the application to Kubernetes, we will consider running JMeter on remote computers outside the cluster.

Before testing, we warmed up the application with 1000 service calls.

For the source code of the application ontology and the load test definition, see GitHub repo: https://github.com/markxnelson/go-java-go

5. First round of testing

In the first round of testing, we ran the test on a small machine with a 2.5 GHz dual-core Intel Core i7 laptop with 16 GB of memory and running MacOS. We ran 100 threads, each with 10000 loops, plus an additional 10-second startup time. The Java application runs on JDK 11 and Helidon 2.0.1. The Go application is compiled using Go 1.13.3.

The test results are as follows:

We announce that Go is the winner of the first round of testing!

The following are the observations based on these results:

Logging seems to be a major performance issue, especially java.util.logging. Therefore, we tested it with logging enabled and disabled. We also note that the performance of Go applications is mainly affected by logging.

Even for such a simple small application, the memory footprint of the Java version is significantly higher.

Warm-up has a big impact on JVM-- we know that JVM is optimized during operation, so warm-up is particularly important for Java applications.

In this test, we also compared different execution models-Go applications are compiled into native executable binaries, while Java applications are compiled into bytecode and then run on a virtual machine. We also decided to introduce GraalVM native images to ensure that the execution environment of Java applications is closer to that of Go applications.

6. GraalVM native image

GraalVM provides native mirroring capabilities that enable you to use Java applications and essentially compile them into native executable code. According to the introduction of the GraalVM project website:

The executable contains application classes, classes in dependencies, runtime library classes, and static link native code in JDK. It does not run on a Java virtual machine, but contains necessary components, such as memory management, thread scheduling, and so on, from different runtime systems (also known as "base virtual machines"). The basic virtual machine represents the runtime components (such as anti-optimizer, garbage collector, thread scheduling, etc.).

After adding the GraalVM native image, which is built from GraalVM EE 20.1.1--JDK 11, the results of the first round of tests are as follows:

In this case, we found that using GraalVM native mirrors did not bring any substantial improvement in terms of throughput or response time compared to applications running on JVM, but the memory footprint did decrease.

The following is the response time chart during the test:

First round response time chart

Note that of all three Java variants, the response time for the first batch of requests is much longer (the blue line is higher than the height of the left axis) and we also see spikes in various tests that may be caused by garbage collection or optimization.

7. Second round of testing

Next, we decided to run the test on a larger computer. In this round, we use a computer with 36 cores (dual threads per core), 256 GB memory, and with the Oracle Linux 7.8 operating system. As in the first round, we still use 100 threads, 10000 cycles per thread, 10-second startup time, and the same versions of Go, Java, Helidon, and GraalVM.

Let's look at the results:

We announced that the GraalVM native image is the winner of the second round of testing!

Let's take a look at the response time diagram for this round of tests:

Enable logging, but unwarmed test run response time

Test run response time without logging and without warm-up

Test run response time that is prewarmed but does not use logging

The results of the second round of observations:

The performance of the Java variant has improved significantly in this round of testing and is much better than Go without logging.

Compared to Go, Java seems to be better at using multiple cores and execution threads on hardware-this is because Go itself exists mainly as a system and network programming language, and the development cycle is relatively short, so it is normal to lag behind Java in terms of maturity and optimization level.

Interestingly, when Java was born, multi-core processors were not common, and when Go was born, multi-core processors had become the industry standard.

Specifically, Java seems to have successfully handed over logging to other threads / cores, thus greatly reducing its impact on performance.

The best performance of this round comes from the GraalVM native mirror, which has an average response time of 0.25ms and can perform 82426 transactions per second; the best result of Go is 1.59ms plus 39227 transactions per second, and its memory footprint is two orders of magnitude higher than the former!

GraalVM native mirror variants are 30 to 40 percent faster than the same application running on JVM.

The response time of the Java variant is more stable, but there are more peaks-- we suspect that this is because Go divides garbage collection into more and smaller batches to execute.

8. The third round of testing: Kubernetes

In the third round, we decided to run the application on the Kubernetes cluster to simulate a more natural microservice runtime environment.

In this round, we use a Kubernets 1.16.8 cluster with three worker nodes, each containing two cores (two threads each), 14 GB memory, and Oracle Linux 7.8. In some tests, we run a Pod; on a variant, while in others, we run a hundred Pod.

Application access is achieved through the Traefik entry controller, where JMeter runs outside the Kubernetes cluster. In some tests, we will also try to use ClusterIP and run JMeter within the cluster. As in the previous test, we used 10000 cycles per thread, plus 10 seconds to start.

The following is the container size for each variant:

Go 11.6MB

Java/Helidon 1.41GB

Java/Helidon JLinked 150MB

Native image 25.2MB

The following are the results of this round of tests:

Response time chart:

Response time in Kubernetes testing

In this round, you can see that Go is sometimes faster, while GraalVM native images often take the lead, but the difference between the two is small (generally less than 5%).

9. Test conclusion

Looking at several rounds of tests and results, we have come to the following conclusions:

Kubernetes doesn't seem to scale out fast.

Java seems to be more about leveraging all available cores / threads than Go, and we found that CPU utilization was higher during Java testing.

Java performs better on cores and computers with higher memory capacity, and Go performs better on smaller / weaker computers.

The performance of Go is generally more consistent, which may be due to the garbage collection mechanism in Java.

On "production scale" computers, Java runs at roughly the same speed as or even faster than Go.

Logging seems to be a major performance bottleneck in Go and Java.

Modern versions of Java and new frameworks such as Helidon perform well in eliminating / alleviating some of the major long-standing problems of Java, such as verbosity, GC performance, startup time, etc.

10. Prospects for the future

After this round of interesting tests, we intend to continue to explore, especially:

We intend to do more through Kubernetes automatic extension, including the introduction of more complex micro-services or higher loads to highlight the performance differences.

We want to study more complex micro-services, multiple service types and patterns, and observe how the network affects performance and how the micro-service network should be tuned.

We also plan to dig deeper into the logging problem to understand how to solve this bottleneck.

We want to look at the target code and compare the actual instructions currently being executed to see if we can make further optimizations in the code path.

We want to know whether JMeter can generate enough load without becoming a bottleneck, but this test results show that JMeter does not have an impact, but can easily keep up with the pace of Go and Java implementations.

We intend to make more detailed measurements of container startup time, memory usage and other indicators.

At this point, I believe you have a deeper understanding of "what are the advantages of Java micro services?" you might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report