自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

SpringBoot 與 Sentinel 整合,解決 DDoS 攻擊與異常爬蟲(chóng)請(qǐng)求問(wèn)題

開(kāi)發(fā) 安全
雖然 Sentinel 主要用于微服務(wù)場(chǎng)景下的流量管理和故障隔離,但也可以通過(guò)一些策略和配置來(lái)輔助防御 DDoS 攻擊和異常爬蟲(chóng)請(qǐng)求。

Sentinel 是阿里巴巴開(kāi)源的一款面向分布式服務(wù)架構(gòu)的輕量級(jí)高可用流量控制組件,主要用于流量控制、熔斷降級(jí)和系統(tǒng)負(fù)載保護(hù)。 雖然 Sentinel 主要用于微服務(wù)場(chǎng)景下的流量管理和故障隔離,但也可以通過(guò)一些策略和配置來(lái)輔助防御 DDoS 攻擊和異常爬蟲(chóng)請(qǐng)求。

DDoS攻擊

DDoS(Distributed Denial of Service)是一種惡意攻擊手段,攻擊者通過(guò)控制大量計(jì)算機(jī)設(shè)備(如僵尸網(wǎng)絡(luò)),向目標(biāo)服務(wù)器發(fā)送大量的數(shù)據(jù)包或請(qǐng)求,從而耗盡服務(wù)器的帶寬、CPU資源或其他系統(tǒng)資源,導(dǎo)致合法用戶無(wú)法正常訪問(wèn)服務(wù)。

(1) 常見(jiàn)類(lèi)型:

① Volume-based Attacks (體積型攻擊):

  • 例如ICMP Flood、UDP Flood。
  • 攻擊者發(fā)送大量無(wú)用的數(shù)據(jù)包,占用帶寬。

② Protocol Attacks (協(xié)議型攻擊):

  • 例如SYN Flood、ACK Flood。
  • 攻擊者利用TCP/IP協(xié)議漏洞,發(fā)送特定的數(shù)據(jù)包使服務(wù)器崩潰。

③ Application Layer Attacks (應(yīng)用層攻擊):

  • 例如HTTP Flood、Slowloris。
  • 攻擊者模擬真實(shí)用戶的行為,發(fā)送大量的HTTP請(qǐng)求,消耗服務(wù)器的應(yīng)用層資源。

(2) 防御措施:

  • 使用CDN: 內(nèi)容分發(fā)網(wǎng)絡(luò)可以幫助分散流量,減輕單個(gè)服務(wù)器的壓力。
  • 負(fù)載均衡: 分散請(qǐng)求到多個(gè)服務(wù)器上,提高系統(tǒng)的可用性。
  • 防火墻和入侵檢測(cè)系統(tǒng): 防止非法流量進(jìn)入服務(wù)器。
  • Rate Limiting (限流): 控制每個(gè)IP地址或來(lái)源的請(qǐng)求速率,防止過(guò)載。
  • Traffic Shaping (流量整形): 調(diào)整進(jìn)出網(wǎng)絡(luò)的數(shù)據(jù)包傳輸速率,優(yōu)化流量分配。
  • Anycast IP Addressing: 使用多條路徑將流量引導(dǎo)至最近的健康節(jié)點(diǎn),提高冗余性和抗攻擊能力。

異常爬蟲(chóng)請(qǐng)求

異常爬蟲(chóng)是指那些不符合正常爬蟲(chóng)行為規(guī)范的自動(dòng)化程序,它們可能會(huì)對(duì)網(wǎng)站造成負(fù)擔(dān),甚至破壞網(wǎng)站的正常運(yùn)行。這些爬蟲(chóng)可能用于抓取敏感信息、進(jìn)行競(jìng)爭(zhēng)情報(bào)收集、參與SEO欺詐等活動(dòng)。

(1) 特點(diǎn):

  • 高頻率請(qǐng)求: 在短時(shí)間內(nèi)發(fā)送大量請(qǐng)求,可能導(dǎo)致服務(wù)器過(guò)載。
  • 不遵循robots.txt: 忽略網(wǎng)站的爬蟲(chóng)協(xié)議文件,訪問(wèn)受保護(hù)的內(nèi)容。
  • 偽裝成普通用戶: 使用偽造的User-Agent字符串,難以識(shí)別。
  • 頻繁更改IP: 使用代理或VPN頻繁更換IP地址,增加追蹤難度。

