For a useful application, the user is likely to grow wildly over a period of time. As more and more critical applications run on Java EE, many Java developers are beginning to focus on scalability. But for now, most Web 2.0 sites are written based on the script language, and many people are skeptical about the scalability of Java applications. In this article, Wang Yu shows how to build scalable Java applications based on his own experience in the lab project, and provides readers with practices, theories, algorithms, frameworks, and experiences to build extensible Java applications based on some of the less-than-successful projects that have been done on scalability.
I've been working for an Internet-quality lab that uses our company's newest large server environment for free performance testing for our partner's products and solutions, and part of my job is to help them tune performance on powerful CMT and SMP servers.
Over the years, I've tested dozens of of Java applications for different solutions. Many of the products are designed to solve the same area problems, so the functionality of these products is basically similar, but the performance is very different in scalability, some of which can not be extended to the server on the CPU, but could be extended to 20 servers to do the cluster run, and some can only run in less than 2 CPU on the machine.
The reason for these differences is the architectural vision of the design of the product, and all the good extensibility Java applications are considered scalable from the requirements requirements phase, the system design phase, and the implementation phase, so the scalability of the Java application you write depends entirely on your vision.
Scalability, as one of the attributes of a system, is a difficult term to define and is often confused with performance. Of course, scalability and performance are related, and it's designed to achieve high performance. But the way to measure scalability and performance is different, and in this article we use the Wikipedia definition:
Scalability is one of the optional attributes of a system, network, or process that can be expressed in an elegant way to handle growing work, or to expand in a clear way. For example, it can be used to indicate that the system has the ability to increase throughput as resources, typically hardware, are increased.
Vertical expansion means adding resources to a single node in the system, typically, the CPU or memory is added to the machine, and the vertical extension provides more shared resources to the operating system and application modules, so it makes virtualization technology (which should mean running multiple virtual machines on a single machine) more efficient to run.
Horizontal scaling means adding more nodes to the system, such as adding new machines to a distributed software system, and a clearer example is adding a Web server to three. As computer prices continue to fall and performance improves, applications such as seismic analysis, bio-computing, which rely on supercomputers for high-performance computing, can now be implemented with this multiple Low-cost application. A cluster of hundreds of ordinary machines can achieve the computational power of a traditional RISC processor based scientific computer.
The first part of this article discusses the vertical expansion of Java applications.
How to get Java EE to apply a vertical extension
Many software designers and developers believe that functionality is the most important factor in the product, and performance and scalability are the additional features and functions that are done after the completion of the work. Most of them think they can use expensive hardware to reduce performance problems.
But sometimes they're wrong, last month, we had an urgent project in our lab where the partners offered products that were tested on their client's CPU machines for failing to meet performance requirements, so the partners wanted to test their products on more CPUs (8 CPUs), but the result was 8 The CPU's machine performance is worse than the 4 CPU machine.
Why is that? First of all, if your system is multithreaded or multi-threaded, and you have exhausted the CPU resources, then increasing the CPU in this case will usually allow the application to expand well.
Java-based applications can be very simple to use threads, the Java language can not only be used to support the writing of multi-threaded applications, while the JVM itself in the implementation of Java Application Management and memory management is also a multi-threaded way, As a rule, Java applications can run better on multiple CPUs, such as Bea WebLogic, IBM Websphere, open source GlassFish and Tomcat applications, running in Java Applications in the EE application Server can immediately benefit from CMT and SMP technology.
But in my lab, I found that a lot of products do not fully use the CPU, some applications on the 8 CPU server can only use less than 20% of the CPU, such as such applications even if the increase in the CPU is not much.
Jes (Hot Lock) is a key impediment to scalability
The most important tool for coordinating threads in a Java program is the Synchronized keyword. Because of the rules used in Java, including cache refreshes and expiration, synchronized blocks in the Java language are often more expensive than similar mechanisms provided by other platforms. Even if the program is just a single-threaded procedure running on a single processor, a synchronized method call is slower than an asynchronous method call.
To check whether the problem is the result of the Synchronized keyword, simply send a quit directive like the JVM process: The kill-3 PID method can also be used to get the thread stack information on Linux. If you see information similar to the following thread stack, it means that there is a hot lock problem with your system:
... ... ...
"Thread-0" prio=10 tid=0x08222eb0 nid=0x9 waiting for monitor entry [0xf927b000..0xf927bdb8]
at testthread.WaitThread.run(WaitThread.java:39)
- waiting to lock <0xef63bf08> (a java.lang.Object)
- locked <0xef63beb8> (a java.util.ArrayList)
at java.lang.Thread.run(Thread.java:595)
... ... ...