面试官:海量请求下的接口并发解决方案,具体聊聊吧

news2024/9/23 17:24:10

设定一个场景,假如一个商品接口在某段时间突然上升,会怎么办?

生活中的例子来说,假设冰墩墩在当天晚上上热搜之后,迅速有十几万人去淘宝下单购买,此时并没有做好对该商品的缓存预热以及准备,如何操作?

 

对于这个问题,在电商高并发系统中,对接口的保护一般采用:缓存、限流、降级 来操作。

假设该接口已经接受过风控的处理,过滤掉一半的机器人脚本请求,剩下都是人为的下单请求。

服务限流

限流 主要的目的是通过对并发访问/请求进行限速,或者对一个时间窗口内的请求进行限速,一旦达到限制速率则可以拒绝服务、排队或等待、降级等处理。

限流算法

1. 漏斗算法

漏桶算法 是当请求到达时直接放入漏桶,如果当前容量已达到上限(限流值),则进行丢弃或其他策略(触发限流策略)。漏桶以固定的速率(根据服务吞吐量)进行释放访问请求(即请求通过),直到漏桶为空。

漏斗算法的思想就是,不管你来多少请求,我的接口消费速度一定是小于等于流出速率的阈值的。

 

可以基于消息队列来实现。

2. 令牌桶算法

令牌桶算法 是程序以v(v = 时间周期 / 限流值)的速度向令牌桶中增加令牌,直到令牌桶满,请求到达时向令牌桶请求令牌,如果获取成功则通过请求,如果获取失败触发限流策略。

令牌桶算法和漏斗算法的思想差别在于,前者可以允许突发请求的发生。

 

3. 滑窗算法

滑窗算法 是将一个时间周期分为N个小周期,分别记录每个小周期内访问次数,并且根据时间滑动删除过期的小周期。

如下图所示,假设时间周期为1分钟,将1分钟再分为2个小周期,统计每个小周期的访问数量,则可以看到,第一个时间周期内,访问数量为75,第二个时间周期内,访问数量为100,如果一个时间周期内所有的小周期总和超过100的话,则会触发限流策略。

 

Sentinel的实现 和 TCP滑窗。

接入层限流

Nginx限流

Nginx 限流采用的是漏桶算法。

它可以根据客户端特征,限制其访问频率,客户端特征主要指 IP、UserAgent等。使用 IP 比 UserAgent 更可靠,因为 IP 无法造假,UserAgent 可随意伪造。

limit_req模块基于IP:

http://nginx.org/en/docs/http/ngx_http_limit_req_module.html

tgngine:

 

http://tengine.taobao.org/document_cn/http_limit_req_cn.html

本地接口限流

 Semaphore

Java 并发库 的 Semaphore 可以很轻松完成信号量控制,Semaphore 可以控制某个资源可被同时访问的个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。

假如我们对外提供一个服务接口,允许最大并发数为40,我们可以这样:

private final Semaphore permit = new Semaphore(40, true);

public void process(){

    try{
        permit.acquire();
        //TODO 处理业务逻辑

    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        permit.release();
    }
}

 

具体的 Semaphore 实现参考源码。

分布式接口限流

使用消息队列

不管是用MQ中间件,或是Redis的List实现的消息队列,都可以作为一个 缓冲队列 来使用。思想就是基于漏斗算法。

当对于一个接口请求达到一定阈值时,就可以启用消息队列来进行接口数据的缓冲,并根据服务的吞吐量来消费数据。

 

服务降级

在接口做好风控的前提下,发现了接口请求的并发量迅速上升,我们可以启用兜底方案,进行服务降级。

一般服务降级应该用来对一些 不重要 或 不紧急 的服务或任务进行服务的 延迟使用 或 暂停使用。

降级方案

比如淘宝双11前,就不可以查询三个月前的订单,对边缘业务进行降级,保证核心业务的高可用。

拒绝请求

在接口请求并发量大于阈值,或是接口出现大量失败请求等等突发情况,可以拒绝一些访问请求。

拒绝策略

  • 随机拒绝:随机拒绝超过阈值的请求 。

  • 拒绝旧请求:按照请求的时间,优先拒绝更早收到的请求。

  • 拒绝非核心请求:根据系统业务设置核心请求清单,将非核心清单内的请求拒绝掉。

恢复方案

在实现服务降级之后,对于突增流量我们可以继续注册多个消费者服务来应对并发量,之后我们再对一些服务器进行慢加载。

降级具体实现参考其他文章。

