基于Eureka搭建Springcloud微服务-17.让微服务区分多种不同环境
原创2020年7月11日大约 6 分钟约 1892 字
17.让微服务区分多种不同环境
17.1.章节内容概述
本章节涉及主要内容有:
17.1.章节内容概述
17.2.章节内容大纲
17.3.模块简介
17.4.模块目录结构
17.5.创建模块
17.6.在父工程pom.xml添加多环境配置
17.7.编写模块pom.xml
17.8.编写模块配置文件
17.9.编写模块config
17.10.编写模块service
17.11.编写模块controller
17.12.编写模块主启动类
17.13.搭建Zipkin和ELK
17.14.测试让微服务区分多种不同环境
具体每个小节中包含的内容可使通过下面的章节内容大纲进行查看。
17.2.章节内容大纲
17.3.模块简介
集成了多种环境的的服务消费端,启动端口: 80
17.4.模块目录结构
springcloud-consumer-loadbalance-openfeign-multiply-env-order80
|-- src
| •-- main
| |-- java
| | •-- org
| | •-- openatom
| | •-- springcloud
| | |-- config
| | | |-- OpenFeignConfig.java
| | | •-- VirtualIpConfig.java
| | |-- controller
| | | •-- OrderConsumerController.java
| | |-- service
| | | •-- PaymentServiceOpenFeign.java
| | •-- OrderServiceConsumerLoadBalanceOpenFeignMultiplyEnv80.java
| •-- resources
| |-- dev
| | |-- application-dev.yml
| | |-- application.yml
| | •-- logback-custom.xml
| •-- test
| |-- application-test.yml
| |-- application.yml
| •-- logback-custom.xml
•-- pom.xml
17.5.创建模块
在父工程(springcloud-eureka)中创建一个名为springcloud-consumer-loadbalance-openfeign-multiply-env-order80的maven模块,注意:当前模块创建成功后,在父工程pom.xml中<modules></modules>中会自动生成有关当前模块的信息
17.6.在父工程pom.xml添加多环境配置
<!--定义多种开发环境:开始-->
<profiles>
<!--开发环境-->
<profile>
<!--不同环境的唯一id-->
<id>dev</id>
<properties>
<!--profile.active对应application.yml中的@profile.active@-->
<profile.active>dev</profile.active>
</properties>
</profile>
<!--测试环境-->
<profile>
<id>test</id>
<properties>
<!--profile.active对应application.yml中的@profile.active@-->
<profile.active>test</profile.active>
</properties>
</profile>
</profiles>
<!--定义多种开发环境:结束-->
17.7.编写模块pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springcloud-eureka</artifactId>
<groupId>org.openatom</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springcloud-consumer-loadbalance-openfeign-multiply-env-order80</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--引入公共的工程-->
<dependency>
<groupId>org.openatom</groupId>
<artifactId>springcloud-api-commons</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
</dependency>
<!--包含了sleuth+zipkin-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
</dependencies>
<!--热部署需要加这个-->
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<!--把当前插件repackage命令和maven的package绑定-->
<id>repackage-original</id>
<phase>package</phase>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
<delimiters>
<delimiter>@</delimiter>
</delimiters>
<useDefaultDelimiters>false</useDefaultDelimiters>
</configuration>
</plugin>
</plugins>
<!--打包多环境-->
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/*.yml</exclude>
<exclude>**/*.xml</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources/${profile.active}</directory>
<!--引入所需环境的配置文件-->
<filtering>true</filtering>
<includes>
<include>application.yml</include>
<!--根据maven选择环境导入配置文件-->
<include>application-${profile.active}.yml</include>
<include>mapper/*.xml</include>
<include>*.xml</include>
</includes>
</resource>
</resources>
</build>
</project>
17.8.编写模块配置文件
dev环境配置文件
application.yml
#设置spring项目运行的环境
spring:
profiles:
active: '@profile.active@'
application-dev.yml
server:
port: 80
spring:
application:
name: SPRINGCLOUD-CONSUMER-LOADBALANCE-OPENFEIGN-MULTIPLY-ENV-ORDER80-DEV #注意:服务名不要出现_
devtools:
restart:
enabled: true
logging: #Spring运行日志配置
level: info
zipkin:
base-url: http://192.168.0.5:9411
sleuth:
sampler:
probability: 1 # span的采样率,默认为 0.1,这个值介于0到1之间
eureka:
client:
register-with-eureka: true #表示是否将自己注册进EurekaServer默认为true。
fetchRegistry: true #是否从EurekaServer抓取已有的注册信息,默认为true。服务提供端是单节点无所谓,是集群必须设置为true才能配合ribbon使用负载均衡,否则报异常No instances available for SPRINGCLOUD-PROVIDER-PAYMENT-SERVICE-CLUSTER
service-url:
#单机版
defaultZone: http://localhost:7001/eureka
#集群版
#defaultZone: http://eureka7002:7002/eureka,http://eureka7003:7003/eureka,http://eureka7004:7004/eureka
instance:
instance-id: ${spring.application.name} #Eureka仪表盘中Instances currently registered with Eureka.Status显示的内容
#当前微服务所在部署机器ip
ip-address: localhost
prefer-ip-address: false #访问路径可以显示IP地址,点击Eureka仪表盘中Instances currently registered with Eureka.Status显示的内容地址栏是否显示IP地址
#服务提供端信息
service:
provider:
provider-1: &provider-1 SPRINGCLOUD-PROVIDER-PAYMENT-SERVICE-CLUSTER-${spring.profiles.active} #服务提供端名称
#某个/某些服务的Ribbon配置
*provider-1: #服务提供端名称
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #Ribbon负载均衡规则类所在的路径,自带七种规则,也可以是自定位规则的类所在的路径
#对OpenFeign进行单独配置
feign:
client:
config:
#这里填具体的服务名称(也可以填default,表示对所有服务生效)
*provider-1: #服务提供端名称
#connectTimeout和readTimeout这两个得一起配置才会生效
connectTimeout: 5000 #指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
readTimeout: 5000 #指的是建立连接后从服务器读取到可用资源所用的时间
#配置文件修改说明-------------------------------------------------:开始
#注意:不同的部署环境需要修改的配置
# 1.${logback.path} #修改日志存放位置,Linxu为/,Windows为\
# 修改原因: Linux和Windows目录结构不同
#配置文件修改说明-------------------------------------------------:结束
#自定义日志配置文件路径
logging:
config: classpath:logback-custom.xml
path: D:\repository\workspace\IDEA\PERSONAL\springcloud-eureka\log\ #所有日志存放在位置,加上\方便Linux环境下配置
level:
root: info #全局日志输出级别
org.openatom.springcloud.services.PaymentServiceOpenFeign: debug #OpenFeign增强日志配置,OpenFeign日志以什么级别监控哪个接口
org.openatom.springcloud.services.PaymentServiceOpenFeignDynamicFeignClientFactory: debug #OpenFeign增强日志配置,OpenFeign日志以什么级别监控哪个接口
logback:
log-name: ${spring.application.name}
append: false #是否启用append(追加到已经存在日志文件尾部),true:重启项目会追加新日志到之前日志,false:重启项目会清空之前的日志
immediate-flush: true #是否启用immediateFlush(立即刷新),true:重启项目自动追加,false:重启项目会情况之前的日志
deploy-machine-ip: ${eureka.instance.ip-address} #当前微服务所在部署机器ip
#logstash相关配置:开始
logstash:
host: 192.168.0.5:5044 # logstash地址
index: '@project.parent.artifactId@' # es中index名称
#logstash相关配置:结束
#actuator监控:开始
#通过下面的配置启用所有的监控端点,默认情况下,这些端点是禁用的;
management:
endpoints:
web:
exposure:
include: '*'
enabled-by-default: true
endpoint:
health:
show-details: always # 访问/actuator/health时,显示详细信息,而不是仅仅显示"status": "UP"
# 日志文件路径:特别注意,此处无法配置日志文件路径,因为rancher会生成虚拟ip,这个虚拟ip是无法在这里获取的,
# 但是虚拟ip是路径的一部分,所以这个路径无法拼接出来,所以这里无法配置日志文件路径
#logfile:
# external-file:
#actuator监控:结束
logback-custom.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
scanPeriod: 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
debug: 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
-->
<!-- 输出logback内部日志信息,每隔30s判断一下配置文件有没有更新,若更新,则重新加载 -->
<configuration scan="true" scanPeriod="30 seconds" debug="false">
<!--从java代码中获取虚拟ip的值-->
<!--获取当前微服务部署虚拟IP,如rancher为当前微服务分配的ip-->
<define name="VIRTUAL_IP" class="org.openatom.springcloud.config.VirtualIpConfig"/>
<!--从Spring容器中获取配置(Spring配置文件加载顺序:bootstrap.yml->logback.xml->application.yml)-->
<!--获取当前微服务部署机器ip-->
<springProperty name="MACHINE_IP" scope="context" source="logback.deploy-machine-ip"/>
<!--应用名称-->
<springProperty name="LOG_NAME" scope="context" source="logback.log-name"/>
<!--是否启用append-->
<springProperty name="IS_APPEND" scope="context" source="logback.append"/>
<!--是否启用立即刷新-->
<springProperty name="IS_IMMEDIATEFLUSH" scope="context" source="logback.immediate-flush"/>
<springProperty name="LOG_PATH" scope="context" source="logging.path"/>
<!--logstash地址-->
<springProperty name="LOGSTASH_HOST" scope="context" source="logstash.host"/>
<!--索引名称-->
<springProperty name="INDEX_NAME" scope="context" source="logstash.index"/>
<!-- name:变量的名称,可以随意起名,但建议名字要简明直译;value:变量的值;在配置文件中,我们可以用 ${} 的方式来使用,将变量引入到其他节点中去。-->
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %msg:日志消息,%n是换行符-->
<!--控制台日志输出预选样式-->
<property name="CONSOLE_LOG_PATTERN_1" value="%red(%d{yyyy-MM-dd HH:mm:ss.SSS}) %green([%thread]) [machineIp:${MACHINE_IP} virtualIp:${VIRTUAL_IP}] [TraceId:%X{X-B3-TraceId:-} SpanId:%X{X-B3-SpanId:-} %highlight(%-5level) %boldMagenta(%logger{10}): %cyan(%msg%n)"/>
<property name="CONSOLE_LOG_PATTERN_2" value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) [machineIp:${MACHINE_IP} virtualIp:${VIRTUAL_IP}] [TraceId:%X{X-B3-TraceId:-} SpanId:%X{X-B3-SpanId:-} %highlight([%-5level]) %green(%logger) %msg%n"/>
<property name="CONSOLE_LOG_PATTERN_3" value="%date{yyyy-MM-dd HH:mm:ss} [machineIp:${MACHINE_IP} virtualIp:${VIRTUAL_IP}] [TraceId:%X{X-B3-TraceId:-} SpanId:%X{X-B3-SpanId:-} Span-Export:%X{X-Span-Export:-}] %green(%-5level) %boldMagenta(${PID:-}) -- [%+20thread] %cyan(%logger{20}) %line : %msg%n"/>
<!--文件中日志输出预选样式-->
<property name="FILE_LOG_PATTERN_1" value="%d{yyyyMMdd:HH:mm:ss.SSS} [machineIp:${MACHINE_IP} virtualIp:${VIRTUAL_IP}] [TraceId:%X{X-B3-TraceId:-} SpanId:%X{X-B3-SpanId:-} [%thread] %-5level %msg%n"/>
<!--控制台日志输出格式-->
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN_3}"/>
<!--文件中日志输出格式-->
<property name="FILE_LOG_PATTERN" value="${FILE_LOG_PATTERN_1}"/>
<!--日志名称-->
<!--定义默认日志输出级别-->
<property name="LOG_OUTPUT_LEVEL" value="${LOG_LEVEL}" />
<!--定义默认日志输出编码-->
<property name="ENCODING" value="UTF-8" />
<!-- 控制台输出:开始 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 用来设置日志的输入格式,使用“%+转换符”的方式,如果要输出”%”则必须使用”\”进行转义。-->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 格式化输出:https://logback.qos.ch/manual/layouts.html
%d 表示日期,
%thread 表示线程名,
%level 日志级别从左显示5个字符宽度,
%t 线程名
%file:%line 文件名+行号,
%m 日志消息,%n是换行符
%X{traceId}:自定义设置的参数,后面会说。
-->
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>
</appender>
<!-- 控制台输出:结束 -->
<!--输出到文件:开始-->
<!-- 将项目本次运行INFO日志同步输出到文件,会自动清空文件中上一次的日志 -->
<appender name="APPENDER-FILEAPPENDER-INFO" class="ch.qos.logback.core.FileAppender">
<!-- 过滤器,只记录 info 级别以上的日志 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<!-- 写入的日志文件名,可以使相对目录也可以是绝对目录,如果上级目录不存在则自动创建 -->
<file>${LOG_PATH}/${MACHINE_IP}/${VIRTUAL_IP}/${LOG_NAME}-info.log</file>
<!-- 如果为true表示日志被追加到文件结尾,如果是false表示清空文件 -->
<append>${IS_APPEND}</append>
<!--立即刷新,设置成false可以提高日志吞吐量-->
<immediateFlush>${IS_IMMEDIATEFLUSH}</immediateFlush>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>
</appender>
<!-- 将项目本次运行INFO日志异步输出到文件,会自动清空文件中上一次的日志 -->
<appender name="ASYNC-APPENDER-FILEAPPENDER-INFO" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="APPENDER-FILEAPPENDER-INFO" />
<!-- 设置异步阻塞队列的大小,为了不丢失日志建议设置的大一些,单机压测时100000是没问题的,应该不用担心OOM -->
<queueSize>10000</queueSize>
<!-- 设置丢弃DEBUG、TRACE、INFO日志的阀值,不丢失 -->
<discardingThreshold>0</discardingThreshold>
<!-- 设置队列入队时非阻塞,当队列满时会直接丢弃日志,但是对性能提升极大 -->
<neverBlock>${IS_IMMEDIATEFLUSH}</neverBlock>
</appender>
<!-- 将项目本次运行DEBUG日志同步输出到文件,会自动清空文件中上一次的日志 -->
<appender name="APPENDER-FILEAPPENDER-DEBUG" class="ch.qos.logback.core.FileAppender">
<!-- 过滤器,只记录 info 级别以上的日志 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<!-- 写入的日志文件名,可以使相对目录也可以是绝对目录,如果上级目录不存在则自动创建 -->
<file>${LOG_PATH}/${MACHINE_IP}/${VIRTUAL_IP}/${LOG_NAME}-debug.log</file>
<!-- 如果为true表示日志被追加到文件结尾,如果是false表示清空文件 -->
<append>${IS_APPEND}</append>
<!--立即刷新,设置成false可以提高日志吞吐量-->
<immediateFlush>true</immediateFlush>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>
</appender>
<!-- 将项目本次运行DEBUG日志异步输出到文件,会自动清空文件中上一次的日志 -->
<appender name="ASYNC-APPENDER-FILEAPPENDER-DEBUG" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="APPENDER-FILEAPPENDER-DEBUG" />
<!-- 设置异步阻塞队列的大小,为了不丢失日志建议设置的大一些,单机压测时100000是没问题的,应该不用担心OOM -->
<queueSize>10000</queueSize>
<!-- 设置丢弃DEBUG、TRACE、INFO日志的阀值,不丢失 -->
<discardingThreshold>0</discardingThreshold>
<!-- 设置队列入队时非阻塞,当队列满时会直接丢弃日志,但是对性能提升极大 -->
<neverBlock>true</neverBlock>
</appender>
<!-- 将项目本次运行ERROR日志同步输出到文件,会自动清空文件中上一次的日志 -->
<appender name="APPENDER-FILEAPPENDER-ERROR" class="ch.qos.logback.core.FileAppender">
<!-- 过滤器,只记录 info 级别以上的日志 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<!-- 写入的日志文件名,可以使相对目录也可以是绝对目录,如果上级目录不存在则自动创建 -->
<file>${LOG_PATH}/${MACHINE_IP}/${VIRTUAL_IP}/${LOG_NAME}-error.log</file>
<!-- 如果为true表示日志被追加到文件结尾,如果是false表示清空文件 -->
<append>${IS_APPEND}</append>
<!--立即刷新,设置成false可以提高日志吞吐量-->
<immediateFlush>${IS_IMMEDIATEFLUSH}</immediateFlush>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>
</appender>
<!-- 将项目本次运行ERROR日志异步输出到文件,会自动清空文件中上一次的日志 -->
<appender name="ASYNC-APPENDER-FILEAPPENDER-ERROR" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="APPENDER-FILEAPPENDER-ERROR" />
<!-- 设置异步阻塞队列的大小,为了不丢失日志建议设置的大一些,单机压测时100000是没问题的,应该不用担心OOM -->
<queueSize>10000</queueSize>
<!-- 设置丢弃DEBUG、TRACE、INFO日志的阀值,不丢失 -->
<discardingThreshold>0</discardingThreshold>
<!-- 设置队列入队时非阻塞,当队列满时会直接丢弃日志,但是对性能提升极大 -->
<neverBlock>true</neverBlock>
</appender>
<!--输出到文件:结束-->
<!--滚动输出到文件(按照天保存):开始-->
<!-- 将项目本次运行INFO日志同步输出到文件,按照每天生成日志文件,会自动拼接上一次日志 -->
<appender name="APPENDER-ROLLINGFILEAPPENDER-INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 过滤器,只记录 info 级别以上的日志 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<!--立即刷新,设置成false可以提高日志吞吐量-->
<immediateFlush>false</immediateFlush>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 日志文件输出的文件名:
%d:可以包含一个Java.text.SimpleDateFormat指定的时间格式
%i:自增数字
-->
<fileNamePattern>${LOG_PATH}/${MACHINE_IP}/${VIRTUAL_IP}/HISTORY/${LOG_NAME}-info-%d{yyyy-MM-dd}-index%i.log</fileNamePattern>
<!-- 日志文件保存历史数量:控制保留的归档文件的最大数量,如果超出数量就删除旧文件 -->
<maxHistory>10</maxHistory>
<!-- 文件大小超过100MB归档 -->
<maxFileSize>20MB</maxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>
</appender>
<!-- 将项目本次运行INFO日志异步输出到文件,按照每天生成日志文件,会自动拼接上一次日志 -->
<appender name="ASYNC-APPENDER-ROLLINGFILEAPPENDER-INFO" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="APPENDER-ROLLINGFILEAPPENDER-INFO" />
<!-- 设置异步阻塞队列的大小,为了不丢失日志建议设置的大一些,单机压测时100000是没问题的,应该不用担心OOM -->
<queueSize>10000</queueSize>
<!-- 设置丢弃DEBUG、TRACE、INFO日志的阀值,不丢失 -->
<discardingThreshold>0</discardingThreshold>
<!-- 设置队列入队时非阻塞,当队列满时会直接丢弃日志,但是对性能提升极大 -->
<neverBlock>true</neverBlock>
</appender>
<!-- 将项目本次运行DEBUG日志同步输出到文件,按照每天生成日志文件,会自动拼接上一次日志 -->
<appender name="APPENDER-ROLLINGFILEAPPENDER-DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 过滤器,只记录 info 级别以上的日志 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<!--立即刷新,设置成false可以提高日志吞吐量-->
<immediateFlush>false</immediateFlush>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 日志文件输出的文件名:
%d:可以包含一个Java.text.SimpleDateFormat指定的时间格式
%i:自增数字
-->
<fileNamePattern>${LOG_PATH}/${MACHINE_IP}/${VIRTUAL_IP}/HISTORY/${LOG_NAME}-debug-%d{yyyy-MM-dd}-index%i.log</fileNamePattern>
<!-- 日志文件保存历史数量:控制保留的归档文件的最大数量,如果超出数量就删除旧文件 -->
<maxHistory>10</maxHistory>
<!-- 文件大小超过100MB归档 -->
<maxFileSize>20MB</maxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>
</appender>
<!-- 将项目本次运行DEBUG日志异步输出到文件,按照每天生成日志文件,会自动拼接上一次日志 -->
<appender name="ASYNC-APPENDER-ROLLINGFILEAPPENDER-DEBUG" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="APPENDER-ROLLINGFILEAPPENDER-DEBUG" />
<!-- 设置异步阻塞队列的大小,为了不丢失日志建议设置的大一些,单机压测时100000是没问题的,应该不用担心OOM -->
<queueSize>10000</queueSize>
<!-- 设置丢弃DEBUG、TRACE、INFO日志的阀值,不丢失 -->
<discardingThreshold>0</discardingThreshold>
<!-- 设置队列入队时非阻塞,当队列满时会直接丢弃日志,但是对性能提升极大 -->
<neverBlock>true</neverBlock>
</appender>
<!-- 将项目本次运行ERROR日志同步输出到文件,按照每天生成日志文件,会自动拼接上一次日志 -->
<appender name="APPENDER-ROLLINGFILEAPPENDER-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 过滤器,只记录error级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!--立即刷新,设置成false可以提高日志吞吐量-->
<immediateFlush>false</immediateFlush>
<!-- 每天生成一个日志文件,保存30天的日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 日志文件输出的文件名:按天回滚 daily -->
<fileNamePattern>${LOG_PATH}/${MACHINE_IP}/${VIRTUAL_IP}/HISTORY/${LOG_NAME}-error-%d{yyyy-MM-dd}-index%i.log</fileNamePattern>
<!-- 日志文件保留天数 -->
<maxHistory>10</maxHistory>
<!-- 文件大小超过100MB归档 -->
<maxFileSize>20MB</maxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<appender name="ASYNC-APPENDER-ROLLINGFILEAPPENDER-ERROR" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="APPENDER-ROLLINGFILEAPPENDER-ERROR" />
<!-- 设置异步阻塞队列的大小,为了不丢失日志建议设置的大一些,单机压测时100000是没问题的,应该不用担心OOM -->
<queueSize>10000</queueSize>
<!-- 设置丢弃DEBUG、TRACE、INFO日志的阀值,不丢失 -->
<discardingThreshold>0</discardingThreshold>
<!-- 设置队列入队时非阻塞,当队列满时会直接丢弃日志,但是对性能提升极大 -->
<neverBlock>true</neverBlock>
</appender>
<!--滚动输出到文件(按照天保存):结束-->
<!--输出到LOGSTASH:开始-->
<!-- 将项目本次运行ERROR日志同步输出到文件,按照每天生成日志文件,会自动拼接上一次日志 -->
<appender name="APPENDER-LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<!-- logstash服务器地址-->
<destination>${LOGSTASH_HOST}</destination>
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<pattern>
<pattern>
{
"appName":"${INDEX_NAME}",
"machineIp":"${MACHINE_IP}",
"virtualIp":"${VIRTUAL_IP}",
"serviceName":"${LOG_NAME}",
"timestamp": "%date{\"yyyy-MM-dd'T'HH:mm:ss,SSSZ\"}",
"logLevel":"%level",
"message":"%msg%n",
"traceId": "%X{X-B3-TraceId:-}",
"spanId": "%X{X-B3-SpanId:-}",
"spanExport": "%X{X-Span-Export:-}"
}
</pattern>
</pattern>
</providers>
</encoder>
</appender>
<appender name="ASYNC-APPENDER-LOGSTASH" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="APPENDER-LOGSTASH" />
<!-- 设置异步阻塞队列的大小,为了不丢失日志建议设置的大一些,单机压测时100000是没问题的,应该不用担心OOM -->
<queueSize>10000</queueSize>
<!-- 设置丢弃DEBUG、TRACE、INFO日志的阀值,不丢失 -->
<discardingThreshold>0</discardingThreshold>
<!-- 设置队列入队时非阻塞,当队列满时会直接丢弃日志,但是对性能提升极大 -->
<neverBlock>true</neverBlock>
</appender>
<!--输出到logstash:结束-->
<!--
开发环境日志级别为DEBUG
level:用来设置打印级别
五个常用打印级别从低至高依次为TRACE、DEBUG、INFO、WARN、ERROR
-->
<springProfile name="dev">
<root>
<!--输出到控制台-->
<appender-ref ref="STDOUT"/>
<!--异步非滚动输出到文件-->
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-INFO"/>
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-DEBUG"/>
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-ERROR"/>
<!--异步滚动输出到文件:dev环境不开启-->
<!-- <appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-INFO"/>-->
<!-- <appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-DEBUG"/>-->
<!-- <appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-ERROR"/>-->
<!--异步滚动输出到logstash-->
<appender-ref ref="ASYNC-APPENDER-LOGSTASH"/>
</root>
</springProfile>
<!-- 测试环境日志级别为INFO -->
<springProfile name="test">
<root>
<!--输出到控制台-->
<appender-ref ref="STDOUT"/>
<!--异步非滚动输出到文件-->
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-INFO"/>
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-DEBUG"/>
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-ERROR"/>
<!--异步滚动输出到文件:test环境不开启-->
<!-- <appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-INFO"/>-->
<!-- <appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-DEBUG"/>-->
<!-- <appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-ERROR"/>-->
<!--异步滚动输出到logstash-->
<appender-ref ref="ASYNC-APPENDER-LOGSTASH"/>
</root>
</springProfile>
<!-- 生产环境日志级别为INFO -->
<springProfile name="prod">
<root>
<!--输出到控制台-->
<appender-ref ref="STDOUT"/>
<!--异步非滚动输出到文件-->
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-INFO"/>
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-DEBUG"/>
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-ERROR"/>
<!--异步滚动输出到文件-->
<appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-INFO"/>
<appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-DEBUG"/>
<appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-ERROR"/>
<!--异步滚动输出到logstash-->
<appender-ref ref="ASYNC-APPENDER-LOGSTASH"/>
</root>
</springProfile>
<!-- rancher环境日志级别为INFO -->
<springProfile name="rancher">
<root>
<!--输出到控制台-->
<appender-ref ref="STDOUT"/>
<!--异步非滚动输出到文件-->
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-INFO"/>
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-DEBUG"/>
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-ERROR"/>
<!--异步滚动输出到文件-->
<appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-INFO"/>
<appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-DEBUG"/>
<appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-ERROR"/>
<!--异步滚动输出到logstash-->
<appender-ref ref="ASYNC-APPENDER-LOGSTASH"/>
</root>
</springProfile>
</configuration>
test环境配置文件
application.yml
#设置spring项目运行的环境
spring:
profiles:
active: '@profile.active@'
application-test.yml
server:
port: 80
spring:
application:
name: SPRINGCLOUD-CONSUMER-LOADBALANCE-OPENFEIGN-MULTIPLY-ENV-ORDER80-TEST #注意:服务名不要出现_
devtools:
restart:
enabled: true
logging: #Spring运行日志配置
level: info
eureka:
client:
register-with-eureka: true #表示是否将自己注册进EurekaServer默认为true。
fetchRegistry: true #是否从EurekaServer抓取已有的注册信息,默认为true。服务提供端是单节点无所谓,是集群必须设置为true才能配合ribbon使用负载均衡,否则报异常No instances available for SPRINGCLOUD-PROVIDER-PAYMENT-SERVICE-CLUSTER
service-url:
#单机版
defaultZone: http://localhost:7001/eureka
#集群版
#defaultZone: http://eureka7002:7002/eureka,http://eureka7003:7003/eureka,http://eureka7004:7004/eureka
instance:
instance-id: ${spring.application.name} #Eureka仪表盘中Instances currently registered with Eureka.Status显示的内容
#当前微服务所在部署机器ip
ip-address: localhost
prefer-ip-address: false #访问路径可以显示IP地址,点击Eureka仪表盘中Instances currently registered with Eureka.Status显示的内容地址栏是否显示IP地址
#服务提供端信息
service:
provider:
provider-1: &provider-1 SPRINGCLOUD-PROVIDER-PAYMENT-SERVICE-CLUSTER-${spring.profiles.active} #服务提供端名称
#某个/某些服务的Ribbon配置
*provider-1: #服务提供端名称
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #Ribbon负载均衡规则类所在的路径,自带七种规则,也可以是自定位规则的类所在的路径
#对OpenFeign进行单独配置
feign:
client:
config:
#这里填具体的服务名称(也可以填default,表示对所有服务生效)
*provider-1: #服务提供端名称
#connectTimeout和readTimeout这两个得一起配置才会生效
connectTimeout: 5000 #指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
readTimeout: 5000 #指的是建立连接后从服务器读取到可用资源所用的时间
#配置文件修改说明-------------------------------------------------:开始
#注意:不同的部署环境需要修改的配置
# 1.${logback.path} #修改日志存放位置,Linxu为/,Windows为\
# 修改原因: Linux和Windows目录结构不同
#配置文件修改说明-------------------------------------------------:结束
#自定义日志配置文件路径
logging:
config: classpath:logback-custom.xml
path: D:\repository\workspace\IDEA\PERSONAL\springcloud-eureka\log\ #所有日志存放在位置,加上\方便Linux环境下配置
level:
root: info #全局日志输出级别
org.openatom.springcloud.services.PaymentServiceOpenFeign: debug #OpenFeign增强日志配置,OpenFeign日志以什么级别监控哪个接口
org.openatom.springcloud.services.PaymentServiceOpenFeignDynamicFeignClientFactory: debug #OpenFeign增强日志配置,OpenFeign日志以什么级别监控哪个接口
logback:
log-name: ${spring.application.name}
append: false #是否启用append(追加到已经存在日志文件尾部),true:重启项目会追加新日志到之前日志,false:重启项目会清空之前的日志
immediate-flush: true #是否启用immediateFlush(立即刷新),true:重启项目自动追加,false:重启项目会情况之前的日志
deploy-machine-ip: ${eureka.instance.ip-address} #当前微服务所在部署机器ip
#logstash相关配置:开始
logstash:
host: 192.168.0.5:5044 # logstash地址
index: '@project.parent.artifactId@' # es中index名称
#logstash相关配置:结束
#actuator监控:开始
#通过下面的配置启用所有的监控端点,默认情况下,这些端点是禁用的;
management:
endpoints:
web:
exposure:
include: '*'
enabled-by-default: true
endpoint:
health:
show-details: always # 访问/actuator/health时,显示详细信息,而不是仅仅显示"status": "UP"
# 日志文件路径:特别注意,此处无法配置日志文件路径,因为rancher会生成虚拟ip,这个虚拟ip是无法在这里获取的,
# 但是虚拟ip是路径的一部分,所以这个路径无法拼接出来,所以这里无法配置日志文件路径
#logfile:
# external-file:
#actuator监控:结束
logback-custom.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
scanPeriod: 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
debug: 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
-->
<!-- 输出logback内部日志信息,每隔30s判断一下配置文件有没有更新,若更新,则重新加载 -->
<configuration scan="true" scanPeriod="30 seconds" debug="false">
<!--从java代码中获取虚拟ip的值-->
<!--获取当前微服务部署虚拟IP,如rancher为当前微服务分配的ip-->
<define name="VIRTUAL_IP" class="org.openatom.springcloud.config.VirtualIpConfig"/>
<!--从Spring容器中获取配置(Spring配置文件加载顺序:bootstrap.yml->logback.xml->application.yml)-->
<!--获取当前微服务部署机器ip-->
<springProperty name="MACHINE_IP" scope="context" source="logback.deploy-machine-ip"/>
<!--应用名称-->
<springProperty name="LOG_NAME" scope="context" source="logback.log-name"/>
<!--是否启用append-->
<springProperty name="IS_APPEND" scope="context" source="logback.append"/>
<!--是否启用立即刷新-->
<springProperty name="IS_IMMEDIATEFLUSH" scope="context" source="logback.immediate-flush"/>
<springProperty name="LOG_PATH" scope="context" source="logging.path"/>
<!--logstash地址-->
<springProperty name="LOGSTASH_HOST" scope="context" source="logstash.host"/>
<!--索引名称-->
<springProperty name="INDEX_NAME" scope="context" source="logstash.index"/>
<!-- name:变量的名称,可以随意起名,但建议名字要简明直译;value:变量的值;在配置文件中,我们可以用 ${} 的方式来使用,将变量引入到其他节点中去。-->
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %msg:日志消息,%n是换行符-->
<!--控制台日志输出预选样式-->
<property name="CONSOLE_LOG_PATTERN_1" value="%red(%d{yyyy-MM-dd HH:mm:ss.SSS}) %green([%thread]) [machineIp:${MACHINE_IP} virtualIp:${VIRTUAL_IP}] [TraceId:%X{X-B3-TraceId:-} SpanId:%X{X-B3-SpanId:-} %highlight(%-5level) %boldMagenta(%logger{10}): %cyan(%msg%n)"/>
<property name="CONSOLE_LOG_PATTERN_2" value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) [machineIp:${MACHINE_IP} virtualIp:${VIRTUAL_IP}] [TraceId:%X{X-B3-TraceId:-} SpanId:%X{X-B3-SpanId:-} %highlight([%-5level]) %green(%logger) %msg%n"/>
<property name="CONSOLE_LOG_PATTERN_3" value="%date{yyyy-MM-dd HH:mm:ss} [machineIp:${MACHINE_IP} virtualIp:${VIRTUAL_IP}] [TraceId:%X{X-B3-TraceId:-} SpanId:%X{X-B3-SpanId:-} Span-Export:%X{X-Span-Export:-}] %green(%-5level) %boldMagenta(${PID:-}) -- [%+20thread] %cyan(%logger{20}) %line : %msg%n"/>
<!--文件中日志输出预选样式-->
<property name="FILE_LOG_PATTERN_1" value="%d{yyyyMMdd:HH:mm:ss.SSS} [machineIp:${MACHINE_IP} virtualIp:${VIRTUAL_IP}] [TraceId:%X{X-B3-TraceId:-} SpanId:%X{X-B3-SpanId:-} [%thread] %-5level %msg%n"/>
<!--控制台日志输出格式-->
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN_3}"/>
<!--文件中日志输出格式-->
<property name="FILE_LOG_PATTERN" value="${FILE_LOG_PATTERN_1}"/>
<!--日志名称-->
<!--定义默认日志输出级别-->
<property name="LOG_OUTPUT_LEVEL" value="${LOG_LEVEL}" />
<!--定义默认日志输出编码-->
<property name="ENCODING" value="UTF-8" />
<!-- 控制台输出:开始 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 用来设置日志的输入格式,使用“%+转换符”的方式,如果要输出”%”则必须使用”\”进行转义。-->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 格式化输出:https://logback.qos.ch/manual/layouts.html
%d 表示日期,
%thread 表示线程名,
%level 日志级别从左显示5个字符宽度,
%t 线程名
%file:%line 文件名+行号,
%m 日志消息,%n是换行符
%X{traceId}:自定义设置的参数,后面会说。
-->
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>
</appender>
<!-- 控制台输出:结束 -->
<!--输出到文件:开始-->
<!-- 将项目本次运行INFO日志同步输出到文件,会自动清空文件中上一次的日志 -->
<appender name="APPENDER-FILEAPPENDER-INFO" class="ch.qos.logback.core.FileAppender">
<!-- 过滤器,只记录 info 级别以上的日志 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<!-- 写入的日志文件名,可以使相对目录也可以是绝对目录,如果上级目录不存在则自动创建 -->
<file>${LOG_PATH}/${MACHINE_IP}/${VIRTUAL_IP}/${LOG_NAME}-info.log</file>
<!-- 如果为true表示日志被追加到文件结尾,如果是false表示清空文件 -->
<append>${IS_APPEND}</append>
<!--立即刷新,设置成false可以提高日志吞吐量-->
<immediateFlush>${IS_IMMEDIATEFLUSH}</immediateFlush>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>
</appender>
<!-- 将项目本次运行INFO日志异步输出到文件,会自动清空文件中上一次的日志 -->
<appender name="ASYNC-APPENDER-FILEAPPENDER-INFO" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="APPENDER-FILEAPPENDER-INFO" />
<!-- 设置异步阻塞队列的大小,为了不丢失日志建议设置的大一些,单机压测时100000是没问题的,应该不用担心OOM -->
<queueSize>10000</queueSize>
<!-- 设置丢弃DEBUG、TRACE、INFO日志的阀值,不丢失 -->
<discardingThreshold>0</discardingThreshold>
<!-- 设置队列入队时非阻塞,当队列满时会直接丢弃日志,但是对性能提升极大 -->
<neverBlock>${IS_IMMEDIATEFLUSH}</neverBlock>
</appender>
<!-- 将项目本次运行DEBUG日志同步输出到文件,会自动清空文件中上一次的日志 -->
<appender name="APPENDER-FILEAPPENDER-DEBUG" class="ch.qos.logback.core.FileAppender">
<!-- 过滤器,只记录 info 级别以上的日志 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<!-- 写入的日志文件名,可以使相对目录也可以是绝对目录,如果上级目录不存在则自动创建 -->
<file>${LOG_PATH}/${MACHINE_IP}/${VIRTUAL_IP}/${LOG_NAME}-debug.log</file>
<!-- 如果为true表示日志被追加到文件结尾,如果是false表示清空文件 -->
<append>${IS_APPEND}</append>
<!--立即刷新,设置成false可以提高日志吞吐量-->
<immediateFlush>true</immediateFlush>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>
</appender>
<!-- 将项目本次运行DEBUG日志异步输出到文件,会自动清空文件中上一次的日志 -->
<appender name="ASYNC-APPENDER-FILEAPPENDER-DEBUG" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="APPENDER-FILEAPPENDER-DEBUG" />
<!-- 设置异步阻塞队列的大小,为了不丢失日志建议设置的大一些,单机压测时100000是没问题的,应该不用担心OOM -->
<queueSize>10000</queueSize>
<!-- 设置丢弃DEBUG、TRACE、INFO日志的阀值,不丢失 -->
<discardingThreshold>0</discardingThreshold>
<!-- 设置队列入队时非阻塞,当队列满时会直接丢弃日志,但是对性能提升极大 -->
<neverBlock>true</neverBlock>
</appender>
<!-- 将项目本次运行ERROR日志同步输出到文件,会自动清空文件中上一次的日志 -->
<appender name="APPENDER-FILEAPPENDER-ERROR" class="ch.qos.logback.core.FileAppender">
<!-- 过滤器,只记录 info 级别以上的日志 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<!-- 写入的日志文件名,可以使相对目录也可以是绝对目录,如果上级目录不存在则自动创建 -->
<file>${LOG_PATH}/${MACHINE_IP}/${VIRTUAL_IP}/${LOG_NAME}-error.log</file>
<!-- 如果为true表示日志被追加到文件结尾,如果是false表示清空文件 -->
<append>${IS_APPEND}</append>
<!--立即刷新,设置成false可以提高日志吞吐量-->
<immediateFlush>${IS_IMMEDIATEFLUSH}</immediateFlush>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>
</appender>
<!-- 将项目本次运行ERROR日志异步输出到文件,会自动清空文件中上一次的日志 -->
<appender name="ASYNC-APPENDER-FILEAPPENDER-ERROR" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="APPENDER-FILEAPPENDER-ERROR" />
<!-- 设置异步阻塞队列的大小,为了不丢失日志建议设置的大一些,单机压测时100000是没问题的,应该不用担心OOM -->
<queueSize>10000</queueSize>
<!-- 设置丢弃DEBUG、TRACE、INFO日志的阀值,不丢失 -->
<discardingThreshold>0</discardingThreshold>
<!-- 设置队列入队时非阻塞,当队列满时会直接丢弃日志,但是对性能提升极大 -->
<neverBlock>true</neverBlock>
</appender>
<!--输出到文件:结束-->
<!--滚动输出到文件(按照天保存):开始-->
<!-- 将项目本次运行INFO日志同步输出到文件,按照每天生成日志文件,会自动拼接上一次日志 -->
<appender name="APPENDER-ROLLINGFILEAPPENDER-INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 过滤器,只记录 info 级别以上的日志 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<!--立即刷新,设置成false可以提高日志吞吐量-->
<immediateFlush>false</immediateFlush>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 日志文件输出的文件名:
%d:可以包含一个Java.text.SimpleDateFormat指定的时间格式
%i:自增数字
-->
<fileNamePattern>${LOG_PATH}/${MACHINE_IP}/${VIRTUAL_IP}/HISTORY/${LOG_NAME}-info-%d{yyyy-MM-dd}-index%i.log</fileNamePattern>
<!-- 日志文件保存历史数量:控制保留的归档文件的最大数量,如果超出数量就删除旧文件 -->
<maxHistory>10</maxHistory>
<!-- 文件大小超过100MB归档 -->
<maxFileSize>20MB</maxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>
</appender>
<!-- 将项目本次运行INFO日志异步输出到文件,按照每天生成日志文件,会自动拼接上一次日志 -->
<appender name="ASYNC-APPENDER-ROLLINGFILEAPPENDER-INFO" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="APPENDER-ROLLINGFILEAPPENDER-INFO" />
<!-- 设置异步阻塞队列的大小,为了不丢失日志建议设置的大一些,单机压测时100000是没问题的,应该不用担心OOM -->
<queueSize>10000</queueSize>
<!-- 设置丢弃DEBUG、TRACE、INFO日志的阀值,不丢失 -->
<discardingThreshold>0</discardingThreshold>
<!-- 设置队列入队时非阻塞,当队列满时会直接丢弃日志,但是对性能提升极大 -->
<neverBlock>true</neverBlock>
</appender>
<!-- 将项目本次运行DEBUG日志同步输出到文件,按照每天生成日志文件,会自动拼接上一次日志 -->
<appender name="APPENDER-ROLLINGFILEAPPENDER-DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 过滤器,只记录 info 级别以上的日志 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<!--立即刷新,设置成false可以提高日志吞吐量-->
<immediateFlush>false</immediateFlush>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 日志文件输出的文件名:
%d:可以包含一个Java.text.SimpleDateFormat指定的时间格式
%i:自增数字
-->
<fileNamePattern>${LOG_PATH}/${MACHINE_IP}/${VIRTUAL_IP}/HISTORY/${LOG_NAME}-debug-%d{yyyy-MM-dd}-index%i.log</fileNamePattern>
<!-- 日志文件保存历史数量:控制保留的归档文件的最大数量,如果超出数量就删除旧文件 -->
<maxHistory>10</maxHistory>
<!-- 文件大小超过100MB归档 -->
<maxFileSize>20MB</maxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>
</appender>
<!-- 将项目本次运行DEBUG日志异步输出到文件,按照每天生成日志文件,会自动拼接上一次日志 -->
<appender name="ASYNC-APPENDER-ROLLINGFILEAPPENDER-DEBUG" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="APPENDER-ROLLINGFILEAPPENDER-DEBUG" />
<!-- 设置异步阻塞队列的大小,为了不丢失日志建议设置的大一些,单机压测时100000是没问题的,应该不用担心OOM -->
<queueSize>10000</queueSize>
<!-- 设置丢弃DEBUG、TRACE、INFO日志的阀值,不丢失 -->
<discardingThreshold>0</discardingThreshold>
<!-- 设置队列入队时非阻塞,当队列满时会直接丢弃日志,但是对性能提升极大 -->
<neverBlock>true</neverBlock>
</appender>
<!-- 将项目本次运行ERROR日志同步输出到文件,按照每天生成日志文件,会自动拼接上一次日志 -->
<appender name="APPENDER-ROLLINGFILEAPPENDER-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 过滤器,只记录error级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!--立即刷新,设置成false可以提高日志吞吐量-->
<immediateFlush>false</immediateFlush>
<!-- 每天生成一个日志文件,保存30天的日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 日志文件输出的文件名:按天回滚 daily -->
<fileNamePattern>${LOG_PATH}/${MACHINE_IP}/${VIRTUAL_IP}/HISTORY/${LOG_NAME}-error-%d{yyyy-MM-dd}-index%i.log</fileNamePattern>
<!-- 日志文件保留天数 -->
<maxHistory>10</maxHistory>
<!-- 文件大小超过100MB归档 -->
<maxFileSize>20MB</maxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<appender name="ASYNC-APPENDER-ROLLINGFILEAPPENDER-ERROR" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="APPENDER-ROLLINGFILEAPPENDER-ERROR" />
<!-- 设置异步阻塞队列的大小,为了不丢失日志建议设置的大一些,单机压测时100000是没问题的,应该不用担心OOM -->
<queueSize>10000</queueSize>
<!-- 设置丢弃DEBUG、TRACE、INFO日志的阀值,不丢失 -->
<discardingThreshold>0</discardingThreshold>
<!-- 设置队列入队时非阻塞,当队列满时会直接丢弃日志,但是对性能提升极大 -->
<neverBlock>true</neverBlock>
</appender>
<!--滚动输出到文件(按照天保存):结束-->
<!--输出到LOGSTASH:开始-->
<!-- 将项目本次运行ERROR日志同步输出到文件,按照每天生成日志文件,会自动拼接上一次日志 -->
<appender name="APPENDER-LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<!-- logstash服务器地址-->
<destination>${LOGSTASH_HOST}</destination>
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<pattern>
<pattern>
{
"appName":"${INDEX_NAME}",
"machineIp":"${MACHINE_IP}",
"virtualIp":"${VIRTUAL_IP}",
"serviceName":"${LOG_NAME}",
"timestamp": "%date{\"yyyy-MM-dd'T'HH:mm:ss,SSSZ\"}",
"logLevel":"%level",
"message":"%msg%n",
"traceId": "%X{X-B3-TraceId:-}",
"spanId": "%X{X-B3-SpanId:-}",
"spanExport": "%X{X-Span-Export:-}"
}
</pattern>
</pattern>
</providers>
</encoder>
</appender>
<appender name="ASYNC-APPENDER-LOGSTASH" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="APPENDER-LOGSTASH" />
<!-- 设置异步阻塞队列的大小,为了不丢失日志建议设置的大一些,单机压测时100000是没问题的,应该不用担心OOM -->
<queueSize>10000</queueSize>
<!-- 设置丢弃DEBUG、TRACE、INFO日志的阀值,不丢失 -->
<discardingThreshold>0</discardingThreshold>
<!-- 设置队列入队时非阻塞,当队列满时会直接丢弃日志,但是对性能提升极大 -->
<neverBlock>true</neverBlock>
</appender>
<!--输出到logstash:结束-->
<!--
开发环境日志级别为DEBUG
level:用来设置打印级别
五个常用打印级别从低至高依次为TRACE、DEBUG、INFO、WARN、ERROR
-->
<springProfile name="dev">
<root>
<!--输出到控制台-->
<appender-ref ref="STDOUT"/>
<!--异步非滚动输出到文件-->
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-INFO"/>
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-DEBUG"/>
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-ERROR"/>
<!--异步滚动输出到文件:dev环境不开启-->
<!-- <appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-INFO"/>-->
<!-- <appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-DEBUG"/>-->
<!-- <appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-ERROR"/>-->
<!--异步滚动输出到logstash-->
<appender-ref ref="ASYNC-APPENDER-LOGSTASH"/>
</root>
</springProfile>
<!-- 测试环境日志级别为INFO -->
<springProfile name="test">
<root>
<!--输出到控制台-->
<appender-ref ref="STDOUT"/>
<!--异步非滚动输出到文件-->
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-INFO"/>
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-DEBUG"/>
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-ERROR"/>
<!--异步滚动输出到文件:test环境不开启-->
<!-- <appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-INFO"/>-->
<!-- <appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-DEBUG"/>-->
<!-- <appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-ERROR"/>-->
<!--异步滚动输出到logstash-->
<appender-ref ref="ASYNC-APPENDER-LOGSTASH"/>
</root>
</springProfile>
<!-- 生产环境日志级别为INFO -->
<springProfile name="prod">
<root>
<!--输出到控制台-->
<appender-ref ref="STDOUT"/>
<!--异步非滚动输出到文件-->
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-INFO"/>
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-DEBUG"/>
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-ERROR"/>
<!--异步滚动输出到文件-->
<appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-INFO"/>
<appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-DEBUG"/>
<appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-ERROR"/>
<!--异步滚动输出到logstash-->
<appender-ref ref="ASYNC-APPENDER-LOGSTASH"/>
</root>
</springProfile>
<!-- rancher环境日志级别为INFO -->
<springProfile name="rancher">
<root>
<!--输出到控制台-->
<appender-ref ref="STDOUT"/>
<!--异步非滚动输出到文件-->
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-INFO"/>
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-DEBUG"/>
<appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-ERROR"/>
<!--异步滚动输出到文件-->
<appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-INFO"/>
<appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-DEBUG"/>
<appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-ERROR"/>
<!--异步滚动输出到logstash-->
<appender-ref ref="ASYNC-APPENDER-LOGSTASH"/>
</root>
</springProfile>
</configuration>
17.9.编写模块config
OpenFeignConfig.java
package org.openatom.springcloud.config;
import feign.Logger;
import feign.Retryer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;
@Configuration
public class OpenFeignConfig {
/**
* NONE:默认的,不显示任何日志;
* BASIC:仅记录请求方法、URL、响应状态码及执行时间;
* HEADERS:除了BASIC中定义的信息之外,还有请求和响应的头信息;
* FULL:除了HEADERS中定义的信息之外,还有请求和响应的正文及元数据。
* @return
*/
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
VirtualIpConfig.java
package org.openatom.springcloud.config;
import ch.qos.logback.core.PropertyDefinerBase;
import lombok.extern.slf4j.Slf4j;
import java.net.InetAddress;
import java.net.UnknownHostException;
@Slf4j
public class VirtualIpConfig extends PropertyDefinerBase {
private static String virtualIp;
static {
try {
virtualIp = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
log.error("获取日志Ip异常", e);
virtualIp = null;
}
}
@Override
public String getPropertyValue() {
return virtualIp;
}
}
17.10.编写模块service
package org.openatom.springcloud.service;
import org.openatom.springcloud.entities.CommonResult;
import org.openatom.springcloud.entities.Payment;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
/**
* 使用系统自带的OpenFeignClient发起调用
*/
@Component
@FeignClient(name="SPRINGCLOUD-BASIC-SAMPLE-PROVIDER-PAYMENT-SERVICE-CLUSTER-DEV")
public interface PaymentServiceOpenFeign {
@PostMapping(value = "/provider/payment/create")
CommonResult create(@RequestBody Payment payment);
@GetMapping(value = "/provider/payment/get/{id}")
CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
/**
* 使用拦截器替换路由服务提供端URL中的占位符
* @param id
* @return
*/
@GetMapping(value = "/provider/$evn/get/{id}")
CommonResult<Payment> getPaymentByIdReplaceRouter(@PathVariable("id") Long id);
@GetMapping(value = "/provider/payment/openfeign/timeout")
String getPaymentByIdTimeout();
}
17.11.编写模块controller
package org.openatom.springcloud.controller;
import lombok.extern.slf4j.Slf4j;
import org.openatom.springcloud.service.PaymentServiceOpenFeign;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.openatom.springcloud.entities.CommonResult;
import org.openatom.springcloud.entities.Payment;
import javax.annotation.Resource;
/**
* DEV环境测试用这个Controller,可以动态获取服务名
*/
@RestController
@Slf4j
public class OrderConsumerController {
//单机版
// public static final String PAYMENT_URL = "http://localhost:8001";
// public static final String PAYMENT_URL = "http://localhost:8002";
@Resource
private PaymentServiceOpenFeign paymentServiceOpenFeign;
@GetMapping("/consumer/payment/create")
public CommonResult<Payment> create(Payment payment) {
return paymentServiceOpenFeign.create(payment);
}
/**
* 测试url:
* http://localhost/consumer/payment/get/1
* @param id
* @return
*/
@GetMapping("/consumer/payment/get/{id}")
public CommonResult<Payment> getPayment(@PathVariable("id") Long id) {
return paymentServiceOpenFeign.getPaymentById(id);
}
/**
* 使用拦截器替换路由服务提供端URL中的占位符
* 测试url:
* http://localhost/consumer/payment/replace_router/get/1
* @param id
* @return
*/
@GetMapping("/consumer/payment/replace_router/get/{id}")
public CommonResult<Payment> getPaymentReplaceRouter(@PathVariable("id") Long id) {
return paymentServiceOpenFeign.getPaymentByIdReplaceRouter(id);
}
@GetMapping("/consumer/payment/openfeign/timeout")
public String getPaymentByIdTimeout() {
return paymentServiceOpenFeign.getPaymentByIdTimeout();
}
}
17.12.编写模块主启动类
package org.openatom.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* 1.使用OpenFeign完成远程调用,如果要配置负载均衡策略,和Ribbon配置负载均衡策略方式相同
* 本微服务主要测试OpenFeign的功能,所以采用YML文件配置Ribbon的负载均衡策略
* 2.OpenFeign是对Ribbon和RestTemplate的封装,所以配置负载均衡方式同Ribbon配置负载均衡方式,而且不需要在容器中手动注入ResTemplate对象
* 3.OpenFeign YML文件配置实现远程调用,但不是完全将服务信息配置在YML中,只是在YML中写一些增强的配置,相关的服务中仍然要写服务名,@FeignClient(name="SPRING-CLOUD-PROVIDER-CONSUL-PAYMENT-SERVICE")
* 4.对每个微服务单独进行配置,如连接超时时间配置、读取超时时间配置,YML没有把OpenFegin的配置和对Ribbon的配置写在一起
* 5.开启OpenFeign增强日志后可以看到Http调用的详细信息
* 2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign : [PaymentServiceOpenFeign#getPaymentById] <--- HTTP/1.1 200 (59ms)
* 2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign : [PaymentServiceOpenFeign#getPaymentById] connection: keep-alive
* 2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign : [PaymentServiceOpenFeign#getPaymentById] content-type: application/json
* 2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign : [PaymentServiceOpenFeign#getPaymentById] date: Tue, 31 May 2022 19:51:37 GMT
* 2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign : [PaymentServiceOpenFeign#getPaymentById] keep-alive: timeout=60
* 2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign : [PaymentServiceOpenFeign#getPaymentById] transfer-encoding: chunked
* 2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign : [PaymentServiceOpenFeign#getPaymentById]
* 2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign : [PaymentServiceOpenFeign#getPaymentById] {"code":200,"message":"查询成功,serverPort: 8006","data":{"id":1,"serial":"15646546546"}}
* 2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign : [PaymentServiceOpenFeign#getPaymentById] <--- END HTTP (94-byte body)
*/
@EnableEurekaClient //添加@EnableEurekaClient好像没什么用,但是还是加上
@SpringBootApplication
@EnableFeignClients
public class OrderServiceConsumerLoadBalanceOpenFeignMultiplyEnv80 {
public static void main(String[] args) {
SpringApplication.run(OrderServiceConsumerLoadBalanceOpenFeignMultiplyEnv80.class, args);
}
}
17.13.搭建Zipkin和ELK
为了更完善的展示添加多环境后支持后,日志系统会针对不同的环境生成对应的日志,完整的日志系统需要Zipkin和ELK的支持,所以先搭建好Zipkin和ELK
在192.168.0.5上搭建Zipkin
详细参考-> 搭建Zipkin 在192.168.0.5上搭建ELK 详细参考-> Docker中安装ELK
17.14.测试让微服务区分多种不同环境
17.14.1.测试多环境运行
dev环境
在浏览器访问
http://localhost:7001/
可以看到服务名为SPRINGCLOUD-CONSUMER-LOADBALANCE-OPENFEIGN-MULTIPLY-ENV-ORDER80-DEV
test环境
在浏览器访问
http://localhost:7001/
可以看到服务名为SPRINGCLOUD-CONSUMER-LOADBALANCE-OPENFEIGN-MULTIPLY-ENV-ORDER80-TEST
17.14.2.测试多环境打包
dev环境
执行如下命令
jar xf springcloud-consumer-loadbalance-openfeign-multiply-env-order80.jar &&
ls BOOT-INF/classes/
查看jar包中使用的配置文件
application.yml application-dev.yml logback-custom.xml org
只包含了application-dev.yml这个多环境配置文件,其他的多环境配置配置都没有被包含进来
test环境
执行如下命令
jar xf springcloud-consumer-loadbalance-openfeign-multiply-env-order80.jar &&
ls BOOT-INF/classes/
查看jar包中使用的配置文件
application.yml application-test.yml logback-custom.xml org
只包含了application-test.yml这个多环境配置文件,其他的多环境配置配置都没有被包含进来
17.14.2.测试多环境输出对应环境的日志
运行系统,产生对应环境的日志
dev环境
在当前项目根目录执行命令
ls -R log
log:
localhost
log/localhost:
192.168.0.1
log/localhost/192.168.0.1:
HISTORY SPRINGCLOUD-CONSUMER-LOADBALANCE-OPENFEIGN-MULTIPLY-ENV-ORDER80-DEV-error.log
SPRINGCLOUD-CONSUMER-LOADBALANCE-OPENFEIGN-MULTIPLY-ENV-ORDER80-DEV-debug.log SPRINGCLOUD-CONSUMER-LOADBALANCE-OPENFEIGN-MULTIPLY-ENV-ORDER80-DEV-info.log
log/localhost/192.168.0.1/HISTORY:
SPRINGCLOUD-CONSUMER-LOADBALANCE-OPENFEIGN-MULTIPLY-ENV-ORDER80-DEV-debug-2022-08-31-index0.log
SPRINGCLOUD-CONSUMER-LOADBALANCE-OPENFEIGN-MULTIPLY-ENV-ORDER80-DEV-error-2022-08-31-index0.log
SPRINGCLOUD-CONSUMER-LOADBALANCE-OPENFEIGN-MULTIPLY-ENV-ORDER80-DEV-info-2022-08-31-index0.log
可以看到了生成了dev环境的日志
test环境
在当前项目根目录执行命令
ls -R log
log:
localhost
log/localhost:
192.168.0.1
log/localhost/192.168.0.1:
HISTORY SPRINGCLOUD-CONSUMER-LOADBALANCE-OPENFEIGN-MULTIPLY-ENV-ORDER80-TEST-error.log
SPRINGCLOUD-CONSUMER-LOADBALANCE-OPENFEIGN-MULTIPLY-ENV-ORDER80-TEST-debug.log SPRINGCLOUD-CONSUMER-LOADBALANCE-OPENFEIGN-MULTIPLY-ENV-ORDER80-TEST-info.log
log/localhost/192.168.0.1/HISTORY:
SPRINGCLOUD-CONSUMER-LOADBALANCE-OPENFEIGN-MULTIPLY-ENV-ORDER80-TEST-debug-2022-08-31-index0.log
SPRINGCLOUD-CONSUMER-LOADBALANCE-OPENFEIGN-MULTIPLY-ENV-ORDER80-TEST-error-2022-08-31-index0.log
SPRINGCLOUD-CONSUMER-LOADBALANCE-OPENFEIGN-MULTIPLY-ENV-ORDER80-TEST-info-2022-08-31-index0.log
可以看到了生成了test环境的日志
评论