小易说IT 小易说IT

SpringBoot 完整配置模板

环境:SpringBoot 2.7.x/ 3.x,Java17;使用 application.yml + JavaConfig; 包含:自定义业务线程池、HikariCP、Redis、Sentinel 熔断限流; 配套依赖 maven,代码可直接复制使用,注意根据业务调整参数。

一、Maven 依赖 pom.xml

<!-- SpringBoot Web -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- HikariCP 数据库连接池(spring-boot-starter-jdbc自带) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
</dependency>

<!-- Redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

<!-- Sentinel 限流熔断 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>2022.0.0.0</version>
</dependency>

<!-- 注解异步 @Async -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

二、application.yml 配置

spring:
  # ========== HikariCP 数据库连接池 ==========
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/db_test?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    hikari:
      # 最小空闲连接
      minimum-idle: 5
      # 最大连接数,根据数据库能力设置,不要过大
      maximum-pool-size: 15
      # 空闲连接超时时间,毫秒
      idle-timeout: 300000
      # 连接最大生命周期,小于mysql wait_timeout
      max-lifetime: 1800000
      # 获取连接超时
      connection-timeout: 3000
      # 测试连接有效性sql
      connection-test-query: SELECT 1

  # ========== Redis 连接池配置 ==========
  redis:
    host: 127.0.0.1
    port: 6379
    password:
    database: 0
    timeout: 3000ms
    lettuce:
      pool:
        max-active: 16
        max-idle: 8
        min-idle: 4
        max-wait: 2000ms

# ========== Sentinel 限流熔断配置 ==========
spring.cloud.sentinel:
  # sentinel控制台地址
  transport:
    dashboard: 127.0.0.1:8080
    # 客户端端口,默认8719,占用则自动+1
    port: 8719
  # 开启Sentinel注解支持
  web-context-unify: false
  # 规则持久化到nacos,这里先注释;测试可内存模式
  # datasource:
  #   flow:
  #     nacos:
  #       server-addr: 127.0.0.1:8848
  #       dataId: sentinel-flow-rules
  #       groupId: DEFAULT_GROUP
  #       rule-type: flow

# 自定义业务线程池配置(放到yml,方便外部调整参数)
biz:
  thread-pool:
    core-size: 8
    max-size: 20
    queue-capacity: 200
    keep-alive-seconds: 60
    thread-name-prefix: biz-async-

三、Java Config 配置类

1. 自定义业务线程池 ThreadPoolConfig.java

推荐业务单独线程池,和 Tomcat 线程隔离,禁止使用 Executors 创建; 用于 @Async("bizThreadPool") 异步执行非主链路任务。

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

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

@Configuration
@EnableAsync
public class ThreadPoolConfig {

    @Value("${biz.thread-pool.core-size}")
    private Integer coreSize;

    @Value("${biz.thread-pool.max-size}")
    private Integer maxSize;

    @Value("${biz.thread-pool.queue-capacity}")
    private Integer queueCapacity;

    @Value("${biz.thread-pool.keep-alive-seconds}")
    private Integer keepAliveSeconds;

    @Value("${biz.thread-pool.thread-name-prefix}")
    private String threadNamePrefix;

    @Bean("bizThreadPool")
    public Executor bizThreadPool() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心线程数
        executor.setCorePoolSize(coreSize);
        // 最大线程数
        executor.setMaxPoolSize(maxSize);
        // 队列容量
        executor.setQueueCapacity(queueCapacity);
        // 线程空闲时间
        executor.setKeepAliveSeconds(keepAliveSeconds);
        // 线程名称前缀,方便日志排查
        executor.setThreadNamePrefix(threadNamePrefix);
        // 拒绝策略:调用者执行,不丢弃任务
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 等待所有任务完成再关闭线程池
        executor.setWaitForTasksToCompleteOnShutdown(true);
        // 等待关闭超时时间
        executor.setAwaitTerminationSeconds(30);
        executor.initialize();
        return executor;
    }
}

使用示例:

@Async("bizThreadPool")
public void asyncSendLog(String content) {
    // 非核心链路,异步执行
}

2. RedisTemplate 配置 RedisConfig.java

使用 String 序列化,避免默认 JDK 序列化带来的二进制乱码,减少存储空间; 可按需替换为 Protobuf 序列化。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);

        StringRedisSerializer stringSerializer = new StringRedisSerializer();
        // key 序列化
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setHashKeySerializer(stringSerializer);
        // value 序列化
        redisTemplate.setValueSerializer(stringSerializer);
        redisTemplate.setHashValueSerializer(stringSerializer);

        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

3. Sentinel 全局异常处理器 SentinelExceptionHandler.java

捕获 Sentinel 限流、熔断异常,返回统一 JSON 响应; 配合注解 @SentinelResource 使用。

import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

@Component
public class SentinelExceptionHandler implements BlockExceptionHandler {

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
        response.setContentType("application/json;charset=utf-8");
        response.setStatus(HttpServletResponse.SC_OK);
        Map<String, Object> result = new HashMap<>();
        if (e instanceof FlowException) {
            result.put("code", 429);
            result.put("msg", "请求过于频繁,请稍后重试");
        } else if (e instanceof DegradeException) {
            result.put("code", 503);
            result.put("msg", "服务暂时不可用,已熔断");
        } else {
            result.put("code", 500);
            result.put("msg", "服务访问受限");
        }
        PrintWriter writer = response.getWriter();
        writer.write(objectMapper.writeValueAsString(result));
        writer.flush();
        writer.close();
    }
}

Sentinel 注解使用示例

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

    @GetMapping("/api/test")
    @SentinelResource(value = "api_test", blockHandler = "blockHandler", fallback = "fallback")
    public String test() {
        return "success";
    }

    // 限流/熔断触发
    public String blockHandler(BlockException e) {
        return "block";
    }

    // 业务异常降级
    public String fallback() {
        return "fallback";
    }
}

四、参数调优建议(重点)

✅ HikariCP

  1. maximum-pool-size:不要超过数据库实例最大连接数,单库一般 10~30;

  2. connection-timeout:3000ms,超过直接放弃获取连接,防止大量线程卡在获取连接;

  3. max-lifetime 必须小于 mysql wait_timeout(默认 28800 秒)。

✅ Redis Lettuce

  • lettuce 是线程安全,不需要像 jedis 每个线程拿连接;max-active 不要设置过大。

✅ 业务线程池

IO 密集场景:核心线程数 ≈ CPU 核心数 * 2 拒绝策略:CallerRunsPolicy 适合允许延迟;高吞吐可考虑 DiscardPolicy(丢弃),业务自己评估。 不要把 Tomcat 线程池和业务线程池混在一起!

✅ Sentinel 规则建议(控制台配置)

  1. 流控:QPS 限流,单机阈值;

  2. 熔断:慢调用比例 / 异常比例,熔断时长 5~10s;

  3. 热点参数限流:针对高热度 id(商品 id、用户 id);

  4. 规则生产环境建议持久化到 Nacos/Apollo,重启不丢失。

五、补充:可选增强

  1. Caffeine 本地缓存配置类(多级缓存)

  2. Feign 连接池 + 超时配置

  3. 线程池监控(Micrometer/Prometheus 暴露线程池指标)

  4. Arthas 监控埋点


本文原创作者:易君召,详见:https://www.yijunzhao.cc/about,转载请注明出处。

原文链接 https://www.yijunzhao.cc/archives/springboot-complete-configuration-template

欢迎访问 https://www.yijunzhao.cc/

https://www.yijunzhao.cc/