微服务版后端初始化

This commit is contained in:
yaoyn
2025-02-08 17:51:37 +08:00
parent 54af6be188
commit da009a7cc4
1897 changed files with 429541 additions and 81 deletions

View File

@ -0,0 +1,15 @@
# 基础镜像
FROM nexus.gdyditc.com:8082/openjdk:11-arm64
# author
MAINTAINER xjrsoft
# 挂载目录
VOLUME /home/xjrsoft
# 创建目录
RUN mkdir -p /home/xjrsoft
# 指定路径
WORKDIR /home/xjrsoft
# 复制jar文件到路径
COPY ./xjrsoft-gateway/target/xjrsoft-gateway.jar /home/xjrsoft/xjrsoft-gateway.jar
# 启动认证服务
ENTRYPOINT ["java","-jar","xjrsoft-gateway.jar","-Dfile.encoding=UTF-8"]

154
xjrsoft-gateway/pom.xml Normal file
View File

@ -0,0 +1,154 @@
<?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>xjrsoft-cloud</artifactId>
<groupId>com.xjrsoft</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>xjrsoft-gateway</artifactId>
<properties>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--基于 reactive stream 的redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<!--引入spring-cloud-alibaba-nacos-config依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--引入spring-cloud-alibaba-nacos-config bootstrap依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!--引入sentinel依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!--引入sentinel-datasource-nacos依赖-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<dependency>
<groupId>com.xjrsoft</groupId>
<artifactId>xjrsoft-common-core</artifactId>
<version>${xjrsoft.framework.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Sa-Token 权限认证Reactor响应式集成, 在线文档http://sa-token.dev33.cn/ -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-reactor-spring-boot-starter</artifactId>
</dependency>
<!-- Sa-Token 整合 Redis (使用jackson序列化方式) -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-dao-redis-jackson</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- Sa-Token插件权限缓存与业务缓存分离 -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-alone-redis</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-gateway-spring-boot-starter</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.apache.tomcat.embed</groupId>-->
<!-- <artifactId>tomcat-embed-core</artifactId>-->
<!-- </dependency>-->
<!--caffeine 替换LB 默认缓存实现-->
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,14 @@
package com.xjrsoft.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
//@ComponentScan(value = "com.xjrsoft")
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}

View File

@ -0,0 +1,23 @@
package com.xjrsoft.gateway.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @Author: tzx
* @Date: 2023/10/11 19:43
*/
@Data
@RefreshScope
@Component
@ConfigurationProperties("xjrsoft.common")
public class GatewayConfig {
private List<String> excludeUrls;
private List<String> whiteList;
}

View File

@ -0,0 +1,23 @@
package com.xjrsoft.gateway.config;
import com.xjrsoft.common.core.domain.result.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @author Zexy
*/
@ControllerAdvice
@Slf4j
public class MyExceptionHandler {
@ResponseBody
@ExceptionHandler(value =Exception.class)
public R exceptionHandler(Exception e){
log.error("网关错误", e);
return R.error("网关错误,请联系管理员!");
}
}

View File

