SpringCloud

您所在的位置:网站首页 网关怎么配置的 SpringCloud

SpringCloud

2023-12-27 08:01| 来源: 网络整理| 查看: 265

一、网关(Gateway)

1.1 什么是网关(Gateway)?

API网关,就是指系统的统一入口,它封装了应用程序的内部结构,为客户端提供统一服 务,一些与业务本身功能无关的公共逻辑可以在这里实现,诸如认证、鉴权、监控(黑白名单)、路由转发等等.

1.2 为什么需要网关?

微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端(pc androud ios 平板)要如何去调用这么多的微服务呢?如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去调用。总的来说,网关具有以下功能:

协议转换,路由转发流量聚合,对流量进行监控,日志输出作为整个系统的钱罐,对流量进行控制,有限流的作用作为系统的前端界面,外部流量只能通过网关才能访问系统可以在网关层做权限判断可以在网关层做缓存

1.3 Gateway快速入门

增强版

要求功能:客户端访问api网关,网关将请求转到商品微服务

步骤一:创建一个api-gateway工程(微服务),并在pom文件中,引入gateway依赖

步骤二:创建网关的主启动类

步骤三:修改配置文件

#普通版 server: port: 8000 spring: cloud: gateway: routes: - id: shop-product #路由的唯一标识,只要不重复都可以,如果不写默认的是通过UUID产生的,一般写成被路由服务的名称 uri: http://locahhost/8081 #被路由的地址 order: 0 #优先级,数字越小,优先级越高 predicates: # 断言,执行路由的判断条件,只有断言都为真,才会执行路由 - Path=/product/** - id: shop-order uri: http://locahhost/8091 order: 0 predicates: - Path=/order/** # 过滤器,可以再请求前或者请求后做一些动作 # filters: # -StripPrefix=1 #将网关添加到注册中心 nacos: server-addr: localhost:8848 application: name: my-gateway #增强版 server: port: 8000 spring: cloud: gateway: routes: - id: shop-product #路由的唯一标识,只要不重复都可以,如果不写默认的是通过UUID产生的,一般写成被路由服务的名称 uri: lb://shop-product #被路由的地址, lb代表lb协议 order: 0 #优先级,数字越小,优先级越高 predicates: # 断言,执行路由的判断条件,只有断言都为真,才会执行路由 - Path=/product/** # - Age=18,60 - id: shop-order uri: lb://shop-order order: 0 predicates: - Path=/order/** # 过滤器,可以再请求前或者请求后做一些动作 # filters: # -StripPrefix=1 #将网关添加到注册中心 nacos: server-addr: localhost:8848 application: name: my-gateway

增强版与普通版的区别:普通版路由路径是写死的,当微服务的端口修改时,还需要修改网关的配置文件,比较麻烦,增强版将网关作为一个微服务,注册到注册中心,然后从注册中心中下载其他微服务的服务名

步骤四:通过网关访问微服务

还有一个简写版实用性不大,就不再赘述。

1.4 Gateway的实现原理

1.4.1 路由

路由(Route) 是 gateway 中最基本的组件之一,表示一个具体的路由信息载体。主要定义了下面的几个信息:

id,路由标识符,区别于其他 Route。 uri,路由指向的目的地 uri,即客户端请求最终被转发到的微服务。 order,用于多个 Route 之间的排序,数值越小排序越靠前,匹配优先级越高。 predicate,断言的作用是进行条件判断,只有断言都返回真,才会真正的执行路由。 filter,过滤器用于修改请求和响应信息。

1.4.2 执行流程

执行流程大体如下:

1. Gateway Client(网关客户端)向Gateway Server发送请求

2. 请求首先会被HttpWebHandlerAdapter进行提取组装成网关上下文

3. 然后网关的上下文会传递到DispatcherHandler,它负责将请求分发给 RoutePredicateHandlerMapping

4. RoutePredicateHandlerMapping负责路由查找,并根据路由断言判断路由是否可用

5. 如果过断言成功,由FilteringWebHandler创建过滤器链并调用

6. 请求会一次经过PreFilter--微服务--PostFilter的方法,最终返回响应

1.4.3 断言

Predicate(断言, 谓词) 用于进行条件判断,只有断言都返回真,才会真正的执行路由。

断言就是说: 在 什么条件下 才能进行路由转发。

内置路由断言工厂 

实操几个断言:

server: port: 8000 spring: cloud: gateway: routes: - id: shop-product #路由的唯一标识,只要不重复都可以,如果不写默认的是通过UUID产生的,一般写成被路由服务的名称 uri: lb://shop-product #被路由的地址, lb代表lb协议 order: 0 #优先级,数字越小,优先级越高 predicates: # 断言,执行路由的判断条件,只有断言都为真,才会执行路由 - Path=/product/** #访问路径 - Before=2020-11-28T00:00:00.000+08:00 # 表示在2020前访问 - Method=POST # 请求方式必须为POST nacos: server-addr: localhost:8848 application: name: my-gateway

1.4.3.2 自定义断言

假设我们的应用仅仅让age在(min,max)之间的人来访问。

步骤一:在配置文件中,配置一个Age的断言

server: port: 8000 spring: cloud: gateway: routes: - id: shop-product #路由的唯一标识,只要不重复都可以,如果不写默认的是通过UUID产生的,一般写成被路由服务的名称 uri: lb://shop-product #被路由的地址, lb代表lb协议 order: 0 #优先级,数字越小,优先级越高 predicates: # 断言,执行路由的判断条件,只有断言都为真,才会执行路由 - Path=/product/** - Age=18,60

步骤二:自定义一个工厂, 实现断言方法

package com.dhy.gateway.config; import lombok.Data; import lombok.NoArgsConstructor; import org.apache.commons.lang.StringUtils; import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import java.util.Arrays; import java.util.List; import java.util.function.Predicate; /** * @program: springcloud-father * @description: zidingyiduanyan * @author: 杜航宇 * @create: 2021-07-08 11:21 **/ @Component // 泛型为自定义的配置类,用来存储配置中真的值 public class AgeRoutePredicateFactory extends AbstractRoutePredicateFactory { @Data @NoArgsConstructor //这里的Static不要漏,需要静态方法 public static class Config { private Integer minAge; private Integer maxAge; } //读取配置文件中的值,并配置为配置类中的属性 public AgeRoutePredicateFactory(){ super(AgeRoutePredicateFactory.Config.class); } public List shortcutFieldOrder(){ return Arrays.asList("minAge","maxAge"); } public Predicate apply(AgeRoutePredicateFactory.Config config){ return (exchange) -> { String age = exchange.getRequest().getQueryParams().getFirst("age"); if (StringUtils.isNotEmpty(age)) { int a = Integer.parseInt(age); return a >= config.minAge && a


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3