(2) 防御措施:

  • 設(shè)置Robots.txt: 明確告知爬蟲(chóng)哪些內(nèi)容可以抓取,哪些不可以。
  • Rate Limiting (限流): 限制每個(gè)IP地址或來(lái)源的請(qǐng)求速率,防止濫用。
  • CAPTCHA (驗(yàn)證碼): 在關(guān)鍵操作前要求用戶提供驗(yàn)證碼,區(qū)分人機(jī)。
  • IP黑名單/白名單: 阻止已知惡意IP地址的訪問(wèn),允許信任的IP地址。
  • User-Agent過(guò)濾: 檢查請(qǐng)求的User-Agent字段,阻止非標(biāo)準(zhǔn)的爬蟲(chóng)請(qǐng)求。
  • Session Management: 使用會(huì)話管理技術(shù),識(shí)別和限制可疑的爬蟲(chóng)行為。
  • Dynamic Content Delivery: 動(dòng)態(tài)生成內(nèi)容,使得爬蟲(chóng)難以抓取有用的信息。
  • Monitoring and Logging: 實(shí)時(shí)監(jiān)控和記錄異常請(qǐng)求,及時(shí)發(fā)現(xiàn)和響應(yīng)潛在威脅。

實(shí)現(xiàn)思路

(1) 流控(Flow Control):

  • 流控用于限制某個(gè)資源的訪問(wèn)速率,防止系統(tǒng)過(guò)載。
  • 通過(guò)設(shè)置每秒允許的最大請(qǐng)求數(shù),當(dāng)超過(guò)這個(gè)閾值時(shí),Sentinel會(huì)阻止多余的請(qǐng)求,并返回相應(yīng)的錯(cuò)誤信息。

(2) 降級(jí)(Degrade):

  • 降級(jí)用于在系統(tǒng)壓力過(guò)大時(shí)自動(dòng)降低服務(wù)的可用性,保護(hù)核心業(yè)務(wù)不受影響。
  • 可以根據(jù)不同的策略(如RT、異常比例、異常數(shù))來(lái)進(jìn)行降級(jí)處理。

(3) 熱點(diǎn)參數(shù)限流(Hotspot Parameter Flow Control):

熱點(diǎn)參數(shù)限流用于針對(duì)特定參數(shù)進(jìn)行限流,防止某些參數(shù)導(dǎo)致的服務(wù)過(guò)載。

(4) 全局異常處理器:

捕獲并處理由Sentinel拋出的異常,返回友好的錯(cuò)誤信息給客戶端。

(55) 自定義異常處理器:

根據(jù)不同的異常類(lèi)型(如FlowException和DegradeException),返回具體的錯(cuò)誤信息。

先啟動(dòng)Nacos服務(wù)器

我已經(jīng)在本地啟動(dòng)了Nacos服務(wù)器。

你也可以從Nacos GitHub https://github.com/alibaba/nacos 下載并按照說(shuō)明啟動(dòng)。

上傳Sentinel規(guī)則到Nacos

在Nacos配置管理中創(chuàng)建兩個(gè)配置文件:

  • Data ID: sentinel-demo-flow-rules, Group: DEFAULT_GROUP
[
    {
        "resource": "/api/hello",
        "limitApp": "default",
        "grade": 1,
        "count": 10,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    }
]
  • Data ID: sentinel-demo-degrade-rules, Group: DEFAULT_GROUP
[]

代碼實(shí)操

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.5</version>
        <relativePath/><!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>sentinel-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sentinel-demo</name>
    <description>Demo project for Spring Boot with Sentinel</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <!-- Spring Boot Web Starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Alibaba Sentinel Starter -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!-- Lombok for reducing boilerplate code -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- Spring Boot Test Starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR8</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <!-- Spring Boot Maven Plugin -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

application.yml

server:
  port:8080

