阅读 72

搭建大型分布式服务(三)SpringBoot多环境配置

一、本文要点

开发一个系统,至少包含开发环境、测试环境、正式环境,使得系统可以运行在不同的环境运行不同的配置,例如数据库、redis等等,接上文代码,将介绍如何整合 springboot + maven + logback + properties 多环境配置。系列文章完整目录

  • springboot和maven多环境profile

  • logback多环境配置

  • logback按天滚动和压缩日志

二、开发环境

  • jdk 1.8
  • maven 3.6.2
  • lombok 1.18.18
  • springboot 2.4.3
  • idea 2020

三、修改Maven配置文件pom.xml

1、增加profiles标签,dev、test、prod,对应开发、测试、正式环境。

<profiles>
    <profile>
        <id>dev</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <spring.profiles.active>dev</spring.profiles.active>
        </properties>
    </profile>
    <profile>
        <id>test</id>
        <properties>
            <spring.profiles.active>test</spring.profiles.active>
        </properties>
    </profile>
    <profile>
        <id>prod</id>
        <properties>
            <spring.profiles.active>prod</spring.profiles.active>
        </properties>
    </profile>
</profiles>
复制代码

2、默认激活开发环境。

<activation>
    <activeByDefault>true</activeByDefault>
</activation>
复制代码

四、修改项目application.properties

1、修改application.properties,接收maven或者命令行传递过来的profile参数。

spring.profiles.active=@spring.profiles.active@
复制代码

2、增加开发application-dev.properties、测试application-test.properties和正式环境application-prod.properties配置文件,内容为空。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iDEsBj0F-1614002139153)(/Users/yezhouwan/Downloads/write/多环境1-properties文件.png)]

五、增加Logback配置文件logback-spring.xml

为什么不用logback.xml而是logback-spring.xml呢?主要是因为我们需要在logback配置文件中使用application-xxx.properties里的配置,比如可以在 application-dev.properties 中增加 logging.file.path=./logs

<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration  scan="true" scanPeriod="10 seconds">

    <!--<include resource="org/springframework/boot/logging/logback/base.xml" />-->

    <contextName>logback</contextName>
    <!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
    <springProperty scope="context" name="log.path" source="logging.file.path"/>

    <!--输出到控制台-->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <Pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%thread] [%level] [%logger{50}:%L] - %msg%n</Pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!--输出到文件-->

    <!-- 时间滚动输出 level为 DEBUG 日志 -->
    <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>${log.path}/log_debug.log</file>
        <!--日志文件输出格式-->
        <encoder>
            <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%thread] [%level] [%logger{50}:%L] - %msg%n</pattern>
            <charset>UTF-8</charset> <!-- 设置字符集 -->
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志归档 -->
            <fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>7</maxHistory>
            <totalSizeCap>1GB</totalSizeCap>
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
        </rollingPolicy>
        <!-- 此日志文件只记录debug级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>debug</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 时间滚动输出 level为 INFO 日志 -->
    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>${log.path}/log_info.log</file>
        <!--日志文件输出格式-->
        <encoder>
            <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%thread] [%level] [%logger{50}:%L] - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天日志归档路径以及格式 -->
            <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>200MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>7</maxHistory>
            <totalSizeCap>2GB</totalSizeCap>
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
        </rollingPolicy>
        <!-- 此日志文件只记录info级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>info</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 时间滚动输出 level为 WARN 日志 -->
    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>${log.path}/log_warn.log</file>
        <!--日志文件输出格式-->
        <encoder>
            <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%thread] [%level] [%logger{50}:%L] - %msg%n</pattern>
            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>7</maxHistory>
            <totalSizeCap>200MB</totalSizeCap>
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
        </rollingPolicy>
        <!-- 此日志文件只记录warn级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>warn</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>


    <!-- 时间滚动输出 level为 ERROR 日志 -->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>${log.path}/log_error.log</file>
        <!--日志文件输出格式-->
        <encoder>
            <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%thread] [%level] [%logger{50}:%L] - %msg%n</pattern>
            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>200MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>15</maxHistory>
            <totalSizeCap>1GB</totalSizeCap>
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
        </rollingPolicy>
        <!-- 此日志文件只记录ERROR级别的 -->
       <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 异步输出 -->
    <appender name="ASYNC_CONSOLE" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>256</queueSize>
        <!-- 添加附加的appender,最多只能添加一个 -->
        <appender-ref ref="CONSOLE"/>
    </appender>

    <appender name="ASYNC_DEBUG" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="DEBUG_FILE"/>
        <includeCallerData>true</includeCallerData>
    </appender>
    <appender name="ASYNC_INFO" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="INFO_FILE"/>
        <includeCallerData>true</includeCallerData>
    </appender>
    <appender name="ASYNC_WARN" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="WARN_FILE"/>
        <includeCallerData>true</includeCallerData>
    </appender>
    <appender name="ASYNC_ERROR" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="ERROR_FILE"/>
        <includeCallerData>true</includeCallerData>
    </appender>

    <springProfile name="dev">

        <root level="DEBUG">
            <appender-ref ref="ASYNC_CONSOLE" />
            <appender-ref ref="ASYNC_DEBUG"/>
            <appender-ref ref="ASYNC_INFO"/>
            <appender-ref ref="ASYNC_WARN"/>
            <appender-ref ref="ASYNC_ERROR"/>
        </root>

    </springProfile>

    <springProfile name="test">

        <root level="DEBUG">
            <appender-ref ref="ASYNC_DEBUG"/>
            <appender-ref ref="ASYNC_INFO"/>
            <appender-ref ref="ASYNC_WARN"/>
            <appender-ref ref="ASYNC_ERROR"/>
        </root>

    </springProfile>

    <springProfile name="prod">

        <root level="INFO">
            <appender-ref ref="ASYNC_DEBUG"/>
            <appender-ref ref="ASYNC_INFO"/>
            <appender-ref ref="ASYNC_WARN"/>
            <appender-ref ref="ASYNC_ERROR"/>
        </root>

    </springProfile>

</configuration>
复制代码

如果你需要压缩历史日志,只需要把.log后缀改为.zip即可,例如。

    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.zip</fileNamePattern>
        <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <maxFileSize>100MB</maxFileSize>
        </timeBasedFileNamingAndTriggeringPolicy>
        <!--日志文件保留天数-->
        <maxHistory>7</maxHistory>
        <totalSizeCap>200MB</totalSizeCap>
        <cleanHistoryOnStart>true</cleanHistoryOnStart>
    </rollingPolicy>
复制代码

六、运行一下

1、完整项目结构如下。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5zBX1AcC-1614002139154)(/Users/yezhouwan/Downloads/write/多环境2-项目结构.png)]

2、在application-dev.properties增加以下代码。

logging.file.path=./logs
复制代码

3、在application-test.properties增加以下代码。

logging.file.path=./logs-test
复制代码

4、修改Active profiles为dev或test,查看项目日志结构。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IPV4litU-1614002139156)(/Users/yezhouwan/Downloads/write/多环境3-日志目录.png)]

可以看到开发环境、测试环境的日志输出目录不一样了。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y9NkVvqr-1614002139157)(/Users/yezhouwan/Downloads/write/多环境4-日志结构.png)]

七、小结

简单几步,就使项目支持多环境配置了,是不是很简单,完整代码地址:戳这里。下一篇《搭建大型分布式服务(四)Docker搭建开发环境安装Mysql》

加我一起交流学习!

文章分类
后端
文章标签