You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Cloud Gateway集成Hazelcast限流器:对接已有Eureka集群实例

对接Eureka注册的Hazelcast集群实现Spring Cloud Gateway限流

1. 依赖配置

确保项目中引入以下核心依赖(以Maven为例):

<!-- Spring Cloud Eureka Client -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- Hazelcast Eureka Discovery -->
<dependency>
    <groupId>com.hazelcast</groupId>
    <artifactId>hazelcast-eureka-one</artifactId>
</dependency>
<!-- Bucket4j Hazelcast Integration -->
<dependency>
    <groupId>com.github.vladimir-bukhtoyarov</groupId>
    <artifactId>bucket4j-hazelcast</artifactId>
    <version>7.6.0</version>
</dependency>
<!-- Spring Cloud Gateway -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

2. Hazelcast集群发现配置

创建Hazelcast配置类,让客户端通过Eureka发现名为HCAST的集群节点:

import com.hazelcast.client.HazelcastClient;
import com.hazelcast.client.config.ClientConfig;
import com.hazelcast.client.config.ClientNetworkConfig;
import com.hazelcast.config.DiscoveryConfig;
import com.hazelcast.config.DiscoveryStrategyConfig;
import com.hazelcast.core.HazelcastInstance;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class HazelcastEurekaConfig {

    @Bean
    public HazelcastInstance hazelcastInstance() {
        ClientConfig clientConfig = new ClientConfig();
        clientConfig.setClusterName("HCAST"); // 匹配Eureka中注册的Hazelcast集群名称

        ClientNetworkConfig networkConfig = clientConfig.getNetworkConfig();
        networkConfig.getDiscoveryConfig().setEnabled(true);

        // 配置Eureka发现策略
        DiscoveryStrategyConfig eurekaDiscoveryConfig = new DiscoveryStrategyConfig(
                com.hazelcast.eureka.one.EurekaDiscoveryStrategyFactory.class
        );
        eurekaDiscoveryConfig.addProperty("use-metadata-for-host-and-port", "true");
        eurekaDiscoveryConfig.addProperty("namespace", "hazelcast");

        DiscoveryConfig discoveryConfig = networkConfig.getDiscoveryConfig();
        discoveryConfig.addDiscoveryStrategyConfig(eurekaDiscoveryConfig);

        return HazelcastClient.newHazelcastClient(clientConfig);
    }
}

3. Spring Cloud Gateway限流过滤器配置

编写Gateway的限流配置类,使用Hazelcast作为Bucket的后端存储:

import com.github.vladimir_bukhtoyarov.bucket4j.spring.boot.context.config.Bucket4jConfiguration;
import com.github.vladimir_bukhtoyarov.bucket4j.spring.boot.context.config.Bucket4jCustomizer;
import com.hazelcast.core.HazelcastInstance;
import io.github.bucket4j.Bucket;
import io.github.bucket4j.distributed.proxy.ProxyManager;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;

import java.time.Duration;
import java.util.function.Supplier;

@Configuration
public class GatewayRateLimitConfig {

    // 基于请求IP作为限流键
    @Bean
    public KeyResolver ipKeyResolver() {
        return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
    }

    // 配置Bucket4j使用Hazelcast存储
    @Bean
    public Bucket4jCustomizer bucket4jCustomizer(HazelcastInstance hazelcastInstance) {
        ProxyManager<String> proxyManager = io.github.bucket4j.hazelcast.HazelcastProxyManager.builder(hazelcastInstance).build();
        return (Bucket4jConfiguration configuration) -> {
            configuration.setProxyManager(proxyManager);
            configuration.addBucketConfiguration("ip-rate-limit", (Supplier<Bucket>) () -> Bucket.builder()
                    .addLimit(limit -> limit.capacity(100).refillGreedy(100, Duration.ofMinutes(1)))
                    .build());
        };
    }
}

4. 应用配置文件(application.yml)

添加Eureka客户端和Gateway路由配置:

spring:
  application:
    name: gateway-service
  cloud:
    gateway:
      routes:
        - id: example-route
          uri: lb://your-target-service # 替换为你的目标服务名称
          predicates:
            - Path=/api/**
          filters:
            - name: Bucket4J
              args:
                key-resolver: "#{@ipKeyResolver}"
                bucket-config: ip-rate-limit

eureka:
  client:
    service-url:
      defaultZone: http://your-eureka-server:8761/eureka/ # 替换为你的Eureka地址
    fetch-registry: true
    register-with-eureka: true

hazelcast:
  eureka:
    enabled: true
    service-url: http://your-eureka-server:8761/eureka/ # 与Eureka地址保持一致

关键说明

  • 确保Hazelcast集群节点(HCAST)在Eureka上注册时,spring.application.name设置为HCAST,且开启了Eureka发现配置。
  • 限流规则可根据业务需求调整,示例中是每分钟允许100次请求。
  • 若需要自定义限流键(如用户ID),只需修改KeyResolver的实现即可。

内容的提问来源于stack exchange,提问作者spyder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 14:17:16