alibaba / Sentinel

A powerful flow control component enabling reliability, resilience and monitoring for microservices. (面向云原生微服务的高可用流控防护组件)
https://sentinelguard.io/
Apache License 2.0
22.41k stars 8.03k forks source link

@SentinelRestTemplate注解未生效 #1278

Open 8battery opened 4 years ago

8battery commented 4 years ago

Issue Description

@SentinelRestTemplate 注解未生效

请求的地址服务端关闭后,测试请求抛异常退出了,并没有走熔断处理 抛出异常

java.lang.NullPointerException
    at org.springframework.web.client.DefaultResponseErrorHandler.hasError(DefaultResponseErrorHandler.java:55)
    at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:766)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:736)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:670)
    at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:414)

如果去掉@SentinelRestTemplate,抛出 Connection timed out异常

Describe what happened (or what feature you want)

@Configuration
public class RestClientConfig {

    @Bean
    @SentinelRestTemplate(blockHandlerClass = FuseHandlerUtil.class, fallbackClass = FuseHandlerUtil.class,
            blockHandler = "blockHandleException", fallback = "fallBackHandleException")
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

}
@Component
public class RestClient {

    @Autowired
    private RestTemplate restTemplate;

    public String sentPost() {
        String resp = restTemplate.postForObject("http://localhost:8080/hello/normal",null,
                String.class, new Object());
        return resp;
    }
}
public final class FuseHandlerUtil {

    private static Logger logger = LoggerFactory.getLogger(FuseHandlerUtil.class);

    private FuseHandlerUtil(){}

    public static ClientHttpResponse blockHandleException(HttpRequest request, byte[] body,
                                                         ClientHttpRequestExecution execution, BlockException exception) {
        logger.info("触发了限流处理");
        try {
            return execution.execute(request, body);
        } catch (IOException e) {
            logger.info("限流处理失败");
            logger.error(e.getMessage());
            return null;
        }
    }

    public static ClientHttpResponse fallBackHandleException(HttpRequest request, byte[] body,
                                                             ClientHttpRequestExecution execution, BlockException exception) {
        logger.info("触发了降级处理");
        try {
            return execution.execute(request, body);
        } catch (IOException e) {
            logger.info("降级处理失败");
            logger.error(e.getMessage());
            return null;
        }
    }
}
@SpringBootTest
@RunWith(SpringRunner.class)
public class RestClientTest {

    Logger logger = LoggerFactory.getLogger(RestClientTest.class);

    @Autowired
    private RestClient restClient;

    @Test
    public void clientTest() throws InterruptedException {
        logger.info("客户端测试");
        for(int i = 0; i < 100; i++) {
            String rs = restClient.sentPost();
            logger.info("result:{}", rs);
            Thread.sleep(1000);
        }
    }
}

Tell us your environment

jdk1.8 spring boot 2.1.6.RELEASE spring web 5.1.8.RELEASE sentinel 2.1.0.RELEASE

seasidesky commented 4 years ago

@8battery for Connection timed out, on client side, you have to config the sentinel degrade rule, for example

        DegradeRule degradeRule = new DegradeRule();
        degradeRule.setResource("POST:http://localhost:8080/hello/normal");
        degradeRule.setLimitApp("default");
        degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
        degradeRule.setCount(3);
        degradeRule.setTimeWindow(30);
Taogang00 commented 3 years ago

我在本地测试也是一样的问题,我的环境是 `

com.alibaba.cloud
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        <version>2.2.3.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-datasource-apollo</artifactId>
        <version>1.8.0</version>
    </dependency>` 

我的配置是拉的Apollo里的配置: { "resource": "GET:http://localhost:800/hello2", "count": 500.0, "grade": 0, "timeWindow": 10, "minRequestAmount": 3, "statIntervalMs": 3000, "slowRatioThreshold": 0.6 } 也是NPE

sczyh30 commented 3 years ago

cc @yuhuangbin