mirror of
https://gitee.com/dromara/RuoYi-Vue-Plus.git
synced 2026-09-20 10:13:28 +08:00
添加 网关模块
This commit is contained in:
parent
ff1c729385
commit
7da40951e7
7
pom.xml
7
pom.xml
@ -31,6 +31,7 @@
|
|||||||
<hutool.version>5.7.11</hutool.version>
|
<hutool.version>5.7.11</hutool.version>
|
||||||
<guava.version>29.0-jre</guava.version>
|
<guava.version>29.0-jre</guava.version>
|
||||||
<feign.version>3.0.3</feign.version>
|
<feign.version>3.0.3</feign.version>
|
||||||
|
<gateway.version>3.0.3</gateway.version>
|
||||||
<feign-okhttp.version>11.6</feign-okhttp.version>
|
<feign-okhttp.version>11.6</feign-okhttp.version>
|
||||||
<okhttp.version>4.9.1</okhttp.version>
|
<okhttp.version>4.9.1</okhttp.version>
|
||||||
<spring-boot-admin.version>2.5.1</spring-boot-admin.version>
|
<spring-boot-admin.version>2.5.1</spring-boot-admin.version>
|
||||||
@ -155,6 +156,12 @@
|
|||||||
<version>${guava.version}</version>
|
<version>${guava.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-gateway</artifactId>
|
||||||
|
<version>${gateway.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.cloud</groupId>
|
<groupId>org.springframework.cloud</groupId>
|
||||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>ruoyi-monitor-admin</module>
|
<module>ruoyi-monitor-admin</module>
|
||||||
|
<module>ruoyi-isc-gateway</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
45
ruoyi-extend/ruoyi-isc-gateway/pom.xml
Normal file
45
ruoyi-extend/ruoyi-isc-gateway/pom.xml
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?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>ruoyi-vue-plus</artifactId>
|
||||||
|
<groupId>com.ruoyi</groupId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
<relativePath>../../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>ruoyi-isc-gateway</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-gateway</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>io.lettuce</groupId>
|
||||||
|
<artifactId>lettuce-core</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>redis.clients</groupId>
|
||||||
|
<artifactId>jedis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- pool 对象池 -->
|
||||||
|
<!--<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-pool2</artifactId>
|
||||||
|
</dependency>-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.codecentric</groupId>
|
||||||
|
<artifactId>spring-boot-admin-starter-client</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
package com.ruoyi.gateway;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启动程序
|
||||||
|
*
|
||||||
|
* @author Wenchao Gong
|
||||||
|
* @date 2021-09-11
|
||||||
|
*/
|
||||||
|
@SpringBootApplication
|
||||||
|
public class GatewayApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(GatewayApplication.class, args);
|
||||||
|
System.out.println("Gateway 启动成功" );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
package com.ruoyi.gateway.config;
|
||||||
|
|
||||||
|
import com.ruoyi.gateway.config.provider.ComplexRouteDefinitionRepository;
|
||||||
|
import com.ruoyi.gateway.config.provider.RedisRouteDefinitionRepository;
|
||||||
|
import org.springframework.cloud.gateway.route.InMemoryRouteDefinitionRepository;
|
||||||
|
import org.springframework.cloud.gateway.route.RouteDefinition;
|
||||||
|
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||||
|
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gateway 配置文件
|
||||||
|
*
|
||||||
|
* @author Wenchao Gong
|
||||||
|
* @date 2021-09-11
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class GatewayConfig {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RedisTemplate<String, RouteDefinition> redisTemplate;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RedisTemplate<String, RouteDefinition> redisTemplate(RedisConnectionFactory redisConnectionFactory)
|
||||||
|
{
|
||||||
|
final RedisTemplate<String, RouteDefinition> template = new RedisTemplate<>();
|
||||||
|
template.setConnectionFactory(redisConnectionFactory);
|
||||||
|
Jackson2JsonRedisSerializer<RouteDefinition> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(RouteDefinition.class);
|
||||||
|
template.setValueSerializer(jackson2JsonRedisSerializer);
|
||||||
|
template.setHashValueSerializer(jackson2JsonRedisSerializer);
|
||||||
|
final StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
|
||||||
|
template.setKeySerializer(stringRedisSerializer);
|
||||||
|
template.setHashKeySerializer(stringRedisSerializer);
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RouteDefinitionRepository complexRouteDefinitionRepository()
|
||||||
|
{
|
||||||
|
return new ComplexRouteDefinitionRepository(inMemoryRouteDefinitionRepository(), redisRouteDefinitionRepository());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内存 路由仓库
|
||||||
|
*
|
||||||
|
* @return 本地内存路由仓库
|
||||||
|
*/
|
||||||
|
RouteDefinitionRepository inMemoryRouteDefinitionRepository()
|
||||||
|
{
|
||||||
|
return new InMemoryRouteDefinitionRepository();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redis 路由仓库
|
||||||
|
*
|
||||||
|
* @return redis路由仓库
|
||||||
|
*/
|
||||||
|
RouteDefinitionRepository redisRouteDefinitionRepository()
|
||||||
|
{
|
||||||
|
return new RedisRouteDefinitionRepository(redisTemplate);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,65 @@
|
|||||||
|
package com.ruoyi.gateway.config.provider;
|
||||||
|
|
||||||
|
import org.springframework.cloud.gateway.route.RouteDefinition;
|
||||||
|
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
|
||||||
|
import reactor.core.publisher.Flux;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复合的路由存储器
|
||||||
|
*
|
||||||
|
* @author Wenchao Gong
|
||||||
|
* @date 2021-09-11
|
||||||
|
*/
|
||||||
|
public class ComplexRouteDefinitionRepository implements RouteDefinitionRepository {
|
||||||
|
|
||||||
|
private RouteDefinitionRepository localCache;
|
||||||
|
private RouteDefinitionRepository remoteReps;
|
||||||
|
|
||||||
|
public ComplexRouteDefinitionRepository(RouteDefinitionRepository localCache, RouteDefinitionRepository remoteReps)
|
||||||
|
{
|
||||||
|
this.localCache = localCache;
|
||||||
|
this.remoteReps = remoteReps;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Flux<RouteDefinition> getRouteDefinitions()
|
||||||
|
{
|
||||||
|
final Flux<RouteDefinition> routeDefinitions = localCache.getRouteDefinitions();
|
||||||
|
return routeDefinitions.collectList().flatMapIterable(list -> {
|
||||||
|
if(list.isEmpty()) {
|
||||||
|
final Flux<RouteDefinition> definitions = remoteReps.getRouteDefinitions();
|
||||||
|
definitions.collectList().flatMapIterable(routes -> {
|
||||||
|
if(!routes.isEmpty()) {
|
||||||
|
routes.stream().map(m -> {
|
||||||
|
routes.add(m);
|
||||||
|
return Mono.just(m);
|
||||||
|
}).forEach(m -> {
|
||||||
|
localCache.save(m);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return routes;
|
||||||
|
}).filter(l -> Objects.nonNull(l)).map(m -> list.add(m)).collectList();
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mono<Void> save(Mono<RouteDefinition> route)
|
||||||
|
{
|
||||||
|
remoteReps.save(route);
|
||||||
|
return localCache.save(route);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mono<Void> delete(Mono<String> routeId)
|
||||||
|
{
|
||||||
|
remoteReps.delete(routeId);
|
||||||
|
return localCache.delete(routeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
package com.ruoyi.gateway.config.provider;
|
||||||
|
|
||||||
|
import org.springframework.cloud.gateway.route.RouteDefinition;
|
||||||
|
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import reactor.core.publisher.Flux;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redis 路由仓库
|
||||||
|
*
|
||||||
|
* @author Wenchao Gong
|
||||||
|
* @date 2021-09-11
|
||||||
|
*/
|
||||||
|
public class RedisRouteDefinitionRepository implements RouteDefinitionRepository {
|
||||||
|
public static final String KEY_ROUTES = "ROUTES::";
|
||||||
|
private final RedisTemplate<String, RouteDefinition> redisTemplate;
|
||||||
|
|
||||||
|
public RedisRouteDefinitionRepository(RedisTemplate<String, RouteDefinition> redisTemplate)
|
||||||
|
{
|
||||||
|
this.redisTemplate = redisTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Flux<RouteDefinition> getRouteDefinitions()
|
||||||
|
{
|
||||||
|
List<RouteDefinition> values = redisTemplate.<String,RouteDefinition>opsForHash().values(KEY_ROUTES);
|
||||||
|
return Flux.fromIterable(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mono<Void> save(Mono<RouteDefinition> route)
|
||||||
|
{
|
||||||
|
return route.flatMap(definition -> {
|
||||||
|
redisTemplate.opsForHash().put(KEY_ROUTES, definition.getId(), definition);
|
||||||
|
return Mono.empty();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mono<Void> delete(Mono<String> routeId)
|
||||||
|
{
|
||||||
|
return routeId.flatMap(id -> {
|
||||||
|
redisTemplate.opsForHash().delete(KEY_ROUTES, id);
|
||||||
|
return Mono.empty();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
--- # 监控配置
|
||||||
|
spring:
|
||||||
|
boot:
|
||||||
|
admin:
|
||||||
|
# Spring Boot Admin Client 客户端的相关配置
|
||||||
|
client:
|
||||||
|
# 增加客户端开关
|
||||||
|
enabled: true
|
||||||
|
# 设置 Spring Boot Admin Server 地址
|
||||||
|
url: http://localhost:9090/admin
|
||||||
|
instance:
|
||||||
|
prefer-ip: true # 注册实例时,优先使用 IP
|
||||||
|
username: ruoyi
|
||||||
|
password: 123456
|
||||||
|
|
||||||
|
--- # redis 配置
|
||||||
|
spring:
|
||||||
|
redis:
|
||||||
|
# 地址
|
||||||
|
host: 192.168.64.128
|
||||||
|
# 端口,默认为6379
|
||||||
|
port: 6379
|
||||||
|
# 数据库索引
|
||||||
|
database: 0
|
||||||
|
# 密码
|
||||||
|
password:
|
||||||
|
# 连接超时时间
|
||||||
|
timeout: 10s
|
||||||
|
# 是否开启ssl
|
||||||
|
ssl: false
|
||||||
|
|
||||||
|
--- # Actuator 监控端点的配置项
|
||||||
|
management:
|
||||||
|
endpoints:
|
||||||
|
web:
|
||||||
|
# Actuator 提供的 API 接口的根目录。默认为 /actuator
|
||||||
|
base-path: /actuator
|
||||||
|
exposure:
|
||||||
|
# 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
|
||||||
|
# 生产环境不建议放开所有 根据项目需求放开即可
|
||||||
|
include: @endpoints.include@
|
||||||
|
endpoint:
|
||||||
|
logfile:
|
||||||
|
external-file: ./logs/sys-console.log
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
server:
|
||||||
|
port: 8090
|
||||||
|
# Spring配置
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: RuoYi-Gateway
|
||||||
|
profiles:
|
||||||
|
active: @profiles.active@
|
||||||
114
ruoyi-extend/ruoyi-isc-gateway/src/main/resources/logback.xml
Normal file
114
ruoyi-extend/ruoyi-isc-gateway/src/main/resources/logback.xml
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration>
|
||||||
|
<property name="log.path" value="./logs"/>
|
||||||
|
<property name="console.log.pattern"
|
||||||
|
value="%red(%d{yyyy-MM-dd HH:mm:ss}) %highlight(%-5level) %green([%thread]) %boldMagenta(%logger{36}) - %msg%n"/>
|
||||||
|
<property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n"/>
|
||||||
|
|
||||||
|
<!-- 控制台输出 -->
|
||||||
|
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>${console.log.pattern}</pattern>
|
||||||
|
<charset>utf-8</charset>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 控制台输出 -->
|
||||||
|
<appender name="file_console" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<file>${log.path}/sys-console.log</file>
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<!-- 日志文件名格式 -->
|
||||||
|
<fileNamePattern>${log.path}/sys-console.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||||
|
<!-- 日志最大 1天 -->
|
||||||
|
<maxHistory>1</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
<charset>utf-8</charset>
|
||||||
|
</encoder>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||||
|
<!-- 过滤的级别 -->
|
||||||
|
<level>INFO</level>
|
||||||
|
</filter>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 系统日志输出 -->
|
||||||
|
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<file>${log.path}/sys-info.log</file>
|
||||||
|
<!-- 循环政策:基于时间创建日志文件 -->
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<!-- 日志文件名格式 -->
|
||||||
|
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||||
|
<!-- 日志最大的历史 60天 -->
|
||||||
|
<maxHistory>60</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
</encoder>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||||
|
<!-- 过滤的级别 -->
|
||||||
|
<level>INFO</level>
|
||||||
|
<!-- 匹配时的操作:接收(记录) -->
|
||||||
|
<onMatch>ACCEPT</onMatch>
|
||||||
|
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||||
|
<onMismatch>DENY</onMismatch>
|
||||||
|
</filter>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<file>${log.path}/sys-error.log</file>
|
||||||
|
<!-- 循环政策:基于时间创建日志文件 -->
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<!-- 日志文件名格式 -->
|
||||||
|
<fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||||
|
<!-- 日志最大的历史 60天 -->
|
||||||
|
<maxHistory>60</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
</encoder>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||||
|
<!-- 过滤的级别 -->
|
||||||
|
<level>ERROR</level>
|
||||||
|
<!-- 匹配时的操作:接收(记录) -->
|
||||||
|
<onMatch>ACCEPT</onMatch>
|
||||||
|
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||||
|
<onMismatch>DENY</onMismatch>
|
||||||
|
</filter>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 用户访问日志输出 -->
|
||||||
|
<appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<file>${log.path}/sys-user.log</file>
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<!-- 按天回滚 daily -->
|
||||||
|
<fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||||
|
<!-- 日志最大的历史 60天 -->
|
||||||
|
<maxHistory>60</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 系统模块日志级别控制 -->
|
||||||
|
<logger name="com.ruoyi" level="info" />
|
||||||
|
<!-- Spring日志级别控制 -->
|
||||||
|
<logger name="org.springframework" level="warn" />
|
||||||
|
|
||||||
|
<root level="info">
|
||||||
|
<appender-ref ref="console" />
|
||||||
|
</root>
|
||||||
|
|
||||||
|
<!--系统操作日志-->
|
||||||
|
<root level="info">
|
||||||
|
<appender-ref ref="file_info" />
|
||||||
|
<appender-ref ref="file_error" />
|
||||||
|
<appender-ref ref="file_console" />
|
||||||
|
</root>
|
||||||
|
|
||||||
|
<!--系统用户操作日志-->
|
||||||
|
<logger name="sys-user" level="info">
|
||||||
|
<appender-ref ref="sys-user"/>
|
||||||
|
</logger>
|
||||||
|
</configuration>
|
||||||
Loading…
Reference in New Issue
Block a user