亿级流量系统多级缓存架构6

亿级流量系统多级缓存架构6

服务限流

什么叫限流?

Ab测试

yum install httpd-tools

即限制流量进入

缓存,是用来增加系统吞吐量,提升访问速度提供高并发。

降级,是在系统某些服务组件不可用的时候、流量暴增、资源耗尽等情况下,暂时屏蔽掉出问题的服务,继续提供降级服务,给用户尽可能的友好提示,返回兜底数据,不会影响整体业务流程,待问题解决再重新上线服务

限流,是指在使用缓存和降级无效的场景。比如当达到阈值后限制接口调用频率,访问次数,库存个数等,在出现服务不可用之前,提前把服务降级。只服务好一部分用户。

在我们使用微信、支付宝、短信等等这些api的时候,每个接口都会有调用上的限流。

限流是对某一时间窗口内的请求数进行限制,保持系统的可用性、稳定性和安全性,防止因流量暴增而导致的系统运行缓慢或宕机,

app 统计

友盟 cnzz …

限流算法

计数器算法

简单粗暴

比如线程池大小,数据库连接池大小、nginx连接数等都属于计数器算法。

全局或某段时间范围达到阈值则限流。

漏桶算法

在这里插入图片描述

削峰
缓冲
消费速度固定 因为计算性能固定
保证桶不能忙
令牌桶算法

平滑的流入速率限制,消费/秒。

可以用于对外服务接口,内部集群调用

区别

  • 令牌桶是按照固定速率从桶里拿令牌消费,如果令牌为0,则拒绝新请求
  • 漏桶是按照固定速率流出请求,流入速率不控制,当桶内请求达到阈值,新请求则被拒绝。
  • 令牌桶支持每次拿多个令牌,平均流入速率,并支持突发流入,还可以支持缓慢提升流入速度
并发限流

设置系统阈值总的qps个数

Tomcat中配置的

  • acceptCount 响应连接数
  • maxConnections 瞬时最大连接数
  • maxThreads 最大线程数
接口限流
接口总数

可以使用atomic类或者semaphore进行限流

这种方式简单粗暴。没有平滑处理。使用限制某个接口的总并发数,或限制某账号服务调用总次数。

比如某些开放平台限制试用账号。

if (atomic.incrementAndGet() > 100){
    // 拒绝
}finally{
	atomic.decrementAndGet();

}
接口时间窗口

此时可以使用Guava Cache,类似于一个ConcurrentMap,但并不完全一样。

最基础的不同是ConcurrentMap保存所有的元素知道它们被明确删除,Guava Cache可以配置自动过期

//计数器
counter;
// 限制数量
limit;
// 限制单位 1000=秒
unit;
// 获得当前时间
current = system.currentTimeMillis() / unit
//判断时间窗内是否限制访问

if (counter.get(current).incrementAndGet() > limit){
    // 拒绝
}

使用guava实现

引入包

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

核心代码

		LoadingCache<Long, AtomicLong> counter = CacheBuilder.newBuilder().
				expireAfterWrite(2, TimeUnit.SECONDS)
				.build(new CacheLoader<Long, AtomicLong>() {

					@Override
					public AtomicLong load(Long secend) throws Exception {
						// TODO Auto-generated method stub
						return new AtomicLong(0);
					}
				});
		counter.get(1l).incrementAndGet();
令牌桶实现

稳定模式(SmoothBursty:令牌生成速度恒定)

	public static void main(String[] args) {
		// RateLimiter.create(2)每秒产生的令牌数
		RateLimiter limiter = RateLimiter.create(2);
        // limiter.acquire() 阻塞的方式获取令牌
		System.out.println(limiter.acquire());;
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(limiter.acquire());;
		System.out.println(limiter.acquire());;
		System.out.println(limiter.acquire());;
		System.out.println(limiter.acquire());;
		
		System.out.println(limiter.acquire());;
		System.out.println(limiter.acquire());;
	}

