Spring Cloud Gateway 扩展支持动态限流

本文探讨了Spring Cloud Gateway中RequestRateLimiter的局限,并介绍了Sentinel作为流量控制工具的优势。Sentinel从1.6.0版本开始支持Spring Cloud Gateway,提供route和自定义API维度的限流。文章详细讲解了Sentinel的配置、限流策略以及如何通过Nacos数据源动态调整限流参数,最后展示了限流效果并提及1.7.0版本将增加图形化控制功能。

原生RequestRateLimiter 的不足
配置方式

spring:
  cloud:
    gateway:
      routes:
      - id: requestratelimiter_route
        uri: lb://pigx-upms
        order: 10000
        predicates:
        - Path=/admin/**
        filters:
        - name: RequestRateLimiter
          args:
            redis-rate-limiter.replenishRate: 1  
            redis-rate-limiter.burstCapacity: 3
            key-resolver: "#{@remoteAddrKeyResolver}" #SPEL表达式去的对应的bean
        - StripPrefix=1

RequestRateLimiterGatewayFilterFactory

public GatewayFilter apply(Config config) {
   
   
	KeyResolver resolver = getOrDefault(config.keyResolver, defaultKeyResolver);
	RateLimiter<Object> limiter = getOrDefault(config.rateLimiter,
			defaultRateLimiter);
	boolean denyEmpty = getOrDefault(config.denyEmptyKey, this.denyEmptyKey);
	HttpStatusHolder emptyKeyStatus = HttpStatusHolder
			.parse(getOrDefault(config.emptyKeyStatus, this.emptyKeyStatusCode));

	return (exchange, chain) -
### Spring Cloud 中多线程实现的方式 在 Spring Cloud 微服务架构中,多线程技术可以显著提升系统的性能和响应速度。以下是通过 `@Async` 注解以及自定义线程池的方式来实现多线程处理的具体方法。 #### 使用 @Async 注解实现多线程异步调用 Spring 提供了内置的 `@Async` 注解用于简化多线程编程。当某个方法被标注为 `@Async` 时,它将在独立的线程中执行,而不会阻塞主线程[^2]。 下面是一个简单的代码示例: ```java import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; @Service public class AsyncService { @Async // 标识该方法为异步执行 public void performTask() { try { Thread.sleep(2000); // 模拟耗时操作 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("任务完成:" + Thread.currentThread().getName()); } } ``` 要启用 `@Async` 功能,还需要在配置类上添加 `@EnableAsync` 注解: ```java import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; @Configuration @EnableAsync // 启用异步功能 public class AppConfig {} ``` #### 自定义线程池优化多线程性能 默认情况下,`@Async` 使用的是 Spring 内置的任务执行器(SimpleAsyncTaskExecutor),但它并不适合高并发场景。因此可以通过配置自定义线程池来提高效率。 以下是如何创建并应用自定义线程池的一个例子: ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.Executor; @Configuration public class ThreadPoolConfig { @Bean(name = "myExecutor") // 定义名为 myExecutor 的线程池 Bean public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); // 设置核心线程数 executor.setMaxPoolSize(10); // 设置最大线程数 executor.setQueueCapacity(100); // 设置队列容量 executor.initialize(); // 初始化线程池 return executor; } } // 修改之前的异步方法以使用自定义线程池 @Async("myExecutor") // 显式指定使用的线程池名称 public void performTaskWithCustomThreadPool() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("任务完成于自定义线程池:" + Thread.currentThread().getName()); } ``` #### 结合实际案例分析 在一个具体的业务场景中,比如需要从多个远程 API 获取数据进行汇总展示,采用多线程方式能够有效减少总等待时间。假设存在三个不同的服务接口分别提供用户信息、订单详情和服务状态,则可通过如下方式进行改进[^4]: ```java @Service public class DataService { private final RestTemplate restTemplate; public DataService(RestTemplateBuilder builder){ this.restTemplate = builder.build(); } @Async("myExecutor") public CompletableFuture<User> fetchUserDetails(Long userId) { String url = "http://userservice/user/" + userId; User user = restTemplate.getForObject(url, User.class); return CompletableFuture.completedFuture(user); } @Async("myExecutor") public CompletableFuture<Order[]> fetchOrders(Long userId) { String url = "http://orderservice/orders?userId=" + userId; Order[] orders = restTemplate.getForObject(url, Order[].class); return CompletableFuture.completedFuture(orders); } @Async("myExecutor") public CompletableFuture<ServiceStatus> fetchServiceStatus() { String url = "http://statusservice/status"; ServiceStatus status = restTemplate.getForObject(url, ServiceStatus.class); return CompletableFuture.completedFuture(status); } public CombinedData fetchData(Long userId) throws Exception { CompletableFuture<User> userDetailsFuture = fetchUserDetails(userId); CompletableFuture<Order[]> ordersFuture = fetchOrders(userId); CompletableFuture<ServiceStatus> serviceStatusFuture = fetchServiceStatus(); // 等待所有异步任务完成后再组合结果返回 return new CombinedData( userDetailsFuture.get(), ordersFuture.get(), serviceStatusFuture.get() ); } } ``` 上述代码片段展示了如何利用 Java 的 `CompletableFuture` 来管理多个异步任务的结果,并最终将其合并成单一的数据结构以便进一步处理。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值