Nacos實戰——動態 IP 黑名單過濾

1、需求分析

一些惡意用戶(?可能是黑客、爬蟲、DDoS ?攻擊者)可能頻繁請求服務器資?源,導致資源占用過高。針對這種問題,可以通過IP? 封禁,可以有效拉?黑攻擊者,防止資源?被濫用,保障合法用?戶的正常訪問

2、Nacos 配置管理的核心概念

1、Namespace(命名空間)

命名空間用于隔離不同的配置集?。它允許在同一個 Nacos 集群中將不同的環境(如開發、測試、生?產)或者不同的業務線的配置進行隔離。(默認提供了一個 publ?ic 命名空間)

使用場景:在多租戶系統中,或者需要區分不同的?環境時,可以使用命名空間。例如,開發環境的配置和生產環境的配置?完全隔離,可以通過不同的命名空間來管理。

2、Group(組)

配置組是用于將多個相關的配置?項進行分類管理的邏輯分組機制。每個配置項可以屬于不同的?組,以便于配置管理。

使用場景:當一個應用有多個模塊,?且不同模塊之間共享部分配置時,可以用組來對這些模塊的配?置進行分類和管理。例如,一個系統中的“支付服務”和“訂?單服務”可能需要用不同的組來存儲各自的配置。

3、Data ID

Data I?D 是一個唯一的配置標識?符,通常與具體的應用程序?相關。通過 Data I?D,Nacos 知道如何?獲取特定應用的某個具體配置。

使用場景:每個應用的配置都會有一個獨特的 Data ID。例如,一個支付系統可能有一個配置文件叫 com.payment.pay-service.yaml,這就是它的 Data ID。

4、Config Listener(配置監聽器)

配置監聽器用于讓客戶端實時監聽? Nacos 配置中心中的配置變化,可以自動感知配置的更新?并做出相應的處理

使用場景?:在需要動態調整配置的場景下使用,例如調整緩存大小、切換不?同的服務端點等,應用可以通過監聽器及時感知這些變化并應用新?的配置

3、創建黑名單過濾工具類

InterviewPal 項目 已經使用了 Hu?tool 工具庫,?就用其自帶的 Bi?tMapBloom?Filter 即可。

@Slf4j
public class BlackIpUtils {private static BitMapBloomFilter bloomFilter;// 判斷 ip 是否在黑名單內public static boolean isBlackIp(String ip) {return bloomFilter.contains(ip);}// 重建 ip 黑名單public static void rebuildBlackIp(String configInfo) {if (StrUtil.isBlank(configInfo)) {configInfo = "{}";}// 解析 yaml 文件Yaml yaml = new Yaml();Map map = yaml.loadAs(configInfo, Map.class);// 獲取 ip 黑名單List<String> blackIpList = (List<String>) map.get("blackIpList");// 加鎖防止并發synchronized (BlackIpUtils.class) {if (CollectionUtil.isNotEmpty(blackIpList)) {// 注意構造參數的設置BitMapBloomFilter bitMapBloomFilter = new BitMapBloomFilter(1);for (String ip : blackIpList) {bitMapBloomFilter.add(ip);}bloomFilter = bitMapBloomFilter;} else {bloomFilter = new BitMapBloomFilter(1);}}}
}

注意:

1、synchronized (BlackIpUtils.class) 代表的是這個類的 Class 對象,是 JVM 里唯一的、全局唯一的一個對象實例。換句話說,這個鎖是類級別的鎖,所有線程只要碰到這把鎖,都會排隊等候,不能同時執行里面的代碼塊。

2、 BitMapBloomFilter bitMapBloomFilter = new BitMapBloomFilter(1) 這個構造參數不可以亂傳。如何選擇適合業務的 k 和 m 值呢,幸運的是,布隆過濾器有一個可預測的誤判率(FPP):
在這里插入圖片描述
其中 n 是已經添加元素的數量; k 哈希的次數; m 布隆過濾器的長度(如比特數組的大小);

極端情況下,當布隆過濾器沒有空閑空間時(滿),每一次查詢都會返回 true 。這也就意味著 m 的選擇取決于期望預計添加元素的數量 n ,并且 m 需要遠遠大于 n 。 實際情況中,布隆過濾器的長度 m 可以根據給定的誤判率(FFP)的和期望添加的元素個數 n 的通過如下公式計算:
在這里插入圖片描述
3、注意,因為 ?Nacos 配置文件的監聽的粒度比?較粗,只能知曉配置有變更,無法知曉?是新增、刪除還是修改,因此不論是選?擇布隆過濾器還是 HashSet ?最方便的處理邏輯就是重建。