数据缓存

在接口做好风控的前提下,发现了接口请求的并发量迅速上升,我们可以分以下几个操作执行:

  • 对访问请求使用分布式锁进行阻塞。

  • 在这个短时间中,我们可以将对应操作行的热点数据,缓存在缓存中间件中。

  • 放行请求后,让所有请求优先操作缓存数据。

  • 再将操作的结果通过消息队列发送给消费接口慢慢消费。

缓存问题

假设我们操作的是一个库存接口,此时数据库中只有100个库存。

那假如此时我们将一条数据放入缓存中,如果所有的请求都来访问这个缓存,那它还是被打挂,我们该怎么操作?

 

读写分离

第一种想法,读写分离。

使用Redis的哨兵集群模式来进行主从复制的读写分离操作。读的操作肯定大于写操作,等库存被消费到0时,读操作直接快速失败。

负载均衡

第二种想法,负载均衡。

在缓存数据后,如果所有请求都来缓存中操作这个库存,不管是加悲观锁还是乐观锁,并发率都很低,此时我们可以对这个库存进行拆分。

我们可以参照 ConcurrentHashMap 中的 counterCells 变量的设计思想,将100个库存拆分到10个缓存服务中,每个缓存服务有10个缓存,然后我们再对请求进行负载均衡到各个缓存服务上。

但是这种方式会有问题,如果大部分用户被hash到同一个缓存上,导致其他缓存没有被消费,却返回没有库存,这是不合理的。

 

 

page cache

第三种想法,page cache。

大部分软件架构其实都用到了这种方法,比如linux内核的硬盘写入、mysql的刷盘等等,即将短时间内的写操作聚合结果写入,所有的写操作在缓存内完成。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【力扣刷题】day1-1、两数之和 2、两数相加

力扣刷题笔记day1 1,两数之和 题意 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元…

C++ · 入门 · 04 | 引用

啊我摔倒了..有没有人扶我起来学习.... 👱个人主页:《CGod的个人主页》\color{Darkorange}{《CGod的个人主页》}《CGod的个人主页》交个朋友叭~ 💒个人社区:《编程成神技术交流社区》\color{Darkorange}{《编程成神技术交流社区》…

STM32MP157驱动开发——Linux WIFI驱动

STM32MP157驱动开发——Linux WIFI驱动一、简介二、驱动开发1.wifi驱动添加与编译2.配置 USB 支持设备1)配置 USB 支持设备2)配置支持的 WIFI 设备3)配置支持 IEEE 802.114)使能 STAGING 配置3.设备树配置4.编译 wifi 驱动1&#…

05SpringCloudAlibaba负载均衡服务调用-Ribbon

目录 推荐与004SpringCloud-Ribbon_gh_xiaohe的博客-CSDN博客 对比观看 Ribbon概述 Ribbon官网https://github.com/Netflix/ribbon/wiki/Getting-Started Ribbon是什么 Ribbon也进入维护模式 Ribbon能干什么 LB(负载均衡) 一句话:…

冲击港交所:百果园书写水果连锁运营默示录

卖水果是一门古老的生意,但是长期以来并不受资本重视。一是因为产品口味难以标准化、鲜度要求高、流通环节易损耗、质量控制难度大。二是因为交易主体多,进出壁垒小,经济学中往往将其定义为完全竞争市场,难以出现龙头企业和超额利…

AI与艺术——图像生成模型是否能挑战人类艺术?

