【项目创建流程】Gateway微服务网关

【项目创建流程】Gateway微服务网关

网关基本概念

1、API网关介绍

API 网关出现的原因是微服务架构的出现,不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题:

(1)客户端会多次请求不同的微服务,增加了客户端的复杂性。

(2)存在跨域请求,在一定场景下处理相对复杂。

(3)认证复杂,每个服务都需要独立认证。

(4)难以重构,随着项目的迭代,可能需要重新划分微服务。例如,可能将多个服务合并成一个或者将一个服务拆分成多个。如果客户端直接与微服务通信,那么重构将会很难实施。

以上这些问题可以借助 API 网关解决。API 网关是介于客户端和服务器端之间的中间层,所有的外部请求都会先经过 API 网关这一层。也就是说,API 的实现方面更多的考虑业务逻辑,而安全、性能、监控可以交由 API 网关来做,这样既提高业务灵活性又不缺安全性

2、Spring Cloud Gateway

Spring cloud gateway是spring官方基于Spring 5.0和Spring Boot2.0等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供简单、有效和统一的API路由管理方式,Spring Cloud Gateway作为Spring Cloud生态系统中的网关,目标是替代Netflix Zuul,其不仅提供统一的路由方式,并且还基于Filer链的方式提供了网关基本的功能,例如:安全、监控/埋点、限流等。

3、Spring Cloud Gateway 核心概念

下面介绍一下Spring Cloud Gateway中几个重要的概念。

(1)路由。路由是网关最基础的部分,路由信息有一个ID、一个目的URL、一组断言和一组Filter组成。如果断言路由为真,则说明请求的URL和配置匹配

(2)断言。Java8中的断言函数。Spring Cloud Gateway中的断言函数允许开发者去定义匹配来自于http request中的任何信息,比如请求头和参数等。

(3)过滤器。一个标准的Spring webFilter。Spring cloud gateway中的filter分为两种类型的Filter,分别是Gateway Filter和Global Filter。过滤器Filter将会对请求和响应进行修改处理。

4、执行流程

如下图所示,Spring cloud Gateway发出请求。然后再由Gateway Handler Mapping中找到与请求相匹配的路由,将其发送到Gateway web handler。Handler再通过指定的过滤器链将请求发送到我们实际的服务执行业务逻辑,然后返回。

4、特点

优点:

  • 性能强劲:是第一代网关Zuul的1.6倍
  • 功能强大:内置了很多实用的功能,例如转发、监控、限流等
  • 设计优雅,容易扩展

缺点:

  • 其实现依赖Netty与WebFlux,不是传统的Servlet编程模型,学习成本高
  • 不能将其部署在Tomcat、Jetty等Servlet容器里,只能打成jar包执行
  • 需要Spring Boot 2.0及以上的版本,才支持

搭建Gateway服务

创建父模块infrastructure

创建子模块api_gateway

配置pom

在api_gateway的pom中添加如下依赖

<dependencies>
    
    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-gatewayartifactId>
    dependency>
dependencies>

配置application.yml

server:
  port: 9110 # 服务端口

spring:
  profiles:
    active: dev # 环境设置
  application:
    name: infrastructure-apigateway # 服务名

logback.xml

修改日志输出目录名为 apigateway

创建启动类

gataway依赖common,课是common引入了mybatisplus操作,所有有数据库操作,因此需要排除数据库操作

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class} )

package com.atguigu.guli.infrastructure.apigateway;

@SpringBootApplication
public class InfrastructureApiGatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(InfrastructureApiGatewayApplication.class, args);
    }
}

启动网关

配置路由和跨域

1、路由和断言

