java八股-流量封控系统
文章目录
- 请求后台管理的频率-流量限制
- 流量限制的业务代码
- UserFlowRiskControlFilter
- 短链接中台的流量限制
- CustomBlockHandler
- 对指定接口限流
- UserFlowRiskControlConfiguration
- SentinelRuleConfig
请求后台管理的频率-流量限制
根据登录用户做出控制,比如 x 秒请求后管系统的频率最多 x 次。
实现原理也比较简单,通过 Redis increment 命令对一个数据进行递增,如果超过 x 次就会返回失败。这里有个细节就是我们的这个周期是 x 秒,需要对 Redis 的 Key 设置 x 秒有效期。
但是 Redis 中对于 increment 命令是没有提供过期命令的,这就需要两步操作,进而出现原子性问题。
lua脚本步骤:
- 递增key对应的访问次数
- 給该key设置过期时间TTL,TTL是限制时间内的秒数,
- 最后返回TTL内的访问次数
使用lua脚本保证原子性,这里主要的作用是记录在timeWindow秒限制内的访问次数AccessCnt。
其中timeWindow是多少多少秒,lua脚本返回值(是在timeWindow秒内)被访问了AccessCnt次,
-- 设置用户访问频率限制的参数
local username = KEYS[1]
local timeWindow = tonumber(ARGV[1]) -- 时间窗口,单位:秒-- 构造 Redis 中存储用户访问次数的键名
local accessKey = "short-link:user-flow-risk-control:" .. username-- 原子递增访问次数,并获取递增后的值
local currentAccessCount = redis.call("INCR", accessKey)-- 设置键的过期时间
redis.call("EXPIRE", accessKey, timeWindow)-- 返回当前访问次数
return currentAccessCount
流量限制的业务代码
UserFlowRiskControlFilter
package com.nageoffer.shortlink.admin.common.biz.user;import com.alibaba.fastjson2.JSON;
import com.google.common.collect.Lists;
import com.nageoffer.shortlink.admin.common.convention.exception.ClientException;
import com.nageoffer.shortlink.admin.common.convention.result.Results;
import com.nageoffer.shortlink.admin.config.UserFlowRiskControlConfiguration;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scripting.support.ResourceScriptSource;import java.io.IOException;
import java.io.PrintWriter;
import java.util.Optional;import static com.nageoffer.shortlink.admin.common.convention.errorcode.BaseErrorCode.FLOW_LIMIT_ERROR;@Slf4j
@RequiredArgsConstructor
//用户流量封控过滤器
public class UserFlowRiskControlFilter implements Filter {private final StringRedisTemplate stringRedisTemplate;//用户流量封控配置器//这里这个UserFlowRiskControlConfiguration 在下面会有介绍的,反正这里的MaxAccessCount和time-window都是从Application.yaml里面读取到的private final UserFlowRiskControlConfiguration userFlowRiskControlConfiguration;private static final String USER_FLOW_RISK_CONTROL_LUA_SCRIPT_PATH = "lua/user_flow_risk_control.lua";@SneakyThrows@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();//设置加载到lua脚本对象redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource(USER_FLOW_RISK_CONTROL_LUA_SCRIPT_PATH)));//设置lua脚本返回值类型是LongredisScript.setResultType(Long.class);String username = Optional.ofNullable(UserContext.getUsername()).orElse("other");Long result;try {result = stringRedisTemplate.execute(redisScript, Lists.newArrayList(username), userFlowRiskControlConfiguration.getTimeWindow());} catch (Throwable ex) {//设置为Throwable,防止捕获不到log.error("执行用户请求流量限制LUA脚本出错", ex);returnJson((HttpServletResponse) response, JSON.toJSONString(Results.failure(new ClientException(FLOW_LIMIT_ERROR))));return;}//如果访问次数Result>最大限制访问次数getMaxAccessCount,则返回流量限制异常if (result == null || result > userFlowRiskControlConfiguration.getMaxAccessCount()) {returnJson((HttpServletResponse) response, JSON.toJSONString(Results.failure(new ClientException(FLOW_LIMIT_ERROR))));return;}filterChain.doFilter(request, response);}private void returnJson(HttpServletResponse response, String json) throws Exception {response.setCharacterEncoding("UTF-8");response.setContentType("text/html; charset=utf-8");try (PrintWriter writer = response.getWriter()) {writer.print(json);}}
}
短链接中台的流量限制
使用sentinel来做中台的流量限制,首先引入依赖
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-annotation-aspectj</artifactId>
</dependency>
CustomBlockHandler
package com.nageoffer.shortlink.project.handler;import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.nageoffer.shortlink.project.common.convention.result.Result;
import com.nageoffer.shortlink.project.dto.req.ShortLinkCreateReqDTO;
import com.nageoffer.shortlink.project.dto.resp.ShortLinkCreateRespDTO;public class CustomBlockHandler {public static Result<ShortLinkCreateRespDTO> createShortLinkBlockHandlerMethod(ShortLinkCreateReqDTO requestParam, BlockException exception) {return new Result<ShortLinkCreateRespDTO>().setCode("B100000").setMessage("当前访问网站人数过多,请稍后再试...");}
}
sentinel技术对接口限流,超过指定的QPS之后会接口限流,Block住
下面的@SentinelResource里面的value是对保护资源的名称的指定,Blockhandler是保护资源用到的方法,BlockHandlerClass是保护资源用到的类Class
对指定接口限流
这里对接口限流,指定他的资源名称为create-short-link,以后带着这个名称,在SentinelRuleConfig(文章下面会介绍到位,也可以在目录里面快速定位到相关内容)里面会加入对这个资源的保护
UserFlowRiskControlConfiguration
Application.yaml和UserFlowRiskControlConfiguration
@Data
@Component
@ConfigurationProperties(prefix = "short-link.flow-limit") //从Application.yaml配置文件里面读取相应的数据信息
public class UserFlowRiskControlConfiguration {/*** 是否开启用户流量风控验证*/private Boolean enable;/*** 流量风控时间窗口,单位:秒*/private String timeWindow;/*** 流量风控时间窗口内可访问次数*/private Long maxAccessCount;
}
SentinelRuleConfig
定义接口规则
package com.nageoffer.shortlink.project.config;import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;import java.util.ArrayList;
import java.util.List;//解释一下,实现InitializingBean 接口并重写afterPropertiesSet是为了在Bean初始化完成之后,
//执行FlowRuleManager.loadRules(rules)把这个流量限制规则加入到位!!!!
@Component
public class SentinelRuleConfig implements InitializingBean { //@Overridepublic void afterPropertiesSet() throws Exception {List<FlowRule> rules = new ArrayList<>();FlowRule createOrderRule = new FlowRule();//通过对指定资源名称进行保护限流createOrderRule.setResource("create_short-link");//通过QPS限制createOrderRule.setGrade(RuleConstant.FLOW_GRADE_QPS);//QPS超过1就限流createOrderRule.setCount(1);rules.add(createOrderRule);FlowRuleManager.loadRules(rules);}
}
InitializingBean 接口,实现该接口的类需要提供一个 afterPropertiesSet 方法,该方法会在所有依赖注入完成后被调用
package org.springframework.beans.factory;public interface InitializingBean {void afterPropertiesSet() throws Exception;
}
相关文章:

