简单创建一个SpringCloud2021.0.3项目(四)
1. 项目说明
当前这篇教程是:
1. 日志处理
2. 阶段性代码上传博客园
3. Eureka、Config换成Nacos,注册到Nacos,读取Nacos配置
4. Sentinel读取Nacos配置
简单创建一个SpringCloud2021.0.3项目(一)
简单创建一个SpringCloud2021.0.3项目(二)
简单创建一个SpringCloud2021.0.3项目(三)
简单创建一个SpringCloud2021.0.3项目(四)
Sentinel控制台1.8.3修改源码,修改配置后推送到Nacos
1. 版本
- SpringCloud版本为2021.0.3
- SpringBoot版本为2.7.2
2. 用到组件
- 注册中心、配置中心:Nacos
- 网关:Gateway
- 权限:Security,Gateway集成
- 负载均衡:LoadBalancer,SpringCloud2020版之后就集成LoadBalancer
- 限流、熔断降级:Sentinel
- 服务间访问:Feign
3. 功能
- 项目最基本功能,权限控制,在分布式系统中基于Token的身份验证。
- 前端登陆,做了2种方式。用户、密码、验证码;邮箱、验证码、图片滑块;并且前端加密传给后端解密;登陆异常次数限制;
- 限流、负载均衡,应对高并发情况,降低系统负载;
- 服务熔断降级:避免系统雪崩,提高系统可用性;
- 两种方式的多数据源,一种是通过AOP方式动态切换数据源,另一种是不同数据源管理的数据各不相同;
- 日志系统Logback,是SpringBoot默认集成
2. 上三篇教程
简单创建一个SpringCloud2021.0.3项目(一)
简单创建一个SpringCloud2021.0.3项目(二)
简单创建一个SpringCloud2021.0.3项目(三)
简单创建一个SpringCloud2021.0.3项目(四)
- 新建Eureka注册中心
- 新建Config配置中心,producerService服务读取参数
- 2个业务服务(producerService和webService),webService通过Feign调用producerService的服务
- webService用到多数据源,不同的数据源管理不同的数据;security模块测试通过AOP方式动态切换数据源
- 抽取公共模块common,集成redis
- 新建Gateway网关,集成Security,做登陆和资源权限控制
- 前端登陆,做了2种方式。用户、密码、验证码;邮箱、验证码、图片滑块;并且前端加密传给后端解密;登陆异常次数限制
- 在分布式系统中基于Token的身份验证
- 每次请求刷新用户会话有效时间
- Gateway集成Sentinel做限流、熔断降级(超时、异常比例、异常数),集成Sentinel控制台动态配置策略
- SpringCloud 2020版之后就集成LoadBalancer,默认是轮询策略。自定义负载均衡策略,比如某台服务器性能好,可以多分配
3. 日志处理
SpringBoot默认集成logback日志框架
1. 创建日志公共模块
- pom.xml文件
logCommon的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>SpringCloud202208</artifactId>
<groupId>com.xiaostudy</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>logCommon</artifactId>
</project>
- logback-spring.xml配置文件
有注释
<?xml version="1.0" encoding="UTF-8"?>
<!-- 一、根节点<configuration>,包含下面三个属性-->
<!--1.scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true-->
<!--2.scanPeriod: 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。-->
<!--3.debug: 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。-->
<configuration scan="true">
<!--注册转换器,颜色转化器。spring默认,自定义logback.xml就加上-->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- 二、子节点<property> -->
<!--子节点<property name="" value=""> 用来定义变量值,它有两个属性name和value,通过<property>定义的值会被插入到logger上下文中,可以使“${}”来使用变量。-->
<!--子节点<property resource=""/> :用来引入外部属性文件,可以使“${}”来使用变量。例如<property resource="logback.properties"/>-->
<!-- <property name="LOG_FILE_NAME" value="kvf-admin-preview"/>-->
<!--取yml里面参数-->
<springProperty scope="context" name="LOG_FILE_NAME" source="spring.application.name" defaultValue="application"/>
<springProperty scope="context" name="LOG_PATH" source="logging.file.path" defaultValue="/tmp/"/>
<!--最大日志级别,yml里面配置-->
<springProperty scope="context" name="MAX_LEVEL" source="logging.level.org.springframework.boot" defaultValue="TRACE"/>
<!--控制台日志级别-->
<springProperty scope="context" name="CONSOLE_LEVEL" source="logging.level.console" defaultValue="TRACE"/>
<!-- 日志文件目录(按环境分) -->
<!-- <springProfile name="dev">
<property name="LOG_PATH" value="D://logs"/>
</springProfile> -->
<!-- <springProfile name="test">-->
<!-- <property name="LOG_PATH" value="/tmp/logs/kvf-admin"/>-->
<!-- </springProfile>-->
<!-- <springProfile name="prod">-->
<!-- <property name="LOG_PATH" value="/tmp/logs/kvf-admin"/>-->
<!-- </springProfile>-->
<!-- 文件的保存最大天数 -->
<property name="MAX_HISTORY" value="10"/>
<!-- 文件的最大文件大小 -->
<property name="MAX_FILE_SIZE" value="10MB"/>
<!-- 日志字符编码 -->
<property name="CHARSET" value="UTF-8"/>
<!-- 控制日志是否在控制台打印,默认打印 -->
<property name="IS_OPEN_CONSOLE" value="true"/>
<!--文件info日志级别-->
<property name="FILE_INFO_LEVEL" value="INFO"/>
<!--文件错误日志级别-->
<property name="FILE_ERROR_LEVEL" value="ERROR"/>
<!--日志输出格式-->
<!--控制台-彩色-->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p})
%clr(${PID:- }){magenta} %clr(-){faint} %clr([%15.15t]){faint} %clr([%3L]){blue} %clr(%-40.40logger{39})
{cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!--文件-黑白-->
<property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n" />
<!-- 三、子节点<contextName>:用来设置上下文名称,每个logger都关联到logger上下文,默认上下文名称为default。
但可以使用<contextName>设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改。-->
<contextName>${springApplicationName}</contextName>
<!-- 四、子节点<appender>:负责写日志的组件,它有两个必要属性name和class。
name指定appender名称,class指定appender的全限定名 -->
<!--4.1 class为ch.qos.logback.core.ConsoleAppender 把日志输出到控制台-->
<!--4.2 class为ch.qos.logback.core.FileAppender 把日志添加到文件-->
<!--4.3 class为ch.qos.logback.core.rolling.RollingFileAppender
滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件-->
<!-- 控制台输出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>${CONSOLE_LEVEL}</level>
</filter>
<encoder>
<!-- <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>-->
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<!-- 控制台也要使用UTF-8,不要使用GBK,否则会中文乱码 -->
<charset>${CHARSET}</charset>
</encoder>
</appender>
<!--日志记录器,日期滚动记录,按照每天生成日志文件 -->
<appender name="FILE-INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${LOG_FILE_NAME}_info.log</file>
<!-- 如果true,事件被追加到现存文件尾部。如果false,清空现存文件.默认为true -->
<append>true</append>
<!--临界值过滤器,过滤掉低于指定临界值的日志。当日志级别等于或高于临界值时,过滤器返回NEUTRAL;当日志级别低于临界值时,日志会被拒绝-->
<!-- 此日志文件只记录INFO级别的 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>${FILE_INFO_LEVEL}</level>
</filter>
<!--当发生滚动时,决定RollingFileAppender的行为-->
<!--日志记录器的滚动策略,按日期,按大小记录,涉及文件移动和重命名-->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,例如今天是2018-09-21日志,当前写的日志文件路径为file节点指定,
可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
而2018-09-21的归档日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<!--即file和fileNamePattern同时制定,当天日志名由file决定,前一天的文件名将自动改为fileNamePattern的值-->
<!-- 若要加一层时间目录-->
<fileNamePattern>${LOG_PATH}/${LOG_FILE_NAME}_info.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--控制被保留的归档文件的最大数量,超出数量就删除旧文件-->
<!--日志文件保留天数 -->
<maxHistory>${MAX_HISTORY}</maxHistory>|
<!--指定文件的大小-->
<maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
</rollingPolicy>
<encoder>
<pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
</pattern>
</encoder>
<!-- 日志文件的格式。负责两件事,一是把日志信息转换成字节数组,二是把字节数组写入到输出流-->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>${FILE_LOG_PATTERN}</pattern>
<!--日志字符编码格式-->
<charset>${CHARSET}</charset>
</encoder>
</appender>
<appender name="FILE-ALL" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${LOG_FILE_NAME}_all.log</file>
<append>true</append>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${LOG_FILE_NAME}_all.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxHistory>${MAX_HISTORY}</maxHistory>
<maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${CHARSET}</charset>
</encoder>
</appender>
<appender name="FILE-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${LOG_FILE_NAME}_error.log</file>
<append>true</append>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${LOG_FILE_NAME}_error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxHistory>${MAX_HISTORY}</maxHistory>
<maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${CHARSET}</charset>
</encoder>
</appender>
<!-- 五、子节点<logger>:用来设置某一个包或具体的某一个类的日志打印级别、以及指定<appender>。
<logger>仅有一个name属性,一个可选的level和一个可选的addtivity属性。
可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个logger-->
<!-- <logger name="com.xiaostudy" level="INFO"/>-->
<logger name="org.springframework.boot.web" level="INFO">
<appender-ref ref="CONSOLE" />
</logger>
<!-- 六、子节点<root>:它也是<logger>元素,但是它是根logger,是所有<logger>的上级。只有一个level属性,因为name已经被命名为"root",且已经是最上级了。-->
<!-- 生产环境下,将此级别配置为适合的级别,以免日志文件太多或影响程序性能 -->
<!--这里改level-->
<root level="${MAX_LEVEL}">
<appender-ref ref="FILE-ALL"/>
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE-INFO"/>
<appender-ref ref="FILE-ERROR"/>
</root>
<!--
1. <logger>和<root>至少要有一个,不然不会有任何日志。
2. application配置文件里面logging.level.org.springframework.boot参数配置的等级优先级最高。
如果application里参数为INFO,那么这个日志配置文件里面最大只能控制到INFO级别,TRACE和DEBUG级别的控制不到。
3. <appender><filter><level>的参数配置中等,就低于application配置。
4. 某一个<appender>只使用<logger>而不使用<root>时,<logger>的level参数是指定到包及下所有子包的级别日志,不指定的包是不会打印任何日志。
5. 某一个<appender>同时使用<logger>和<root>时,<logger>的level参数是指定到包及下所有子包的级别日志,不指定的包会根据<appender><filter><level>的参数级别。
6. <root>的level没有任何作用,只是标识方便看。例如可以设置为test可以
-->
</configuration>
无注释
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<springProperty scope="context" name="LOG_FILE_NAME" source="spring.application.name" defaultValue="application"/>
<springProperty scope="context" name="LOG_PATH" source="logging.file.path" defaultValue="/tmp/"/>
<springProperty scope="context" name="MAX_LEVEL" source="logging.level.org.springframework.boot" defaultValue="TRACE"/>
<springProperty scope="context" name="CONSOLE_LEVEL" source="logging.level.console" defaultValue="TRACE"/>
<property name="MAX_HISTORY" value="10"/>
<property name="MAX_FILE_SIZE" value="10MB"/>
<property name="CHARSET" value="UTF-8"/>
<property name="IS_OPEN_CONSOLE" value="true"/>
<property name="FILE_INFO_LEVEL" value="INFO"/>
<property name="FILE_ERROR_LEVEL" value="ERROR"/>
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p})
%clr(${PID:- }){magenta} %clr(-){faint} %clr([%15.15t]){faint} %clr([%3L]){blue} %clr(%-40.40logger{39})
{cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n" />
<contextName>${springApplicationName}</contextName>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>${CONSOLE_LEVEL}</level>
</filter>
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>${CHARSET}</charset>
</encoder>
</appender>
<appender name="FILE-INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${LOG_FILE_NAME}_info.log</file>
<append>true</append>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>${FILE_INFO_LEVEL}</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${LOG_FILE_NAME}_info.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxHistory>${MAX_HISTORY}</maxHistory>|
<maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
</rollingPolicy>
<encoder>
<pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
</pattern>
</encoder>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${CHARSET}</charset>
</encoder>
</appender>
<appender name="FILE-ALL" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${LOG_FILE_NAME}_all.log</file>
<append>true</append>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${LOG_FILE_NAME}_all.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxHistory>${MAX_HISTORY}</maxHistory>
<maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${CHARSET}</charset>
</encoder>
</appender>
<appender name="FILE-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${LOG_FILE_NAME}_error.log</file>
<append>true</append>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${LOG_FILE_NAME}_error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxHistory>${MAX_HISTORY}</maxHistory>
<maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${CHARSET}</charset>
</encoder>
</appender>
<logger name="org.springframework.boot.web" level="INFO">
<appender-ref ref="CONSOLE" />
</logger>
<root level="${MAX_LEVEL}">
<appender-ref ref="FILE-ALL"/>
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE-INFO"/>
<appender-ref ref="FILE-ERROR"/>
</root>
</configuration>
- 配置文件application-log.yml
点击查看代码
logging:
file:
# 存放日志文件及文件名称。相对路径是从父模块目录开始,例如父模块目录为E:/my_code/SpringCloud202208,那么下面就等同于绝对路径E:/my_code/SpringCloud202208/logs/${spring.application.name}
# path: logs/${spring.application.name}
path: E:/my_code/SpringCloud202208/logs/${spring.application.name}
level:
org:
springframework:
# 日志级别TRACE、DEBUG、INFO、WARN和ERROR,这个优先级最高,大于日志配置文件里面配置的
boot: ${log.level}
# 控制台日志级别,logback-spring.xml用到参数
console: ${log.level}
2. Eureka引入日志模块
- 添加依赖
<dependency>
<groupId>com.xiaostudy</groupId>
<artifactId>logCommon</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
- 配置文件配置参数
此时的配置文件
server:
port: '@eureka.port@'
eureka:
url-name: '@eureka.url.name@'
instance:
hostname: '@eureka.ip@'
# 每隔这个时间会主动心跳一次,默认值为30s
leaseRenewalIntervalInSeconds: 25
server:
# 自我保护机制,默认权重0.85。默认情况下会报警告,资料:https://blog.csdn.net/hadues/article/details/105023709
renewalPercentThreshold: 0.49
client:
# 声明是否将自己的信息注册到Eureka服务器上
registerWithEureka: false
# 是否到Eureka服务器中抓取注册信息
fetchRegistry: false
serviceUrl:
defaultZone: http://@eureka.user.name@:@eureka.user.password@@${eureka.instance.hostname}:${server.port}/${eureka.url-name}/
spring:
application:
name: '@eureka.application.name@'
security:
user:
name: '@eureka.user.name@'
password: '@eureka.user.password@'
profiles:
# 使用的配置文件后缀application-log.yml
active: log
log:
# level: DEBUG
level: INFO
- 启动Eureka
4. 到此的功能代码
https://files.cnblogs.com/files/xiaostudy/SpringCloud202208.7z?t=1661694659
5. 注册中心换成nacos
1. 下载安装
GitHub地址:https://github.com/alibaba/nacos/releases/2.1.1
下载2.1.1版本:https://github.com/alibaba/nacos/releases/download/2.1.1/nacos-server-2.1.1.zip
找一个库,执行/conf/nacos-mysql.sql,这里用test_nacos库
设置/conf/application.properties数据库信息、开启密码验证
设置单机启动,不是集群的话,这里演示只用单机
启动nacos
登陆
修改密码
2. 添加命名空间
6. Gateway修改为注册在nacos
- 修改依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>${nacos.version}</version>
</dependency>
- 父模块添加参数
此时父模块的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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
<relativePath/>
</parent>
<groupId>com.xiaostudy</groupId>
<artifactId>SpringCloud202208</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>eureka</module>
<module>config</module>
<module>producerService</module>
<module>feign</module>
<module>webService</module>
<module>common</module>
<module>security</module>
<module>gateway</module>
<module>logCommon</module>
</modules>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<java.version>1.8</java.version>
<spring-cloud.version>2021.0.3</spring-cloud.version>
<eureka.application.name>EUREKA-SERVICE</eureka.application.name>
<eureka.ip>localhost</eureka.ip>
<eureka.port>9900</eureka.port>
<eureka.url.name>eureka</eureka.url.name>
<eureka.user.name>admin</eureka.user.name>
<eureka.user.password>xiaostudy.test</eureka.user.password>
<nacos.ip>localhost</nacos.ip>
<nacos.port>8848</nacos.port>
<gateway.group>gateway</gateway.group>
<nacos.namespace>test</nacos.namespace>
<package.environment>lw</package.environment>
<nacos.username>nacos</nacos.username>
<nacos.password>xiaostudy.test</nacos.password>
<config.application.name>CONFIG-SERVICE</config.application.name>
<config.port>9901</config.port>
<gateway.application.name>GATEWAY-SERVICE</gateway.application.name>
<gateway.port>9904</gateway.port>
<gateway.version>3.1.3</gateway.version>
<producer.application.name>PRODUCER-SERVICE</producer.application.name>
<producer.port>9902</producer.port>
<web.application.name>WEB-SERVICE</web.application.name>
<web.port>9903</web.port>
<sentinel.version>2021.0.1.0</sentinel.version>
<nacos.version>2021.0.1.0</nacos.version>
<sentinel.port>9909</sentinel.port>
<!-- <spring.profiles.active>dev</spring.profiles.active>-->
<spring.profiles.active>prod</spring.profiles.active>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${parent.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
- 修改配置文件
点击查看代码
server:
port: '@gateway.port@'
spring:
application:
name: '@gateway.application.name@'
cloud:
nacos:
discovery:
server-addr: @nacos.ip@:@nacos.port@
service: ${spring.application.name}
group: '@gateway.group@'
namespace: '@nacos.namespace@-@package.environment@'
username: '@nacos.username@'
password: '@nacos.password@'
loadbalancer:
retry:
# 关闭重试
enabled: false
gateway:
routes:
# 路由的id,没有规定规则但要求唯一,建议配合服务名
- id: '@producer.application.name@'
# 匹配后提供服务的路由地址,LoadBalancer做负载均衡
uri: lb://@producer.application.name@
predicates:
# 断言,路径相匹配的进行路由
- Path=/producer/**
filters:
# 去掉url一级前缀,例如http://localhost:9904/producer/producerTest/getByName,等同于http://localhost:9901/producerTest/getByName
- StripPrefix=1
- id: '@web.application.name@'
uri: lb://@web.application.name@
predicates:
- Path=/web/**
filters:
- StripPrefix=1
sentinel:
# 服务启动直接建立心跳连接,饿汉式
eager: true
filter:
# 手动注入Sentinel的过滤器,关闭Sentinel注入CommonFilter实例
enabled: false
# 限流时,自定义返回内容
scg:
fallback:
response-body: '{"code":200,"status":1,"msg":"服务器暂不可用啦!"}'
mode: response
response-status: 200
transport:
# 指定应用与Sentinel控制台交互的端口,应用本地会起一个该端口占用的HttpServer。如果端口被占用会往后+1,直到没有占用
port: '@sentinel.port@'
dashboard: localhost:9910
redis:
host: localhost
port: 6379
# 默认0
database: 1
lettuce:
pool:
# 连接池最大连接数(使用负值表示没有限制),默认值:8
max-active: 20
# 连接池中的最大空闲连接,默认值:8
max-idle: 10
# 连接池中的最小空闲连接,默认值:0
min-idle: 1
# 连接池最大阻塞等待时间(使用负值表示没有限制),默认值:-1,单位:毫秒
max-wait: 2000
profiles:
# 使用的配置文件后缀application-security.yml。一个或多个,中间英文逗号分开
active: security
web:
application:
name: '@web.application.name@'
- 启动
7. 从nacos读取配置文件
-
把gateway需要的文件放上去
-
gateway添加依赖
-
修改配置文件
点击查看代码
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
service: gateway-service
group: gateway
namespace: test-lw
username: nacos
password: xiaostudy.test
config:
server-addr: localhost:8848
namespace: test-lw
# 使用nacos的配置中心配置覆盖本地配置
enabled: true
username: nacos
password: xiaostudy.test
# 读取单个
# file-extension: yml
# group: test
# prefix: gateway
# 读取多个
extension-configs:
- data-id: gateway.yml
group: test
- data-id: security.yml
group: test
-
重启
-
其他的同样,就不一一说明了,先放nacos的配置文件,分组都是test
gateway.yml
server:
port: 9904
spring:
application:
name: gateway-service
cloud:
loadbalancer:
retry:
# 关闭重试
enabled: false
gateway:
routes:
# 路由的id,没有规定规则但要求唯一,建议配合服务名
- id: producer-service
# 匹配后提供服务的路由地址,LoadBalancer做负载均衡
uri: lb://producer-service
predicates:
# 断言,路径相匹配的进行路由
- Path=/producer/**
filters:
# 去掉url一级前缀,例如http://localhost:9904/producer/producerTest/getByName,等同于http://localhost:9901/producerTest/getByName
- StripPrefix=1
- id: web-service
uri: lb://web-service
predicates:
- Path=/web/**
filters:
- StripPrefix=1
sentinel:
# 服务启动直接建立心跳连接,饿汉式
eager: true
filter:
# 手动注入Sentinel的过滤器,关闭Sentinel注入CommonFilter实例
enabled: false
# 限流时,自定义返回内容
scg:
fallback:
response-body: '{"code":200,"status":1,"msg":"服务器暂不可用啦!"}'
mode: response
response-status: 200
transport:
# 指定应用与Sentinel控制台交互的端口,应用本地会起一个该端口占用的HttpServer。如果端口被占用会往后+1,直到没有占用
port: 9909
dashboard: localhost:9910
redis:
host: localhost
port: 6379
# 默认0
database: 1
lettuce:
pool:
# 连接池最大连接数(使用负值表示没有限制),默认值:8
max-active: 20
# 连接池中的最大空闲连接,默认值:8
max-idle: 10
# 连接池中的最小空闲连接,默认值:0
min-idle: 1
# 连接池最大阻塞等待时间(使用负值表示没有限制),默认值:-1,单位:毫秒
max-wait: 2000
web:
application:
name: web-service
server:
port: 9904
spring:
application:
name: gateway-service
cloud:
loadbalancer:
retry:
# 关闭重试
enabled: false
gateway:
routes:
# 路由的id,没有规定规则但要求唯一,建议配合服务名
- id: producer-service
# 匹配后提供服务的路由地址,LoadBalancer做负载均衡
uri: lb://producer-service
predicates:
# 断言,路径相匹配的进行路由
- Path=/producer/**
filters:
# 去掉url一级前缀,例如http://localhost:9904/producer/producerTest/getByName,等同于http://localhost:9901/producerTest/getByName
- StripPrefix=1
- id: web-service
uri: lb://web-service
predicates:
- Path=/web/**
filters:
- StripPrefix=1
sentinel:
# 服务启动直接建立心跳连接,饿汉式
eager: true
filter:
# 手动注入Sentinel的过滤器,关闭Sentinel注入CommonFilter实例
enabled: false
# 限流时,自定义返回内容
scg:
fallback:
response-body: '{"code":200,"status":1,"msg":"服务器暂不可用啦!"}'
mode: response
response-status: 200
transport:
# 指定应用与Sentinel控制台交互的端口,应用本地会起一个该端口占用的HttpServer。如果端口被占用会往后+1,直到没有占用
port: 9909
dashboard: localhost:9910
redis:
host: localhost
port: 6379
# 默认0
database: 1
lettuce:
pool:
# 连接池最大连接数(使用负值表示没有限制),默认值:8
max-active: 20
# 连接池中的最大空闲连接,默认值:8
max-idle: 10
# 连接池中的最小空闲连接,默认值:0
min-idle: 1
# 连接池最大阻塞等待时间(使用负值表示没有限制),默认值:-1,单位:毫秒
max-wait: 2000
web:
application:
name: web-service
log:
# level: DEBUG
level: INFO
security.yml
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/test1?useUnicode=true&characterEncoding=utf8
username: root
password: 密码
druid2:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/test2?useUnicode=true&characterEncoding=utf8
username: root
password: 密码
mail:
default-encoding: UTF-8
# 阿里云发送服务器地址
host: smtp.mxhichina.com
# 发送人地址
username: liwei@xiaostudy.com
# 密码
password: ENC(密钥)
properties:
mail:
smtp:
starttls:
enable: true
required: true
auth: true
socketFactory:
class: javax.net.ssl.SSLSocketFactory
port: 465
jasypt:
encryptor:
password: 密码
mybatis:
configuration:
# 下划线转驼峰
map-underscore-to-camel-case: true
# 注册映射文件
mapper-locations: mapper/*Mapper.xml
# 注册实体类别名
type-aliases-package: com.xiaostudy.security.entity
session:
# session过期时间,单位秒
timeout: 1800
# timeout: 30
producer.yml
server:
port: 9902
spring:
application:
name: producer-service
cloud:
loadbalancer:
retry:
# 关闭重试
enabled: false
my:
test: nacos-test
web-feign.yml
producer:
application:
name: producer-service
gateway:
application:
name: gateway-service
feign:
client:
config:
default:
# 默认1000
connect-timeout: 5000
read-timeout: 5000
web.yml
server:
port: 9903
spring:
application:
name: web-service
cloud:
loadbalancer:
retry:
# 关闭重试
enabled: false
sentinel:
transport:
# 指定应用与Sentinel控制台交互的端口,应用本地会起一个该端口占用的HttpServer。如果端口被占用会往后+1,直到没有占用
port: 9909
dashboard: localhost:9910
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/test1?useUnicode=true&characterEncoding=utf8
username: root
password: 密码
druid2:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/test2?useUnicode=true&characterEncoding=utf8
username: root
password: 密码
druid3:
driverClassName: oracle.jdbc.OracleDriver
url: jdbc:oracle:thin:@//localhost:1521/ORCL
username: lw
password: 密码
redis:
host: localhost
port: 6379
# 默认0
database: 1
lettuce:
pool:
# 连接池最大连接数(使用负值表示没有限制),默认值:8
max-active: 20
# 连接池中的最大空闲连接,默认值:8
max-idle: 10
# 连接池中的最小空闲连接,默认值:0
min-idle: 1
# 连接池最大阻塞等待时间(使用负值表示没有限制),默认值:-1,单位:毫秒
max-wait: 2000
my:
gateway:
ip: localhost
port: 9904
logback.yml
logging:
file:
# 存放日志文件及文件名称。相对路径是从父模块目录开始,例如父模块目录为E:/my_code/SpringCloud202208,那么下面就等同于绝对路径E:/my_code/SpringCloud202208/logs/${spring.application.name}
# path: logs/${spring.application.name}
path: E:/my_code/SpringCloud202208/logs/${spring.application.name}
level:
org:
springframework:
# 日志级别TRACE、DEBUG、INFO、WARN和ERROR,这个优先级最高,大于日志配置文件里面配置的
boot: ${log.level}
# 控制台日志级别,logback-spring.xml用到参数
console: ${log.level}
gateway的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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.xiaostudy</groupId>
<artifactId>SpringCloud202208</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gateway</name>
<description>gateway</description>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>${nacos.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>${nacos.version}</version>
</dependency>
<!--SpringCloud 2020.*以后的版本默认禁用了bootstrap,导致读取配置文件时读取不到该属性-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.xiaostudy</groupId>
<artifactId>security</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.xiaostudy</groupId>
<artifactId>logCommon</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>${sentinel.version}</version>
</dependency>
<!-- SpringCloud Alibaba Sentinel Gateway -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
<version>${sentinel.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
gateway的本地bootstrap.yml文件
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
service: gateway-service
group: groupTest
namespace: test-lw
username: nacos
password: xiaostudy.test
config:
server-addr: localhost:8848
namespace: test-lw
# 使用nacos的配置中心配置覆盖本地配置
enabled: true
username: nacos
password: xiaostudy.test
# 读取单个
# file-extension: yml
# group: test
# prefix: gateway
# 读取多个
extension-configs:
- data-id: gateway.yml
group: test
- data-id: security.yml
group: test
- data-id: logback.yml
group: test
producer的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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.xiaostudy</groupId>
<artifactId>SpringCloud202208</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>producerService</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>producerService</name>
<description>producerService</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--SpringCloud 2020.*以后的版本默认禁用了bootstrap,导致读取配置文件时读取不到该属性-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>${nacos.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>${nacos.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
producer的本地bootstrap.yml文件
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
service: producer-service
group: groupTest
namespace: test-lw
username: nacos
password: xiaostudy.test
config:
server-addr: localhost:8848
namespace: test-lw
# 使用nacos的配置中心配置覆盖本地配置
enabled: true
username: nacos
password: xiaostudy.test
# 读取多个
extension-configs:
- data-id: producer.yml
group: test
web的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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.xiaostudy</groupId>
<artifactId>SpringCloud202208</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>com.xiaostudy</groupId>
<artifactId>webService</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>webService</name>
<description>webService</description>
<dependencies>
<!--SpringCloud 2020.*以后的版本默认禁用了bootstrap,导致读取配置文件时读取不到该属性-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>${nacos.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>${nacos.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>com.xiaostudy</groupId>
<artifactId>feign</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- druid数据源驱动 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<!--MySQL-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- Oracle -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
</dependency>
<dependency>
<groupId>com.oracle.database.nls</groupId>
<artifactId>orai18n</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.xiaostudy</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>${sentinel.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
web的本地bootstrap.yml文件
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
service: web-service
group: groupTest
namespace: test-lw
username: nacos
password: xiaostudy.test
config:
server-addr: localhost:8848
namespace: test-lw
# 使用nacos的配置中心配置覆盖本地配置
enabled: true
username: nacos
password: xiaostudy.test
# 读取多个
extension-configs:
- data-id: web.yml
group: test
- data-id: web-feign.yml
group: test
8. Sentinel配置放nacos,单向,nacos配置Sentinel读取
1. nacos上配置限流和熔断降级
- 限流,组是test,文件格式json
gateway-service-sentinel.json
[
{
"resource": "web-service",
"limitApp": "default",
"grade": 1,
"count": 6,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]
- 熔断降级,这里设置超时
gateway-service-sentinel-degrade.json
[
{
"count":1,
"grade":0,
"limitApp":"default",
"minRequestAmount":1,
"resource":"/webUser/getProducerTest",
"slowRatioThreshold":1,
"statIntervalMs":1000,
"timeWindow":10
}
]
2. gateway服务修改
- 添加依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.8.3</version>
</dependency>
- 本地配置文件修改
点击查看代码
spring:
cloud:
sentinel:
# Map类型,key随便定
datasource:
# 限流
lw1:
nacos:
username: nacos
password: xiaostudy.test
# nacos地址
server-addr: localhost:8848
# 命名空间
namespace: test-lw
# nacos中配置文件的data-id
data-id: ${spring.application.name}-sentinel.json
# nacos 分组
group-id: test
# 规则类型 流控
rule-type: flow
# 降级
lw2:
nacos:
username: nacos
password: xiaostudy.test
server-addr: localhost:8848
namespace: test-lw
data-id: ${spring.application.name}-sentinel-degrade.json
group-id: test
rule-type: degrade
3. 重启gateway服务
4. 测试
-
测超时熔断
-
测限流