• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

spring cloud alibaba(看完即入门)——Gateway篇

武飞扬头像
hmb↑
帮助1

五、Gateway网关

常用功能:路由转发、权限校验、限流控制等

5.1、搭建

5.1.1、新建网关模块
5.1.2、依赖

<!--  公共模块-->
 <dependency>
     <groupId>com.example.mall</groupId>
     <artifactId>mall-common</artifactId>
     <version>0.0.1-SNAPSHOT</version>
 </dependency>
 <!--  网关-->
 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-gateway</artifactId>
     <version>2.2.5.RELEASE</version>
 </dependency>

5.1.3、@EnableDiscoveryClient开启服务注册功能
学新通

5.1.4、新建bootstrap.yml 和 application.yml
bootstrap.yml

spring:
  application:
    name: mall-gateway
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        namespace: 6d405b31-5f62-4105-b8a6-339cc0b8464e

application.yml

server:
  port: 88
spring:
  application:
    name: mall-gateway
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848

5.1.5、新建gateway命名空间 和 配置
学新通
5.1.6、排除数据源相关配置
由于我们引入了公共模块,网关不需要配置数据源,不排除数据源配置会报错
学新通

5.2、路由转发(yml新增网关配置)

server:
  port: 88
spring:
  application:
    name: mall-gateway
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
    #网关配置
    gateway:
      routes:
        - id: coupon
          uri: http://127.0.0.1:8881/                   #要去的请求地址
         # uri: lb://mall-coupon                 #路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates:  # 路由断言,也就是判断请求是否符合路由规则的条件
            - Query=url,coupon      # url 带有/coupon就去上方uri地址 例:url=coupon
           # - Path=/coupon/**      # url 这个是按照路径匹配,只要以/coupon开头就符合要求
		   #- After=2037-01-20T17:42:47.789-07:00[Asia/Shanghai]  # 这个时间之后可以访问
			
        - id: member
          uri: http://127.0.0.1:8882/          #要去的请求地址
          # uri: lb://mall-member          #路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Query=url,member    # url 带有/coupon就去上方uri地址  url=member
           # - Path=/member/**      # url 这个是按照路径匹配,只要以/member开头就符合要求
学新通

测试
学新通

5.2、Predicate断言工厂:

