偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

硬核實戰(zhàn)!分布式系統(tǒng)接口安全三板斧:限流、防重放、簽名驗證全攻略

云計算 分布式
限流的目的在于防止資源被過度消耗,從而避免?DoS/DDoS?攻擊和瞬時高并發(fā)帶來的雪崩效應(yīng)。對于分布式架構(gòu)來說,限流不僅要在?網(wǎng)關(guān)層?生效,還需要深入到?各微服務(wù)節(jié)點,形成多層級的保護體系。

在更廣泛的分布式系統(tǒng)場景中,單一的防護措施遠遠不夠。系統(tǒng)需要面對復(fù)雜的攻擊手法,例如 大規(guī)模惡意請求、請求重放以及參數(shù)篡改 等。本文將聚焦于通用接口的三大安全防護手段,并結(jié)合工程實踐給出詳細實現(xiàn)方案:

  • 限流機制:抵御突發(fā)流量與惡意刷接口,保證系統(tǒng)穩(wěn)定性
  • 防重放策略:避免重復(fù)請求造成業(yè)務(wù)風(fēng)險
  • 簽名校驗:防止請求數(shù)據(jù)被惡意篡改

通過這一系列措施,分布式系統(tǒng)不僅能在高并發(fā)場景下保持服務(wù)可用,還能有效阻斷潛在的攻擊通道。

限流機制:系統(tǒng)穩(wěn)定性的第一道防線

限流的核心目標(biāo)

限流的目的在于防止資源被過度消耗,從而避免 DoS/DDoS 攻擊和瞬時高并發(fā)帶來的雪崩效應(yīng)。對于分布式架構(gòu)來說,限流不僅要在 網(wǎng)關(guān)層 生效,還需要深入到 各微服務(wù)節(jié)點,形成多層級的保護體系。

常見的限流算法

在工程實踐中,通常會使用以下幾種限流算法:

算法

核心機制

優(yōu)點

缺點

適用場景

固定窗口

固定時間段內(nèi)計數(shù)

實現(xiàn)簡單,高效

臨界點突刺問題

非關(guān)鍵接口

滑動窗口

滑動區(qū)間內(nèi)實時統(tǒng)計

精度高,平滑臨界

實現(xiàn)稍復(fù)雜

API 網(wǎng)關(guān)、分布式限流

漏桶算法

恒定速率處理請求

流量絕對平滑

無法應(yīng)對突發(fā)流量

流量整形、數(shù)據(jù)庫保護

令牌桶算法

令牌發(fā)放 + 消耗機制

支持突發(fā),靈活性高

實現(xiàn)復(fù)雜

微服務(wù)、方法級限流

在本文的實現(xiàn)方案中,我們采用 Redis + 滑動窗口,以滿足分布式環(huán)境下的多節(jié)點限流需求。

Redis 滑動窗口限流實現(xiàn)

Redis 的 有序集合(ZSet) 特性使其非常適合實現(xiàn)滑動窗口算法。核心流程如下:

  1. 請求到達時,計算窗口起始時間 T - W。
  2. 使用 ZREMRANGEBYSCORE 移除過期時間戳。
  3. 使用 ZCOUNT 統(tǒng)計當(dāng)前窗口內(nèi)的請求數(shù)量。
  4. 若超出閾值,拒絕請求;否則寫入當(dāng)前時間戳。
  5. 使用 Lua 腳本封裝,保證原子性。

對應(yīng)實現(xiàn)如下:

package com.icoderoad.security.limiter;


import java.util.LinkedList;
import java.util.Queue;


public class SlidingWindowRateLimiter {
    private final int limit; // 限流閾值
    private final long windowSize; // 滑動窗口大小
    private final Queue<Long> requestTimestamps;


    public SlidingWindowRateLimiter(int limit, long windowSize) {
        this.limit = limit;
        this.windowSize = windowSize;
        this.requestTimestamps = new LinkedList<>();
    }


    public synchronized boolean tryAcquire() {
        long now = System.currentTimeMillis();
        while (!requestTimestamps.isEmpty() && now - requestTimestamps.peek() > windowSize) {
            requestTimestamps.poll();
        }
        if (requestTimestamps.size() < limit) {
            requestTimestamps.offer(now);
            return true;
        }
        return false;
    }
}