application.yml文件中添加路由配置

  • -:表示数组元素,可以配置多个节点
  • id:配置的唯一标识,可以和微服务同名,也可以起别的名字,区别于其他 Route。
  • uri:路由指向的目的地 uri,即客户端请求最终被转发到的微服务。
  • predicates:断言的作用是进行条件判断,只有断言都返回真,才会真正的执行路由。
  • Path:路径形式的断言。当匹配这个路径时,断言条件成立
  • /**:一个或多个层次的路径
#spring:
  cloud:
    gateway:
      routes:
      - id: service-edu
        uri: http://localhost:8110
        predicates:
        - Path=/user/**
内置路由断言工厂

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

SpringCloud Gateway包括许多内置的断言工厂,所有这些断言都与HTTP请求的不同属性匹配。具体如下:

1、基于Datetime

此类型的断言根据时间做判断,主要有三个:

  • AfterRoutePredicateFactory: 接收一个日期参数,判断请求日期是否晚于指定日期
  • BeforeRoutePredicateFactory: 接收一个日期参数,判断请求日期是否早于指定日期
  • BetweenRoutePredicateFactory: 接收两个日期参数,判断请求日期是否在指定时间段内
- After=2019-12-31T23:59:59.789+08:00[Asia/Shanghai]
2、基于远程地址

RemoteAddrRoutePredicateFactory:接收一个IP地址段,判断请求主机地址是否在地址段中

- RemoteAddr=192.168.1.1/24
3、基于Cookie

CookieRoutePredicateFactory:接收两个参数,cookie 名字和一个正则表达式。 判断请求cookie是否具有给定名称且值与正则表达式匹配。

-Cookie=chocolate, ch.
4、基于Header

HeaderRoutePredicateFactory:接收两个参数,标题名称和正则表达式。 判断请求Header是否具有给定名称且值与正则表达式匹配。

-Header=X-Request-Id, \d+
5、基于Host

HostRoutePredicateFactory:接收一个参数,主机名模式。判断请求的Host是否满足匹配规则。

-Host=**.testhost.org
6、基于Method请求方法

MethodRoutePredicateFactory:接收一个参数,判断请求类型是否跟指定的类型匹配。

-Method=GET
7、基于Path请求路径

PathRoutePredicateFactory:接收一个参数,判断请求的URI部分是否满足路径规则。

- Path=/foo/**
8、基于Query请求参数

QueryRoutePredicateFactory :接收两个参数,请求param和正则表达式, 判断请求参数是否具有给定名称且值与正则表达式匹配。

-Query=url,baidu
9、基于路由权重

WeightRoutePredicateFactory:接收一个[组名,权重],然后对于同一个组内的路由按照权重转发

routes:
- id: weight_route1 
  uri: host1 
  predicates:
  - Path=/product/**
  - Weight=group3, 1
- id: weight_route2 
  uri: host2 
  predicates:
  - Path=/product/**
  - Weight= group3, 9
过滤器
一、过滤器的基本概念

1、作用

过滤器就是在请求的传递过程中,对请求和响应做一些修改

2、生命周期

客户端的请求先经过“pre”类型的filter,然后将请求转发到具体的业务服务,收到业务服务的响应之后,再经过“post”类型的filter处理,最后返回响应到客户端。

pre: 这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现参数校验、权限校验、流量监控、日志输出、协议转换等;

post:这种过滤器在路由到达微服务以后执行。这种过滤器可用做响应内容、响应头的修改,日志的输出,流量监控等。

3、分类

局部过滤器 GatewayFilter:作用在某一个路由上

全局过滤器 GlobalFilter:作用全部路由上

二、局部过滤器

1、内置局部过滤器

在SpringCloud Gateway中内置了很多不同类型的网关路由过滤器。具体如下

routes:
- id: service-edu
  uri: lb://service-edu
  predicates:
  - Path=/user/**, /*/edu/**
  filters:
  - SetStatus=250 # 修改返回状态码

测试:

三、全局过滤器

1、内置全局过滤器

内置全局过滤器的使用举例:负载均衡过滤器

lb://service-edu

2、自定义全局过滤器

定义一个Filter实现 GlobalFilter 和 Ordered接口

自定义转发路径

filters:
  - RewritePath=/api/(?.*),/renren-fast/$\{segment}

2、测试网关路由转发

访问:http://localhost:9110/user/info

请求转发到:http://localhost:8110/user/info

通过nacos注册中心

1、网关中添加依赖


<dependency>
    <groupId>com.alibaba.cloudgroupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>

2、主类添加注解

@EnableDiscoveryClient  //SpringBoot2.0之后可以省略

3、添加nacos配置

#spring:
#  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 # nacos服务地址

4、添加gateway配置

#spring:
#  cloud:
#    gateway:
      discovery:
        locator:
          enabled: true # gateway可以发现nacos中的微服务

5、修改uri配置

将uri的地址修改成注册中心中的微服务地址,网关姜葱nacos中按照名称获取微服务

lb:表示在集群环境下通过负载均衡的方式调用

uri: lb://service-edu  #内置负载均衡过滤器

6、测试

访问:http://localhost:9110/user/info

7、匹配多个path

- Path=/user/**, /*/edu/**

跨域配置

1、前端配置

修改guli-admin中 config/dev.env.js,BASE_API指定到网关地址

BASE_API: '"http://127.0.0.1:9110"',

2、删除后端跨域配置

此时可以删除微服务中的跨域注解 @CrossOrigin

例如 service_edu中 LoginController的跨域注解

3、跨域配置

package com.atguigu.guli.infrastructure.apigateway.config;

@Configuration
public class CorsConfig {
    @Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedMethod("*");
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/**", config);

        return new CorsWebFilter(source);
    }
}

注意:去掉后端的所有跨域配置

完整的路由配置

yml配置

routes:
- id: service-edu
  uri: lb://service-edu
  predicates:
  - Path=/user/**, /*/edu/**
- id: service-cms
  uri: lb://service-cms
  predicates:
  - Path=/*/cms/**
- id: service-oss
  uri: lb://service-oss
  predicates:
  - Path=/*/oss/**
- id: service-sms
  uri: lb://service-sms
  predicates:
  - Path=/*/sms/**
- id: service-trade
  uri: lb://service-trade
  predicates:
  - Path=/*/trade/**
- id: service-ucenter
  uri: lb://service-ucenter
  predicates:
  - Path=/*/ucenter/**
- id: service-vod
  uri: lb://service-vod
  predicates:
  - Path=/*/vod/**

前端配置

(1)修改guli-site中 utils/request.js,BASE_API指定到网关地址

baseURL: 'http://127.0.0.1:9110',

(2)所有的api模块中的baseURL可以删除

(3)guli-admin上传相关表单中action地址的修改

data中定义:

BASE_API: process.env.BASE_API

html中使用:

:action="BASE_API+'/admin/oss/file/upload?module=avatar'"

你可能感兴趣的:(网关,spring,java,python,spring,boot)