java八股-流量封控系统
文章目录 请求后台管理的频率-流量限制流量限制的业务代码UserFlowRiskControlFilter 短链接中台的流量限制CustomBlockHandler 对指定接口限流UserFlowRiskControlConfigurationSentinelRuleConfig 请求后台管理的频率-流量限制 根据登录用户做出控制,比如 x 秒请…...

【WebRTC】Android SDK使用教学
文章目录 前言PeerConnectionFactoryPeerConnection 前言 最近在学习WebRTC的时候,发现只有JavaScript的API文档,找了很久没有找到Android相关的API文档,所以通过此片文章记录下在Android应用层如何使用WebRTC 本篇文章结合:【W…...

基于单片机的智能晾衣控制系统的设计与实现
摘要:本文是以 AT89C52 单片机为核心来实现智能晾衣控制系统。在这个系统中,雨水检测传感器是用来检测出雨的,而控制器将检测信号的变换,根据变换后的信号自动驱动直流电机将被风干 的棒收回,以便随时控制直流电机来实现晾衣;在光敏模块中检测昼夜的环境,自动控制晾衣杆…...

多人聊天室 NIO模型实现
NIO编程模型 Selector监听客户端不同的zhuangtai不同客户端触发不同的状态后,交由相应的handles处理Selector和对应的处理handles都是在同一线程上实现的 I/O多路复用 在Java中,I/O多路复用是一种技术,它允许单个线程处理多个输入/输出&…...