網(wǎng)關(guān)層限流

在 API 網(wǎng)關(guān)層 進行全局流量控制,可有效抵御惡意流量對下游服務(wù)的沖擊。例如設(shè)置全局 QPS = 100,000,作為兜底防護。

// 路徑:/src/main/java/com/icoderoad/gateway/filter/GlobalRateLimitFilter.java
package com.icoderoad.gateway.filter;


import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;


import java.util.LinkedList;
import java.util.Queue;


/**
 * 全局限流過濾器(基于滑動窗口)
 * 控制 API 網(wǎng)關(guān)層整體流量,避免惡意請求沖擊下游服務(wù)
 */
@Component
public class GlobalRateLimitFilter implements GlobalFilter, Ordered {


    // 每秒最大請求數(shù)(例如全局 QPS = 100,000)
    private static final int LIMIT = 100000;


    // 窗口大?。ê撩耄?    private static final long WINDOW_SIZE = 1000;


    // 請求時間戳隊列
    private final Queue<Long> requestTimestamps = new LinkedList<>();


    /**
     * 滑動窗口限流核心邏輯
     */
    private synchronized boolean tryAcquire() {
        long now = System.currentTimeMillis();


        // 移除過期的請求時間
        while (!requestTimestamps.isEmpty() && now - requestTimestamps.peek() > WINDOW_SIZE) {
            requestTimestamps.poll();
        }


        if (requestTimestamps.size() < LIMIT) {
            requestTimestamps.offer(now);
            return true;
        }
        return false;
    }


    @Override
    public Mono<Void> filter(ServerWebExchange exchange, org.springframework.cloud.gateway.filter.GatewayFilterChain chain) {
        if (!tryAcquire()) {
            // 超過限流閾值,返回 429
            exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
            return exchange.getResponse().setComplete();
        }
        // 放行
        return chain.filter(exchange);
    }


    @Override
    public int getOrder() {
        // 優(yōu)先級最高,先執(zhí)行限流判斷
        return -1;
    }
}

IP 限流

對攻擊者常用的 撞庫、短信轟炸 等行為,可以通過 單 IP 限制請求頻率 來攔截。若單 IP 在固定周期內(nèi)多次觸發(fā)限流規(guī)則,可直接拉黑。

// 路徑:/src/main/java/com/icoderoad/gateway/filter/IpRateLimitFilter.java
package com.icoderoad.gateway.filter;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;


import java.util.concurrent.TimeUnit;


/**
 * IP 限流過濾器(基于 Redis + 黑名單)
 * 攔截異常頻繁的請求,例如撞庫、短信轟炸
 */
@Component
public class IpRateLimitFilter implements GlobalFilter, Ordered {


    @Autowired
    private RedisTemplate<String, String> redisTemplate;


    // 配置參數(shù)
    private static final int LIMIT = 50;              // 單 IP 在周期內(nèi)最大請求數(shù)
    private static final long PERIOD = 60;            // 限流統(tǒng)計周期(秒)
    private static final int BLACKLIST_THRESHOLD = 5; // 觸發(fā)限流多少次后拉黑
    private static final long BLACKLIST_TIME = 3600;  // 黑名單時長(秒)


    @Override
    public Mono<Void> filter(ServerWebExchange exchange, org.springframework.cloud.gateway.filter.GatewayFilterChain chain) {
        String ip = getClientIp(exchange);


        String blacklistKey = "ip:blacklist:" + ip;
        // 檢查是否在黑名單
        if (Boolean.TRUE.equals(redisTemplate.hasKey(blacklistKey))) {
            exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
            return exchange.getResponse().setComplete();
        }


        String counterKey = "ip:counter:" + ip;
        Long count = redisTemplate.opsForValue().increment(counterKey);
        if (count == 1) {
            // 設(shè)置過期時間
            redisTemplate.expire(counterKey, PERIOD, TimeUnit.SECONDS);
        }


        if (count != null && count > LIMIT) {
            // 記錄觸發(fā)次數(shù)
            String triggerKey = "ip:trigger:" + ip;
            Long triggerCount = redisTemplate.opsForValue().increment(triggerKey);
            if (triggerCount == 1) {
                redisTemplate.expire(triggerKey, BLACKLIST_TIME, TimeUnit.SECONDS);
            }


            // 如果觸發(fā)次數(shù)超過閾值,拉黑
            if (triggerCount != null && triggerCount >= BLACKLIST_THRESHOLD) {
                redisTemplate.opsForValue().set(blacklistKey, "1", BLACKLIST_TIME, TimeUnit.SECONDS);
            }


            exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
            return exchange.getResponse().setComplete();
        }


        return chain.filter(exchange);
    }


