在昨天的基础上增加代码
一、限流
限流的目的是通过对并发访问 / 请求进行限速或者对一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可由 拒绝服务 ,就是定向到错误页或友好的展示页,排队或等待。限流可以保障我们的 API 服务对所有用户的可用性,也可以防止网络攻击。在高并发的应用中,限流是一个绕不开的话题。令牌桶算法令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。
QPS每秒请求数,就是说服务器在一秒的时间内处理了多少个请求。提高带宽
1、Gateway限流的实现
①、pom.xml(gateway)
降版本,
导入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis-reactive</artifactId> </dependency>
Gateway 通过内置的 RequestRateLimiter 过滤器实现限流,使用令牌桶算法,借助 Redis 保存中间数据。用户可通过自定义KeyResolver 设置限流维度。·对请求的目标 URL 进行限流·对来源 IP 进行限流·特定用户进行限流
②、application.yml
redis:
host: 127.0.0.1
port: 6379
# password: 123
database: 0
③、增加请求限流配置类
RequestRateLimiterConfig :
package com.mwy.code;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import reactor.core.publisher.Mono;
/**
* 请求限流配置
*/
@Configuration
public class RequestRateLimiterConfig {
/**
* 按IP来限流
*/
@Bean
@Primary
public KeyResolver ipAddrKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
}
/**
* 按用户限流
*/
@Bean
KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
/**
* 按URL限流,即以每秒内请求数按URL分组统计,超出限流的url请求都将返回429状态
*
* @return
*/
@Bean
KeyResolver apiKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getPath().toString());
}
}
④、application.yml
关掉自定义配置
- name: RequestRateLimiter args: #用于限流的键的解析器的 Bean 对象的名字,使用 SpEL表达式根据#{@beanName}获取Bean对象 key-resolver: '#{@ipAddrKeyResolver}' #令牌桶填充速率,允许用户每秒处理多少个请求 redis-rate-limiter.replenishRate: 10 #令牌桶总容量,允许在一秒钟内完成的最大请求数 redis-rate-limiter.burstCapacity: 20
注掉这个依赖,与版本有问题,这个依赖是用来读取远程nacos配置
⑤、测试从网关访问
说明我们已经通过网关访问到消费者了
2、压力测试
压力测试是每一个 Web 应用程序上线之前都需要做的一个测试,他可以帮助我们发现系统中的瓶颈问题,减少发布到生产环境后出问题的几率预估系统的承载能力,使我们能根据其做出一些应对措施。所以压力测试是一个非常重要的步我们虽然访问成功了,但是并不知道有没有限流,所以进行压力测试;
解压:
①、apache-jmeter-5.2.1->bin->双击打开:jmeter.bat
改为中文
②、进行压力测试
添加线程组,模拟多个人去访问
并不知道运作的对象是谁,所以添加HTTP请求
添加查看请求结果:
③、进行压力测试
HTTP请求中点击启动:选择no
表格查看运行结果:代码中允许访问人数为10人,最大访问人数为20人,超过允许访问请求就会变为红色:
二、熔断
知乎好的文章:服务降级与服务熔断区别 - 知乎
在分布式系统中,网关作为流量的入口,大量请求进入网关,向后端远程系统或服务发起调用,后端服务不可避免的会产生调用失败(超时或者异常),失败时不能让请求堆积在网关上,需要快速失败并返回回去,这就需要在网关上做熔断、降级操作。
1、增加熔断的依赖
2020版左右的idea熔断就已经停止了,可以进行降版本操作,还可以进行
sentinel (史上最全+入门教程) - 疯狂创客圈 - 博客园
降级操作在上面就已经写好了
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
2、application.yml
增加熔断配置
- name: Hystrix
args:
name: fallback
fallbackUri: forward:/fallback转发,新建填写路径
3、新建TestController类
package com.mwy.code;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class TestController {
@RequestMapping("fallback")
public Object fallback(){
Map<String,Object> map=new HashMap<>();
map.put("code","204");
map.put("msg","服务已降级");
return map;
}
}
4、测试
①、正常访问
②、关闭消费者服务服务
熔断成功