初次提交
This commit is contained in:
@ -0,0 +1,24 @@
|
||||
package com.ho.gateway;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* @author fancl
|
||||
* @desc: 网关gateway
|
||||
* @date 2022/8/9
|
||||
*/
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableDiscoveryClient
|
||||
public class GatewayApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(GatewayApplication.class,args);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package com.ho.gateway.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.reactive.CorsWebFilter;
|
||||
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
|
||||
import org.springframework.web.util.pattern.PathPatternParser;
|
||||
|
||||
@Configuration
|
||||
public class CorsConfig {
|
||||
@Bean
|
||||
public CorsWebFilter corsFilter() {
|
||||
CorsConfiguration config = new CorsConfiguration();
|
||||
config.addAllowedMethod("*");
|
||||
config.addAllowedOrigin("*");
|
||||
config.addAllowedHeader("*");
|
||||
config.setMaxAge(1800L);
|
||||
UrlBasedCorsConfigurationSource source = new
|
||||
UrlBasedCorsConfigurationSource(new PathPatternParser());
|
||||
source.registerCorsConfiguration("/**", config);
|
||||
return new CorsWebFilter(source);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.ho.gateway.config;
|
||||
|
||||
import com.sun.jna.Library;
|
||||
import com.sun.jna.Native;
|
||||
|
||||
public interface NativeLibrary extends Library{
|
||||
|
||||
int CheckLicence();
|
||||
|
||||
NativeLibrary INSTANCE = (NativeLibrary) Native.loadLibrary("/usr/lib/libauth_lib.so", NativeLibrary.class);
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
package com.ho.gateway.config.listnerForNacosServerUpdated;
|
||||
|
||||
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
|
||||
import com.alibaba.cloud.nacos.NacosServiceManager;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.NamingService;
|
||||
import com.alibaba.nacos.api.naming.listener.NamingEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
/**
|
||||
* @author fancl
|
||||
* @desc:
|
||||
* @date 2022/9/20
|
||||
*/
|
||||
@Component
|
||||
public class NacosServerListListener implements ServerListListener{
|
||||
|
||||
@Autowired
|
||||
private NacosServiceManager nacosServiceManager;
|
||||
|
||||
private NamingService namingService;
|
||||
|
||||
@Autowired
|
||||
private NacosDiscoveryProperties properties;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
namingService = nacosServiceManager.getNamingService(properties.getNacosProperties());
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建监听器
|
||||
*/
|
||||
@Override
|
||||
public void listen(String serviceId, ServerEventHandler eventHandler) {
|
||||
try {
|
||||
namingService.subscribe(serviceId, event -> {
|
||||
if (event instanceof NamingEvent) {
|
||||
NamingEvent namingEvent = (NamingEvent) event;
|
||||
// log.info("服务名:" + namingEvent.getServiceName());
|
||||
// log.info("实例:" + namingEvent.getInstances());
|
||||
// 实际更新
|
||||
eventHandler.update();
|
||||
}
|
||||
});
|
||||
} catch (NacosException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,84 @@
|
||||
package com.ho.gateway.config.listnerForNacosServerUpdated;
|
||||
|
||||
import com.netflix.loadbalancer.BaseLoadBalancer;
|
||||
import com.netflix.loadbalancer.ServerListUpdater;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author fancl
|
||||
* @desc:
|
||||
* @date 2022/9/20
|
||||
*/
|
||||
public class NotificationServerListUpdater implements ServerListUpdater {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(NotificationServerListUpdater.class);
|
||||
|
||||
private final ServerListListener listener;
|
||||
|
||||
public NotificationServerListUpdater(ServerListListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始运行
|
||||
*
|
||||
* @param updateAction
|
||||
*/
|
||||
@Override
|
||||
public void start(UpdateAction updateAction) {
|
||||
// 创建监听
|
||||
String clientName = getClientName(updateAction);
|
||||
listener.listen(clientName, () -> {
|
||||
logger.info("{} 服务变化, 主动刷新服务列表缓存", clientName);
|
||||
// 回调直接更新
|
||||
updateAction.doUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过updateAction获取服务名,这种方法比较粗暴
|
||||
*
|
||||
* @param updateAction
|
||||
* @return
|
||||
*/
|
||||
private String getClientName(UpdateAction updateAction) {
|
||||
try {
|
||||
Class<?> bc = updateAction.getClass();
|
||||
Field field = bc.getDeclaredField("this$0");
|
||||
field.setAccessible(true);
|
||||
BaseLoadBalancer baseLoadBalancer = (BaseLoadBalancer) field.get(updateAction);
|
||||
return baseLoadBalancer.getClientConfig().getClientName();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLastUpdate() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDurationSinceLastUpdateMs() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberMissedCycles() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCoreThreads() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package com.ho.gateway.config.listnerForNacosServerUpdated;
|
||||
|
||||
import com.alibaba.cloud.nacos.ribbon.ConditionalOnRibbonNacos;
|
||||
import com.netflix.loadbalancer.ServerListUpdater;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author fancl
|
||||
* @desc:
|
||||
* @date 2022/9/20
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnRibbonNacos
|
||||
public class RibbonConfig {
|
||||
@Bean
|
||||
public ServerListUpdater ribbonServerListUpdater(NacosServerListListener listener) {
|
||||
return new NotificationServerListUpdater(listener);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package com.ho.gateway.config.listnerForNacosServerUpdated;
|
||||
|
||||
/**
|
||||
* @author fancl
|
||||
* @desc:
|
||||
* @date 2022/9/20
|
||||
*/
|
||||
public interface ServerListListener {
|
||||
/**
|
||||
* 监听
|
||||
* @param serviceId 服务名
|
||||
* @param eventHandler 回调
|
||||
*/
|
||||
void listen(String serviceId, ServerEventHandler eventHandler);
|
||||
|
||||
@FunctionalInterface
|
||||
interface ServerEventHandler {
|
||||
void update();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,69 @@
|
||||
package com.ho.gateway.filter;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.ho.gateway.config.NativeLibrary;
|
||||
import com.ho.gateway.config.listnerForNacosServerUpdated.NotificationServerListUpdater;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* @author xueweizhi
|
||||
* @desc: 网关处加过滤器,看请求是否到达网关
|
||||
* @date 2023/4/12
|
||||
*/
|
||||
@Component
|
||||
public class MyGateWayFilter implements GlobalFilter, Ordered {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(NotificationServerListUpdater.class);
|
||||
|
||||
@Value("${isCheckLicence}")
|
||||
boolean isCheckLicence;
|
||||
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||
URI uri = exchange.getRequest().getURI();
|
||||
logger.info("进入网关过滤器,uri:{}", uri);
|
||||
//todo 先注销,当需要检查licence,打开
|
||||
// -1 失败 0 成功
|
||||
if(isCheckLicence){
|
||||
int result = NativeLibrary.INSTANCE.CheckLicence();
|
||||
logger.info("进入网关过滤器,checkLicence result:{}", result);
|
||||
if(0 != result){
|
||||
return this.getResponseError(exchange, "请检查是否取得licence授权!");
|
||||
}
|
||||
}
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
|
||||
private Mono<Void> getResponseError(ServerWebExchange exchange, String msg) {
|
||||
ServerHttpResponse response = exchange.getResponse();
|
||||
JSONObject message = new JSONObject();
|
||||
message.put("code", HttpStatus.UNAUTHORIZED.value());
|
||||
message.put("message", msg);
|
||||
message.put("success", false);
|
||||
byte[] bits = message.toJSONString().getBytes(StandardCharsets.UTF_8);
|
||||
DataBuffer buffer = response.bufferFactory().wrap(bits);
|
||||
response.setStatusCode(HttpStatus.UNAUTHORIZED);
|
||||
//指定编码,否则在浏览器中会中文乱码
|
||||
response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
|
||||
return response.writeWith(Mono.just(buffer));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
58
api-gateway/src/main/resources/application-dev.yml
Normal file
58
api-gateway/src/main/resources/application-dev.yml
Normal file
@ -0,0 +1,58 @@
|
||||
#网关
|
||||
server:
|
||||
port: 8001
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: api-gateway
|
||||
cloud:
|
||||
nacos:
|
||||
username: nacos
|
||||
password: nacos
|
||||
discovery:
|
||||
server-addr: 127.0.0.1:8848
|
||||
#路由配置
|
||||
gateway:
|
||||
routes:
|
||||
#用户中心
|
||||
- id: user_center_route
|
||||
uri: lb://user-center
|
||||
predicates:
|
||||
- Path=/api/sys/**
|
||||
#业务中心
|
||||
- id: business_route
|
||||
uri: lb://business-service
|
||||
predicates:
|
||||
- Path=/api/business/**
|
||||
#数据采集
|
||||
- id: datacollect_route
|
||||
uri: lb://datacollect-service
|
||||
predicates:
|
||||
- Path=/api/datacollect/**
|
||||
#定时任务中心
|
||||
- id: xxl_job_admin_route
|
||||
uri: lb://xxl-job-admin
|
||||
predicates:
|
||||
- Path=/job-admin/**
|
||||
#多媒体文件
|
||||
- id: file_center_route
|
||||
uri: lb://file-center
|
||||
predicates:
|
||||
- Path=/api/media/**
|
||||
|
||||
#告警和流程中心
|
||||
- id: flow_center_route
|
||||
uri: lb://flowable-center
|
||||
predicates:
|
||||
- Path=/api/flow/**
|
||||
|
||||
#actuator监控检查配置
|
||||
management:
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
health:
|
||||
redis:
|
||||
enabled: false
|
||||
#需要校验:true ,不需要校验:false
|
||||
isCheckLicence: false
|
||||
3
api-gateway/src/main/resources/application.yml
Normal file
3
api-gateway/src/main/resources/application.yml
Normal file
@ -0,0 +1,3 @@
|
||||
spring:
|
||||
profiles:
|
||||
active: dev
|
||||
39
api-gateway/src/main/resources/logback.xml
Normal file
39
api-gateway/src/main/resources/logback.xml
Normal file
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE xml>
|
||||
<configuration>
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%date{yyyy-MM-dd HH:mm:ss.SSS,CTT} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="rollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>/home/hocloud/logs/api-gateway/api-gateway.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>/home/hocloud/logs/api-gateway/api-gateway.%d{yyyy-MM-dd}-%i.log
|
||||
</fileNamePattern>
|
||||
<maxHistory>10</maxHistory>
|
||||
<!-- 除按日志记录之外,还配置了日志文件不能超过2M,若超过2M,日志文件会以索引0开始,
|
||||
命名日志文件,例如log-error-2013-12-21.0.log -->
|
||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||
<maxFileSize>512MB</maxFileSize>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%date{yyyy-MM-dd HH:mm:ss.SSS,CTT} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- project default level -->
|
||||
<!-- <logger name="com.sinoinfo.bill" level="DEBUG"/>-->
|
||||
|
||||
<!-- <!–log4jdbc –>-->
|
||||
<!-- <logger name="jdbc.sqltiming" level="DEBUG"/>-->
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="console"/>
|
||||
<appender-ref ref="rollingFile"/>
|
||||
</root>
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user