alibaba / Sentinel

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

Sentinel Feign error when invoke default method in interface #911

Closed stalary closed 5 years ago

stalary commented 5 years ago

When I used Sentinel, Feign reported the following error:

feign.FeignException: status 500 reading PushClient#pushMessage(String,String,String,String,String,String,String)                                                                      
        at feign.FeignException.errorStatus(FeignException.java:78) ~[feign-core-10.1.0.jar!/:?]                                                                                       
        at feign.codec.ErrorDecoder$Default.decode(ErrorDecoder.java:93) ~[feign-core-10.1.0.jar!/:?]                                                                                  
        at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:149) ~[feign-core-10.1.0.jar!/:?]                                                             
        at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:78) ~[feign-core-10.1.0.jar!/:?]                                                                        
        at org.springframework.cloud.alibaba.sentinel.feign.SentinelInvocationHandler.invoke(SentinelInvocationHandler.java:103) ~[spring-cloud-alibaba-sentinel-0.2.1.RELEASE.jar!/:0.
        at com.sun.proxy.$Proxy183.pushMessage(Unknown Source) ~[?:?]                                                                                                                  
        at outfox.course.tiku.service.kafka.Consumer.genQuizReport(Consumer.java:284) ~[classes!/:?]                                                                                   
        at outfox.course.tiku.service.kafka.Consumer.processQuizCorrect(Consumer.java:144) ~[classes!/:?]                                                                              
        at outfox.course.tiku.service.kafka.Consumer.process(Consumer.java:95) ~[classes!/:?]                                                                                          
        at outfox.course.tiku.kafka.ConsumerGroup$ConsumerThread.run(ConsumerGroup.java:114) ~[tiku-base-kafka-1.1.3.jar!/:?]                                                          
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[?:1.8.0_212]                                                                                      
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_212]                                                                                                     
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[?:1.8.0_212]                                                                              
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[?:1.8.0_212]                                                                              
        at java.lang.Thread.run(Thread.java:748) [?:1.8.0_212]

my code is:

@PostMapping(value = "/pushMessage")
    void pushMessage()
default void pushMessage()

when I used default method, the error occurred.

sczyh30 commented 5 years ago

This might not be related to Sentinel Feign integration. Please check whether your code and configuration is correct.

cc @fangjian0423

fangjian0423 commented 5 years ago

I think there is some problems with your configuration and code.

stalary commented 5 years ago

java.lang.NullPointerException: null at org.springframework.cloud.alibaba.sentinel.feign.SentinelInvocationHandler.invoke(SentinelInvocationHandler.java:97) ~[spring-cloud-alibaba-sentinel-0.2.1.RELEASE.jar:0.2.1.RELEASE] at com.sun.proxy.$Proxy170.pushMessage(Unknown Source) ~[?:?] at outfox.course.tiku.controller.QuizController.push(QuizController.java:322) ~[classes/:?] at outfox.course.tiku.controller.QuizController$$FastClassBySpringCGLIB$$6a3c90ba.invoke(<generated>) ~[classes/:?] at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749) ~[spring-aop-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88) ~[spring-aop-5.1.5.RELEASE.jar:5.1.5.RELEASE] at outfox.course.tiku.aop.CtrlTimerAdvice.process(CtrlTimerAdvice.java:60) ~[classes/:?] at outfox.course.tiku.aop.CtrlTimerAdvice.getMappingAdvice(CtrlTimerAdvice.java:49) ~[classes/:?] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_144] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_144] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_144] at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_144] at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644) ~[spring-aop-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633) ~[spring-aop-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70) ~[spring-aop-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) ~[spring-aop-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93) ~[spring-aop-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) ~[spring-aop-5.1.5.RELEASE.jar:5.1.5.RELEASE] at outfox.course.tiku.controller.QuizController$$EnhancerBySpringCGLIB$$6f92a4c1.push(<generated>) ~[classes/:?] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_144] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_144] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_144] at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_144] at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.16.jar:9.0.16] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:90) ~[spring-boot-actuator-2.1.3.RELEASE.jar:2.1.3.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.springframework.cloud.sleuth.instrument.web.ExceptionLoggingFilter.doFilter(ExceptionLoggingFilter.java:50) ~[spring-cloud-sleuth-core-2.1.0.RELEASE.jar:2.1.0.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at brave.servlet.TracingFilter.doFilter(TracingFilter.java:86) ~[brave-instrumentation-servlet-5.6.1.jar:?] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:117) ~[spring-boot-actuator-2.1.3.RELEASE.jar:2.1.3.RELEASE] at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:106) ~[spring-boot-actuator-2.1.3.RELEASE.jar:2.1.3.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at com.alibaba.csp.sentinel.adapter.servlet.CommonFilter.doFilter(CommonFilter.java:89) ~[sentinel-web-servlet-1.4.0.jar:?] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:668) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[?:1.8.0_144] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[?:1.8.0_144] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.16.jar:9.0.16] at java.lang.Thread.run(Thread.java:748) [?:1.8.0_144] I didn't have this problem when I switched to feign.hystrix.enable