在2018年末的佳士得纽约拍卖场上,一件名为《爱德蒙贝拉米肖像》拍出了43.25万美元的价格,从绘画艺术风格来看,这是一幅有着很明显的印象派主义痕迹的作品。 印象派是19世纪中叶在法国兴起的一种艺术运动。印象派艺术家们拒绝了艺术(“美术”…

Webpack中的文件指纹

1. 什么是文件指纹? 文件指纹就是打包后输出的文件名的后缀,主要用来对修改后的文件做版本区分。 2. 文件指纹有哪几种? 1. Hash:和整个项目的构建相关,只要项目文件有修改,整个项目构建的 hash 值就会更…

CSRF与XSS攻防知识点总结

本章节将用于详细总结记录,跨站脚本攻击XSS(cross site script)与 跨站请求伪造CSRF(cross site request forgery)这两种常见的浏览器安全的攻防手段。本章节会介绍两种攻击的概念,以及相关手段有哪些&…

常见的电动两轮车 BMS 架构

1、摘要 近年来,随着新国标的施行,以及平衡车,滑板车,共享电单车等新应用场景的出现,促使电动两轮车市场迎来了新的发展热潮。 锂电池因为具有能量密度高,循环次数多等优点而逐渐替代铅酸电池&#xff0c…

Spire.XLS for Java 12.12.4 2022-12-30 Version

Spire.XLS for Java 12.12.4 Spire.XLS for Java是一个专业的 Java Excel API,Ω578867473使开发人员无需使用 Microsoft Office 或 Microsoft Excel即可创建、管理、操作、转换和打印 Excel工作表。 Spire.XLS for Java 支持旧的 Excel 97-2003 格式(.…

Java中main函数里的String[] args详解

1)概念 在开始学习 Java 时都会被要求记住主方法(main)的写法,就像以下: public static void main(String[] args) { };public static void main(String args[]) { }; 这里做如下说明&#xff…

什么是 A/B 实验,为什么要开 A/B 实验?

更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群 1、什么是 A/B 实验 A/B 实验也被称为 A/B 测试,实验的基本思路是在线上流量中取出一小部分(较低风险),完全随机地分…

【机器学习】minHash最小哈希原理及其应用

目录1 前言2 哈希函数的定义3 miniHash函数4 miniHash的例子5 miniHash数学原理6 miniHash的应用7 参考文献1 前言 在数据结构中学过哈希概念以及哈希在内存中的应用,在实际的应用问题中哈希技术也应用十分广泛如在推荐系统以及图神经网络技术中,所以在此…

Java多线程之死锁问题,wait和notify

文章目录一. synchronnized 的特性1. 互斥性2. 可重入性二. 死锁问题1. 什么是死锁2. 死锁的四个必要条件3. 常见的死锁场景及解决3.1 不可重入造成的死锁3.2 循环等待的场景哲学家就餐问题(多个线程多把锁)两个线程两把锁三. Object类中提供线程等待的方法1. 常用方法2. wait和…

剑指offer----C语言版----第八天

目录 1. 矩阵中的路径 1.1 题目描述 1.2 基础知识 1.3 思路分析 1.4 小试牛刀 1. 矩阵中的路径 原题链接: 剑指 Offer 12. 矩阵中的路径 - 力扣(LeetCode)https://leetcode.cn/problems/ju-zhen-zhong-de-lu-jing-lcof/submissions/ 1.1 题…

c++11 标准模板(STL)(std::deque)(七)

定义于头文件 <deque> std::deque 修改器 清除内容 std::deque<T,Allocator>::clear void clear(); (C11 前) void clear() noexcept; (C11 起)从容器擦除所有元素。此调用后 size() 返回零。 非法化任何指代所含元素的引用、指针或迭代器。任何尾后迭代器亦被…

静态主机清单

自定义环境 1.操作环境 需要保准三台主机能够互相通信。设置同一种网络模式&#xff08;nat&#xff09;。 2.配置IP地址 server---192.168.90.134 node1---192.168.90.135 node2---192.168.90.133 3.修改主机名 hostnamectl set-hostname server.exmaple.com hostnamec…

【安全硬件】Chap.3 如何插入一个硬件木马到芯片的组合逻辑电路的漏洞里?不影响正常电路的功能的情况下进行硬件的逻辑加密

【安全硬件】Chap.3 如何插入一个硬件木马到芯片的组合逻辑电路的漏洞里&#xff1f;如何进行硬件的逻辑加密在不影响正常电路的功能的情况下1. 组合逻辑电路的漏洞组合逻辑电路中的硬件木马—举例Fault injection attacks士兵巡逻预案系统解决方法——硬件的逻辑加密&#xff…

坦克大战2.0,3.0,4.0版本

1.坦克大战 0.3 在坦克大战游戏(0.2版)基础上添加如下功能:当玩家按一下j键,就发射一颗子弹. 编写Shot类 package com.yt.tankgame03;/*** 射击子弹*/ public class Shot implements Runnable{int x;//子弹的x坐标int y;//子弹的y坐标int direct;//子弹的方向int speed 2;//子…

Python 做了一个 ChatGPT 机器人,表妹玩了一下午

大家好&#xff0c;我是毕加锁。 毫无疑问&#xff0c;ChatGPT 已经是当下编程圈最火的话题之一&#xff0c;它不仅能够回答各类问题&#xff0c;甚至还能执行代码&#xff01; 或者是变成一只猫 因为它实在是太好玩&#xff0c;我使用Python将ChatGPT改造&#xff0c;可以实现…