Spring Boot和Spring Cloud Gateway都是基于Spring生态系统的流行框架,它们提供了丰富的功能来简化微服务架构的开发。在微服务架构中,限流和熔断是两种重要的保护机制,用于防止系统过载和故障扩散。下面分别介绍Spring Boot和Spring Cloud Gateway中的限流和熔断策略。
Spring Boot提供了多种限流策略,可以通过以下几种方式实现:
基于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";
}
}
}
基于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提供了多种限流策略,可以通过以下几种方式实现:
基于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}"
基于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中的限流和熔断策略。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。