stalary commented 5 years ago

` public interface PushClient {

@PostMapping(value = "/pushMessage")
void pushMessage(@RequestParam("product") String product,
                 @RequestParam("platform") String platform,
                 @RequestParam("sendMode") String sendMode,
                 @RequestParam("account") String account,
                 @RequestParam("attachFile") String attachFile,
                 @RequestParam("attachType") String attachType,
                 @RequestParam("content") String content);

@Slf4j
@Component
class Fallback implements FallbackFactory<PushClient> {

    @Override
    public PushClient create(Throwable cause) {
        return (product, platform, sendMode, account, attachFile, attachType, content) -> log.warn("push error product={}, platform={}, sendMode={}, account={}, attachFile={}, attachType={}, content={}, error", product, platform, sendMode, account, attachFile, attachType, content, cause);
    }
}

default void pushMessage(PushMessageBody pushMessageBody) {
    String product = pushMessageBody.getProduct();
    String platform = pushMessageBody.getPlatform();
    String sendMode = pushMessageBody.getSendMode().name();
    String account = pushMessageBody.getAccount();
    String attachFile = pushMessageBody.getAttachFile();
    String attachType = pushMessageBody.getAttachType();
    String content = pushMessageBody.getContent();
    pushMessage(product, platform, sendMode, account, attachFile, attachType, content);
}

} `

stalary commented 5 years ago

when I used default method, the error occurred. use pushMessage no problems

fangjian0423 commented 5 years ago

could you please provide a project that reproduces the issue?

stalary commented 5 years ago

I only have a few company project...,but the error occured in every project

jasonjoo2010 commented 5 years ago

The problem is that your feign interface contains default function which means that it will be run locally (Client side). It is also captured by interpreter but the interpreter will not get the context related information.

Is that the cause?

If so the interpreter should pick this kind of invocation out and ignore them (Locally logic).

@fangjian0423

sczyh30 commented 5 years ago

Any feedback or progress? @fangjian0423 @stalary

stalary commented 5 years ago

temporarily not

fangjian0423 commented 5 years ago

sorry for the late reply, busy with other projects.

Sentinel Feign not support default method in interface.

i think we should discuss it.

we know sentinel need resource name.

The resource name of method pushMessage(String, String, String....) with PostMapping in PushClient is POST:http://pushMessage:

@PostMapping(value = "/pushMessage")
void pushMessage(@RequestParam("product") String product,
                 @RequestParam("platform") String platform,
                 @RequestParam("sendMode") String sendMode,
                 @RequestParam("account") String account,
                 @RequestParam("attachFile") String attachFile,
                 @RequestParam("attachType") String attachType,
                 @RequestParam("content") String content);

But we don't know the resource name of the default method in PushClient:

default void pushMessage(PushMessageBody pushMessageBody) {
    String product = pushMessageBody.getProduct();
    String platform = pushMessageBody.getPlatform();
    String sendMode = pushMessageBody.getSendMode().name();
    String account = pushMessageBody.getAccount();
    String attachFile = pushMessageBody.getAttachFile();
    String attachType = pushMessageBody.getAttachType();
    String content = pushMessageBody.getContent();
    pushMessage(product, platform, sendMode, account, attachFile, attachType, content);
}

how @sczyh30 @jasonjoo2010 think about this?

stalary commented 5 years ago

Because I need to encapsulate the method, default is used, and hystrix is not a problem. If I cannot solve it, I will have to encapsulate from the service layer, but this reduces reusability

@fangjian0423

fangjian0423 commented 5 years ago

hi, refer https://github.com/alibaba/spring-cloud-alibaba/issues/782.

It will be fixed soon, and spring-cloud-alibaba graduate next week. welcome to use graduation version.

stalary commented 5 years ago

thanks @fangjian0423

sczyh30 commented 5 years ago

👍

sczyh30 commented 5 years ago

Fixed via https://github.com/alibaba/spring-cloud-alibaba/commit/9f8e6b2f5fa5f41c176c7cc911648acd2b88f124