    /**
     * 獲取客戶端真實 IP
     */
    private String getClientIp(ServerWebExchange exchange) {
        String ip = exchange.getRequest().getHeaders().getFirst("X-Forwarded-For");
        if (ip == null || ip.isEmpty()) {
            ip = exchange.getRequest().getRemoteAddress() != null ?
                    exchange.getRequest().getRemoteAddress().getAddress().getHostAddress() : "unknown";
        } else {
            // 取第一個 IP
            ip = ip.split(",")[0];
        }
        return ip;
    }


    @Override
    public int getOrder() {
        // 高優(yōu)先級執(zhí)行,避免攻擊流量進入業(yè)務(wù)邏輯
        return -2;
    }
}

微服務(wù)層限流

服務(wù)級別的限流側(cè)重 自治能力,例如對某個接口設(shè)置 QPS = 200,以避免單服務(wù)過載影響全局。

// 路徑:/src/main/java/com/icoderoad/service/filter/ResourceLimiterFilter.java
package com.icoderoad.service.filter;


import com.alibaba.nacos.api.config.annotation.NacosValue;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;


import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/**
 * 微服務(wù)級別的接口限流過濾器
 * 支持從 Nacos 動態(tài)加載配置,實現(xiàn)服務(wù)自治
 */
@Component
public class ResourceLimiterFilter extends OncePerRequestFilter {


    // Nacos 動態(tài)配置:例如 {"api:/order/create":200,"api:/user/login":100}
    @NacosValue(value = "${service.limiter.config:{}}", autoRefreshed = true)
    private String limiterConfig;


    // 保存各接口的限流器
    private final Map<String, SimpleRateLimiter> limiters = new ConcurrentHashMap<>();


    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        String uri = request.getRequestURI();
        int qpsLimit = getLimit(uri);


        if (qpsLimit > 0) {
            SimpleRateLimiter limiter = limiters.computeIfAbsent(uri, k -> new SimpleRateLimiter(qpsLimit));
            if (!limiter.tryAcquire()) {
                response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
                response.getWriter().write("Too Many Requests for API: " + uri);
                return;
            }
        }


        filterChain.doFilter(request, response);
    }


    /**
     * 根據(jù) URI 獲取限流閾值(從 Nacos 動態(tài)配置加載)
     */
    private int getLimit(String uri) {
        try {
            // 假設(shè)配置格式是 JSON:{"api:/order/create":200,"api:/user/login":100}
            Map<String, Object> configMap = new com.fasterxml.jackson.databind.ObjectMapper()
                    .readValue(limiterConfig, Map.class);
            Object limit = configMap.get("api:" + uri);
            return limit != null ? Integer.parseInt(limit.toString()) : 0;
        } catch (Exception e) {
            return 0;
        }
    }


    /**
     * 簡單的滑動窗口限流器(服務(wù)級別)
     */
    static class SimpleRateLimiter {
        private final int limit;
        private final long windowSize = 1000L; // 1秒
        private long windowStart = System.currentTimeMillis();
        private int count = 0;


        public SimpleRateLimiter(int limit) {
            this.limit = limit;
        }


        public synchronized boolean tryAcquire() {
            long now = System.currentTimeMillis();
            if (now - windowStart > windowSize) {
                windowStart = now;
                count = 0;
            }
            if (count < limit) {
                count++;
                return true;
            }
            return false;
        }
    }
}

防重放機制:阻斷重復(fù)提交的風(fēng)險