spring:
cloud:
    sentinel:
      transport:
        dashboard:localhost:8080# 配置Sentinel控制臺(tái)地址
      datasource:
        ds1:
          nacos:
            server-addr:localhost:8848# Nacos服務(wù)器地址
            data-id:${spring.application.name}-flow-rules# 流控規(guī)則數(shù)據(jù)ID
            group:DEFAULT_GROUP# 流控規(guī)則組名
            rule-type:flow# 規(guī)則類(lèi)型為流控規(guī)則

logging:
level:
    root:INFO# 設(shè)置根日志級(jí)別為INFO
    com.example.sentineldemo:DEBUG# 設(shè)置應(yīng)用包的日志級(jí)別為DEBUG

logback-spring.xml

<!-- Logback日志配置文件 -->
<configuration>
    <!-- 定義控制臺(tái)輸出器 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern><!-- 日志格式 -->
        </encoder>
    </appender>

    <!-- 根日志記錄器配置 -->
    <root level="info">
        <appender-ref ref="STDOUT"/><!-- 將日志輸出到控制臺(tái) -->
    </root>
</configuration>

flow-rules.json

放在 src/main/resources/sentinel/

[
    {
        "resource": "/api/hello", // 資源路徑
        "limitApp": "default", // 默認(rèn)限流應(yīng)用
        "grade": 1, // QPS模式
        "count": 10, // 每秒最大請(qǐng)求數(shù)
        "strategy": 0, // 直接模式
        "controlBehavior": 0, // 快速失敗策略
        "clusterMode": false // 非集群模式
    }
]

定義了一個(gè)流控規(guī)則,限制 /api/hello 接口每秒最多允許 10 個(gè)請(qǐng)求。

如果超過(guò)這個(gè)閾值,Sentinel 會(huì)阻止多余的請(qǐng)求,并返回 "Too many requests, please try again later."。

SentinelDemoApplication.java

package com.example.sentineldemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Spring Boot應(yīng)用主類(lèi)
 */
@SpringBootApplication
public class SentinelDemoApplication {

    /**
     * 應(yīng)用程序入口點(diǎn)
     *
     * @param args 命令行參數(shù)
     */
    public static void main(String[] args) {
        SpringApplication.run(SentinelDemoApplication.class, args);
    }
}

Sentinel配置類(lèi)

package com.example.sentineldemo.config;

import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;
import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
import com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.util.List;

/**
 * Sentinel配置類(lèi)
 */
@Configuration
publicclass SentinelConfig {

    /**
     * 初始化Sentinel規(guī)則
     */
    @PostConstruct
    private void initRules() {
        String serverAddr = "localhost"; // Nacos服務(wù)器地址
        String groupId = "DEFAULT_GROUP"; // 規(guī)則組名
        String dataId = "${spring.application.name}-flow-rules"; // 流控規(guī)則數(shù)據(jù)ID

        // 從Nacos讀取流控規(guī)則
        ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(serverAddr, groupId, dataId,
                source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));
        FlowRuleManager.register2Property(flowRuleDataSource.getProperty());

        String degradeDataId = "${spring.application.name}-degrade-rules"; // 降級(jí)規(guī)則數(shù)據(jù)ID
        // 從Nacos讀取降級(jí)規(guī)則
        ReadableDataSource<String, List<DegradeRule>> degradeRuleDataSource = new NacosDataSource<>(serverAddr, groupId, degradeDataId,
                source -> JSON.parseObject(source, new TypeReference<List<DegradeRule>>() {}));
        DegradeRuleManager.register2Property(degradeRuleDataSource.getProperty());
    }

    /**
     * 自定義請(qǐng)求來(lái)源解析器
     *
     * @return RequestOriginParser實(shí)例
     */
    @Bean
    public RequestOriginParser requestOriginParser() {
        return request -> request.getHeader("origin"); // 使用HTTP頭中的origin字段作為請(qǐng)求來(lái)源
    }
}

Controller

使用 @SentinelResource 注解來(lái)標(biāo)識(shí)需要保護(hù)的方法。

當(dāng)方法被調(diào)用時(shí),Sentinel 會(huì)根據(jù)預(yù)先定義的規(guī)則進(jìn)行檢查。

