前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >springcloud之GateWay

springcloud之GateWay

作者头像
冬天vs不冷
发布2025-01-20 22:07:24
发布2025-01-20 22:07:24
5500
代码可运行
举报
文章被收录于专栏:springbootspringboot
运行总次数:0
代码可运行

1、概述简介

  • SpringCloud GateWay是基于Spring5.0+Spring Boot2.0 和 Project Reator等技术开发的网关,目标是替代Zuul。
  • SpringCloud GateWay是基于WebFlux框架实现的,WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。

GateWay相对Zuul的优点

  • GateWay是基于异步非阻塞,Zuul是一个基于IO阻塞的
  • 动态路由:能够匹配任何请求属性
  • 可以对路由指定Predicate(断言)和Filter(过滤)
  • 集成Hystrix的断路器功能
  • 集成SpringCloud服务发现功能

三大核心概念

  • Rout(路由):路由是构建网关的基本模块,它由ID、目标URL、一些列断言和过滤器组成,如果断言为true则匹配该路由
  • Predicate(断言):可以匹配HTTP请求中所有的内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由
  • Filter(过滤):使用过滤器,可以在请求被路由前或者后对请求进行修改

2、项目搭建

2.1、网关微服务-YML方式

项目结构及jar包

启动类

代码语言:javascript
代码运行次数:0
复制
@SpringBootApplication
@EnableEurekaClient
public class GateWayMain9527 {
    public static void main(String[] args) {
        SpringApplication.run(GateWayMain9527.class,args);
    }
}

单机版yml

代码语言:javascript
代码运行次数:0
复制
server:
  port: 9527

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      routes:
        - id: payment_get               #路由ID,没有固定规则,要求唯一
          uri: http://localhost:8001    #匹配后提供服务的路由地址
          predicates:
            - Path=/payment/get/**      #断言,路径相匹配后进行路由

        - id: payment_port              #路由ID,没有固定规则,要求唯一
          uri: http://localhost:8001    #匹配后提供服务的路由地址
          predicates:
            - Path=/payment/port/**     #断言,路径相匹配后进行路由
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka

调用支付微服务Payment8001

代码语言:javascript
代码运行次数:0
复制
@RestController
@Slf4j
public class PaymentController {
    @Resource
    private PaymentService paymentService;

    @Value("${server.port}")
    private String serverPort;

    @GetMapping(value = "/payment/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){
        Payment payment = paymentService.getPaymentById(id);
        log.info("查询结果:"+payment);
        if(payment != null){
            return new CommonResult<>(200,"查询成功,serverPort: "+serverPort,payment);
        }else {
            return new CommonResult<>(444,"没有记录",null);
        }
    }

    @GetMapping(value = "/payment/port")
    public String getServerPort(){
        return serverPort;
    }

}

1、微服务Payment8001自测

2、通过GateWay网关微服务调用微服务Payment8001自测

这样可以做到隐藏实际端口的功能

2.2、网关微服务-代码中注入
代码语言:javascript
代码运行次数:0
复制
@Configuration
public class GateWayConfig {
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        routes.route("path_route_xc", r -> r.path("/guonei","/guoji").uri("http://news.baidu.com"));
        return routes.build();
    }
}

1、国内新闻

2、国际新闻

3、动态路由

之前使用Ribbon实现复杂均衡,这里GateWay网关实现复杂均衡

启动两个服务端,只有端口不一样

代码语言:javascript
代码运行次数:0
复制
@GetMapping(value = "/payment/port")
public String getServerPort(){
    return serverPort;
}

网关微服务yml

代码语言:javascript
代码运行次数:0
复制
server:
  port: 9527

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true   # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: payment_get                          # 路由的id,没有固定的规则但要求统一,建议配合服务名
          uri: lb://cloud-payment-service          # lb表示负载均衡
          predicates:                              # 断言
            - Path=/payment/get/**                 # 指定的路径才可生效


        - id: payment_port                         # 路由的id,没有固定的规则但要求统一,建议配合服务名
          uri: lb://cloud-payment-service          # lb表示负载均衡
          predicates:
            - Path=/payment/port/**                # 断言,路径相对应的进行路由
eureka:
  client:
    service-url:
      fetch-registry: true
      # true将服务注册到eureka
      register-with-eureka: true
#      单机版Eureka
      defaultZone: http://localhost:7001/eureka

访问获取端口的url

第一次

第二次

4、predicate断言

同时满足这些条件才能路由对应的url

5、自定义过滤器

代码语言:javascript
代码运行次数:0
复制
@Component
@Slf4j
public class LogGatewayFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("*****come in LogGatewayFilter"+ new Date());
        String username = exchange.getRequest().getQueryParams().getFirst("username");
        if (StringUtils.isEmpty(username)){
            log.info("***用户名为空,非法进入");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    //过个过滤器顺序,越小越先执行
    public int getOrder() {
        return 0;
    }
}

正常访问

带username参数访问

无效访问

不带username参数访问

这里相当于用username参数识别请求,只过滤带username参数的请求,无此参数,将被拒绝请求访问

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-01-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、概述简介
  • 2、项目搭建
    • 2.1、网关微服务-YML方式
    • 2.2、网关微服务-代码中注入
  • 3、动态路由
  • 4、predicate断言
  • 5、自定义过滤器
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档