一:网关简介

在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢?如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去调用。这样的话会产生很多问题,例如:

  • 客户端多次请求不同的微服务,增加客户端代码或配置编写的复杂性
  • 认证复杂,每个微服务都有独立认证
  • 存在跨域请求,在一定场景下处理相对复杂

为解决上面的问题所以引入了网关的概念:所谓的API网关,就是指系统的统一入口,它封装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑可以在这里实现,诸如认证、鉴权、监控、路由转发等。

比较流行的网关对比

  • Nginx+lua

  使用nginx的反向代理和负载均衡可实现对api服务器的负载均衡及高可用lua是一种脚本语言,可以来编写一些简单的逻辑, nginx支持lua脚本

  • Kong

  基于Nginx+Lua开发,性能高,稳定,有多个可用的插件(限流、鉴权等等)可以开箱即用。 问题:只支持Http协议;二次开发,自由扩展困难;提供管理API,缺乏更易用的管控、配置方式。

  • Zuul

  Netflix开源的网关,功能丰富,使用JAVA开发,易于二次开发 问题:缺乏管控,无法动态配置;依赖组件较多;处理Http请求依赖的是Web容器,性能不如Nginx

  • Spring Cloud Gateway

  Spring公司为了替换Zuul而开发的网关服务,将在下面具体介绍。

二:Gateway简介

Spring Cloud Gateway是Spring公司基于Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。它的目标是替代Netflix Zuul,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控和限流。

  • 优点:
  1. 性能强劲:是第一代网关Zuul的1.6倍
  2. 功能强大:内置了很多实用的功能,例如转发、监控、限流等
  3. 设计优雅,容易扩展
  • 缺点:
  1. 其实现依赖Netty与WebFlux,不是传统的Servlet编程模型,学习成本高
  2. 不能将其部署在Tomcat、Jetty等Servlet容器里,只能打成jar包执行
  3. 需要Spring Boot 2.0及以上的版本,才支持

三:Gateway核心架构

3.1:基本概念

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

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

3.2:执行流程

  1. Gateway Client向Gateway Server发送请求
  2. 请求首先会被HttpWebHandlerAdapter进行提取组装成网关上下文
  3. 然后网关的上下文会传递到DispatcherHandler,它负责将请求分发给RoutePredicateHandlerMapping
  4. RoutePredicateHandlerMapping负责路由查找,并根据路由断言判断路由是否可用
  5. 如果过断言成功,由FilteringWebHandler创建过滤器链并调用
  6. 请求会一次经过PreFilter--微服务--PostFilter的方法,最终返回响应

四:Gateway快速入门

4.1:创建一个api-gateway模块,导入相关依赖

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springcloud-alibaba</artifactId>
<groupId>com.chenpt</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.</modelVersion> <artifactId>api-gateway</artifactId> <dependencies>
<!--nacos客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--gateway网关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>
</dependencies> </project>

完整版pom.xml

4.2:创建启动类

@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication { public static void main(String[] args){
SpringApplication.run(GatewayApplication.class, args);
}
}

GatewayApplication

4.3:添加配置文件