package com.example.sentineldemo.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.example.sentineldemo.exception.BlockExceptionHandler;
import com.example.sentineldemo.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 控制器類(lèi),處理API請(qǐng)求
 */
@RestController
publicclass HelloController {

    @Autowired
    private HelloService helloService; // 注入服務(wù)層對(duì)象

    /**
     * 處理GET /api/hello請(qǐng)求
     *
     * @param name 請(qǐng)求參數(shù),用戶名
     * @return 返回問(wèn)候語(yǔ)
     */
    @GetMapping("/api/hello")
    @SentinelResource(value = "hello", blockHandlerClass = BlockExceptionHandler.class, blockHandler = "handleException")
    public String sayHello(@RequestParam(required = false) String name) {
        if (name == null || name.isEmpty()) {
            name = "World"; // 如果未提供名字,默認(rèn)為"World"
        }
        return helloService.getGreeting(name); // 調(diào)用服務(wù)層獲取問(wèn)候語(yǔ)
    }
}

全局異常處理器

捕獲并處理由 Sentinel 拋出的 BlockException 異常。

返回友好的錯(cuò)誤信息給客戶端。

package com.example.sentineldemo.exception;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

/**
 * 全局異常處理器
 */
@ControllerAdvice
publicclass GlobalExceptionHandler {

    /**
     * 處理Sentinel阻塞異常
     *
     * @param ex 異常對(duì)象
     * @return 返回錯(cuò)誤信息和狀態(tài)碼
     */
    @ExceptionHandler(BlockException.class)
    public ResponseEntity<String> handleBlockException(BlockException ex) {
        returnnew ResponseEntity<>("Blocked by Sentinel: " + ex.getClass().getSimpleName(), HttpStatus.TOO_MANY_REQUESTS);
    }
}

Sentinel資源塊處理異常處理器

package com.example.sentineldemo.exception;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;

/**
 * Sentinel資源塊處理異常處理器
 */
publicclass BlockExceptionHandler {

    /**
     * 處理Sentinel資源塊異常
     *
     * @param ex 異常對(duì)象
     * @return 返回錯(cuò)誤信息
     */
    public static String handleException(BlockException ex) {
        if (ex instanceof FlowException) {
            return"Too many requests, please try again later."; // 流控異常處理
        } elseif (ex instanceof DegradeException) {
            return"Service is degraded, please try again later."; // 降級(jí)異常處理
        }
        return"Request blocked by Sentinel."; // 其他異常處理
    }
}

服務(wù)層

package com.example.sentineldemo.service;

import org.springframework.stereotype.Service;

/**
 * 服務(wù)層類(lèi),處理業(yè)務(wù)邏輯
 */
@Service
public class HelloService {

    /**
     * 獲取問(wèn)候語(yǔ)
     *
     * @param name 用戶名
     * @return 返回問(wèn)候語(yǔ)
     */
    public String getGreeting(String name) {
        return "Hello, " + name + "!"; // 構(gòu)造問(wèn)候語(yǔ)
    }
}
責(zé)任編輯:趙寧寧 來(lái)源: Java知識(shí)日歷
相關(guān)推薦

2025-03-06 08:37:01

2012-11-30 14:54:48

2012-02-14 09:43:08

2024-05-08 16:44:40

TCPRST網(wǎng)絡(luò)協(xié)議

2015-05-18 13:51:08

2016-09-29 22:54:55

2013-04-27 10:24:03

2022-05-03 19:38:15

限流微服務(wù)Sentinel

2025-03-18 08:55:48

語(yǔ)言服務(wù)開(kāi)發(fā)框架

2025-03-07 08:31:54

2009-01-16 10:40:50

2017-08-03 09:37:35

SparkStreamKafkaDirect

2017-10-08 07:52:33

2023-10-07 12:06:52

2011-08-03 10:39:06

IOS程序 HTTP 請(qǐng)求

2025-03-12 08:42:28

2025-04-23 08:50:00

SpringBootCurator分布式鎖

2010-09-30 10:41:29

2014-07-01 09:54:13

2013-04-26 09:29:00

點(diǎn)贊
收藏

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