名称 说明 示例
After 是某个时间点后的请求 - After=2037-01-20T17:42:47.789-07:00[America/Denver]
Before 是某个时间点之前的请求 - Before=2031-04-13T15:14:47.433 08:00[Asia/Shanghai]
Between 是某两个时间点之前的请求 - Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver]
Cookie 请求必须包含某些cookie - Cookie=chocolate, ch.p
Header 请求必须包含某些header - Header=X-Request-Id, \d
Host 请求必须是访问某个host(域名) - Host=.somehost.org,.anotherhost.org
Method 请求方式必须是指定方式 - Method=GET,POST
Path 请求路径必须符合指定规则 - Path=/red/{segment},/blue/**
Query 请求参数必须包含指定参数 - Query=name或者 - Query=name(参数), Jack.(值,如Jacks,没有点就全匹配,两个.就是Jackss)
RemoteAddr 请求者的ip必须是指定范围 - RemoteAddr=192.168.1.1/24
Weight 权重处理  

学新通

routes:
  - id: coupon
#          uri: http://127.0.0.1:8881/                   #要去的请求地址
    uri: lb://mall-coupon                 #路由的目标地址 lb就是负载均衡,后面跟服务名称
    predicates:  # 路由断言,也就是判断请求是否符合路由规则的条件
      - Query=url   # 请求参数中带有 url的都将被匹配。
      - Query=url,coupon.      # url 带有/coupon就去上方uri地址 例:url=coupons,【① coupon全值匹配  ;  ② coupon.后面需多随便一位,例coupons  ;  ③coupon..后面需多随便两位例,couponst】

      - Path=/foo/{segment},/bar/**  # ① /foo/1 或者 /foo/bar,②只要以/bar开头就符合要求
      # URI模板变量 (如上例中的 segment )将以Map的方式保存于ServerWebExchange.getAttributes() key为ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE.
      #这些值将在GatewayFilter Factories使用
      # 可以用这个方法获取变量:  Map<String, String> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);
      #                      String segment = uriVariables.get("segment");

      - After=2017-01-20T17:42:47.789-07:00[Asia/Shanghai] # 在该日期时间之后发生的请求都将被匹配

      - Before=2017-01-20T17:42:47.789-07:00[Asia/Shanghai] # 在该日期时间之前发生的请求都将被匹配

      - Between=2017-01-20T17:42:47.789-07:00[Asia/Shanghai], 2017-01-21T17:42:47.789-07:00[America/Denver] # 在两个时间之间的请求将被匹配

      - Cookie=chocolate, ch.p # cookie名称和正则表达式。请求包含次cookie名称且正则表达式为真的将会被匹配。

      - Header=X-Request-Id, \d  # header名称和正则表达式。请求包含次header名称且正则表达式为真的将会被匹配。

      - Host=**.somehost.org,**.anotherhost.org # host name列表。使用Ant路径匹配规则,.作为分隔符。

      - Method=GET,POST # 请求方式必须是指定方式

      - RemoteAddr=192.168.1.1/24 # 一个CIDR符号(IPv4或IPv6)字符串的列表,最小值为1,例如192.168.0.1/16(其中192.168.0.1是IP地址并且16是子网掩码)。
学新通

5.3、路由过滤GatewayFilterFactory(filters过滤器)

spring提供了31种不同的路由过滤器工厂。

名称 说明
AddRequestHeader 给当前请求添加一个请求头
RemoveRequestHeader 移除请求中的一个请求头
AddResponseHeader 给响应结果中添加一个响应头
RemoveResponseHeader 从响应结果中移除有一个响应头
RequestRateLimiter 限制请求的流量
。。。  

学新通

 filters:
   - AddRequestHeader=X-Request-Foo, Bar # 对于所有匹配的请求,这将向下游请求的头中添加 x-request-foo:bar header
   - AddRequestParameter=foo, bar # 对于所有匹配的请求,这将向下游请求添加foo=bar查询字符串
   - AddResponseHeader=X-Response-Foo, Bar # 对于所有匹配的请求,这会将x-response-foo:bar头添加到下游响应的header中
   - RemoveRequestHeader=X-Request-Foo # 这将在X-Request-Foo header被发送到下游之前删除它。
   - RemoveResponseHeader=X-Response-Foo # - RemoveResponseHeader=X-Response-Foo
   - SetResponseHeader=X-Response-Foo, Bar # 替换所有header,而不是添加。因此,如果下游服务器响应为X-Response-Foo:1234,则会将其替换为X-Response-Foo:Bar,这是网关客户端将接收的内容。


   - SetPath=/{segment} # 如果 - Path=/foo/{segment} 那么对于一个 /foo/bar请求,在做下游请求前,路径将被设置为/bar
   - PrefixPath=/mypath  #对于所有匹配的请求, 这将给所有匹配请求的路径加前缀/mypath。因此,向/hello发送的请求将发送到/mypath/hello。
   - RewritePath=/foo/(?<segment>.*), /$\{segment} # 对于请求路径/foo/bar,将在发出下游请求之前将路径设置为/bar。注意,由于YAML规范,请使用 $\替换 $。
   - StripPrefix=1 # 表示在将请求发送到下游之前从请求中剥离的路径个数
   - RewriteResponseHeader=X-Response-Foo, , password=[^&] , password=***
   # 对于一个/42?user=ford&password=omg!what&flag=true的header值,在做下游请求时将被设置为/42?user=ford&password=***&flag=true,由于YAML规范,请使用 $\替换 $。

   - SetStatus=401 #对于所有匹配的请求,HTTP返回码将设置为401.
   - RedirectTo=302, http://acme.org  # 对于所有匹配的请求,发送一个302状态码和一个Location:http://acme.org header来执行重定向。
   - SaveSession # 对于所有匹配的请求,将调用转发到下游之前强制执行WebSession::save 操作
学新通

测试
1、添加配置
学新通2、在接口中获取请求头
学新通3、已添加到请求头里
学新通4、对所有路由请求都生效
学新通5、代码

server:
  port: 88
spring:
  application:
    name: mall-gateway
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
    #网关配置
    gateway:
      routes:
        - id: coupon
          uri: http://127.0.0.1:8881/                   #要去的请求地址
         # uri: lb://coupon                 #路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates:  # 路由断言,也就是判断请求是否符合路由规则的条件
            #- Query=url,coupon      # url 带有/coupon就去上方uri地址 例:url=coupon
            - Path=/coupon/**      # url 这个是按照路径匹配,只要以/coupon开头就符合要求
            #- After=2037-01-20T17:42:47.789-07:00[Asia/Shanghai]  # 这个时间之后可以访问
          #filters: #过滤器
            #- AddRequestHeader=Truth,niubi!  #添加请求头

        - id: member
          uri: http://127.0.0.1:8882/          #要去的请求地址
          # uri: lb://member                 #路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            #- Query=url,member    # url 带有/coupon就去上方uri地址  url=member
            - Path=/member/**      # url 这个是按照路径匹配,只要以/member开头就符合要求

      default-filters: #默认过滤器,会对所有的路由请求都生效
        - AddRequestHeader=Truth,niubi!
学新通

5.4、全局过滤器(GlobalFilter)

与GetewayFilter区别在于,GetewayFilter是通过配置定义,处理逻辑是固定的。而GlobalFilter的逻辑需要自己写代码实现。
定义方式是实现GlobalFilter接口。

案例:定义全局过滤器,拦截并判断用户身份
需求:定义全局过滤器,拦截请求,判断请求的参数是否满足下面的条件:
1、 参数中是否有authorization
2、authorization参数值是否为admin
如果同时满足则放行,否则拦截

学新通

@Order(-1)  // 多个过滤器,这个值越小,优先级越高
@Component
public class AuthorizationFilter implements GlobalFilter {
	@Override
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
		// 1、获取请求头
		ServerHttpRequest request = exchange.getRequest();
		MultiValueMap<String, String> params = request.getQueryParams();
		// 2、获取参数中的authorization 参数
		String auth = params.getFirst("authorization");
		// 3、判断参数值是否等于admin
		if ("admin".equals(auth)){
			// 4、是,放行
			return	chain.filter(exchange);
		} // 5、否,拦截
		// 设置状态码
		exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
		return exchange.getResponse().setComplete();
	}
}
学新通

测试
正确
学新通错误的
学新通

5.5、过滤器执行顺序

学新通

每一个过滤器都必须指定order值,order值越小,优先级却高,执行顺序越前
.
GlobalFilter通过实现@Order注解来指定order值,有我们自己指定
.
路由过滤器和defaultFilter的order由Spring指定,默认是按声明顺序从1递增(就是yml配置,越上面的的越高)
.
当过滤器的order值一样时,会按照defaultFilter > 路由过滤器 > GlobalFilter的顺序执行。

5.6、跨域问题处理

跨域:域名不一致就是跨域,主要包括
1、域名不同:www.taobao.com 和 www.taobao.org 和 www.jd.com
2、域名相同,端口不同:8080和8081
跨域问题:浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截问题
解决方案:CORS

学新通

 #网关配置
    gateway:
      discovery:
        locator:
          enabled: true
      globalcors:
        cors-configurations:
          '[/**]':
            allowCredentials: true
            allowedOrigins: "*"
            allowedMethods: "*"
            allowedHeaders: "*"  #允许在请求中携带的头信息
            allowCredentials: true  # 是否允许携带cookie
            maxAge: 360000 # 这次跨域检测的有效期

5.7、配置所有代码

server:
  port: 88
spring:
  application:
    name: mall-gateway
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
    #网关配置
    gateway:
      discovery:
        locator:
          enabled: true
      globalcors:
        cors-configurations:
          '[/**]':
            allowCredentials: true
            allowedOrigins: "*"
            allowedMethods: "*"
            allowedHeaders: "*"  #允许在请求中携带的头信息
            allowCredentials: true  # 是否允许携带cookie
            maxAge: 360000 # 这次跨域检测的有效期
      routes:
        - id: coupon
          uri: http://127.0.0.1:8881/                   #要去的请求地址
         # uri: lb://coupon                 #路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates:  # 路由断言,也就是判断请求是否符合路由规则的条件
            #- Query=url,coupon      # url 带有/coupon就去上方uri地址 例:url=coupon
            - Path=/coupon/**      # url 这个是按照路径匹配,只要以/coupon开头就符合要求
            #- After=2037-01-20T17:42:47.789-07:00[Asia/Shanghai]  # 这个时间之后可以访问
          #filters: #过滤器
            #- AddRequestHeader=Truth,niubi!  #添加请求头

        - id: member
          #uri: http://127.0.0.1:8882/          #要去的请求地址
          uri: lb://mall-member                 #路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            #- Query=url,member    # url 带有/coupon就去上方uri地址  url=member
            - Path=/member/**      # url 这个是按照路径匹配,只要以/member开头就符合要求

        - id: product
          #uri: http://127.0.0.1:8884/          #要去的请求地址
          uri: lb://mall-product                 #路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            #- Query=url,member    # url 带有/coupon就去上方uri地址  url=member
            - Path=/product/**,/renren-fast/product/**      # url 这个是按照路径匹配,只要以/member开头就符合要求
          filters:
            - RewritePath=/renren-fast/(?<segment>.*),/$\{segment}  #路径重写,去除/renren-fast

        - id: renrenfast
          uri: lb://renrenfast       #要去的请求地址
          #uri: http://127.0.0.1:8883/       #要去的请求地址
          # uri: lb://member                 #路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            #- Query=url,member    # url 带有/coupon就去上方uri地址  url=member
            - Path=/renren-fast/** # url 这个是按照路径匹配,只要以/member开头就符合要求
          filters:
            - RewritePath=/api/(?<segment>.*), /renren-fast/$\{segment}
            - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin

      default-filters: #默认过滤器,会对所有的路由请求都生效
        - AddRequestHeader=origin,gateway # 添加为origin的请求头,值为gateway


学新通

spring cloud alibaba组件集合地址

原文地址

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfjaeaa
系列文章
更多 icon
同类精品
更多 icon
继续加载