外包做网站的要求怎么写,网站建设调查分析,国外红人营销网站,烟台做网站多少钱文章目录 前言第一层限流#xff1a;Nginx 层面的 IP 限流第二层限流#xff1a;Gateway 对用户层级的限流第三层限流#xff1a;微服务限流分布式限流和单机限流的优缺点#xff1a;1、RateLimiter的使用2、Hystrix的使用3、Redislua脚本4、使用Sentinel 关于为何同时使用… 文章目录 前言第一层限流Nginx 层面的 IP 限流第二层限流Gateway 对用户层级的限流第三层限流微服务限流分布式限流和单机限流的优缺点1、RateLimiter的使用2、Hystrix的使用3、Redislua脚本4、使用Sentinel 关于为何同时使用 Nginx 和 Spring Cloud Gateway 前言
在高并发网络环境中确保系统的可用性、稳定性以及防范恶意流量攻击至关重要。为此在我们的项目中构建了三层限流设计。
第一层是 Nginx 层面的 IP 限流借助 Nginx 的 http_limit_req_module 模块依据用户 IP 设限这是抵御恶意 IP 的 DDoS 攻击、阻挡大量非法请求深入系统的首道防线。
第二层为 gateway 针对用户层级的限流通过用户的唯一标识如 user_id控制每个用户在单位时间内的请求数量确保公平避免单一用户过度占用资源而影响他人体验。
第三层则是微服务限流每个微服务运用如 Google 的 Guava RateLimiter 等技术限流防止服务过载影响系统稳定且各服务根据自身能力和业务需求独立设定限流阈值。
三层限流的结构图如下
第一层限流Nginx 层面的 IP 限流
Nginx 的 http_limit_req_module 模块是我们构建的第一道坚固防线。 其工作原理基于定义一个明确的“速率”值用于对单位时间内的请求数量进行严格的限制。比如说您可以设定每分钟只处理 100 个请求。当某个客户端的请求速率超过预先设定的限制时Nginx 就会地将这些请求放入一个专门的队列中等待后续的处理。然而如果队列中的请求数量过多或者等待处理的时间超出了可接受的范围那么这些请求将会被果断丢弃。
在配置方面首先需要在 Nginx 的 http 块中使用 limit_req_zone 指令来定义限制速率的区域。例如如果我们决定根据客户端的 IP 进行限制限流20MB每秒允许处理1000个请求配置如下
http http { limit_req_zone $binary_remote_addr zoneperip:20m rate1000r/s; ...
} 这里$binary_remote_addr 代表客户端的 IP 地址zonetotalLimit:20m 定义了一个名为 totalLimit 的存储区域其大小为 20M用于存储每个 IP 的状态信息而 rate10r/s 则清晰地设定了每秒 1000 个请求的限制速率。
接下来在需要应用这个限制的 server 块或 location 块中使用 limit_req 指令来设定这个限制。例如
json server { location / { limit_req zonetotalLimit burst1000 nodelay;...}
} 在上述配置中zonetotalLimit 明确表示应用之前定义的 totalLimit 区域而 burst1000 则意味着允许在短时间内超过定义的速率最多累积 1000 个请求等待处理。 通过调整 rate 、burst 和 nodelay 等配置参数我们能够根据不同的业务需求灵活定制限流策略。比如假设我们的业务主要面向个人用户并且大部分时间请求量相对稳定但在某些特定的高峰期会出现请求量的突然增加。在这种情况下我们可能会选择设定一个适中的 rate 并同时允许一定数量的 burst 以在保障系统稳定性的同时最大程度地优化用户体验。
第二层限流Gateway 对用户层级的限流
为了进一步增强系统的限流效果和精细化管理我们在 API 网关层面也实施了限流策略。 首先在 Spring Cloud Gateway 中通过在配置文件中明确地定义限流规则我们能够基于 user_id 这一关键标识精准地控制每个用户在单位时间内所能发送的请求数量。以下是一个针对 user_id 进行限流的配置示例
spring:cloud:gateway:routes:- id: user_routeuri: http://mybackend.compredicates:- Path/api/**filters:- name: RequestRateLimiterargs:redis-rate-limiter.replenishRate: 10redis-rate-limiter.burstCapacity: 20key-resolver: #{userIdResolver}在这个配置中redis-rate-limiter.replenishRate 定义了每秒可以处理的请求数量而 redis-rate-limiter.burstCapacity 则设定了可以接受的突发请求数量。同时key-resolver 用于明确如何从请求中准确获取 user_id 。
为了实现从请求中提取 user_id 我们需要实现一个 KeyResolver 接口。以下是一个使用 Java 语言实现的示例代码展示了如何从请求的查询参数中获取 user_id
1、引入依赖
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis-reactive/artifactIdversion3.3.1/version
/dependency2、配置获取用户id的方法
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;Configuration
public class RateLimiterConfigurationBeanKeyResolver userIdKeyResolver(){return Mono.just(exchange.getRequest().getQueryParams().getFirst(user_id));}
}3、配置c配置文件中的过滤配置
spring:cloud:gateway:filters:- name: RequestRateLimiterargs:redis-rate-limiter.replenishRate: 1000 # 令牌桶每秒填充平均速率redis-rate-limiter.burstCapacity: 2000 # 令牌桶的上限key-resolver: #{userIdResolver} # 使用spel表达式从spring容器中获取Bean对象网关层面限流的好处众多通过这样的设计极大地简化了整个系统的工作流程和管理复杂度。 网关层面实现限流机制带来了诸多显著的好处。
首先它能够为所有的应用程序提供一个统一的流量控制管理使得我们能够在一个集中的位置对所有服务的流量进行有效的监管和控制而无需在每个服务中分别进行复杂的配置。
其次限流机制能够有效地防止任何一个服务由于过大的流量冲击而陷入崩溃的境地从而显著增强了系统的稳定性。
再者它能够有效地对系统中的每个用户的请求进行精确控制避免了某些用户过度占用系统资源而对其他用户的体验造成不良影响。
最后对于可预期的高流量请求场景我们能够在网关层面迅速而灵活地进行调整和应对保障系统的正常运行。
第三层限流微服务限流
在每个微服务内部每个微服务都能够根据自身的处理能力和独特的业务需求独立设定限流阈值。这种个性化的设置确保了每个微服务在面对不同的负载情况时都能够保持稳定的性能和可靠的服务质量从而有效地防止了某个服务的过载对整个系统的稳定性产生不利影响。
在这层中有多种技术来实现微服务限流可以采用如 Google 的 Guava RateLimiter、SpringCloud的Hystrix等框架来实施单机限流策略也可以采用 阿里的Sentinel、或者自己用Redislua脚本实现分布式限流对微服务多个实例统一限流。
分布式限流和单机限流的优缺点
分布式限流的优点
全局一致确保整个系统限流策略统一维持稳定。适应高并发处理大规模、高流量场景保障系统稳定。弹性扩展随系统规模变化能灵活调整限流策略。精准控制依据系统整体情况精确限流。
**分布式限流的缺点 ** 复杂实现和维护难度大涉及协调和同步问题。 有性能开销节点通信带来一定性能损失。 依赖外部组件增加系统依赖和故障点。
单机限流的优点 简单实现逻辑简单无需复杂协调机制。 低开销无节点通信性能影响小。 独立限流策略不受其他节点干扰。
单机限流的缺点
局限只能处理单机器流量。缺乏协调不同机器策略难统一影响系统稳定。难扩展无法直接用于多机环境。
1、RateLimiter的使用
RateLimiter使用起来比较简单代码示例如下 public static void main(String[] args) {// 创建一个每秒放入5个令牌的RateLimiterRateLimiter limiter RateLimiter.create(100.0);for (int i 0; i 10; i) {// 请求一个令牌limiter.acquire();System.out.println(处理请求: i);}}这段代码创建了一个RateLimiter它每秒产生100个令牌。在一个循环中我们通过acquire()方法从RateLimiter获取令牌。如果令牌不够acquire()会阻塞直到获取到令牌
2、Hystrix的使用
Hystrix的限流是基于线程池的所以在配置文件里设置hystrix线程池的核心线程数就可实现限流
hystrix:threadpool:default:coreSize: 200 #并发执行的最大线程数默认10maxQueueSize: 1000 #BlockingQueue的最大队列数默认值-1queueSizeRejectionThreshold: 800 #即使maxQueueSize没有达到达到queueSizeRejectionThreshold该值后请求也会被拒绝默认值53、Redislua脚本
limit.lua
local count
- 获取调用脚本时传入的第一个key值用作限流的 key
count redis.call(get,KEYS[1])
-- 获取调用脚本时传入的第一个参数值限流大小
if count and tonumber(count) tonumber(ARGV[1]) thenreturn count;
endcount redis.call(incr,KEYS[1])
if tonumber(count) 1 then--从第一次调用开始限流设置对应key的过期时间redis.call(expire,KEYS[1],ARGV[2])
end
return count;大致的代码逻辑实际使用建议封装成一个注解来使用 DefaultRedisScriptNumber redisScript new DefaultRedisScript();redisScript.setResultType(Number.class);ClassPathResource classPathResource new ClassPathResource(LIMIT_LUA_PATH);try {classPathResource.getInputStream();//探测资源是否存在redisScript.setScriptSource(new ResourceScriptSource(classPathResource));} catch (IOException e) {logger.error(未找到文件{}, LIMIT_LUA_PATH);} List result stringRedisTemplate.execute(redisScript, keyList, String.valueOf(value),String.valueOf(time));Object result stringRedisTemplate.execute(redisScript, keys, limitCount, limitPeriod);if (result null) {//降级} Integer count Integer.valueOf(result.toString());if (count limitCount) {//执行业务逻辑} else {//降级}
4、使用Sentinel
Sentinel 是阿里出品的一个功能强大的分布式限流框架具体使用可以参考下面的官方文档
quick-start | Sentinel (sentinelguard.io)
关于为何同时使用 Nginx 和 Spring Cloud Gateway
首先我们的项目主要基于 Spring Boot 和 Spring Cloud 进行开发而 Spring Cloud Gateway 能够与这些技术实现无缝的集成。这种紧密的集成特性不仅减少了我们在处理不同组件之间兼容性问题上所花费的时间和精力还极大地提高了开发和维护的效率。
其次Spring Cloud Gateway 支持非阻塞的方式来处理请求这一特性在处理高并发请求时表现出了显著的优势是 Nginx 所无法提供的。非阻塞的处理方式能够更高效地利用系统资源提升系统的整体性能和响应速度。
再者Spring Cloud Gateway 允许我们通过动态的编程方式来定义路由规则与 Nginx 相对静态的配置方式形成了鲜明的对比。这种动态定义路由规则的能力使我们能够更加灵活地应对复杂多变的业务需求和系统架构调整为系统的持续演进提供了有力的支持。
最后Spring Cloud Gateway 还集成了 Spring Cloud 的服务发现功能以及与 Spring Cloud 集群紧密配合的断路、降级和限流等机制。这些集成的功能共同强化了微服务架构的健壮性和可靠性确保系统在面对各种异常情况和高负载场景时依然能够保持稳定的运行状态为用户提供持续、优质的服务。
综上所述虽然 Nginx 已经在网络服务领域展现出了强大的实力但在我们特定的项目架构中Spring Cloud Gateway 凭借其与现有技术栈的高度适配性、独特的功能特性以及对微服务架构的全面支持更加符合我们的项目需求。
综上所述这三层限流设计相互协作、相辅相成从不同的层面和角度全方位地保障了系统在高并发场景下的稳定运行。