4、創建 Nacos 配置監聽類

新增監聽器代碼?,追求性能的話可以?自定義線程池:

@Slf4j
@Component
public class NacosListener implements InitializingBean {@NacosInjectedprivate ConfigService configService;@Value("${nacos.config.data-id}")private String dataId;@Value("${nacos.config.group}")private String group;@Overridepublic void afterPropertiesSet() throws Exception {log.info("nacos 監聽器啟動");String config = configService.getConfigAndSignListener(dataId, group, 3000L, new Listener() {final ThreadFactory threadFactory = new ThreadFactory() {private final AtomicInteger poolNumber = new AtomicInteger(1);@Overridepublic Thread newThread(@NotNull Runnable r) {Thread thread = new Thread(r);thread.setName("refresh-ThreadPool" + poolNumber.getAndIncrement());return thread;}};final ExecutorService executorService = Executors.newFixedThreadPool(1, threadFactory);// 通過線程池異步處理黑名單變化的邏輯@Overridepublic Executor getExecutor() {return executorService;}// 監聽后續黑名單變化@Overridepublic void receiveConfigInfo(String configInfo) {log.info("監聽到配置信息變化:{}", configInfo);BlackIpUtils.rebuildBlackIp(configInfo);}});// 初始化黑名單BlackIpUtils.rebuildBlackIp(config);}
}

4.1 詳細解讀作用

4.1.1、類定義部分

  • @Component:讓這個類在 Spring 啟動時自動加載;
  • @Slf4j:自動注入日志記錄器;
  • 實現了 InitializingBean,所以會在 Spring 完成依賴注入后執行 afterPropertiesSet()。

4.1.2、注解部分

    @Value("${nacos.config.data-id}")private String dataId;@Value("${nacos.config.group}")private String group;

這個注解@Value("${nacos.config.data-id}")的意思就是說:讀取yml配置文件,令dataId = "interviewPal";

# 配置中心
nacos:config:server-addr: 127.0.0.1:8848  # nacos 地址bootstrap:enable: true  # 預加載data-id: interviewPal # 控制臺填寫的 Data IDgroup: DEFAULT_GROUP # 控制臺填寫的 grouptype: yaml  # 選擇的文件格式auto-refresh: true # 開啟自動刷新

4.1.3、自定義線程工廠

自定義線程池工廠,給新建的線程起個名字,如:refresh-ThreadPool1、refresh-ThreadPool2。

final ThreadFactory threadFactory = new ThreadFactory() {private final AtomicInteger poolNumber = new AtomicInteger(1);@Overridepublic Thread newThread(@NotNull Runnable r) {Thread thread = new Thread(r);thread.setName("refresh-ThreadPool" + poolNumber.getAndIncrement());return thread;}};

4.1.4、創建線程池

final ExecutorService executorService = Executors.newFixedThreadPool(1, threadFactory);

用自定義的線程工廠 threadFactory 創建了一個固定大小為1的線程池(FixedThreadPool)

5、創建黑名單過濾器

黑名單應該對所有請求生?效(不止是 Controller 的接口),?所以基于 WebFilter 實現而不是 A?OP 切面。WebFilter 的優先級高于? @Aspect 切面,因為它在整個 Web? 請求生命周期中更早進行處理。

請求進入時的順序:

  • WebFilter:首先,WebFilter 攔截 HTTP 請求,并可以根據邏輯決定是否繼續執行請求。
  • Spring AOP切面(@Aspect):如果請求經過過濾器并進入 Spring 管理的 Bean(例如 Controller 層),此時切面生效,對匹配的Bean 方法進行攔截。
  • Controller 層:如果 @Aspect 沒有阻止執行,最終請求到達 @Controller 或 @RestController 的方法。
/*** 全局 IP 黑名單過濾請求攔截器*/
@WebFilter(urlPatterns = "/*", filterName = "blackIpFilter")
public class BlackIpFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {String ipAddress = NetUtils.getIpAddress((HttpServletRequest) servletRequest);if (BlackIpUtils.isBlackIp(ipAddress)) {servletResponse.setContentType("text/json;charset=UTF-8");servletResponse.getWriter().write("{\"errorCode\":\"-1\",\"errorMsg\":\"黑名單IP,禁止訪問\"}");return;}filterChain.doFilter(servletRequest, servletResponse);}}

@WebFilter(urlPatterns = "/*", filterName = "blackIpFilter")的作用是告訴 Tomcate 這兒有個過濾器,名字叫 blackIpFilter,它得攔截所有請求(/*)

6、 @ServletComponentScan

最后要在啟動類上加上 @ServletComponentScan,這樣過濾器才會被掃描到。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/907813.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/907813.shtml
英文地址,請注明出處:http://en.pswp.cn/news/907813.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

opencv + jpeg_turbo(啟用SIMD加速)

背景 opencv的imreadimwrite耗時過大 一張5M的圖片讀用了140ms,寫一張1.7M的圖片用149ms 平臺&#xff1a;mingw64編譯Windows程序版本&#xff1a;opencv4.5.4 加速方案 opencv啟用openmpopencv啟用jpeg_turbojpeg_turbo啟動SIMD加速 下載jpeg_turbo源碼 opencv源碼自帶…

Redis 主從節點

Redis 主從節點的核心區別 特性主節點 (Master)從節點 (Slave/Replica)讀寫權限可讀可寫只讀&#xff08;默認配置&#xff09;數據流向數據來源從主節點同步數據連接關系可連接多個從節點只能連接一個主節點故障切換故障時需要手動/自動提升從節點可被提升為新的主節點命令執…

汽車安全:功能安全FuSa、預期功能安全SOTIF與網絡安全Cybersecurity 解析

汽車安全的三重防線&#xff1a;深入解析FuSa、SOTIF與網絡安全技術 現代汽車已成為裝有數千個傳感器的移動計算機&#xff0c;安全挑戰比傳統車輛復雜百倍。 隨著汽車智能化、網聯化飛速發展&#xff0c;汽車電子電氣架構已從簡單的分布式控制系統演變為復雜的移動計算平臺。現…

github好玩的工具

以下是 GitHub 上一些有趣且實用的開源工具推薦,涵蓋 AI 應用、效率提升、趣味開發等方向,結合最新趨勢和項目熱度整理: 一、AI 與深度偽造工具 Deep-Live-Cam 僅需一張圖片即可在視頻直播中實時替換人臉,適用于內容創作和虛擬角色開發,支持多平臺硬件運行(如 NVIDIA CUD…

Python應用for循環臨時變量作用域

大家好!如果你剛開始學習Python&#xff0c;可能會對for循環中臨時變量的作用域感到好奇。下面通過一個簡單的練習&#xff0c;幫助你理解這個概念。 代碼呈現: i 0 for i in range(5):print(i)print(i)代碼介紹: 首先我們初始化變量i 0然后進入for循環&#xff0c;這里i成為…

深度學習---負樣本訓練

一、負樣本的本質與核心作用 1. 定義與范疇 負樣本&#xff08;Negative Sample&#xff09;是與目標樣本&#xff08;正樣本&#xff09;在語義、特征或任務目標上存在顯著差異的樣本。其核心價值在于通過對比學習引導模型學習樣本間的判別性特征&#xff0c;而非僅記憶正樣本…

實驗設計與分析(第6版,Montgomery)第3章單因子實驗:方差分析3.11思考題3.7 R語言解題

本文是實驗設計與分析&#xff08;第6版&#xff0c;Montgomery著&#xff0c;傅玨生譯) 第3章單因子實驗&#xff1a;方差分析3.11思考題3.7 R語言解題。主要涉及單因子方差分析&#xff0c;正態性假設檢驗&#xff0c;殘差與擬合值的關系圖&#xff0c;平方根變換。 X<-c(…

【PhysUnits】15.8 引入P1后的減法運算(sub.rs)

一、源碼 這段代碼實現了一個類型級別的二進制數減法系統&#xff0c;包含標準減法和帶借位減法。 use core::ops::{Neg, Not, Sub}; use super::basic::{Z0, N1, P1, B0, B1, Integer, NonZero}; use super::add1::Add1; use super::sub1::Sub1; use super::standardization…

npm install命令都做了哪些事情

npm install&#xff08;或其簡寫 npm i&#xff09;是 Node.js 項目中最重要的命令之一&#xff0c;它負責安裝項目所需的所有依賴項。下面我將詳細解釋這個命令的完整執行過程和底層機制&#xff0c;讓你徹底理解它背后的工作原理。 一、npm install 的完整工作流程 1. 依賴…

mkdir: cannot create directory ‘gitlab-stu’: No space left on device

Linux中創建目錄時報錯“mkdir: cannot create directory ‘gitlab-stu’: No space left on device”&#xff0c;磁盤空間不足。 使用df命令查看&#xff0c;發現 / 下面use%占滿了&#xff1a; 查看inode使用情況&#xff1a; 可以看到docker的數據大部分存放在/var/lib/do…

中國高分辨率高質量地面NO2數據集(2008-2023)

時間分辨率&#xff1a;日空間分辨率&#xff1a;1km - 10km共享方式&#xff1a;開放獲取數據大小&#xff1a;15.36 GB數據時間范圍&#xff1a;2008-01-01 — 2023-12-31元數據更新時間&#xff1a;2024-08-19 數據集摘要 ChinaHighNO2數據集是中國高分辨率高質量近地表空氣…

Redis實戰-基于redis和lua腳本實現分布式鎖以及Redission源碼解析【萬字長文】

前言&#xff1a; 在上篇博客中&#xff0c;我們探討了單機模式下如何通過悲觀鎖&#xff08;synchronized&#xff09;實現"一人一單"功能。然而&#xff0c;在分布式系統或集群環境下&#xff0c;單純依賴JVM級別的鎖機制會出現線程并發安全問題&#xff0c;因為這…

剪枝中的 `break` 與 `return` 區別詳解

在回溯算法的剪枝操作中&#xff1a; if (sum candidates[i] > target) break;這個 break 既不等效于 return&#xff0c;也不會終止整個回溯過程。它只會終止當前層循環的后續迭代&#xff0c;而不會影響其他分支的回溯。讓我用圖解和示例詳細說明&#xff1a; &#x1…

計算機網絡第1章(下):網絡性能指標與分層模型全面解析

目錄 一、計算機網絡的性能指標1.1 性能指標1&#xff1a;速率1.2 性能指標2&#xff1a;帶寬1.3 性能指標3&#xff1a;吞吐量1.4 性能指標4&#xff1a;時延1.5 性能指標5&#xff1a;時延帶寬積1.6 性能指標6&#xff1a;往返時延1.7 性能指標7&#xff1a;信道利用率 二、計…

C#數字圖像處理(二)

文章目錄 1.灰度直方圖1.1 灰度直方圖定義1.2 灰度直方圖編程實例 2.線性點運算2.1線性點運算定義2.2 線性點運算編程實例 3.全等級直方圖灰度拉伸3.1 灰度拉伸定義3.2 灰度拉伸編程實例 4.直方圖均衡化4.1 直方圖均衡化定義4.2 直方圖均衡化編程實例 5.直方圖匹配5.1 直方圖匹…

訓練中常見的運動強度分類

概述 有氧運動是耐力基礎&#xff0c;乳酸閾值是耐力突破的關鍵&#xff0c;提升乳酸閾值可以延緩疲勞&#xff0c;無氧運動側重速度和力量&#xff0c;混氧和最大攝氧量用于細化訓練強度和評估潛力。 分類強度供能系統乳酸濃度訓練目標有氧運動低&#xff08;60%-80% HR&…

數智管理學(十五)

第五章 數智化時代的組織結構模型 第一節 傳統金字塔型結構向分布式網絡型的演變 在當今數智化時代&#xff0c;企業所處的市場環境發生了翻天覆地的變化&#xff0c;技術創新日新月異&#xff0c;客戶需求日益多樣化和個性化&#xff0c;市場競爭愈發激烈。傳統的金字塔型組…

AAA基礎配置

文章目錄 組網需求組網拓撲實驗步驟測試結果配置文件 組網需求 為組網安全&#xff0c;經常會使用AAA技術&#xff0c;本次以CE12800交換機Window為例&#xff0c;實現AAA本地認證登錄 組網拓撲 實驗步驟 配置接口IP&#xff0c;連通終端進入AAA視圖配置用戶名密碼配置賬戶權…

基于微信小程序的云校園信息服務平臺設計與實現(源碼+定制+開發)云端校園服務系統開發 面向師生的校園事務小程序設計與實現 融合微信生態的智慧校園管理系統開發

博主介紹&#xff1a; ?我是阿龍&#xff0c;一名專注于Java技術領域的程序員&#xff0c;全網擁有10W粉絲。作為CSDN特邀作者、博客專家、新星計劃導師&#xff0c;我在計算機畢業設計開發方面積累了豐富的經驗。同時&#xff0c;我也是掘金、華為云、阿里云、InfoQ等平臺…

RV1126-OPENCV Mat理解和AT函數

一.Mat概念 Mat 是整個圖像存儲的核心也是所有圖像處理的最基礎的類&#xff0c;Mat 主要存儲圖像的矩陣類型&#xff0c;包括向量、矩陣、灰度或者彩色圖像等等。Mat由兩部分組成&#xff1a;矩陣頭&#xff0c;矩陣數據。矩陣頭是存儲圖像的長度、寬度、色彩信息等頭部信息&a…