How can spring boot applications improve service throughput?

Time:2021-4-14

I don’t know which comes first, accident or tomorrow. No crisis is the biggest crisis, to meet the status quo is the biggest trap.

background

Occasionally, there will be some slow requests in the production environment, which will lead to system performance degradation and throughput degradation. Here are several optimization suggestions.

programme

1. Undertow replaces Tomcat

Most e-commerce websites are short requests, and the response time is generally 100 ms. at this time, you can replace the web container from Tomcat to undertow. 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 relevant configuration

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

Restart to see that the container has been switched to undertow 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, we don’t need to wait for the return result, that is, part of the code can be executed in parallel. At this time, asynchrony can be used. The simplest solution is to use the @ async annotation provided by springboot. Of course, it can also be implemented through the thread pool. Here’s a brief introduction to the asynchronous steps. 1. POM relies on general spring boot. Just introduce web related dependencies

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

2. Add @ enableasync annotation to the startup class

import org.springframework.boot.SpringApplication

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

3. If necessary, add @ async annotation to the specified method. 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 summary
    Return new asyncresult < string > ("asynchronous call");
}

4. If you have thread variables 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

Time consuming or different services can be split to provide single node throughput

5. Integrated message queuing

There are many scenarios that require less real-time data, or can send messages to Kafka when processing business fault tolerance, and then delay consumption. For example, according to the condition query, the specified user can send push messages. Here, you can query by time, by day, by month, and so on
How can spring boot applications improve service throughput?

Recommended Today

Review of SQL Sever basic command

catalogue preface Installation of virtual machine Commands and operations Basic command syntax Case sensitive SQL keyword and function name Column and Index Names alias Too long to see? Space Database connection Connection of SSMS Connection of command line Database operation establish delete constraint integrity constraint Common constraints NOT NULL UNIQUE PRIMARY KEY FOREIGN KEY DEFAULT […]