三、使用 Maven:命令行环境
文章目录 1. 第一节 实验一:根据坐标创建 Maven 工程1.1 Maven 核心概念:坐标1.2 实验操作1.3 Maven核心概念:POM1.4 Maven核心概念:约定的目录结构 2. 实验二:在 Maven 工程中编写代码2.1 主体程序2.2 测试程序 3. 执…...

Blender导入下载好的fbx模型像的骨骼像针戳/像刺猬
为什么我下载下来的骨骼模型和我自己绑定的模型骨骼朝向完全不一样 左边是下载的模型 右边是我自己绑定的模型 左边的模型刚刚感觉都是像针一样往外戳的,像刺猬一样那种。 解决方法勾选自动骨骼坐标系...

如何高效搭建智能BI数据分析系统
作为当今信息化时代,数据资产已经成为企业最为核心倚重的,自然企业也就面临来自于对内部这些数据的处理和分析。如何在大批量的数据当中提取有用信息,帮助企业做出智慧决策,是不少企业面临的问题。作为国内知名的BI数据分析系统服…...

第 6 章 Java 并发包中锁原理剖析Part one
目录 6.1 LockSupport 工具类 6.2 独占锁 ReentrantLock 的原理 获取锁 1.void lock() 方法 2.void lockInterruptibly() 方法 3.boolean tryLock() 方法 4.boolean tryLock(long timeout, TimeUnit unit) 方法 释放锁 6.1 Lo…...

使用 Canvas 绘制一个镂空的圆形区域
如果要实现一个类似人脸识别的界面,要求使用 canvas 进行绘制,中间镂空透明区域,背景是白色的画布。 技术方案: 首先,使用 canvas 绘制一个白色画布其次,使用 context.globalCompositeOperation 合成属性进…...

【Notepad++】---设置背景为护眼色(豆沙绿)最新最详细
在编程的艺术世界里,代码和灵感需要寻找到最佳的交融点,才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里,我们将共同追寻这种完美结合,为未来的世界留下属于我们的独特印记。 【Notepad】---设置背景为护眼色…...