重放攻擊的典型手法是 攔截合法請求并重復(fù)發(fā)送,例如重復(fù)支付、重復(fù)下單。 防護策略常用 Nonce + Timestamp,確保請求 唯一且有時效性

  • Nonce(隨機數(shù)):保證請求唯一。
  • Timestamp(時間戳):限制請求有效期,例如 5 分鐘內(nèi)有效。
  • RequestId(唯一標(biāo)識):防止同一請求多次提交。

簽名校驗:確保請求未被篡改

簽名驗證的核心思路是:請求參數(shù) + 隨機數(shù) + 請求方法 + 加密算法 生成簽名,服務(wù)端對其進行解密和比對,保證數(shù)據(jù)完整性。

簽名生成流程

  1. 生成隨機數(shù) requestId
  2. 使用公鑰加密生成 idSign
  3. 隨機抽取部分字符作為 idSecretIndex
  4. 拼接 URL / 方法 / requestId 等數(shù)據(jù),使用對稱密鑰生成 signature
  5. 客戶端請求時在 Header 攜帶:
X-Request-ID: idSign
X-Request-Index: idSecretIndex
X-Signature: signature

前端簽名工具(Vue + Axios 示例)

// 路徑:/src/frontend/utils/signature.js
import CryptoJS from 'crypto-js'
import JSEncrypt from 'jsencrypt'


export function generateSignature(url, method, requestId, secretKey) {
  const signContent = [`url=${url}`, `method=${method}`, `requestId=${requestId}`].join('&')
  return CryptoJS.HmacSHA256(signContent, secretKey).toString(CryptoJS.enc.Hex)
}


export function encryptRequestId(requestId, publicKey) {
  const encryptor = new JSEncrypt()
  encryptor.setPublicKey(publicKey)
  return encryptor.encrypt(requestId)
}

總結(jié)

在分布式系統(tǒng)中,接口安全防護不是可選項,而是生死攸關(guān)的必備能力。

  • 限流 保護系統(tǒng)不被突發(fā)流量擊垮,確保整體穩(wěn)定。
  • 防重放 避免業(yè)務(wù)重復(fù)執(zhí)行,保證交易安全。
  • 簽名校驗 阻止數(shù)據(jù)被篡改,提升接口的可信度。

這三大措施相輔相成:

  • 限流提供流量層面的穩(wěn)定性;
  • 防重放確保請求唯一性;
  • 簽名校驗保障數(shù)據(jù)完整性。

如果把分布式系統(tǒng)比作一座城市,那么限流就是交通燈,防重放是門禁系統(tǒng),而簽名驗證則是身份證認(rèn)證。三者協(xié)同,才能讓城市安全高效地運行。

在后續(xù)實踐中,還可以結(jié)合 零信任架構(gòu)、API 網(wǎng)關(guān)安全插件、AI 風(fēng)控模型 等手段,構(gòu)建更加全面的防御體系。

責(zé)任編輯:武曉燕 來源: 路條編程
相關(guān)推薦

2025-07-28 01:00:00

2013-07-03 11:13:58

DevOps

2022-12-12 11:22:52

數(shù)據(jù)中心新能源

2014-07-29 11:25:18

LinuxMySQL

2012-11-08 16:05:23

2011-03-09 15:23:25

Windows Ser

2020-09-03 15:32:08

Wireshark數(shù)據(jù)包分析

2017-03-23 10:54:58

LINUXMYSQL優(yōu)化

2009-11-10 12:08:15

2017-08-21 23:50:45

線上內(nèi)存OOM

2009-02-19 10:20:00

2024-12-04 11:09:10

2020-11-18 08:17:14

Java源碼Class

2020-03-09 13:37:49

Serverless無服務(wù)器騰訊云

2019-05-30 14:30:42

技術(shù)管理架構(gòu)

2023-09-25 15:34:14

2022-07-22 09:55:29

軟件工程師

2023-09-18 14:39:02

2022-05-07 11:47:36

服務(wù)器架構(gòu)

2021-02-15 22:07:18

項目策略模式
點贊
收藏

51CTO技術(shù)棧公眾號