@SentinelResource 注解在 Controller 函数上配置使用问题

使用 @SentinelResource的时候自定了降级处理但是不能生效

@GetMapping("/getUserInfoById") @SentinelResource(value = "getUserInfoById",blockHandler = "getUserInfoByIdHand") public String getUserInfoById(@RequestParam("id") Integer id) { log.info("getUserInfoById"); try { TimeUnit.MILLISECONDS.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } return "ok"; }

public String getUserInfoByIdHand(@RequestParam("id") Integer id,BlockException ex) {
    log.info("getUserInfoByIdHand");
    return "出现异常了......";
}

查看源代码发现在拦截器层就进行了流量统计的异常计算统计导致不能进入SentinelResource 的核心SentinelResourceAspect类里面,因为SentinelResourceAspect的调用在拦截器后面, 跟踪源码发现在 AbstractSentinelInterceptor拦截里面就被处理了异常

@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { try { String resourceName = getResourceName(request);

        if (StringUtil.isNotEmpty(resourceName)) {
            // Parse the request origin using registered origin parser.
            String origin = parseOrigin(request);
            ContextUtil.enter(SENTINEL_SPRING_WEB_CONTEXT_NAME, origin);
            Entry entry = SphU.entry(resourceName, ResourceTypeConstants.COMMON_WEB, EntryType.IN);

            setEntryInRequest(request, baseWebMvcConfig.getRequestAttributeName(), entry);
        }
        return true;
    } catch (BlockException e) {
        handleBlockException(request, response, e);
        return false;
    }
}

--》 handleBlockException(request, response, e); public class DefaultBlockExceptionHandler implements BlockExceptionHandler {

@Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
    // Return 429 (Too Many Requests) by default.
    response.setStatus(429);

    StringBuffer url = request.getRequestURL();

    if ("GET".equals(request.getMethod()) && StringUtil.isNotBlank(request.getQueryString())) {
        url.append("?").append(request.getQueryString());
    }

    PrintWriter out = response.getWriter();
    out.print("Blocked by Sentinel (flow limiting)");
    out.flush();
    out.close();
}

out.print("Blocked by Sentinel (flow limiting)");

页面就一直输出 "Blocked by Sentinel (flow limiting)" 所有不能返回正确的异常处理 有什么好的处理方法没还是我的使用有问题

原提问者GitHub用户zhoushisheng001

展开
收起
学习娃 2023-05-19 15:32:48 120 分享 版权
1 条回答
写回答
取消 提交回答
  • 配置规则在注解定义的资源名配置,且注解定义的资源名不要和 API path 重复。你这个应该是配的 API path 的规则,走的自带的 Spring Web 埋点。

    注意:在 Controller 上面配置的注解,资源名请不要与 URL 重合;因 Sentinel 自带 Web adapter 也会将 URL pattern 作为资源名,这会导致重复统计+注解 blockHandler 不生效。

    原回答者GitHub用户sczyh30

    2023-05-19 20:32:18
    赞同 展开评论
问答分类:
问答地址:

阿里云拥有国内全面的云原生产品技术以及大规模的云原生应用实践,通过全面容器化、核心技术互联网化、应用 Serverless 化三大范式,助力制造业企业高效上云,实现系统稳定、应用敏捷智能。拥抱云原生,让创新无处不在。

还有其他疑问?
咨询AI助理