server:
port: 7000
spring:
application:
name: api-gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
routes: # 路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]
- id: product_route # 当前路由的标识, 要求唯一
uri: lb://service-product # lb指的是从nacos中按照名称获取微服务,并遵循负载均衡策略
predicates: # 断言(就是路由转发要满足的条件)
- Path=/shop-pro/** # 当请求路径满足Path指定的规则时,才进行路由转发
filters: # 过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
- StripPrefix=1 # 转发之前去掉1层路径
- id: order_route
uri: lb://service-order
predicates:
- Path=/shop-order/**
filters:
- StripPrefix=1

application.yml

4.4:测试

五:网关限流

采用前面学过的Sentinel组件来实现网关的限流

5.1:导入依赖

<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>

5.2:编写配置类

基于Sentinel 的Gateway限流是通过其提供的Filter来完成的,使用时只需注入对应的SentinelGatewayFilter实例以及 SentinelGatewayBlockExceptionHandler 实例即可。

@Configuration
public class GatewayConfig {
private final List<ViewResolver> viewResolvers;
private final ServerCodecConfigurer serverCodecConfigurer; public GatewayConfig(List<ViewResolver> viewResolvers, ServerCodecConfigurer serverCodecConfigurer) {
this.viewResolvers = viewResolvers;
this.serverCodecConfigurer = serverCodecConfigurer;
} // 初始化一个限流的过滤器
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public GlobalFilter sentinelGatewayFilter() {
return new SentinelGatewayFilter();
} // 配置初始化的限流参数
@PostConstruct
public void initGatewayRules() {
// Set<GatewayFlowRule> rules = new HashSet<>();
// rules.add(
// new GatewayFlowRule("product_route") //资源名称,对应路由id
// .setCount(1) // 限流阈值
// .setIntervalSec(1) // 统计时间窗口,单位是秒,默认是 1 秒
// );
// GatewayRuleManager.loadRules(rules); Set<GatewayFlowRule> rules = new HashSet<>();
rules.add(new GatewayFlowRule("product_route").setCount(1).setIntervalSec(1));
rules.add(new GatewayFlowRule("order_route").setCount(1).setIntervalSec(1));
GatewayRuleManager.loadRules(rules);
} // 配置限流的异常处理器
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
} // 自定义限流异常页面
@PostConstruct
public void initBlockHandlers() {
BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
Map map = new HashMap<>();
map.put("code", 0);
map.put("message", "接口被限流了");
return ServerResponse.status(HttpStatus.OK).
contentType(MediaType.APPLICATION_JSON_UTF8).
body(BodyInserters.fromObject(map));
}
};
GatewayCallbackManager.setBlockHandler(blockRequestHandler);
} }

GatewayConfig

5.3:测试

SpringCloudAlibaba-服务网关Gateway的更多相关文章

  1. SpringCloud Alibaba实战(11:引入服务网关Gateway)

    源码地址:https://gitee.com/fighter3/eshop-project.git 持续更新中-- 大家好,我是三分恶. 在前面的章节中,我们已经完成了服务间的调用.统一配置等等,在这 ...

  2. springcloud(十五):Spring Cloud 终于按捺不住推出了自己的服务网关 Gateway

    Spring 官方最终还是按捺不住推出了自己的网关组件:Spring Cloud Gateway ,相比之前我们使用的 Zuul(1.x) 它有哪些优势呢?Zuul(1.x) 基于 Servlet,使 ...

  3. SpringCloud之服务网关Gateway,入门+实操

    SpringCloudAlibaba微服务实战教程系列 Spring Cloud 微服务架构学习记录与示例 一. GateWay简介 Spring Cloud GateWay是Spring Cloud ...

  4. 微服务网关Gateway实践总结

    有多少请求,被网关截胡: 一.Gateway简介 微服务架构中,网关服务通常提供动态路由,以及流量控制与请求识别等核心能力,在之前的篇幅中有说过Zuul组件的使用流程,但是当下Gateway组件是更常 ...

  5. 限流10万QPS、跨域、过滤器、令牌桶算法-网关Gateway内容都在这儿

    一.微服务网关Spring Cloud Gateway 1.1 导引 文中内容包含:微服务网关限流10万QPS.跨域.过滤器.令牌桶算法. 在构建微服务系统中,必不可少的技术就是网关了,从早期的Zuu ...

  6. Spring Cloud 系列之 Gateway 服务网关(四)

    本篇文章为系列文章,未读第一集的同学请猛戳这里: Spring Cloud 系列之 Gateway 服务网关(一) Spring Cloud 系列之 Gateway 服务网关(二) Spring Cl ...

  7. SpringCloud初体验:四、API GateWay 服务网关

    网关服务很多,比如:Zuul.Kong.spring cloud gateway ……, 这里不纠结哪种性能好,本次体验是用的 spring cloud gateway 更多网关比较可以了解这篇文章: ...

  8. 再谈API GateWay服务网关

    前面在谈微服务架构的时候,我博客上转过Chris Richardson 微服务系列中对微服务网关的描述: 通常来说,使用 API 网关是更好的解决方式.API 网关是一个服务器,也可以说是进入系统的唯 ...

  9. 微服务网关实战——Spring Cloud Gateway

    导读 作为Netflix Zuul的替代者,Spring Cloud Gateway是一款非常实用的微服务网关,在Spring Cloud微服务架构体系中发挥非常大的作用.本文对Spring Clou ...

  10. 第6章 服务模式 在 .NET 中实现 Service Gateway(服务网关)

    上下文 您正在设计企业应用程序,该程序需要使用由其他应用程序提供的服务.该服务定义了一个合约,所有服务使用者要访问该服务都必须遵守该合约.该合约定义了与此服务通信所需的技术.通信协议和消息定义等内容. ...

随机推荐

  1. 统计M

    链接:https://vjudge.net/problem/UVA-1586 题意:给出一分子化学式,包含C,N,O,H四种元素,求M 题解:这是字符串题.分为几种情况:第一种是一个原子:第二种是多原 ...

  2. Android复习准备

    1. 四大组件是什么? Activity(活动):用于表现功能 Service(服务):后台运行服务,不提供界面呈现 BroadcastReceiver(广播接收器):用来接收广播 ContentPr ...

  3. Java线程池ThreadPoolExecutor面试总结思维导图速记

    优点 降低资源消耗,通过重复利用已创建的线程降低线程创建和销毁造成的消耗. 提高响应速度,当任务到达时,可以不需要等待线程创建就能立即执行. 提高线程的可管理性 类关系 接 Executor 一个无返 ...

  4. Lua学习入门(基本数据类型)

    数据类型 Lua 中有 8 个基本类型分别为:nil.boolean.number.string.userdata.function.thread 和 table. 数据类型 描述 nil 这个最简单 ...

  5. 线程_FIFO队列实现生产者消费者

    import threading # 导入线程库 import time from queue import Queue # 队列 class Producer(threading.Thread): ...

  6. PHP asinh() 函数

    实例 返回不同数的反双曲正弦: <?phpecho(asinh(7) . "<br>");echo(asinh(56) . "<br>&qu ...

  7. PDOStatement::setAttribute

    PDOStatement::setAttribute — 设置一个语句属性(PHP 5 >= 5.1.0, PECL pdo >= 0.2.0)高佣联盟 www.cgewang.com 说 ...

  8. 2020牛客暑期多校训练营 第二场 J Just Shuffle 置换 群论

    LINK:Just Shuffle 比较怂群论 因为没怎么学过 置换也是刚理解. 这道题是 已知一个置换\(A\)求一个置换P 两个置换的关键为\(P^k=A\) 且k是一个大质数. 做法是李指导教我 ...

  9. Linux的VMWare中Centos7查看文件内容命令 (more-less-head-tail)

    一.More分页查看文件 more 命令类似 cat ,不过会以一页一页的形式显示,更方便使用者逐页阅读, 而最基本的指令就是按空白键(space)就往下一页显示, 按 b 键就会往回(back)一页 ...

  10. __STL_VOLATILE

    _Obj* __STL_VOLATILE* __my_free_list = _S_free_list + _S_freelist_index(__n); _Obj* * __my_free_list ...