How do I increase the concurrency of spring boot projects by ten times

Keywords: Java Spring Tomcat SpringBoot

Yun Qi Hao: https://yqh.aliyun.com
The first-hand cloud information, the selected cloud enterprise case base of different industries, and the best practices extracted from many successful cases help you to make cloud decision!

background

Occasionally, there are some slow requests in the production environment, resulting in system performance degradation and throughput degradation. Here are some optimization suggestions.

programme

1. Under to replace tomcat

Most e-commerce websites are short requests, and the response time is generally 100ms. At this time, you can replace the web container from tomcat to underow. The following steps are introduced: 1. Add pom configuration

<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-web</artifactid>
    <exclusions>
       <exclusion>
          <groupid>org.springframework.boot</groupid>
          <artifactid>spring-boot-starter-tomcat</artifactid>
       </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-undertow</artifactid>
</dependency>

2. Add related configuration

server:
  undertow:
    direct-buffers: true
    io-threads: 4
    worker-threads: 160

Restart. You can see that the container has been switched to "below" in the console

2, cache

Put some hot data or static data into the local cache or redis, and update the cache data regularly if necessary

3, asynchronous

In the code process, many of our codes do not need to wait for the return result, that is to say, part of the code can be executed in parallel. At this time, Async can be used. The simplest solution is to use @ Async annotation provided by springboot, which can also be realized through thread pool. The following is a brief introduction of asynchronous steps. 1. pom dependency general springboot introduces web dependency

<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-web</artifactid>
</dependency>

2. Add @ EnableAsync annotation to startup class

@EnableAsync
@SpringBootApplication
public class AppApplication
{
    public static void main(String[] args)
    {
        SpringApplication.run(AppApplication.class, args);
    }
}

3. Add @ Async annotation in the specified method if necessary. If you need to wait for the return value, the demo is as follows

@Async
public Future<string> doReturn(int i){
    try {
        // This method takes 500 milliseconds to call
         Thread.sleep(500);
     } catch (InterruptedException e) {
       e.printStackTrace();
    }
    / Message aggregation
    return new AsyncResult&lt;&gt;("Asynchronous call");
}

4. If there is thread variable or mdc in logback, you can increase the delivery

import org.slf4j.MDC;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskDecorator;
import org.springframework.scheduling.annotation.AsyncConfigurerSupport;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.Map;
import java.util.concurrent.Executor;

/**
 * @Description:
 */
@EnableAsync
@Configuration
public class AsyncConfig extends AsyncConfigurerSupport {
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setTaskDecorator(new MdcTaskDecorator());
        executor.initialize();
        return executor;
    }
}

class MdcTaskDecorator implements TaskDecorator {

    @Override
    public Runnable decorate(Runnable runnable) {
        Map<string, string> contextMap = MDC.getCopyOfContextMap();
        return () -&gt; {
            try {
                MDC.setContextMap(contextMap);
                runnable.run();
            } finally {
                MDC.clear();
            }
        };
    }
}

5. Sometimes asynchrony needs to increase blocking

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@Configuration
@Slf4j
public class TaskExecutorConfig {

    @Bean("localDbThreadPoolTaskExecutor")
    public Executor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(5);
        taskExecutor.setMaxPoolSize(200);
        taskExecutor.setQueueCapacity(200);
        taskExecutor.setKeepAliveSeconds(100);
        taskExecutor.setThreadNamePrefix("LocalDbTaskThreadPool");
        taskExecutor.setRejectedExecutionHandler((Runnable r, ThreadPoolExecutor executor) -&gt; {
                    if (!executor.isShutdown()) {
                        try {
                            Thread.sleep(300);
                            executor.getQueue().put(r);
                        } catch (InterruptedException e) {
                            log.error(e.toString(), e);
                            Thread.currentThread().interrupt();
                        }
                    }
                }
        );
        taskExecutor.initialize();
        return taskExecutor;
    }


}

4, Business split

You can split the time-consuming or different businesses to provide the throughput of a single node

5. Integrated message queuing

There are many scenarios where the requirements for real-time data are not so strong, or messages can be sent to kafka for business fault-tolerant processing, and then consumption is delayed. For example, you can query the specified user to send push messages according to the criteria. Here, you can send push messages on time, by day, by month, and so on

Yun Qi Hao: https://yqh.aliyun.com
The first-hand cloud information, the selected cloud enterprise case base of different industries, and the best practices extracted from many successful cases help you to make cloud decision!

Original release time: February 19, 2020
By Lipeng Heke
This article comes from:“ Internet architect official account ”, you can pay attention to“ Internet architect"

Posted by tomhoad on Thu, 20 Feb 2020 03:13:33 -0800