首页 » Web前端 » phplimit跳转掉败技巧_面试官限流的实现办法有哪些

phplimit跳转掉败技巧_面试官限流的实现办法有哪些

访客 2024-11-02 0

扫一扫用手机浏览

文章目录 [+]

限流是指在各种运用处景中,通过技能和策略手段对数据流量、要求频率或资源花费进行有操持的限定,以避免系统负载过高、性能低落乃至崩溃的情形发生。
限流的目标在于掩护系统的稳定性和可用性,并确保做事质量。

利用限流的好处有以下几个:

phplimit跳转掉败技巧_面试官限流的实现办法有哪些

保护系统稳定性:过多的并发要求可能导致做事器内存耗尽、CPU 利用率饱和,从而引发系统相应慢、无法正常做事的问题。
防止资源滥用:确保有限的做事资源被合理公正地分配给所有用户,防止个别用户或恶意程序过度花费资源。
优化用户体验:对付网站和运用程序而言,如果任由高并发导致相应速率变慢,会影响所有用户的正常利用体验。
保障安全:在网络层面,限流有助于戒备 DoS/DDoS 攻击,降落系统遭受恶意攻击的风险。
运维本钱掌握:合理的限流方法可以帮助企业减少不必要的硬件投入,节省运营本钱。

在 Java 中,限流的实现办法有很多种,例如以下这些:

phplimit跳转掉败技巧_面试官限流的实现办法有哪些
(图片来自网络侵删)
单机限流:利用 JUC 下的 Semaphore 限流,或一些常用的框架,例如 Google 的 Guava 框架进行限流,但这种限流办法都是基于 JVM 层面的内存级别的单台机器限流。
网关层限流:单机限流每每不适用于分布式系统,而分布式系统可以在网关层限流,如 Spring Cloud Gateway 通过 Sentinel、Hystrix 对全体集群进行限流。
Nginx 限流:常日在网关层的上游,我们会利用 Nginx 一起来合营利用,也便是用户要求会先到 Nginx(或 Nginx 集群),然后再将要求转发给网关,网关再调用其他的微做事,从而实现全体流程的要求调用,因此 Nginx 限流也是分布式系统中常用的限流手段。

它们限流的详细实现如下。

1.单机限流

JVM 层面多线程级别的限流可以利用 JUC 下的 Semaphore,详细利用示例如下:

import java.util.concurrent.Semaphore;import java.util.concurrent.TimeUnit;public class SemaphoreExample { private final Semaphore semaphore = new Semaphore(5); // 只许可5个线程同时访问 public void accessResource() { try { semaphore.acquire(); // 获取容许,如果当前容许数不敷,则会壅塞 System.out.println(Thread.currentThread().getName() + "得到了容许,正在访问资源..."); // 仿照访问资源的韶光花费 Thread.sleep(2000); System.out.println(Thread.currentThread().getName() + "访问资源结束,开释容许..."); } catch (InterruptedException e) { Thread.currentThread().interrupt(); e.printStackTrace(); } finally { semaphore.release(); // 访问结束后开释容许 } } public static void main(String[] args) { SemaphoreExample example = new SemaphoreExample(); for (int i = 0; i < 10; i++) { new Thread(() -> example.accessResource()).start(); } }}

想要实现更平滑的单机限流,可以考虑 Google 供应的 Guava 框架,它的利用示例如下。

首先在 pom.xml 添加 guava 引用,配置如下:

<!-- https://mvnrepository.com/artifact/com.google.guava/guava --><dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>28.2-jre</version></dependency>

详细实当代码如下:

import com.google.common.util.concurrent.RateLimiter;import java.time.Instant;/ Guava 实现限流 /public class RateLimiterExample { public static void main(String[] args) { // 每秒产生 10 个令牌(每 100 ms 产生一个) RateLimiter rt = RateLimiter.create(10); for (int i = 0; i < 11; i++) { new Thread(() -> { // 获取 1 个令牌,获取到令牌就实行,否则就壅塞等待 rt.acquire(); System.out.println("正常实行方法,ts:" + Instant.now()); }).start(); } }}2.网关层限流

在 Spring Cloud Gateway 网关层限流,可以借助 Sentinel 等限流框架来实现,它的实现步骤如下。

首先,在 pom.xml 中添加 Gateway 和 Sentinel 干系依赖,如下所示:

<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId></dependency>

配置限流干系的规则,如下示例所示:

spring: application: name: gate-way-blog cloud: sentinel: transport: dashboard: localhost:18080 scg: # 配置限流之后,相应内容 fallback: # 两种模式,一种是 response 返回笔墨提示信息, # 另一种是 redirect 重定向跳转,不过配置 redirect 也要配置对应的跳转的 uri mode: response # 相应的状态 response-status: 200 # 相应体 response-body: '{"code": -10,"message": "被熔断或限流!
"}'

末了在 Sentinel 掌握台配置网关的限流设置即可,当然也可以利用 Nacos 作为数据源,两者选择配置个中一个即可。

3.Nginx 限流

Nginx 供应了两种限流手段:

通过掌握速率来实现限流。
通过掌握并发连接数来实现限流。

我们一个一个来看。

3.1 掌握速率实现限流

我们须要利用 limit_req_zone 用来限定单位韶光内的要求数,即速率限定,示例配置如下:

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;server { location / { limit_req zone=mylimit; }}

以上配置表示,限定每个 IP 访问的速率为 2r/s,由于 Nginx 的限流统计是基于毫秒的,我们设置的速率是 2r/s,转换一下便是 500ms 内单个 IP 只许可通过 1 个要求,从 501ms 开始才许可通过第 2 个要求。

我们利用单 IP 在 10ms 内发并发送了 6 个要求的实行结果如下:

从以上结果可以看出他的实行符合我们的预期,只有 1 个实行成功了,其他的 5 个被谢绝了(第 2 个在 501ms 才会被正常实行)。

速率限定升级版

上面的速率掌握虽然很精准但是运用于真实环境难免不免太苛刻了,真实情形下我们该当掌握一个 IP 单位总韶光内的总访问次数,而不是像上面那么精确但毫秒,我们可以利用 burst 关键字开启此设置,示例配置如下:

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;server { location / { limit_req zone=mylimit burst=4; }}

burst=4 表示每个 IP 最多许可4个突发要求,如果单个 IP 在 10ms 内发送 6 次要求的结果如下:

从以上结果可以看出,有 1 个要求被立即处理了,4 个要求被放到 burst 行列步队里排队实行了,其余 1 个要求被谢绝了。

3.2 掌握并发数实现限流

利用 limit_conn_zone 和 limit_conn 两个指令即可掌握并发数,示例配置如下:

limit_conn_zone $binary_remote_addr zone=perip:10m;limit_conn_zone $server_name zone=perserver:10m;server { ... limit_conn perip 10; limit_conn perserver 100;}

个中 limit_conn perip 10 表示限定单个 IP 同时最多能持有 10 个连接;limit_conn perserver 100 表示 server 同时能处理并发连接的总数为 100 个。

小贴士:只有当 request header 被后端处理后,这个连接才进行计数。

课后思考

Semaphore 限流和 Guava 限流有什么差异?Sentinel 和 Nginx 限流有什么不敷?该当如何避免?

本文已收录到我的口试小站 [www.javacn.site](https://www.javacn.site),个中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、行列步队等模块。

标签:

相关文章