apache / shenyu

Apache ShenYu is a Java native API Gateway for service proxy, protocol conversion and API governance.
https://shenyu.apache.org/
Apache License 2.0
8.41k stars 2.92k forks source link

[Question] when the client return an error(status code 500) immediately , bootstrap(springCloud sentinel plugin enabled) sentinel didn't fallback as expected,but only return the client response #2291

Closed huwenming-saw closed 2 years ago

huwenming-saw commented 2 years ago

Question

  1. run admin dashboard enabled springCloud and sentinel plugin (2.4.1)
  2. run bootstrap (2.4.1)
  3. run a client which throws a error immediately (2.4.1)
  4. my sentinel rule image
  5. response
    {
    "timestamp": "2021-11-02T02:12:06.970+0000",
    "status": 500,
    "error": "Internal Server Error",
    "message": "服务暂不可用!",
    "path": "/springcloud/nlog/save"
    }
  6. in the source code
    protected Mono<Void> doExecute(final ServerWebExchange exchange, final ShenyuPluginChain chain, final SelectorData selector, final RuleData rule) {
        final ShenyuContext shenyuContext = exchange.getAttribute(Constants.CONTEXT);
        assert shenyuContext != null;
        String resourceName = CacheKeyUtils.INST.getKey(rule);
        SentinelHandle sentinelHandle = GsonUtils.getInstance().fromJson(rule.getHandle(), SentinelHandle.class);
        sentinelHandle.checkData(sentinelHandle);
        return chain.execute(exchange).transform(new SentinelReactorTransformer<>(resourceName)).doOnSuccess(v -> {
            HttpStatus status = exchange.getResponse().getStatusCode();//debug step here , status = 200, so it didn't throw a error and then sentinel mistakenly assumed that no error has occurred
            if (status == null || !status.is2xxSuccessful()) {
                exchange.getResponse().setStatusCode(null);
                throw new SentinelFallbackException(status == null ? HttpStatus.INTERNAL_SERVER_ERROR : status);
            }
        }).onErrorResume(throwable -> fallbackHandler.fallback(exchange, UriUtils.createUri(sentinelHandle.getFallbackUri()), throwable));
    }
  7. Maybe you need to reuse Constants.CLIENT_RESPONSE_RESULT_TYPE:ResultEnum in the source code org.apache.shenyu.plugin.httpclient.WebClientPlugin#doNext
SaberSola commented 2 years ago

Hi big brother, iIf you want to trigger the degradation,your http code can not be 2xx

huwenming-saw commented 2 years ago

image

image

I don't think you understand what i describe, because the webclient exchange (downstream) is 5xx, but gateway exchange is still 200, WebClientPlugin just set a attributes flag but do nothing.

please have a try.

midnight2104 commented 2 years ago

Hi, does this question still exist? If there is still a problem, please resubmit the issue.