0


SpringCloud之Gateway

简介

  Gateway是SpringCloud Alibaba中的路由组件(前身是Zuul),作为浏览器端请求的统一入口。当项目采用微服务模式时,若包含了路由模块,浏览器端的请求都不会直接请求含有业务逻辑的各个业务模块,而是请求这个路由模块,然后再由它来转发到各个业务模块去。

核心概念

  Gateway中的三个核心概念:路由、断言(Predicate)、过滤器。
  路由:由唯一id、目的url、断言和过滤组成
  断言:即路由规则,用来判断哪些请求符合规则,符合的请求进行转发
  过滤器:分为GatewayFilter和GlobalFilter,前者作用于单一路由,后者作用于所有路由。过滤器可以对请求或者返回进行处理,如增加请求头、删除请求头

  配置文件如下:

spring:cloud:gateway:# 网关路由配置routes:# 路由id,自定义,只要唯一即可-id: user-service
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址# 路由的目标地址 lb就是负载均衡,后面跟服务名称,要和nacos的注册中心结合uri: lb://userservice
          # 断言predicates:# 这个是按照路径匹配,只要以/user/开头就符合要求- Path=/user/**# 过滤器filters:# 添加请求头- AddRequestHeader=sign, xn2001.com is eternal

  上面写到了根据路径匹配的断言,Gateway提供了十几种内置的断言:
名称说明示例After是某个时间点之后的请求- After=2022-08-26T18:34:10.475+08:00[Asia/Shanghai]Before是某个时间点之前的请求- Before=2022-11-26T18:34:10.475+08:00[Asia/Shanghai]Between是某两个时间点之前的请求- Between=2022-10-26T18:35:15.093+08:00[Asia/Shanghai], 2022-11-26T18:35:15.093+08:00[Asia/Shanghai]Cookie请求必须包含某些cookie- Cookie=chocolate, ch.pHeader请求必须包含某些header- Header=sign, internalHost请求必须是访问某个host(域名)- Host=**.somehost.org, **.anotherhost.orgMethod请求方式必须是指定方式- Method=GET,POSTPath请求路径必须符合指定规则- Path=/blue/**Query请求参数必须包含指定参数- Query=name, Jack或- Query=nameRemoteAddr请求者的ip必须是指定范围- RemoteAddr=192.168.1.1/24Weight权重处理

  配置中的AddRequestHeader就是其中一种Gateway Filter,还有其余的内置的:
名称说明AddRequestHeader给当前请求添加一个请求头RemoveRequestHeader移除请求中的一个请求头AddResponseHeader给响应结果中添加一个响应头RemoveResponseHeader从响应结果中移除一个响应头RequestRateLimiter限制请求的流量
  全局过滤器,后面的示例给出具体用法

具体示例

  这里新建2个模块,路由模块和用户模块

  用户模块,引入依赖spring-boot-starter-web、spring-cloud-starter-alibaba-nacos-discovery,bootstrap.yml配置端口号、nacos注册中心的地址,并提供接口:

importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.RequestHeader;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.ResponseBody;@Controller@RequestMapping("/user")publicclassUserController{@ResponseBody@RequestMapping("/sayHello")publicStringsayHello(@RequestHeader(value ="sign", 
    required =false)String sign){return"这是好吃的:"+ sign;}}

  路由模块,引入依赖:

<dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config
        </artifactId><version>2.2.0.RELEASE</version></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery
        </artifactId><version>2.2.0.RELEASE</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId><version>2.2.0.RELEASE</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies>

  bootstrap.yml的配置:

server:port:8086servlet:context-path: /gateway

spring:application:name: gateway
  profiles:active: dev
  cloud:nacos:config:server-addr: 127.0.0.1:8848file-extension: yml
      discovery:server-addr: 127.0.0.1:8848

  2个模块都启动后,nacos的服务列表显示:

在这里插入图片描述

  nacos中新建名为gateway-dev.yml的配置,内容为:

spring:cloud:gateway:discovery:locator:# 通过服务名称转发,默认falseenabled:true# 服务名称不用大写lower-case-service-id:true# routes:#   - id: user-service#     uri: lb://supplier#     predicates:#       - Path=/provider/**#     filters:#       - AddRequestHeader=sign, big JavaCoder

  此时,请求路径:http://localhost:8086/supplier/provider/user/sayHello
  注:supplier是服务名称,provider是模块访问路径(server.servlet.context-path)
但这种配置不是很推荐

  把spring.cloud.gateway.discovery及子配置注释掉,把spring.cloud.gateway.routes及子配置取消注释,重启路由模块,这时访问路径:
http://localhost:8086/provider/user/sayHello。
  注:这是访问的路径,经过gateway处理后,实际访问的是lb://supplier/provider/user/sayHello(见RouteToRequestUrlFilter的filter方法);provider是模块访问路径(server.servlet.context-path),如果用户模块没有设置的话,filters下添加- StripPrefix=1,这时访问路径不变,实际的访问路径是lb://supplier/user/sayHello。

GlobalFilter

  处理一切进入网关的请求和响应,并且也是可以编写代码自定义逻辑;在执行顺序上,GatewayFilter先执行,GlobalFilter后执行。

importorg.springframework.cloud.gateway.filter.GatewayFilterChain;importorg.springframework.cloud.gateway.filter.GlobalFilter;importorg.springframework.http.HttpHeaders;importorg.springframework.http.HttpStatus;importorg.springframework.http.server.reactive.ServerHttpRequest;importorg.springframework.http.server.reactive.ServerHttpResponse;importorg.springframework.stereotype.Component;importorg.springframework.web.server.ServerWebExchange;importreactor.core.publisher.Mono;importjava.util.List;@ComponentpublicclassAuthorizeFilterimplementsGlobalFilter{@OverridepublicMono<Void>filter(ServerWebExchange exchange,GatewayFilterChain chain){ServerHttpRequest request = exchange.getRequest();HttpHeaders headers = request.getHeaders();List<String> sign = headers.get("sign");if(sign.size()<1){ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.BAD_REQUEST);//被拦截,请求不到对应模块了return exchange.getResponse().setComplete();}

        headers =HttpHeaders.writableHttpHeaders(headers);
        headers.set("sign1","bigAAA");//放行return chain.filter(exchange);}}

本文转载自: https://blog.csdn.net/gs2436/article/details/128050750
版权归原作者 尚少 所有, 如有侵权,请联系我们删除。

“SpringCloud之Gateway”的评论:

还没有评论