开发喵星球

若依微服务Sentinel自定义异常(233)

为了展示更加友好的限流提示, Sentinel支持自定义异常处理。

方案一:yml配置

# Spring
spring: 
  cloud:
    sentinel:
      scg:
        fallback:
          mode: response
          response-body: '{"code":403,"msg":"请求超过最大数,请稍后再试"}'

这种方式比较简单,直接在配置文件中指定了限流异常时的响应体内容。当触发限流时,会返回 {"code":403,"msg":"请求超过最大数,请稍后再试"} 这样的 JSON 响应。

方案二:GatewayConfig注入Bean

@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelFallbackHandler sentinelGatewayExceptionHandler()
{
    return new SentinelFallbackHandler();
}

这种方式需要自定义 SentinelFallbackHandler 类,实现 WebExceptionHandler 接口。在 handle() 方法中,先判断是否为 Sentinel 限流异常,如果是,则调用 handleBlockedRequest() 方法获取响应,并通过 writeResponse() 方法写入响应体。

SentinelFallbackHandler.java

package com.ruoyi.gateway.handler;

import java.nio.charset.StandardCharsets;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebExceptionHandler;
import reactor.core.publisher.Mono;

/**
 * 自定义限流异常处理
 *
 * @author ruoyi
 */
public class SentinelFallbackHandler implements WebExceptionHandler
{
    private Mono<Void> writeResponse(ServerResponse response, ServerWebExchange exchange)
    {
        ServerHttpResponse serverHttpResponse = exchange.getResponse();
        serverHttpResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        byte[] datas = "{\"code\":429,\"msg\":\"请求超过最大数,请稍后再试\"}".getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = serverHttpResponse.bufferFactory().wrap(datas);
        return serverHttpResponse.writeWith(Mono.just(buffer));
    }

    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex)
    {
        if (exchange.getResponse().isCommitted())
        {
            return Mono.error(ex);
        }
        if (!BlockException.isBlockException(ex))
        {
            return Mono.error(ex);
        }
        return handleBlockedRequest(exchange, ex).flatMap(response -> writeResponse(response, exchange));
    }

    private Mono<ServerResponse> handleBlockedRequest(ServerWebExchange exchange, Throwable throwable)
    {
        return GatewayCallbackManager.getBlockHandler().handleRequest(exchange, throwable);
    }
}

这个实现与第一种方案的区别在于,它可以自定义更复杂的限流异常处理逻辑。例如,可以根据不同的限流规则,返回不同的响应内容。

总的来说,这两种实现方式都可以实现自定义的 Sentinel 限流异常处理,选择哪种方式取决于具体的需求。
– 如果需求比较简单,可以选择第一种基于配置文件的方式;
– 如果需求比较复杂,需要根据不同的限流规则返回不同的响应,可以选择第二种自定义 SentinelFallbackHandler 的方式。

   
分类:Java/OOP 作者:无限繁荣, 吴蓉 发表于:2024-06-07 09:09:43 阅读量:130
<<   >>


powered by kaifamiao