@ -0,0 +1,70 @@
package com.xjrsoft.gateway.config;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.exception.DisableLoginException;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import cn.dev33.satoken.reactor.filter.SaReactorFilter;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.xjrsoft.common.core.config.CommonPropertiesConfig;
import com.xjrsoft.common.core.enums.ResponseCode;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* [Sa-Token 权限认证] 配置类
* @author kong
*/
@Configuration
public class SaTokenConfigure {
@Resource
private GatewayConfig gatewayConfig;
// 注册 Sa-Token全局过滤器
@Bean
public SaReactorFilter getSaReactorFilter() {
return new SaReactorFilter()
.addInclude("/**")
.addExclude(gatewayConfig.getExcludeUrls().toArray(new String[0]))
// 认证函数: 每次请求执行
.setAuth(r -> {
// 登录验证 -- 拦截所有路由,并排除/user/doLogin 用于开放登录
SaRouter.match("/**", "/login", StpUtil::checkLogin);
})
// 异常处理方法每次setAuth函数出现异常时进入
.setError(e -> {
if (e instanceof NotLoginException) { // 如果是未登录异常3
return SaResult.get(ResponseCode.UN_AUTHORIZED.getCode(),ResponseCode.UN_AUTHORIZED.getMessage(),null);
} else if(e instanceof NotRoleException) { // 如果是角色异常
return SaResult.get(ResponseCode.REQ_REJECT.getCode(),ResponseCode.REQ_REJECT.getMessage(),null);
} else if(e instanceof NotPermissionException) { // 如果是权限异常
return SaResult.get(ResponseCode.REQ_REJECT.getCode(),ResponseCode.REQ_REJECT.getMessage(),null);
} else if(e instanceof DisableLoginException) { // 如果是被封禁异常
return SaResult.get(ResponseCode.REQ_REJECT.getCode(),ResponseCode.REQ_REJECT.getMessage(),null);
} else { // 普通异常, 输出500 + 异常信息
return SaResult.get(ResponseCode.INTERNAL_SERVER_ERROR.getCode(),ResponseCode.INTERNAL_SERVER_ERROR.getMessage(),null);
}
}).setBeforeAuth(r ->{
// ---------- 设置一些安全响应头 ----------
SaHolder.getResponse()
.setHeader("Access-Control-Allow-Origin","*")
.setHeader("Access-Control-Allow-Methods","POST,GET,OPTIONS,DELETE,PUT")
.setHeader("Access-Control-Max-Age","3600")
.setHeader("Access-Control-Allow-Headers","*");
if("OPTIONS".equals(SaHolder.getRequest().getMethod())){
SaRouter.back();
}
});
}
}

View File

@ -0,0 +1,27 @@
package com.xjrsoft.gateway.config;
import cn.dev33.satoken.stp.StpInterface;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* 自定义权限验证接口扩展
*/
@Component
public class StpInterfaceImpl implements StpInterface {
@Override
public List<String> getPermissionList(Object loginId, String loginType) {
// 返回此 loginId 拥有的权限列表
return new ArrayList<>();
}
@Override
public List<String> getRoleList(Object loginId, String loginType) {
// 返回此 loginId 拥有的角色列表
return new ArrayList<>();
}
}

View File

@ -0,0 +1,49 @@
package com.xjrsoft.gateway.filter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.RequestPath;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.Optional;
/**
* @des 日志
* @author tzx
*/
@Slf4j
@Configuration
@RequiredArgsConstructor
@ConditionalOnProperty(value = "xjrsoft.log.enabled", havingValue = "true", matchIfMissing = true)
public class LogFilter implements GlobalFilter, Ordered {
// @Value("${xjrsoft.log.logType}")
// private String logType;
//
// @Value("${xjrsoft.log.logIgnore}")
// private List<String> logIgnore;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
// ServerHttpResponse response = exchange.getResponse();
RequestPath path = request.getPath();
Optional<HttpMethod> method = Optional.ofNullable(request.getMethod());
method.ifPresent(r -> log.info("请求地址:{}, 方式:{}", path, method.get()));
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}

View File

@ -0,0 +1,4 @@
spring:
profiles:
active: public

View File

@ -0,0 +1,56 @@
server:
port: 9527
spring:
application:
name: gateway-service
cloud:
nacos: #nacos监控
discovery:
server-addr: 10.0.252.1:8848 # nacos 注册中心地址
namespace: ITC
group: DNE
username: nacos
password: ABcd1234@
config:
server-addr: 10.0.252.1:8848 # nacos 配置中心地址
namespace: ITC
group: DNE
username: nacos
password: ABcd1234@
file-extension: yml # 指定格式
extension-configs:
- data-id: magicapi-config.yml #magic api 配置
refresh: true
group: DNE
- data-id: global-config.yml #导入全局配置
refresh: true
group: DNE
- data-id: sa-token-client-config.yml #导入sa-token配置
refresh: true
group: DNE
- data-id: redis-config.yml #导入redis配置
refresh: true
group: DNE
- data-id: gateway.yml #网关配置
refresh: true
group: DNE
sentinel:
transport:
dashboard: localhost:8080 #sentinel dashboard 地址
port: 8719 #默认端口, 如果 被占用,会一直+1 直到未被占用为止
knife4j:
gateway:
enabled: true
strategy: discover
discover:
version: openapi3
enabled: true
tags-sorter: order
operations-sorter: order