Spring Cloud之Gateway网关应⽤

使⽤⽹关对静态化微服务进⾏代理(添加在它的上游,相当于隐藏了具体微服务的信息,对外暴露的是⽹关)。

1. 右键⽗⼯程【 yx-parent 】选择【 New - Module 】选项,然后选择创建【 Maven 】类型项⽬(不勾选模 板),将项⽬名称设置为 注意这⾥不选择⽗⼯程

Spring Cloud之Gateway网关应⽤_第1张图片项⽬的pom.xml⽂件引⼊以下依赖。注意,Gateway不需要使⽤Web模块,使⽤的是 WebFlux(类似于Spring MVC)模块,因此不要引⼊starter-web模块,⽽引⼊的是starter-webflux模块。

    
    
        org.springframework.boot
        spring-boot-starter-parent
        2.1.6.RELEASE
        
    

    
        
            org.springframework.cloud
            spring-cloud-commons
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
        
        
        
            org.springframework.cloud
            spring-cloud-starter-gateway
        
        
        
            org.springframework.boot
            spring-boot-starter-webflux
        
        
        
            org.springframework.boot
            spring-boot-starter-logging
        
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
        
            org.projectlombok
            lombok
            1.18.4
            provided
        
        
        
            com.sun.xml.bind
            jaxb-core
            2.2.11
        
        
            javax.xml.bind
            jaxb-api
        
        
            com.sun.xml.bind
            jaxb-impl
            2.2.11
        
        
            org.glassfish.jaxb
            jaxb-runtime
            2.2.10-b140310.1920
        
        
            javax.activation
            activation
            1.1.1
        
        
        
        
            org.springframework.boot
            spring-boot-starter-actuator
        
        
        
            org.springframework.boot
            spring-boot-devtools
            true
        
        
        
            org.springframework.cloud
            spring-cloud-starter-sleuth
        
        
            org.springframework.cloud
            spring-cloud-starter-zipkin
        
    

    
        
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                Greenwich.RELEASE
                pom
                import
            
        
    

    
        
            
            
                org.apache.maven.plugins
                maven-compiler-plugin
                
                    1.8
                    1.8
                    utf-8
                
            
            
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    
3. 如果导⼊ Maven 依赖后,提示 'parent.relativePath' of POM com.yx:yx-cloud-gateway:1.0-SNAPSHOT 问题,则 解决⽅案是在 标签中加上 标签,然后重新编译,解决问题

Spring Cloud之Gateway网关应⽤_第2张图片

 

错误原因:
1.xxx parent ⾥写的并不是 xxx 的上⼀级,⽽是继承了 Spring Boot
2.Maven 构建 jar 包的时候查找顺序: relativePath 元素中的地址 -> 本地仓库 -> 远程仓库。
3. 设定⼀个空值将始终从仓库中获取,不从本地路径获取。

.在项⽬的com.yx.gateway包下创建GatewayApplication启动类。

package com.qf.product;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient  //将当前的项目标记为注册中心的客户端,然后向注册信息
public class ProductApplication9001 {
    public static void main(String[] args) {
        SpringApplication.run(ProductApplication9001.class,args);
    }
}

在项⽬的resources⽬录下创建application.yml配置⽂件并添加以下内容。

server:
  port: 9300
eureka:
  client:
    serviceUrl: # Eureka Server的路径
      defaultZone: http://YXCloudEurekaServerC:9200/eureka,http://YXCloudEurekaServerD:9201/eureka
  instance:
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}:@project.version@
spring:
  application:
   name: yx-cloud-gateway
  # gateway⽹关配置
  cloud:
    gateway:   # gateway⽹关配置
      routes: # 配置路由
        - id: service-page-router
           # 动态路由:从(消费)注册中⼼获取对应服务的实例
          #lb://表示从注册中心获取服务信息(//后更的是具体服务实例的具体名称)
          uri:  lb://yx-service-page
          predicates: # 当断⾔匹配成功后,则将请求转发给某个微服务
            - Path=/page/**
        - id: service-product-router
          uri: lb://yx-service-product
          predicates:
    # http://127.0.0.1:9300/product/query/1 - /query/1 - 商品微服务
            - Path=/product/**
          filters:
    # 访问uri时,会过滤掉uri中Path取值匹配上的前⼀部分,uri中第⼆部分才是⽬标访问路径
            - StripPrefix=1

Spring Cloud之Gateway网关应⽤_第3张图片

 

⾃定义全局过滤器实现 IP 访问限制
y.filter 包下创建 BlackListGlobalFilter 全局过滤器
package com.qf.product.fifter;

import lombok.extern.slf4j.Slf4j;
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.ServerHttpRequest;
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.util.ArrayList;
import java.util.List;

/**
 * 定义全局过滤器,会对所有路由⽣效
 */
@Slf4j
@Component
public class BlackListGlobalFilter implements GlobalFilter, Ordered {
    // 模拟⿊名单(实际可以去数据库或者Redis中查询)
    private static List blackList = new ArrayList<>();

    static {
        // 模拟本机地址
        blackList.add("127.0.0.1");
        blackList.add("10.48.185.11");
    }

    /**
     * 过滤器核⼼⽅法
     *
     * @param exchange 封装了request和response对象的上下⽂
     * @param chain    ⽹关过滤器链(包含全局过滤器和单路由过滤器)
     * @return
     */
    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        /* 实现思路:获取客户端IP,判断是否在⿊名单中,在的话就拒绝访问,不在的话就放⾏ */
        // 从上下⽂中取出request和response对象
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        // 从request对象中获取客户端IP
        String clientIP = request.getRemoteAddress().getHostString();
        log.info("=====>IP: " + clientIP);
        // 获取到客户端IP后去⿊名单中查询,存在的话就决绝访问
        if (blackList.contains(clientIP)) {
            // 状态码
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            String data = "Request be denied!";
            //响应的字符串转化成字节数组,将来输出返回客户端
            DataBuffer wrap = response.bufferFactory().wrap(data.getBytes());
            // 决绝访问,直接返回指定结果数据
            return response.writeWith(Mono.just(wrap));
        }
        // 合法请求,放⾏,执⾏后续的过滤器
        return chain.filter(exchange);
    }

    /**
     * 返回值表示当前过滤器的顺序(优先级),数值越⼩,优先级越⾼
     */
    @Override
    public int getOrder() {
        return 0;
    }
}

你可能感兴趣的:(spring,cloud,gateway,spring)