# boot **Repository Path**: webthree/boot ## Basic Information - **Project Name**: boot - **Description**: springboot演示项目 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-07-18 - **Last Updated**: 2026-07-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # boot > spring boot2 演示程序 ## 手册 - [spring-boot](https://springdoc.cn/spring-boot/) - [apolloconfig](https://www.apolloconfig.com/#/zh/README) - [版本对应关系](https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E) ## 开发知识 ### SpringBoot启动原理 > - spring-boot-maven-plugin -> spring-boot-loader-tools > - spring-boot-loader模块让你的springboot应用具备打包为可执行jar或war文件的能力 > - 在jar文件中,我们必须要将mainclass的入口的那个类放于jar包的根目录中,否则无法启动该jar文件 > - jar文件中不能够在套嵌jar文件 ```text 为什么不直接将BootApplication.class放于根目录中呢? 这样做理论上是可以的,但是随之面临的就是第三方jar包也要全部解压出来放置于该应用jar包的根目录, 因为jar规范中是不允许再含有jar包的。那么有人就会说那就全拿出来放在根目录中呗? 那这样就会出现包名重复的问题。所以我们需要一个启动类来帮我们实现,那就是spring-boot-loader ``` ## 配置说明 ### spring-boot-starter-web #### 自动配置 - 1)spring.factories ```text EnableAutoConfiguration:用于注册自动配置类。Spring Boot会根据这些类自动配置应用程序 EnvironmentPostProcessor:用于在Spring Boot应用启动前对环境进行修改。这些处理器可以通过spring.factories文件进行配置 ApplicationListener:用于监听Spring Boot应用的生命周期事件,如启动、关闭等。这些监听器也可以通过spring.factories文件进行配置 ApplicationContextInitializer:用于在应用上下文初始化时执行特定的操作 AutoConfigurationImportListener:用于监听自动配置导入事件 AutoConfigurationImportFilter:用于过滤自动配置类 ``` #### 创建Spring应用 ###### 方式一 ```java public class BootApplication { public static void main(String[] args) { new SpringApplicationBuilder(BootApplication.class).run(args); SpringApplication.run(BootApplication.class, args); } } ``` ###### 方式二 ```java public class BootApplication { public static void main(String[] args) { SpringApplication application = new SpringApplication(BootApplication.class); application.run(args); } } ``` #### 创建监听器 ###### 配置方式 - application.properties ```properties context.listener.classes=xyz.lisys.hook.MyApplicationListener ``` ###### 编程方式 ```java public class BootApplication { public static void main(String[] args) { SpringApplication application = new SpringApplication(BootApplication.class); application.addListeners(); application.run(args); } } ``` #### 启用servlet注解并进行扫描 - 1)配置BootApplication.java ```java @ServletComponentScan public class BootApplication { } ``` #### 启用熔断器并配置openFeign - 1)配置BootApplication.java ```java @EnableHystrix @EnableFeignClients(basePackages = {"xyz.lisys.boot.client"}) public class BootApplication { } ``` ### spring-boot-starter-actuator #### 端点列表 - 获取所有可配置项(@ConfigurationProperties) - /actuator/configprops - 获取所有环境属性 - /actuator/env - 获取所有Spring Bean信息 - /actuator/beans - 获取自动配置条件评估报告(匹配/不匹配原因) - /actuator/conditions - 获取应用健康状态 - /actuator/health - 获取应用自定义信息 - /actuator/info - 获取所有请求映射路径(@RequestMapping) - /actuator/mappings - 获取或动态修改日志级别 - /actuator/loggers - 获取应用度量指标(内存、CPU、HTTP请求量等) - /actuator/metrics - 获取线程转储 - /actuator/threaddump - 获取堆转储文件(hprof格式) - /actuator/heapdump - 获取缓存信息 - /actuator/caches - 获取定时任务信息 - /actuator/scheduledtasks - 获取审计事件 - /actuator/auditevents - 获取HTTP请求-响应交换记录(最近100条) - /actuator/httpexchanges - 获取日志文件内容(需配置logging.file或logging.path) - /actuator/logfile - 获取Flyway数据库迁移信息 - /actuator/flyway - 获取Liquibase数据库迁移信息 - /actuator/liquibase - 获取Quartz调度器作业信息 - /actuator/quartz - 获取Spring Session会话信息(支持删除) - /actuator/sessions - 获取Spring Integration图信息 - /actuator/integrationgraph - 以Prometheus格式暴露指标(供抓取) - /actuator/prometheus - 通过HTTP公开JMX Beans(需依赖Jolokia) - /actuator/jolokia - 优雅关闭应用(默认禁用,需手动启用) - /actuator/shutdown #### 获取所有自动配置类 - 通过编程方式 ```java @RestController public class AutoConfigController { @Autowired private ConditionEvaluationReport report; @GetMapping("/auto-config-report") public Map> getAutoConfigReport() { // 获取所有自动配置类的评估结果 return report.getConditionAndOutcomesBySource(); } } ``` ### dynamic-datasource-spring-boot-starter > 动态配置数据源 ### sharding-jdbc-spring-boot-starter > 读写分离、分库分表 ### spring-kafka #### Spring-Kafka 完整防数据库压崩落地方案 ##### 一、基础消费者核心参数配置(先从配置层面控并发、单次拉取量) ```yaml spring: kafka: bootstrap-servers: 192.168.1.10:9092 consumer: group-id: custom-group auto-offset-reset: earliest enable-auto-commit: false max-poll-records: 500 heartbeat-interval: 3000 fetch-max-wait: 1000 fetch-min-size: 1048576 key-deserializer: org.apache.kafka.common.serialization.StringDeserializer value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer properties: session.timeout.ms: 30000 max.poll.interval.ms: 180000 listener: type: batch ack-mode: manual concurrency: 3 ``` ##### 二、批量消费 + 批量 JDBC 入库(最核心优化) 单条消息一条 SQL 是压垮数据库头号原因,批量拉取消息 + MyBatis/JDBC 批量插入,大幅降低数据库请求频次。 ##### 三、控制并发消费线程数,防止并发打爆数据库连接池 ```java @Bean public ConcurrentKafkaListenerContainerFactory batchFactory(ConsumerFactory consumerFactory) { ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); factory.setConsumerFactory(consumerFactory); // 开启批量消费 factory.setBatchListener(true); // 设置并发消费线程,严格根据DB承载能力调整 factory.setConcurrency(6); // 手动ack factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL); return factory; } ``` ##### 四、本地限流 + 分布式限流,控制写入 QPS - 单机本地限流(Guava RateLimiter) ```text // 每秒允许处理300条消息,根据DB承载能力调整 private static final RateLimiter rateLimiter = RateLimiter.create(300.0); // 在消费逻辑开头判断 if (!rateLimiter.tryAcquire(records.count())) { // 超出限速,直接丢进死信,不入库 sendToDlq(records); ack.acknowledge(); return; } ``` - 分布式限流(多实例集群场景) 单机限流不够,多实例叠加依然压库,使用 Redis 令牌桶实现全局总 QPS 管控: 所有消费实例共用同一个 Redis 令牌池,总写入速率固定,超出令牌直接跳过入库。 ##### 五、死信队列 DLQ 解决异常消息无限重试刷库 如果一条脏数据触发 SQL 报错,不提交 offset 会导致这条消息被无限重复消费,疯狂循环调用 DB,最终打崩数据库。 Spring-Kafka 内置DeadLetterPublishingRecoverer快速实现 DLQ: 消费异常消息自动转发到 topic-dlq 原消息 offset 提交,停止重复消费 后台单独消费 DLQ,人工修复数据后重放 ```java @Bean public KafkaTemplate kafkaTemplate(KafkaProducerFactory factory) { return new KafkaTemplate<>(factory); } @Bean public ConcurrentKafkaListenerContainerFactory batchFactory(ConsumerFactory consumerFactory, KafkaTemplate kafkaTemplate) { ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); factory.setConsumerFactory(consumerFactory); factory.setBatchListener(true); factory.setConcurrency(6); factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL); // 死信处理器 DeadLetterPublishingRecoverer recoverer = new DeadLetterPublishingRecoverer(kafkaTemplate, (record, ex) -> new TopicPartition(record.topic() + "-dlq", record.partition())); // 异常重试策略:重试2次后直接进DLQ,不再无限重试 RetryTemplate retryTemplate = new RetryTemplate(); SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(); retryPolicy.setMaxAttempts(2); retryTemplate.setRetryPolicy(retryPolicy); factory.setRetryTemplate(retryTemplate); factory.setRecoveryCallback(context -> recoverer.accept((ConsumerRecord) context.getAttribute(RetryContextAccessor.RECORD), context.getLastThrowable())); return factory; } ``` ##### 六、数据库异常背压机制:DB 卡顿 / 宕机时主动暂停消费 当捕获数据库异常(连接耗尽、SQL 超时、数据库不可用),不提交 offset,同时暂停 poll 拉取消息,让流量堆积在 Kafka,等数据库恢复再继续消费 ##### 七、Sentinel/Hystrix 熔断兜底 ##### 八、数据库侧配套防护(配合 Kafka 消费) ## Issue - swagger2无法启动? > 因Springfox 使用的路径匹配是基于AntPathMatcher的,而Spring Boot 2.6.X使用的是PathPatternMatcher - bootstrap.yml无法加载启动? > SpringBoot 2.4.x的版本之后(我们合起来成为Bootstrap配置文件)的支持,需要导入如下的依赖 ```xml org.springframework.cloud spring-cloud-starter-bootstrap ``` - Apollo为什么会加载application? ```text 1、spring-boot配置文件中指定namespaces的同时增加了@EnableApolloConfig会造成这样的问题 2、如果@EnableApolloConfig加上注解后会默认加载application配置项 ``` - spring boot 自动配置? > 自动加载 META-INF/spring.factories 配置类 ```text 1、@ConfigurationProperties("") 用于注册指定配置属性 2、@Import() 通过快速导入的方式实现把实例加入spring的IOC容器中 - 1)、直接填class数组方式 - 2)、ImportSelector方式 - 3)、ImportBeanDefinitionRegistrar方式 ``` - zuul 最高支持spring boot版本? ```text 由于最新的 spring-boot 2.5.5 版本,从 ErrorController 中删除了 getErrorPath() API, 但spring-cloud-starter-netflix-zuul 2.2.7.RELEASE 仍然调用此 API 并导致此错误, 对于zuul来说spring-boot最高版本为2.3.4.RELEASE ``` - Hystrix 配置场景 ```text 你的熔断需求是什么? │ ├─ 对 Service/Controller 中任意方法做熔断 │ └─ 使用 @EnableHystrix + @HystrixCommand │ └─ 配置写在 application.yml 的 hystrix.* 下 │ └─ 对 Feign 远程调用做熔断 └─ 使用 feign.circuitbreaker.enabled=true + @EnableFeignClients └─ 配置写在 Java Customizer 中,基于 CircuitBreakerFactory 调用 └─ ⚠️ 切记:手动设置超时,覆盖默认 1000ms ```