Spring Cloud(二):使用Gradle搭建Gateway

一.创建gradle项目(步骤省略)

二.添加Gateway所需的mvn依赖

buildscript {
    ext{
        springBootVersion = '2.1.7.RELEASE'    
    }
    repositories {
         maven{ url 'http://nexus.d17w.cn:9092/nexus/content/groups/public'}
         maven{ url 'http://repo.spring.io/libs-milestone'}
    }
    dependencies {
        classpath ( "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath ( "io.spring.gradle:dependency-management-plugin:1.0.8.RELEASE")
        classpath ( "com.bmuschko:gradle-cargo-plugin:2.6.1")
    }
}

apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'


group 'com.claimplat'
version = '1.0.0'
sourceCompatibility = 1.8
targetCompatibility = 1.8


tasks.withType(JavaCompile){
    options.encoding = "UTF-8"
}

def env = System.getProperty("package.environment") ?: "dev"

repositories {
    maven{ url 'http://nexus.d17w.cn:9092/nexus/content/groups/public'}
    maven{ url 'http://repo.spring.io/libs-milestone'}
}

dependencyManagement{
    imports {
        mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Greenwich.SR2'
    }
}

dependencies {   
        compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-config'
        compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-netflix-eureka-client'
        
        compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-gateway'
        compile group: 'org.springframework.boot', name: 'spring-boot-starter-webflux'
        compile group: 'org.springframework.boot', name: 'spring-boot-autoconfigure'
        compile group: 'org.springframework.boot', name: 'spring-boot-starter-logging'
        compile group: 'org.springframework.boot', name: 'spring-boot-starter-aop'
        compile group: 'org.springframework.boot', name: 'spring-boot-starter-actuator'
        compile group: 'org.springframework.boot', name: 'spring-boot-devtools'
        
        testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test'
        testCompile group: 'junit', name: 'junit'
}


注:添加依赖后需要刷新gradle工程(下载依赖)

三.创建主启动类与配置文件

主启动类如下:

@EnableDiscoveryClient
@SpringBootApplication
public class GatewayApplication implements ApplicationListener{
    
    private static final Logger LOGGER = LoggerFactory.getLogger(GatewayApplication.class);
    
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
    
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if(event instanceof ApplicationEnvironmentPreparedEvent) {
            LOGGER.info("初始化环境变量");
        }else if(event instanceof ApplicationPreparedEvent) {
            LOGGER.info("初始化完成");
        }else if(event instanceof ContextRefreshedEvent) {
            LOGGER.info("应用刷新");
        }else if(event instanceof ApplicationReadyEvent) {
            LOGGER.info("应用已启动完成");
        }else if(event instanceof ContextStartedEvent) {
            LOGGER.info("应用启动");
        }else if(event instanceof ContextStoppedEvent) {
            LOGGER.info("应用停止");
        }else if(event instanceof ContextClosedEvent) {
            LOGGER.info("应用关闭");
        }else {
            //LOGGER.info("其他事件"+event.toString());
        }        
    }
    
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(r -> r.path("/serviceApi/**").filters(f -> f.filter(new MonitoringGatewayFilter()))
                        .uri("lb://claimplat-service-API"))
                .route(r -> r.path("/offline/**").filters(f -> f.filter(new MonitoringGatewayFilter()))
                        .uri("lb://claimplat-offline"))
                
                .route(r -> r.order(11000).path("/baidu")
                        .filters(f -> f.addRequestHeader("x-request-uuid", UUID.randomUUID().toString())
                                .filter(new MonitoringGatewayFilter()))
                        .uri("https://www.baidu.com"))
                .build();
    }

    @Bean
    public RouterFunction defaultRouterFunction(){
        RouterFunction route = RouterFunctions.route(RequestPredicates.path("ack"),
                request -> ServerResponse.ok().body(BodyInserters.fromObject("ack ok")));
        return route;
    }
}

 

filter类如下:

public class MonitoringGatewayFilter implements GatewayFilter,Ordered{
    
    private static final Logger logger = LoggerFactory.getLogger(MonitoringGatewayFilter.class);

    @Override
    public int getOrder() {
        return -2;
    }

    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        URI requestURI = exchange.getRequest().getURI();
        String requestUUID = UUID.randomUUID().toString();
        LocalDateTime beginDateTime = LocalDateTime.now();
        //添加x-request-uuid请求头
        ServerHttpRequest request = exchange.getRequest().mutate().header("x-request-uuid", requestUUID).build();
        ServerWebExchange newExchange = exchange.mutate().request(request).build();
        return chain.filter(newExchange).then(Mono.defer(() -> {
            if(logger.isInfoEnabled()) {
                LocalDateTime endDateTime = LocalDateTime.now();
                Duration duration = Duration.between(beginDateTime,endDateTime);
                String clientIp = RequestUtil.getClientIp(request);
                logger.info("请求的uuid={},请求的ip={},请求的url={},消耗的时间{}ms",requestUUID,clientIp,
                        requestURI.getPath(),duration.toMillis());
            }
            return Mono.empty();
        }));
    }
}


util类如下:

public class RequestUtil {
private static Logger logger = LoggerFactory.getLogger(RequestUtil.class);
    /**获取请求主机IP地址,若通过代理进来则透过防火墙获取真实IP地址
     * @param request
     * @return
     */
    public static String getClientIp(ServerHttpRequest request) {
        try {
            String ip = request.getHeaders().getFirst("X-Real-IP");
            
            if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                if(StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                    ip = request.getHeaders().getFirst("X-Forwarded-For");
                }
                
                if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                    ip = request.getHeaders().getFirst("Proxy-Client-IP");
                }
                
                if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                    ip = request.getHeaders().getFirst("WL-Proxy-Client-IP");
                }
                
                if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                    ip = request.getHeaders().getFirst("HTTP-Client-IP");
                }
                
                if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                    ip = request.getHeaders().getFirst("HTTP-X-Forwarded-For");
                }
                
                if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                    ip = request.getRemoteAddress().getHostString();
                }
            }else if (ip.length() > 15) {
                String[] ips = ip.split(",");
                for(int index = 0; index < ips.length; index++) {
                    String strIP = (String) ips[index];
                    if(!("unknown".equalsIgnoreCase(strIP))) {
                        ip = strIP;
                        break;
                    }
                }
            }
            return ip;
        } catch (Exception e) {
            logger.error("获取IP地址发生错误",e);
            return "";
        }        
    }
}


application.properties配置文件如下:

package.environment=dev
debug=false

server.port=3562
spring.application.name=claimplat-gateway

#eureka client config
eureka.client.serviceUrl.defaultZone=http://localhost:8761/claimplat-eureka/eureka/
eureka.instance.preferIpAddress=true

spring.cloud.gateway.locator.enabled=true


最后,Run As运行(需先运行Eureka再运行Gateway网关)

你可能感兴趣的:(Spring Cloud(二):使用Gradle搭建Gateway)