2024 数学建模国一经验分享
2024 数学建模国一经验分享 背景:武汉某211,专业:计算机科学 心血来潮,就从学习和组队两个方面指点下后来者,帮新人避坑吧 2024年我在数学建模比赛中获得了国一(教练说论文的分数是湖北省B组第一࿰…...

安全见闻2
安全见闻,犹如一座庞大而深邃的知识宝库,其中涵盖了形形色色的网络安全知识与错综复杂的网络技术体系。在当今数字化时代,这些领域的重要性不言而喻,它们不仅关乎个人信息的保护与隐私安全,更是支撑着整个互联网世界以…...

Web游戏开发指南:在 Phaser.js 中读取和管理游戏手柄输入
前言 Phaser.js 是一个广受欢迎的 HTML5 游戏框架,为开发者提供了创建跨平台 2D 游戏的强大工具。在现代游戏开发中,支持游戏手柄已成为提升玩家体验的重要方面。本文将详细介绍如何在 Phaser.js 中监听和处理游戏手柄的输入,帮助开发者为他…...

代码随想录32 动态规划理论基础,509. 斐波那契数,70. 爬楼梯,746. 使用最小花费爬楼梯。
1.动态规划理论基础 动态规划刷题大纲 什么是动态规划 动态规划,英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。 所以动态规划中每一个状态一定是由上一个状态推导出来的…...

记录一个Flutter 3.24单元测试点击事件bug
哈喽,我是老刘 这两天发现一个Flutter 3.24版本的单元测试的一个小bug,提醒大家注意一下。 老刘自己写代码十多年了,写Flutter也6年多了,没想到前两天在一个小小的BottomNavigationBar 组件上翻了车。 给大家分享一下事件的经过。…...

使用Python将 word文档转pdf文档
第一步:我们需要导入支持包 >pip install pywin32 如果下载速度比较慢的话,可以考虑使用国内镜像源。 第二步:我们需要导入文件,这里采用 input,用户填入路径后,直接获取路径下的word文档,实现批量转换…...

基于C#+SQLite开发数据库应用的示例
SQLite数据库,小巧但功能强大;并且是基于文件型的数据库,驱动库就是一个dll文件,有些开发工具 甚至不需要带这个dll,比如用Delphi开发,用一些三方组件;数据库也是一个文件,虽然是个文…...

Vue基本语法
Options API 选项式/配置式api 需要在script中的export default一个对象对象中可以包含data、method、components等keydata是数据,数据必须是一个方法(如果是对象,会导致多组件的时候,数据互相影响,因为对象赋值后&…...

芯片发展史
芯片的发展史可分为几个重要的阶段,从早期的真空管到现代的集成电路,反映了技术进步和创新的历程: 1. 真空管时代 (1904 - 1950年代) 真空管是20世纪初的电子元件,用于放大信号和开关,广泛应用在早期的收音机、电视机…...

我的知识图谱和Neo4j数据库的使用
知识图谱概述 知识图谱的含义 RDF与RDFS RDF(Resource Description Framework,资源描述框架)和RDFS(RDF Schema,RDF模式)是构建知识图谱的基础技术之一。它们提供了一种标准的方式来表示信息,…...

ASP.NET CORE API 解决跨域问题
环境 vs2022 .net 8 创建ASP.net Core API项目 配置跨域 编写ApiController 启动项目 得到服务器运行的 地址 在Hbuiler中创建web项目,编写代码 【运行】-【运行到浏览器】-选择一个浏览器,查看结果 正常显示 问题 如果允许所有源访问,有安全风险方…...

sram测试注意讨论
常规测试首先是mbist测试,原理不用多说,自己看,主要是注意点和考虑点: 1、明确测试用的到func_clk的频率的大小,根据经验值一般大于800M的时钟需要特别考虑Timing的问题:由于pr摆放的位置原因,…...

Mybatis 支持延迟加载的详细内容
延迟加载的概念深入 延迟加载是一种在处理复杂对象关系时非常有用的策略。在企业级应用开发中,数据库中的表之间往往存在着各种关联关系,如一对多(一个用户有多个订单)、多对多(一个学生可以选多门课程,一门…...

word文档使用技巧笔记
中文和数字断开到第二行 word一串数字断开_百度知道 下划线对齐 word下划线怎么固定长度一致-百度经验...

使用docker-compose部署搜索引擎ElasticSearch6.8.10
背景 Elasticsearch 是一个开源的分布式搜索和分析引擎,基于 Apache Lucene 构建。它被广泛用于实时数据搜索、日志分析、全文检索等应用场景。 Elasticsearch 支持高效的全文搜索,并提供了强大的聚合功能,可以处理大规模的数据集并进行快速…...

bugku-web-login2
不知道为啥用bp始终登不上hackbar可以 随便输入个账号密码bp抓包,发现个小tip是base64加密的解密 $sql"SELECT username,password FROM admin WHERE username".$username.""; if (!empty($row) && $row[password]md5($password)){ } …...

【 AI技术赋能有限元分析与材料科学应用实践】Neo-Hookean 材料与深度学习结合的有限元分析
Neo-Hookean 材料模型是用于描述非线性弹性材料(如软组织和橡胶等)的经典模型,特别适用于大变形问题。其基本思想是通过应变能密度函数来描述材料的弹性行为。在该模型中,材料的应力-应变关系不仅依赖于应变能,还通过变…...

StarRocks关于ConcurrentModificationException 问题的解决
背景 本文基于 StarRocks 3.1.7 目前在基于Starrocks做一些数据分析的操作(主要是做一些简单的查询),同事遇到了一些并发的问题: ontent:2024-11-27 07:04:34,048 WARN (starrocks-mysql-nio-pool-214933|3593819) [StmtExecutor.execute():643] execute Exceptio…...

网络安全防护指南:筑牢网络安全防线(5/10)
一、网络安全的基本概念 (一)网络的定义 网络是指由计算机或者其他信息终端及相关设备组成的按照一定的规则和程序对信息收集、存储、传输、交换、处理的系统。在当今数字化时代,网络已经成为人们生活和工作中不可或缺的一部分。它连接了世…...

替代FTP最佳跨网文件传输解决方案——FileLink
在传统的企业文件传输中,FTP(文件传输协议)曾因其便捷性和高效性被广泛应用。然而,其固有的安全漏洞、对大文件传输支持的局限性、易受网络攻击等问题,已逐渐暴露出FTP在现代企业环境下的不足。针对这一问题࿰…...