In the second half of the year, I changed my working environment and gained some new insights. On New Year's Eve, summarize what you've done over the past few months to improve program performance.

1. Asynchronous thread

When I first entered the industry, it was annoying to be tested in multiple threads during the interview. After all, it was rarely used at work at that time. But after working for a few years, I found that as long as you want to improve the performance of the program, you can't get around it. The most common scenario is to use multiple threads to execute multiple local events concurrently to shorten the overall completion time. In development, usually the entire project registers a bean of a thread pool, and each method uses the thread to execute business based on this thread pool, which is easy to do parameter tuning for the thread pool.

Asynchronous with return parameters, you can try CompletableFuture , which is also an artifact provided by jdk8, which is easier to use than the traditional Feature . For usage, please refer to CompletableFuture tutorial . For example, when the interface needs to fetch data from multiple external systems, it can be executed asynchronously, and then the return value is collected uniformly. Even take advantage of the features in CompletableFuture to automatically execute callback methods.

But note that async is not always used:

  • Machine CPU resources are limited: the number of cores of a single machine CPU is limited. When the number of concurrent threads of multiple threads reaches the peak, adding threads will be counterproductive. At this point, load balancing can be considered to distribute concurrent threads to multiple machines.
  • Faster synchronization: Some programs are originally executed quickly, but after adding asynchrony, they become slower. After all, it takes time to allocate thread resources. For example, there are only a dozen pieces of data in total, and parallelStream stream

2. Cache middleware

Redis

Redis is the most commonly used cache middleware. It supports a lot of common data structures, which should be selected according to the actual application scenario. I currently use String, Hash, Set, and List.

The raw data of course falls in the relational database, but what is commonly used in business is usually transformed intermediate data. For example, data such as departments, role permissions, and points of employees after logging in come from different microservices, and the interfaces of each service cannot be adjusted every time they are used. These need to be cached.

Using the cache is very mindless, but refreshing the cache is the problem. Like the example just now, all cached data cannot be placed at the granularity of employees, but should be stratified according to business. For example, for the data at the organization level, save one copy for each organization and check it according to the organization to which the employee belongs; for the data at the department level, save one copy for each department and check it according to the department to which the employee belongs. etc.

Elastic Search

Cache with ES? It is estimated that many people are a big question mark, who made Redis not support Json at that time. The data extracted from the relational database is sometimes complex, such as the department, role, position, etc. to which the person belongs. For each attribute down, there is a lot of data behind it. Some people say that Redis caches department IDs and role IDs, and the rest look up the table according to the ID. But these are basic data, not to mention whether the database will be found out. If you want to check personnel based on department attributes, role attributes, and position attributes, how should you write this SQL?

The best way is to extract these data from the relational database and cache them in the form of Json documents. MongoDB and ES can do this. However, in order to deal with the subsequent query scenarios that may be strange, it is still ES insurance.

But ES is not a professional caching middleware after all, I am very optimistic about the recently released RedisJson . It fully meets the needs of daily work, and it is said that the query performance is hundreds of times that of ES. But after all, I am afraid that there will be pits when I just came out. Let’s wait for a period of stability before starting.

3. Message middleware

I won't talk about other features of MQ here, let's talk about optimizing performance. As mentioned earlier, the CPU resources of a single machine are limited, and we can consider allocating concurrent threads to multiple machines. How to do it?

The tasks that need to be processed are delivered to MQ through messages, and the consumers actually execute them after listening to the messages of MQ. If there are 1000 tasks, and the maximum number of concurrent threads that a single machine can handle is 100, then 10 machines are enough.

4. Reduce system interaction

In-memory operations are the fastest, and the number of interactions with external systems should be minimized.

For example, when querying a batch of data, each piece of data needs to pass the foreign key to query other matching system information. If there are not many types of other system information, is it possible to get it all at once by checking the SQL or calling the interface once? Then write code to do data stitching. Instead of traversing every piece of data, go to the external system to check it again.

There are also some batches of data inserted into MySQL and Redis, or a batch of messages sent to MQ. If possible, they should be processed inside the program, and then the method of batch insertion and sending will be called, which will definitely save a lot of performance.

5. JVM Tuning

It's a commonplace! I have written the article before, and there is more information on the Internet, so I will not talk about it. Just to say one thing, try not to doubt that JVM tuning can improve the performance of your program, and reflect more on program design and code.

happy new year~


KerryWu
641 声望159 粉丝

保持饥饿