Spring Boot与Spring Cloud Gateway的限流与熔断策略

发布时间:2024-11-15 16:36:26 作者:小樊
来源:亿速云 阅读:78

Spring Boot和Spring Cloud Gateway都是基于Spring生态系统的流行框架,它们提供了丰富的功能来简化微服务架构的开发。在微服务架构中,限流和熔断是两种重要的保护机制,用于防止系统过载和故障扩散。下面分别介绍Spring Boot和Spring Cloud Gateway中的限流和熔断策略。

Spring Boot中的限流与熔断策略

限流

Spring Boot提供了多种限流策略,可以通过以下几种方式实现:

  1. 基于Guava RateLimiter: Spring Boot可以集成Guava库中的RateLimiter来实现限流。首先,需要在pom.xml中添加Guava依赖:

    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>30.1-jre</version>
    </dependency>
    

    然后,在配置类中配置RateLimiter:

    import com.google.common.util.concurrent.RateLimiter;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class RateLimiterConfig {
    
        @Bean
        public RateLimiter rateLimiter() {
            return RateLimiter.create(1); // 每秒最多处理1个请求
        }
    }
    

    在需要限流的方法上使用@RateLimiter注解:

    import com.google.common.util.concurrent.RateLimiter;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class MyController {
    
        @Autowired
        private RateLimiter rateLimiter;
    
        @GetMapping("/limited")
        public String limited() {
            if (rateLimiter.tryAcquire()) {
                return "Request accepted";
            } else {
                return "Request rejected";
            }
        }
    }
    
  2. 基于Redis的限流: 可以使用Spring Data Redis来实现基于Redis的限流。首先,需要在pom.xml中添加Redis依赖:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    

    然后,在配置类中配置Redis:

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    
    @Configuration
    public class RedisConfig {
    
        @Bean
        public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
            RedisTemplate<String, String> template = new RedisTemplate<>();
            template.setConnectionFactory(factory);
            template.setKeySerializer(new StringRedisSerializer());
            template.setValueSerializer(new StringRedisSerializer());
            return template;
        }
    }
    

    创建一个限流器:

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.stereotype.Component;
    
    import java.util.concurrent.TimeUnit;
    
    @Component
    public class RedisRateLimiter {
    
        @Autowired
        private RedisTemplate<String, String> redisTemplate;
    
        public boolean tryAcquire(String key, int permits, long timeout, TimeUnit timeUnit) {
            String current = redisTemplate.opsForValue().get(key);
            if (current == null || Integer.parseInt(current) < permits) {
                redisTemplate.opsForValue().set(key, permits, timeout, timeUnit);
                return true;
            }
            return false;
        }
    }
    

    在需要限流的方法上使用@RedisRateLimiter注解:

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class MyController {
    
        @Autowired
        private RedisRateLimiter redisRateLimiter;
    
        @GetMapping("/redis-limited")
        public String redisLimited() {
            if (redisRateLimiter.tryAcquire("myKey", 1, 10, TimeUnit.SECONDS)) {
                return "Request accepted";
            } else {
                return "Request rejected";
            }
        }
    }
    

熔断

Spring Boot可以通过Hystrix来实现熔断功能。首先,需要在pom.xml中添加Hystrix依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

然后,在启动类上添加@EnableCircuitBreaker注解:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableCircuitBreaker;

@SpringBootApplication
@EnableCircuitBreaker
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

在需要熔断的方法上添加@HystrixCommand注解:

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @HystrixCommand(fallbackMethod = "fallbackMethod")
    public String myMethod() {
        // 实际的业务逻辑
        return "Success";
    }

    public String fallbackMethod() {
        return "Fallback response";
    }
}

Spring Cloud Gateway中的限流与熔断策略

限流

Spring Cloud Gateway提供了多种限流策略,可以通过以下几种方式实现:

  1. 基于Guava RateLimiter: 可以使用Spring Cloud Gateway的RateLimiter GatewayFilter Factory来实现限流。首先,需要在pom.xml中添加Guava依赖:

    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>30.1-jre</version>
    </dependency>
    

    然后,在配置类中配置RateLimiter:

    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;
    
    @Configuration
    public class RateLimiterConfig {
    
        @Bean
        public KeyResolver userKeyResolver() {
            return new KeyResolver() {
                @Override
                public Mono<String> resolve(ServerWebExchange exchange) {
                    return Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
                }
            };
        }
    }
    

    在路由配置中使用RateLimiter GatewayFilter Factory:

    spring:
      cloud:
        gateway:
          routes:
            - id: my_route
              uri: http://my-service-url
              filters:
                - name: RequestRateLimiter
                  args:
                    redis-rate-limiter.replenishRate: 10
                    redis-rate-limiter.burstCapacity: 20
                    key-resolver: "#{@userKeyResolver}"
    
  2. 基于Redis的限流: 可以使用Spring Cloud Gateway的RedisRateLimiter GatewayFilter Factory来实现基于Redis的限流。首先,需要在pom.xml中添加Spring Data Redis依赖:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    

    然后,在配置类中配置Redis:

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    
    @Configuration
    public class RedisConfig {
    
        @Bean
        public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
            RedisTemplate<String, String> template = new RedisTemplate<>();
            template.setConnectionFactory(factory);
            template.setKeySerializer(new StringRedisSerializer());
            template.setValueSerializer(new StringRedisSerializer());
            return template;
        }
    }
    

    在路由配置中使用RedisRateLimiter GatewayFilter Factory:

    spring:
      cloud:
        gateway:
          routes:
            - id: my_route
              uri: http://my-service-url
              filters:
                - name: RedisRateLimiter
                  args:
                    redis-rate-limiter.replenishRate: 10
                    redis-rate-limiter.burstCapacity: 20
    

熔断

Spring Cloud Gateway可以通过Resilience4j来实现熔断功能。首先,需要在pom.xml中添加Resilience4j依赖:

<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-spring-boot2</artifactId>
</dependency>

然后,在配置类中配置Resilience4j:

import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
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;

@Configuration
public class Resilience4jConfig {

    @Bean
    public KeyResolver userKeyResolver() {
        return new KeyResolver() {
            @Override
            public Mono<String> resolve(ServerWebExchange exchange) {
                return Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
            }
        };
    }

    @Bean
    public CircuitBreakerRegistry circuitBreakerRegistry() {
        CircuitBreakerConfig config = CircuitBreakerConfig.custom()
                .failureRateThreshold(50)
                .waitDurationInOpenState(Duration.ofMillis(1000))
                .permittedNumberOfCallsInHalfOpenState(10)
                .build();
        return CircuitBreakerRegistry.of(config);
    }

    @Bean
    public CircuitBreaker circuitBreaker(CircuitBreakerRegistry registry) {
        return registry.circuitBreaker("myCircuitBreaker");
    }
}

在路由配置中使用CircuitBreaker GatewayFilter Factory:

spring:
  cloud:
    gateway:
      routes:
        - id: my_route
          uri: http://my-service-url
          filters:
            - name: CircuitBreaker
              args:
                name: myCircuitBreaker
                fallbackUri: forward:/fallback

通过以上配置,可以实现Spring Boot和Spring Cloud Gateway中的限流和熔断策略。

推荐阅读:
  1. 微服务网关实战——Spring Cloud Gateway
  2. spring cloud 2.x版本 Gateway熔断、限流教程

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

spring boot

上一篇:Spring Boot中集成Spring Cloud Sleuth进行分布式追踪

下一篇:Spring Boot中集成Spring Data JPA的查询分页与排序

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》