首页 文章 精选 留言 我的

精选列表

搜索[SpringBoot],共4560篇文章
优秀的个人博客,低调大师

你所遗漏的SpringBoot日志管理知识

Spring Boot对所有内部日志记录使用了Commons Logging,但是底层日志实现是开放的。可以为 Java Util日志、Log4J2和Logback。对于每种日志都预先配置为使用控制台输出和可选的文件输出。默认为Logback 日志配置 通过将相应的库添加到classpath可以激活各种日志系统,然后在classpath根目录下提供合适的配置文件可以进一步定制日志系统,配置文件也可以通过Spring Environment的logging.config属性指定。 以下文件会根据你选择的日志系统进行加载: 日志系统 定制配置 Logback logback-spring.xml,logback-spring.groovy,logback.xml或logback.groovy Log4j log4j.properties或log4j.xml Log4j2 log4j2-spring.xml或log4j2.xml JDK (Java Util Logging) logging.properties 注 如果可能的话,建议你使用-spring变种形式定义日志配置(例如,使用logback-spring.xml而不是logback.xml)。如果你使用标准的配置路径,Spring可能不能够完全控制日志初始化。 注 Java Util Logging从可执行jar运行时会导致一些已知的类加载问题,我们建议尽可能不使用它。 以下是从SpringEnvrionment转换为System properties的一些有助于定制的配置属性: Spring Environment System Property Comments logging.exception-conversion-word LOG_EXCEPTION_CONVERSION_WORD 记录异常使用的关键字 logging.file LOG_FILE 如果指定就会在默认的日志配置中使用 logging.path LOG_PATH 如果指定就会在默认的日志配置中使用 logging.pattern.console CONSOLE_LOG_PATTERN 日志输出到控制台(stdout)时使用的模式(只支持默认的logback设置) logging.pattern.file FILE_LOG_PATTERN 日志输出到文件时使用的模式(如果LOG_FILE启用,只支持默认的logback设置) logging.pattern.level LOG_LEVEL_PATTERN 用来渲染日志级别的格式(默认%5p,只支持默认的logback设置) PID PID 当前的处理进程(process)ID(能够找到,且还没有用作OS环境变量) 所有支持的日志系统在解析配置文件时都能获取系统属性的值,具体可以参考spring-boot.jar中的默认配置。 log4j2配置 一份史诗级配置 /home/logs/log/dev \ \ \ \ </Appenders> <Loggers> <Root level="debug"> <AppenderRef ref="Console"/> <AppenderRef ref="debug"/> <AppenderRef ref="info"/> <AppenderRef ref="warn"/> <AppenderRef ref="error"/> </Root> </Loggers> 各个文件输出到不同级别的目录 设置最大保存时间为15天 每个文件最大50M tomcat的日志 在properties文件添加如下配置: server.tomcat.basedir=/home/logs/log-api/tomcat-logs server.tomcat.accesslog.enabled=true server.tomcat.accesslog.pattern=%t %a "%r" %s %D (%D ms) server.use-forward-headers=true lombok的神组合 使用lombok的@Slf4j注解,省去配置声明log的繁琐,提高开发效率。 idea的 grep console组合 Grep Console 自定义设置控制台输出颜色,这样控制台就能比较明显的看到警告或者错误的信息,方便查找问题 本文来自云栖社区合作伙伴“开源中国” 本文作者:melon_jj 原文链接

优秀的个人博客,低调大师

SpringBoot项目在IntelliJ IDEA中实现热部署

spring-boot-devtools是一个为开发者服务的一个模块,其中最重要的功能就是自动应用代码更改到最新的App上面去。 原理是在发现代码有更改之后,重新启动应用,但是速度比手动停止后再启动更快。 其深层原理是使用了两个ClassLoader,一个Classloader加载那些不会改变的类(第三方Jar包),另一个ClassLoader加载会更改的类,称为restart ClassLoader ,这样在有代码更改的时候,原来的restart ClassLoader被丢弃,重新创建一个restart ClassLoader,由于需要加载的类相比较少,所以实现了较快的重启时间。 即devtools会监听classpath下的文件变动,并且会立即重启应用(发生在保存时机) 一、开启idea自动make功能 1、CTRL + SHIFT + A --> 查找make project automatically --> 选中 2、CTRL + SHIFT + A --> 查找Registry --> 找到并勾选compiler.automake.allow.when.app.running 最后重启idea 二、使用spring-boot-1.3开始有的热部署功能 1、加maven依赖 org.springframework.boot spring-boot-devtools true 2、开启热部署 org.springframework.boot spring-boot-maven-plugin true//该配置必须 三、Chrome禁用缓存 F12(或Ctrl+Shift+J或Ctrl+Shift+I)--> NetWork --> Disable Cache(while DevTools is open) 至此,在idea中就可以愉快的修改代码了,修改后可以及时看到效果,无须手动重启和清除浏览器缓存。 测试方法: 修改类-->保存:应用会重启 修改配置文件-->保存:应用会重启 修改页面-->保存:应用会重启,页面会刷新(原理是将spring.thymeleaf.cache设为false) 不能使用分析: 对应的spring-boot版本是否正确,我这里使用的是1.5.3.RELEASE版本; 是否加入plugin了,以及属性true Intellij IDEA是否开启了Make Project Automatically。 如果设置SpringApplication.setRegisterShutdownHook(false),则自动重启将不起作用。 欢迎工作一到五年的Java程序员朋友们加入Java架构开发:744677563 本群提供免费的学习指导 架构资料 以及免费的解答 不懂得问题都可以在本群提出来 之后还会有职业生涯规划以及面试指导

