Solutions Architect at IntexSoft
Recently, my colleagues and I discussed the popularity of a couple of technologies — in particular, Java and node.js. After a brief Internet surfing session, it turned out that these technologies are used by many information giants to develop and maintain their platforms. Below, I will mention only a few of them.
Companies using Java:
Companies using node.js:
One more interesting fact is that according to indeed.com Java developers (about 29000 jobs) and node.js developers (about 5000 jobs) are quite in demand.
Java is a language, while node.js can be called an ecosystem built on the basis of JS, and, above all, on the basis of Google’s V8 engine.
However, when we talk about Java, we are talking not only about the language but about the Java Virtual Machine (JVM), as well as the entire ecosystem and infrastructure built around this machine. That’s the first reason why we can compare them.
As a result, in both cases, we have the execution environment. In the case of Java, it’s a virtual machine. In the case of node.js, this is the V8 engine that presents on most operating systems, such as Windows, Linux, MacOS, and those lesser known. Developers can write code using the same language, and this will work in more or less the same way on different operating systems due to the fact that there is a runtime environment. The execution environment influences how it interacts with the OS. In addition, they can be compared because they are used to solve a similar range of tasks.
When a JS code enters the V8, it is compiled into a byte code due to the just in time (JIT) compilation that is used in the virtual machine, therefore the JS code runs faster.
Byte code is an intermediate, high-level language, so in a JVM, they write not only in Java but also in Scala and Kotlin.
There are prerequisites that in the near future for V8 it will be possible to use not only JS but also TypeScript or others. At the moment, a transpiling of these languages in JS is going on. The perspective for the technology will see that, they will probably be supported out of the box, and everything will work much faster.
Now, when the continuous development of V8 takes place, the emergence of new node.js versions is associated with the appearance of a new version of the V8 engine. They are directly interrelated.
Node.js was created by Ryan Dahl in 2009.
The node.js itself includes several key components:
Now let us turn to the pros and cons of node.js.
In contrast, let’s consider the main characteristics of Java.
Recently, JS has begun to overtake Java. Java is also leaving the Android world: it is being replaced by Kotlin, which, although using the JVM, is still a different language.
Java was created by Sun, which was later acquired by Oracle. For this reason, for many companies, the use of Java causes some issues.
Google had problems when Oracle started a trial with them to use Java on Android. Because of this, Google has very actively adopted Kotlin, which appeared independently.
Java is proprietary. But there is an Oracle virtual machine, as well as an open Java virtual machine (open JVM), which is used in Linux and written in open source. Sometimes there are some incompatibilities, but in recent times these have been fewer.
By the way, Google could not completely abandon Java. In Dalvik, which is used as the core in Android, JVM is utilized. Perhaps they will change this one day, but it will be very difficult since the entire Android ecosystem is built on Java, specifically on an upgraded JVM. And at some point, this was also the cause of the conflict between Oracle and Google, because Oracle prohibits modernizing the JVM. This is the most important part of Java. However, the language itself can be used with no restrictions.
First of all, it should be noted that Java performance is much higher than on JS, and, accordingly, node.js.
If you run a simple task, like squaring, then in tests the indicators can differ up to 10 times. If you run loops in millions of calculating tasks, Java will almost always exceed node.js.
Plus, the huge difference between Java and node.js is that node is single-threaded, that may be considered its advantage, and its disadvantage on the other hand.
Java can work with threads that are supported at the OS level, and it turns out that a program written in Java makes the most of the OS features. And if you need to write a high-load application that will use a large number of calculations, then Java will definitely work better for this.
The problem is that even a small server written in Java will take up a lot of memory — both on disk and operational.
Node.js is lightweight due to its event-based architecture. It is built to work as a web server and copes very well with servicing lightweight tasks. For example, a simple query like calculating, or writing to a database happens very quickly. And if there are a lot of requests and we want to scale the system into a node, you can use the Nginx or Apache web server. You can have many identical node instances. Then everything will be distributed through load balancing on round-robin. If we run 8 node instances on 16 cores respectively, the OS itself will distribute the instances between the cores. Node does not control this, it will have one thread.
In Java, we can create an application and run 8 threads in it. Due to the fact that there is a closer interaction with the OS, you can distribute the load.
One of the well-known web servers written in Java is tomcat. There you can clearly see that when a user makes a request, additional threads are started. And when the request for a node arrives, the event loop will be processed and sent back, then the next request will appear. And, due to the fact that we are not waiting for the results of the first, it will also be picked up. If the requests are lightweight, all is great. However, when a heavy computation is performed, if there is even one instance, the node stops and a timeout occurs.
In node, you can write literally a few lines of code and get a simple web server. Naturally, for a wider functionality, where there will be notifications, authorizations, logging, etc. It is more difficult to implement, but there are frameworks that allow you to solve such issues.
Java has a developed API — concurrency api, which allows you to work with competitive streams. But at the same time, one of the problems as concurrency is that it is a pretty difficult thing which not every developer understands well enough to be able to implement.
Web, REST API is the node’s thing, and sometimes it is used for that. But if we are dealing with complex calculations, it’s still better to use Java.
I had an interesting project in Java — a distributed application, where the key task was the processing of large volumes of graphical information for further use in catalogs. When creating a catalog, it is necessary to prepare sets of a large number of images in various resolutions that will be used when creating the catalog. In short, this is an application to automate prepress catalog preparation.
Previously, photographers had to do everything manually. In the beginning, it was necessary to use some small application in order to upload all the images. Next, the specialist who created the catalog had to develop the catalog structure using another application. Then, in another application, they should create a workflow, which scattered the pictures into the structure that was created beforehand. In general, the process was quite difficult. ImageMagick which is available for Linux, Windows, and MacOS was used. We worked with Linux.
For example, a .tiff image with a size of 200–300 MB was loaded into the application; it was necessary to make pictures in various resolutions, cut something out, or make a background.
The first version of the application could not cope with a large load; even a server with a 16-core processor was not enough. We improved the architecture of the application to use several instances at the same time, in order not to radically change the operation of the application. Many instances started up and interacted with each other and each of them processed a piece of the task. It was difficult, but we managed to successfully implement everything in a couple of months. And the system is still working. The process had to deal with competitiveness and various aspects of interaction.
Something from this project could still be done in node, but some things would still have to be done in Java since there were a lot of different calculations. Basically, we could make parts in node that would call certain parts on Java and use its microservice architecture. We could use a mixed version. But this approach does not always work, because a developer specializing in node may not be a Java expert and vice versa. And finding multi-talented developers is much more difficult.
There was a project for organizing a large amount of data. Something similar to the project described above. But here we have an uploaded file that contains a large set of information that is subjected to validation through a third-party service (written in Java), several times and according to different rules. It was necessary to process hundreds of gigabytes of information, and node was not intended for this.
Designing the system architecture was especially interesting since the application consisted of several microservices, including third-party ones. When working with a third-party service that performed validation, we used RabbitMQ message broker. We gave the third-party server the necessary information and received a message from RabbitMQ at the end of validation, then the data was processed in sections to avoid an out of memory error.
If the application initially processed a file containing 10,000 entries, it can now process up to a million. We still managed to solve this problem with the help of node.js, although in Java it could have been solved more simply. The client insisted on using node.js since they needed a single infrastructure and architecture with microservices written in JS. Using node to solve the problem was much more difficult, and took more time, but node.js wins due to its scalability. That is why now we can increase the number of workers and process and more and more data. In Java, this would be more complicated.
In fact, any problem can be solved both ways, but as I’ve said before, if there are a lot of calculations, then it is better to use Java, if not then use node.
Now there’s a tendency that node.js will often be used as a “wrapper”, and the “stuffing” will be written in other languages. Its shortcomings are already well noted. For example, such a conditional flaw as single-threading has already been fixed. The latest version of node provides the ability to use multiple threads.
Java was originally created as a lightweight solution replacing C++ and now has become heavyweight. It’s like an evolution. Maybe someday there will be something that will replace node.js as well.
At the moment, according to the number of requests, and to my own feelings, node.js has already overtaken Java. JS is actively developing and it will continue to do so. But, at the moment, there is no potential competitor that could replace Java or node.js.
The problem is that lately Java is developing quite slowly, and node.js is developing at such a rate that it just cannot be replaced in the nearest future.
(Originally published here)