```RateLimiter.create(2)`` 容量和突发量,令牌桶算法允许将一段时间内没有消费的令牌暂存到令牌桶中,用来突发消费。

渐进模式(SmoothWarmingUp:令牌生成速度缓慢提升直到维持在一个稳定值)

	// 平滑限流,从冷启动速率(满的)到平均消费速率的时间间隔
		RateLimiter limiter = RateLimiter.create(2,1000l,TimeUnit.MILLISECONDS);
		System.out.println(limiter.acquire());;
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(limiter.acquire());;
		System.out.println(limiter.acquire());;
		System.out.println(limiter.acquire());;
		System.out.println(limiter.acquire());;
		
		System.out.println(limiter.acquire());;
		System.out.println(limiter.acquire());;

超时

boolean tryAcquire = limiter.tryAcquire(Duration.ofMillis(11));

在timeout时间内是否能够获得令牌,异步执行

分布式系统限流

Nginx + Lua

可以使用resty.lock保持原子特性,请求之间不会产生锁的重入

https://github.com/openresty/lua-resty-lock

使用lua_shared_dict存储数据

local locks = require "resty.lock"

local function acquire()
    local lock =locks:new("locks")
    local elapsed, err =lock:lock("limit_key") --互斥锁 保证原子特性
    local limit_counter =ngx.shared.limit_counter --计数器

    local key = "ip:" ..os.time()
    local limit = 5 --限流大小
    local current =limit_counter:get(key)

    if current ~= nil and current + 1> limit then --如果超出限流大小
       lock:unlock()
       return 0
    end
    if current == nil then
       limit_counter:set(key, 1, 1) --第一次需要设置过期时间,设置key的值为1,
过期时间为1else
        limit_counter:incr(key, 1) --第二次开始加1即可
    end
    lock:unlock()
    return 1
end
ngx.print(acquire())

nginx配置

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/554045.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

宠物店小程序如何搭建制作?宠物店小程序核心功能有哪些?

随着宠物经济的兴起&#xff0c;宠物店的线上服务需求日益增长。微信小程序作为一种便捷的线上服务平台&#xff0c;为宠物店提供了一个与爱宠人士建立联系的新渠道。面对市场上众多的小程序开发选项&#xff0c;宠物店应该如何选择或制作一款适合自己的小程序呢&#xff1f;本…

[spring] Spring Boot REST API - CRUD 操作

Spring Boot REST API - CRUD 操作 这里主要提一下 spring boot 创建 rest api&#xff0c;并对其进行 CRUD 操作 jackson & gson 目前浏览器和服务端主流的交互方式是使用 JSON(JavaScript Object Notation)&#xff0c;但是 JSON 没有办法直接和 Java 的 POJO 创建对应…

【网络运维知识】—路由器与交换机区别

【网络运维知识】—路由器与交换机区别 一、路由器&#xff08;Router&#xff09;和交换机&#xff08;Switch&#xff09;对比1.1 功能1.2 转发方式1.3 范围1.4 处理方式 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 路由器&#xff08…

ShadowFormer:Global Context Helps Images Shadow Removal

本论文主要是对图像阴影去除工作的研究。现有工作都是针对于局部阴影或阴影部分分别进行优化&#xff0c;这就会导致在分界线上有明显不同&#xff08;光照不一致&#xff0c;伪影情况&#xff09;。因此&#xff0c;本文提出一种全局优化算法shandowFormer来解决分界不一致问题…

Springboot+Vue项目-基于Java+MySQL的企业客户管理系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

数据结构中的顺序表的删除和查找

对于顺序表&#xff0c;它包括&#xff1a;初始化&#xff0c;取值&#xff0c;查找&#xff0c;插入&#xff0c;以及删除。接下来就讲一讲删除和查找。 删除&#xff1a;它包括头删和尾删&#xff0c;为什么顺序表中要用到删除呢&#xff1f;按我的理解就是&#xff1a;为插入…

SRIO系列-基本概念及IP核使用

参考&#xff1a;串行RapidIO: 高性能嵌入式互连技术 | 德州仪器 SRIO协议技术分析 - 知乎 PG007 目录 一、SRIO介绍 1.1 概要 1.2 SRIO与传统互联方式的比较 1.3 串行SRIO标准 1.4 SRIO层次结构&#xff1a; 1.4.1 逻辑层 1.4.2 传输层协议 1.4.3 物理层 二、Xilinx…

内网隧道技术总结

隧道技术解决的是网络通信问题&#xff0c;因为在内网环境下&#xff0c;我们不同的内网主机管理员会进行不同的网络配置&#xff0c;我们就需要使用不同的方式去控制我们的内网主机。隧道技术是一个后渗透的过程&#xff0c;是可以是我们已经取得了一定的权限&#xff0c;在这…

【Visual Studio 2012中文版】下载安装以及使用方法

文章目录 前言一、下载安装包二、安装步骤1.双击VS2012_ULT_chs.iso文件打开2.双击vs_ultimate.exe打开安装程序3.选择要安装的功能4.软件正在安装&#xff0c;请耐心等待10分钟5.安装成功&#xff0c;点击“启动”6.激活码&#xff08;产品密钥&#xff09; 三、VS2012使用&am…

软考 系统架构设计师系列知识点之大数据设计理论与实践(10)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之大数据设计理论与实践&#xff08;9&#xff09; 所属章节&#xff1a; 第19章. 大数据架构设计理论与实践 第3节 Lambda架构 19.3.5 Lambda架构优缺点 1. 优点 &#xff08;1&#xff09;容错性好 Lambda架构为大数…

HTML:Form表单控件主要标签及属性。name属性,value属性,id属性详解。表单内容的传递流程,get和post数据传递样式。表单数据传递实例

form表单 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </head> &…

Vue源码解读学习

Vue源码 观察者模式 & 发布订阅 观察者模式&#xff1a;中心一对多 系统单点间的灵活和拓展&#xff08;广播的方式&#xff09; 发布订阅&#xff1a;将注册列表遍历发布给订阅者 initInject initState initProvide他们挂载顺序为什么这样设计&#xff1f; initstate…

【春秋云镜】CVE-2023-43291 emlog SQL注入

靶场介绍 emlog是一款轻量级博客及CMS建站系统&#xff0c;在emlog pro v.2.1.15及更早版本中的不受信任数据反序列化允许远程攻击者通过cache.php组件执行SQL语句。 不感兴趣的可以直接拉到最后面&#xff0c;直接获取flag 备注&#xff1a;没有通过sql注入获取到flag&…

C语言 【基础语法】

一、编程环境搭建 编译器&#xff1a;gcc 集成开发环境&#xff1a;vscode 1.1 安装vscode 1.2 设置中文包 插件 1.3 设置C/C扩展 安装 C/C Compile Run extension 和 C/C Extension Pack 扩展 二、基础语法 2.1 第一个c语言程序 2.2 数据类型 2.2.1 变量的语法(重点) …

RK3588 Android13 TvSetting 中增加 Usb 模式 Host/OTG 切换

前言 电视产品,客户要求在设置中设备偏好设置子菜单下增加一个USB模式切换菜单,一开始准备直接开整。但发现在开发者选项里就已经包含了一个USB模式 菜单了,只是没有 OTG HOST 这两选项,那就把这个菜单挪出来再增加一下就完事了,开整。 客户提供对比机图 效果图 framew…

OpenCV从入门到精通实战(六)——多目标追踪

基于原生的追踪 使用OpenCV库实现基于视频的对象追踪。通过以下步骤和Python代码&#xff0c;您将能够选择不同的追踪器&#xff0c;并对视频中的对象进行实时追踪。 步骤 1: 导入必要的库 首先&#xff0c;我们需要导入一些必要的Python库&#xff0c;包括argparse、time、…

Redis从入门到精通(十四)Redis分布式缓存(二)Redis哨兵集群的搭建和原理分析

文章目录 前言5.3 Redis哨兵5.3.1 哨兵原理5.3.1.1 集群的结构和作用5.3.1.2 集群监控原理5.3.1.3 集群故障恢复原理 5.3.2 搭建哨兵集群5.3.3 RedisTemplate5.3.3.1 搭建测试项目5.3.3.2 场景测试 前言 Redis分布式缓存系列文章&#xff1a; Redis从入门到精通(十三)Redis分…

回文链表题解

题目&#xff1a;回文链表 分析 这道题目标签为简单题&#xff0c;但是如果要实现下面的进阶过程不是很简单。 拿到题目一般来说就是赶时间&#xff0c;没有要求的情况下直接使用一个列表存储所有的数值&#xff0c;然后判断这个列表是否满足回文&#xff0c;这个思路是比较简…

【1524】java投票管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java 投票管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0&…

IO引脚服用和映射

什么是端口复用 STM32F4 有很多的内置外设&#xff0c;这些外设的外部引脚都是与 GPIO 复用的。也就是说&#xff0c;一个 GPIO如果可以复用为内置外设的功能引脚&#xff0c;那么当这个 GPIO 作为内置外设使用的时候&#xff0c;就叫做复用。在芯片数据手册或STM32F4XX参考手…