优秀的个人博客,低调大师

SpringBoot 项目优雅实现读写分离 | 京东云技术团队

一、读写分离介绍 当使用Spring Boot开发数据库应用时,读写分离是一种常见的优化策略。读写分离将读操作和写操作分别分配给不同的数据库实例,以提高系统的吞吐量和性能。 读写分离实现主要是通过动态数据源功能实现的,动态数据源是一种通过在运行时动态切换数据库连接的机制。它允许应用程序根据不同的条件或配置选择不同的数据源,以实现更灵活和可扩展的数据库访问。 二、实现读写分离-基础 1. 配置主数据库和从数据库的连接信息 # 主库配置 spring.datasource.master.jdbc-url=jdbc:mysql://ip:port/master?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false spring.datasource.master.username=master spring.datasource.master.password=123456 spring.datasource.master.driver-class-name=com.mysql.jdbc.Driver # 从库配置 spring.datasource.slave.jdbc-url=jdbc:mysql://ip:port/slave?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false spring.datasource.slave.username=slave spring.datasource.slave.password=123456 spring.datasource.slave.driver-class-name=com.mysql.jdbc.Driver 2. 创建主数据库和从数据库的数据源配置类 通过不同的条件限制和配置文件前缀可以完成不同数据源的创建工作,不止是主从也可以是多个不同的数据库 主库数据源配置 @Configuration @ConditionalOnProperty("spring.datasource.master.jdbc-url") public class MasterDataSourceConfiguration { @Bean("masterDataSource") @ConfigurationProperties(prefix = "spring.datasource.master") public DataSource masterDataSource() { return DataSourceBuilder.create().build(); } } 从库数据源配置 @Configuration @ConditionalOnProperty("spring.datasource.slave.jdbc-url") public class SlaveDataSourceConfiguration { @Bean("slaveDataSource") @ConfigurationProperties(prefix = "spring.datasource.slave") public DataSource slaveDataSource() { return DataSourceBuilder.create().build(); } } 3. 创建主从数据源枚举 public enum DataSourceTypeEnum { /** * 主库 */ MASTER, /** * 从库 */ SLAVE, ; } 4. 创建动态路由数据源 这儿做了一个开关,可以控制读写分离的开启和关闭工作,可以讲操作全部切换到主库进行。然后根据上下文中的数据源类型来返回不同的数据源类型枚举 @Slf4j public class DynamicRoutingDataSource extends AbstractRoutingDataSource { @Value("${DB_RW_SEPARATE_SWITCH:false}") private boolean dbRwSeparateSwitch; @Override protected Object determineCurrentLookupKey() { if(dbRwSeparateSwitch && DataSourceTypeEnum.SLAVE.equals(DataSourceContextHolder.getDataSourceType())) { log.info("DynamicRoutingDataSource 切换数据源到从库"); return DataSourceTypeEnum.SLAVE; } log.info("DynamicRoutingDataSource 切换数据源到主库"); // 根据需要指定当前使用的数据源,这里可以使用ThreadLocal或其他方式来决定使用主库还是从库 return DataSourceTypeEnum.MASTER; } } 5. 创建动态数据源配置类 将主数据库和从数据库的数据源添加到动态数据源中,并可以通过枚举创建一个数据源 map,这样就可以通过上面的路由返回的枚举来切换数据源 @Configuration @ConditionalOnProperty("spring.datasource.master.jdbc-url") public class DynamicDataSourceConfiguration { @Bean("dataSource") @Primary public DataSource dynamicDataSource(DataSource masterDataSource, DataSource slaveDataSource) { Map<Object, Object> targetDataSources = new HashMap<>(); targetDataSources.put(DataSourceTypeEnum.MASTER, masterDataSource); targetDataSources.put(DataSourceTypeEnum.SLAVE, slaveDataSource); DynamicRoutingDataSource dynamicDataSource = new DynamicRoutingDataSource(); dynamicDataSource.setTargetDataSources(targetDataSources); dynamicDataSource.setDefaultTargetDataSource(masterDataSource); return dynamicDataSource; } } 6. 创建DatasourceContextHolder类使用ThreadLocal存储当前线程的数据源类型 注意这儿有个潜在风险就是创建新的线程时会导致 ThreadLocal 中的数据无法正确读取,如果涉及到在开启新线程可以使用 TransmittableThreadLocal 来进行父子线程数据的同步,git 地址: https://github.com/alibaba/transmittable-thread-local public class DataSourceContextHolder { private static final ThreadLocal<DataSourceTypeEnum> contextHolder = new ThreadLocal<>(); public static void setDataSourceType(DataSourceTypeEnum dataSourceType) { contextHolder.set(dataSourceType); } public static DataSourceTypeEnum getDataSourceType() { return contextHolder.get(); } public static void clearDataSourceType() { contextHolder.remove(); } } 7. 创建自定义注解,用于标记主和从数据源 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MasterDataSource { } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface SlaveDataSource { } 8. 创建切面类,拦截数据库操作,并根据注解设置切换数据源参数 @Aspect @Component public class DataSourceAspect { @Before("@annotation(xxx.MasterDataSource)") public void setMasterDataSource(JoinPoint joinPoint) { DataSourceContextHolder.setDataSourceType(DataSourceTypeEnum.MASTER); } @Before("@annotation(xxx.SlaveDataSource)") public void setSlaveDataSource(JoinPoint joinPoint) { DataSourceContextHolder.setDataSourceType(DataSourceTypeEnum.SLAVE); } @After("@annotation(xxx.MasterDataSource) || @annotation(xxx.SlaveDataSource)") public void clearDataSource(JoinPoint joinPoint) { DataSourceContextHolder.clearDataSourceType(); } } 9. 在Service层的方法上使用自定义注解标记查询数据源 @Service public class TestService { @Autowired private TestDao testDao; @SlaveDataSource public Test test() { return testDao.queryByPrimaryKey(11L); } } 10. 排除掉数据源自动配置类 如果不排除自动配置类会导致初始化多个 dataSource 对象导致出现问题 SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) 三、实现读写分离-进阶 1. 使用链接池,以Hikari为例 修改链接配置,加入链接池相关配置即可 # 主库配置 spring.datasource.master.jdbc-url=jdbc:mysql://ip:port/master?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false spring.datasource.master.username=master spring.datasource.master.password=123456 spring.datasource.master.driver-class-name=com.mysql.jdbc.Driver spring.datasource.master.type=com.zaxxer.hikari.HikariDataSource spring.datasource.master.hikari.name=master spring.datasource.master.hikari.minimum-idle=5 spring.datasource.master.hikari.idle-timeout=30 spring.datasource.master.hikari.maximum-pool-size=10 spring.datasource.master.hikari.auto-commit=true spring.datasource.master.hikari.pool-name=DatebookHikariCP spring.datasource.master.hikari.max-lifetime=1800000 spring.datasource.master.hikari.connection-timeout=30000 spring.datasource.master.hikari.connection-test-query=SELECT 1 # 从库配置 spring.datasource.slave.jdbc-url=jdbc:mysql://ip:port/slave?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false spring.datasource.slave.username=root spring.datasource.slave.password=123456 spring.datasource.slave.driver-class-name=com.mysql.jdbc.Driver spring.datasource.slave.type=com.zaxxer.hikari.HikariDataSource spring.datasource.slave.hikari.name=master spring.datasource.slave.hikari.minimum-idle=5 spring.datasource.slave.hikari.idle-timeout=30 spring.datasource.slave.hikari.maximum-pool-size=10 spring.datasource.slave.hikari.auto-commit=true spring.datasource.slave.hikari.pool-name=DatebookHikariCP spring.datasource.slave.hikari.max-lifetime=1800000 spring.datasource.slave.hikari.connection-timeout=30000 spring.datasource.slave.hikari.connection-test-query=SELECT 1 2. 集成 mybatis 并在写入时强制切换到主库 不需要做任何配置,正常集成 mybatis 即可使用读写分离功能 可以通过 mybatis 的拦截器在写入操作时强制切换到主库 @Intercepts({ @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}), }) @Component public class WriteInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { // 获取 SQL 类型 DataSourceTypeEnum dataSourceType = DataSourceContextHolder.getDataSourceType(); if(DataSourceTypeEnum.SLAVE.equals(dataSourceType)) { DataSourceContextHolder.setDataSourceType(DataSourceTypeEnum.MASTER); } try { // 执行 SQL return invocation.proceed(); } finally { // 恢复数据源 考虑到写入后可能会反查,后续都走主库 // DataSourceContextHolder.setDataSourceType(dataSourceType); } } }  作者:京东健康苏曼 来源:京东云开发者社区 转发请注明来源

资源下载

更多资源
Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册