SpringCloud-Greenwich版本新特性探索(1)---SpringCloudGateway
一、前言
1、SpringCloudGateway是SpringCloud新推出的网关框架,比较于上一代Zuul,功能和性能有很大的提升。Zuul1.x采用的是阻塞多线程方式,也就是一个线程处理一个连接请求,高并发情况下性能较差,即使是Zuul2.x虽然做到了非阻塞,但是面对连续跳票,看起来Zuul要被抛弃了。取而代之的是SpringCloudGateway,SpringCloudGateway是基于Webflux,是一个非阻塞异步的框架,性能上有很大提升,而且包含了Zuul的所有功能,可以从Zuul无缝切换到SpringCloudGateway
2、SpringCloud环境版本:Greenwich.RELEASE
3、SpringBoot环境版本:2.1.3.RELEASE
二、环境搭建
1、在父工程下新建一个网关模块
2、引入SpringCloudGateway需要的POM,记得引入actuator组件,否则服务发现中心会认为服务不在线,导致网关无法路由到服务,并且加入熔断组件Hystrix
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!-- 健康检查 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
3、主函数很简单,加入必要的注解,比如服务发现等
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayCarfacApplication
{
public static void main(String[] args)
{
SpringApplication.run(GatewayCarfacApplication.class, args);
}
}
4、进行SpringCloudGateway的配置,配置可以使用Java代码进行配置或者yml配置,这里使用yml进行配置
spring:
cloud:
gateway:
discovery:
locator:
enabled: true # 设置可以路由到其他服务
routes: # 可以配置多个路由
- id: service-media- # 路由id唯一
uri: lb://service-media # 可以直接跳转到具体的地址,如果要跳转到其他服务,则填写lb://<服务id>
predicates:
- Path=/media/** # 路由规则
filters:
- StripPrefix= # 不填则无法路由到其他服务
- AddRequestHeader=X-Request-Foo, Bar
- name: Hystrix # 添加熔断
args:
name: fallbackcmd
fallbackUri: forward:/test/fallback # 熔断跳转地址 # 熔断超时时间
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds:
5、上面我们配置了熔断的配置,一旦发生熔断就会跳转到/test/fallback这个地址,下面我们实现一下这个接口,这里简单的返回了error,我们可以自定义处理熔断的逻辑
@Controller
@RequestMapping(value = "/test")
public class TestController
{
@RequestMapping(value = "/fallback", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<String> fallback()
{
return new ResponseEntity<>("error.", HttpStatus.OK);
}
}
6、网关配置好后,再启动一个其他的服务模块,记得添加引入actuator,否则无法被路由到
<!-- Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 健康检查 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
7、编写一个HTTP接口,来测试网关的调用,为了检测熔断的效果,这里通过参数来控制接口的响应时间
@Controller
@RequestMapping(value = "/test")
public class TestController
{
@Value("${server.port}")
private String port; @RequestMapping(value = "/get/{time}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<String> get(@PathVariable("time") long time)
{
try
{
Thread.sleep(time);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
return new ResponseEntity<>(port + " get ok.", HttpStatus.OK);
}
}
8、在同一注册中心下启动网关和服务,根据我们配置的路由规则/media/**,我们可以这样调用http://127.0.0.1:8501/media/get/100,可以看到正确的路由到了服务
9、我们将响应时间改成5秒http://127.0.0.1:8501/media/get/5000,超高熔断的检测时间,可以发现接口熔断,并且跳转到了指定的链接
三、高级特性---断言
1、以上我们实现了SpringCloudGateway的基本使用办法,可以应付大部分应用场景了,我们同时可以细粒度的去改造路由,就使用到了断言Predict,如果不满足我们设置的断言条件,则无法被路由
2、设置断言,我们只需要在predicates下面加入配置即可,要注意如果设置了多个断言,则请求必须满足所有断言才可以被正确路由到
spring:
cloud:
gateway:
routes: # 可以配置多个路由
- id: service-media-1 # 路由id唯一
uri: lb://service-media # 可以直接跳转到具体的地址,如果要跳转到其他服务,则填写lb://<服务id>
predicates:
# 加入断言
3、常用的一些断言,还有很多其他断言就不一一列举了,当然最常用的可能是Path断言,我们需要通过路径来指定路由
(1)- Header=<key>, <value>(必须有指定的HTTP Header才能路由)
(2)- Cookie=<key>, <value>(必须有指定的Cookie才能路由)
(3)- Host=aaa.bbb.com(请求域名必须是aaa.bbb.com才能路由)
(4)- Method=GET(请求方式必须是Get请求才能路由)
四、高级特性---过滤器
1、通过设置网关的过滤器,我们可以在用户访问的入口增加一些处理,比如鉴权、接口监控等,下面介绍一些常用的过滤器
2、常用的过滤器
(1)- AddRequestHeader=<key>, <value>(增加自定义HTTP请求头)
(2)- SetStatus=401(设置响应的HTTP错误码)
(3)- RedirectTo=302, http://acme.org(重定向到指定链接)
3、自定义过滤器,可以通过代码定制更加灵活的过滤器,下面实现一个简单的接口耗时统计的过滤器,思路:设置两个过滤器,一个前置过滤器用来收集接口开始调用的时间,一个后置过滤器来将结束时间减去开始时间得到接口的耗时时间,并打印出来
(1)前置过滤器工厂,将开始时间写到attributes里面
public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> { public PreGatewayFilterFactory() {
super(Config.class);
} @Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
exchange.getAttributes().put("requestTime", System.currentTimeMillis());
return chain.filter(exchange);
};
} public static class Config { } }
(2)后置过滤器工厂,获取attribute里面的开始时间,并用当前时间减去,得到耗时时间,打印
public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config>
{
public PostGatewayFilterFactory() {
super(Config.class);
} @Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
Long startTime = exchange.getAttribute("requestTime");
long time = System.currentTimeMillis() - startTime;
System.out.println("接口耗时时间(ms):"+time);
}));
};
} public static class Config { } }
(3)接下来将两个过滤器注入到Spring里面
@Configuration
public class FilterConfig
{
@Bean
public PreGatewayFilterFactory preGatewayFilterFactory() {
return new PreGatewayFilterFactory();
} @Bean
public PostGatewayFilterFactory postGatewayFilterFactory() {
return new PostGatewayFilterFactory();
}
}
(4)前往application.yml进行过滤器的配置,在filter属性下配置上我们的自定义过滤器,根据框架的约定引用过滤器:比如我们的过滤器名称是PreGatewayFilterFactory,那我们引用的名称就是去掉GatewayFilterFactory这个后缀,也就是Pre,具体配置如下
spring:
cloud:
gateway:
discovery:
locator:
enabled: true # 设置可以路由到其他服务
routes: # 可以配置多个路由
- id: service-media- # 路由id唯一
uri: lb://service-media # 可以直接跳转到具体的地址,如果要跳转到其他服务,则填写lb://<服务id>
predicates:
- Path=/media/** # 路由规则
filters:
- StripPrefix= # 不填则无法路由到其他服务
- Pre # 自定义过滤器
- Post # 自定义过滤器
(5)接下来我们调用接口,可以看到耗时时间打在公屏上
五、网关限流
1、我们可以在网关层面做限流的功能,防止高并发时把服务器搞崩,或者应对一些网络攻击等情况
2、SpringCloudGateway为我们提供了一个很方便使用的令牌桶限流,思路:我们设置一个固定大小的令牌桶,如果令牌桶不满,则根据一定的频率向桶里放入令牌,每当有客户端的请求发来,会先从令牌桶里面取令牌,取到了则继续执行,取不到请求则会被拒绝,这样就达到了限流的作用,我们可以灵活地调整令牌补充速率和令牌桶大小,来细粒度的控制限流,我们使用redis来存储令牌,下面是一个简单的demo
(1)引入redis依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
(2)接下来自定义限流的维度,我们可以从域名、uri等维度进行限流
public class HostAddrKeyResolver implements KeyResolver
{
@Override
public Mono<String> resolve(ServerWebExchange exchange)
{
// 域名维度限流
return Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
// uri维度限流
// return Mono.just(exchange.getRequest().getURI().getPath());
}
}
(3)将解析器注入到Spring
@Configuration
public class TokenLimitConfig
{
@Bean
public HostAddrKeyResolver hostAddrKeyResolver() {
return new HostAddrKeyResolver();
}
}
(4)接下来配置限流器的配置,将我们编写的解析器引用,并且配置令牌桶的属性,这里我配置的是,每秒补充一个令牌,令牌桶的大小为3,最后配置redis的参数,用起来非常简单
spring:
cloud:
gateway:
discovery:
locator:
enabled: true # 设置可以路由到其他服务
routes: # 可以配置多个路由
- id: service-media- # 路由id唯一
uri: lb://service-media # 可以直接跳转到具体的地址,如果要跳转到其他服务,则填写lb://<服务id>
predicates:
- Path=/media/** # 路由规则
filters:
- StripPrefix= # 不填则无法路由到其他服务
- name: RequestRateLimiter # 配置限流器
args:
key-resolver: '#{@hostAddrKeyResolver}' # 自定义限流过滤器
redis-rate-limiter.replenishRate: # 令牌桶每秒填充平均速率
redis-rate-limiter.burstCapacity: # 令牌桶总容量
redis:
host: 127.0.0.1
port:
password:
(5)配置好后,使用JMeter来压测一下接口,可以发现某些请求返回429错误码,被限流
SpringCloud-Greenwich版本新特性探索(1)---SpringCloudGateway的更多相关文章
- Atitit.c# .net 3.5 4.0 4.5 5.0 6.0各个版本新特性战略规划总结
Atitit.c# .net 3.5 4.0 各个版本新特性战略规划总结 1. --------------.Net Framework版本同CLR版本的关系1 2. paip.----------- ...
- c# .net 3.5 4.0 4.5 5.0 6.0各个版本新特性战略规划总结【转载】
引用:http://blog.csdn.net/attilax/article/details/42014327 c# .net 3.5 4.0 各个版本新特性战略规划总结 1. ---------- ...
- Atitit opencv版本新特性attilax总结
Atitit opencv版本新特性attilax总结 1.1. :OpenCV 3.0 发布,史上功能最全,速度最快的版1 1.2. 应用领域2 1.3. OPENCV2.4.3改进 2.4.2就有 ...
- Atitit mac os 版本 新特性 attilax大总结
Atitit mac os 版本 新特性 attilax大总结 1. Macos概述1 2. 早期2 2.1. Macintosh OS (系统 1.0) 1984年2 2.2. Mac OS 7. ...
- IOS第三天-新浪微博 - 版本新特性,OAuth授权认证
*********版本新特性 #import "HWNewfeatureViewController.h" #import "HWTabBarViewController ...
- 【开源】OSharp3.3框架解说系列:重新开源及3.3版本新特性
OSharp是什么? OSharp是个快速开发框架,但不是一个大而全的包罗万象的框架,严格的说,OSharp中什么都没有实现.与其他大而全的框架最大的不同点,就是OSharp只做抽象封装,不做实现.依 ...
- Atitit 发帖机系列(8) 词法分析器v5 版本新特性说明)
Atitit 发帖机系列(8) 词法分析器v5 版本新特性说明) v5 增加对sql单引号的内部支持.可以作为string 结构调整,使用递归法重构循环发..放弃循环发. V4 java dsl词 ...
- [iOS微博项目 - 1.7] - 版本新特性
A.版本新特性 1.需求 第一次使用新版本的时候,不直接进入app,而是展示新特性界面 github: https://github.com/hellovoidworld/HVWWeibo ...
- framework各版本新特性(为面试准备)
菜鸟D估计描述这些新特性的文章都是烂大街的货色,之所以拿出来分(e)享(xin)一下,有两个原因:1.当年面试的时候有人问到,我不知道该怎么回答:2.项目需要发布了,但是考虑到framework的版本 ...
随机推荐
- SDN网络中hypervisor带来的控制器时延(Hypervisor位置的优化)
一,问题背景 1.介绍监督器大部分由软件实现,可灵活放置,高效的SDN网络虚拟化需要复杂的技术来放置hypervisor在合适的位置,才能提供租户最佳的性能.称为k-Network Hyperviso ...
- 执行grunt命令报错 Cannot find module 'coffee-script'
Failed to list grunt tasks in yudian-frontend-salesplatform\Gruntfile.js: process finished with exit ...
- kvm+libvirt虚拟机快照浅析[转]
浅析snapshots, blockcommit,blockpull 作者:Kashyap Chamarthy <kchamart#redhat.com> Date: Tue, 23 Oc ...
- docker 设计原理
自从上次更新博客截至目前已经8个多月之久,在这大半年里面,我自己经历了好多,换了工作,换了定位,从之前的小运维,到现在负责整个运维部的工作,需要自己协调的事情更多了,最大的成长是可以通过自己的见解对公 ...
- 快速搭建react项目骨架(按需加载、redux、axios、项目级目录等等)
一.前言 最近整理了一下项目骨架,顺便自定义了一个脚手架,方便日后使用.我会从头开始,步骤一步步写明白,如果还有不清楚的可以评论区留言.先大致介绍一下这个骨架,我们采用 create-react-ap ...
- php使用protobuf3
protoc的介绍,安装 1.定义一个protoc 文件 示例:person.proto syntax="proto3"; //声明版本,3x版本支持php package tes ...
- linux mysql 安装
操作系统 Centos 7.2以上版本 操作系统 centos 7.2以上版本 mysql 版本 mysql-5.7.23-el7-x86_64.tar.gz 1.1 安装准备 1. 创建安装文件存 ...
- 1、了解计算机与操作系统发展阶段 2、选择一个具体的操作系统,结合计算机与操作系统的发展阶段,详细了解其渊源、发展过程、趋势,整理成简洁美观的图文博客发布。 Windows Mac os x Unix Linux Android 等。
1.了解计算机与操作系统发展阶段 操作系统并不是与计算机硬件一起诞生的,它是在人们使用计算机的过程中,为了满足两大需求:提高资源利用率.增强计算机系统性能,伴随着计算机技术本身及其应用的日益发展,而逐 ...
- git mvn 使用
git 更换远程仓库地址: stps:先删除远程仓库地址,然后再添加 [git remote rm origin] 删除现有远程仓库 [git remote add origin url]添加新远程仓 ...
- C语言复习5_调试
使用CodeBlocks调试程序 首先要注意,只有打开projects(.cbp文件)的情况下才能debug,单独打开.c文件是不能debug的 1.在行号旁边左键,出现红点,表示为断点breakpo ...