marcosbarbero / spring-cloud-zuul-ratelimit

Rate limit auto-configure for Spring Cloud Netflix Zuul

Home Page:https://blog.marcosbarbero.com/spring-cloud-netflix-zuul-rate-limit/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Getting RateLimitExceeded when posting to other microservice

innocode78 opened this issue · comments

I have set limit of 3 in my config for certain service-id

When the limit reached I would like to hit another endpoint/microservice from my zuul gateway but still got the limit reached. I use restTemplate to POST to another microservice in order to save the log of the filtered / limit-reached users.

I put my restTemplate code using EventListener, something like this:

    @EventListener
    public void observe(RateLimitExceededEvent event) {
        System.out.println("event: " + event);

        // Call another private method in this class to post to another microsvc using restTemplate
            try {
                ApiResponse<LockedUserResponse> apiResponse = handleTooManyRequestError(authentication);
                logger.info("Lock user successful: {}", apiResponse);
            } catch (Exception e) {
                logger.warn("failed when handle Too Many Request error ", e);
            }
}

I got this exception on infinite loop:

event: com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.support.RateLimitExceededEvent[source=com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.filters.RateLimitPreFilter@5e1db27e]
RateLimitExceededEvent for user: shenli
28-05-2020 19:57:56.994 [http-nio-8762-exec-8] WARN  com.microservices...zuulgateway.exception.handler.ErrorHandlerController.handleTooManyRequestError - Too many request for user: shenli
28-05-2020 19:57:57.010 [http-nio-8762-exec-8] INFO  com.microservices...zuulgateway.exception.handler.ErrorHandlerController.handleTooManyRequestError - .
28-05-2020 19:57:57.013 [http-nio-8762-exec-8] INFO  com.microservices...zuulgateway.exception.handler.ErrorHandlerController.handleTooManyRequestError - body req: LockedUserRequest(refId=edbc5ce9-639f-4688-83b3-111ed26d33a1, userName=shenli)
event: com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.support.RateLimitExceededEvent[source=com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.filters.RateLimitPreFilter@5e1db27e]
RateLimitExceededEvent for user: shenli
28-05-2020 19:57:57.871 [http-nio-8762-exec-10] WARN  com.microservices...zuulgateway.exception.handler.ErrorHandlerController.handleTooManyRequestError - Too many request for user: shenli
28-05-2020 19:57:57.882 [http-nio-8762-exec-10] INFO  com.microservices...zuulgateway.exception.handler.ErrorHandlerController.handleTooManyRequestError - .
28-05-2020 19:57:57.884 [http-nio-8762-exec-10] INFO  com.microservices...zuulgateway.exception.handler.ErrorHandlerController.handleTooManyRequestError - body req: LockedUserRequest(refId=edbc5ce9-639f-4688-83b3-111ed26d33a1, userName=shenli)
event: com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.support.RateLimitExceededEvent[source=com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.filters.RateLimitPreFilter@5e1db27e]
RateLimitExceededEvent for user: shenli
28-05-2020 19:57:58.587 [http-nio-8762-exec-1] WARN  com.microservices...zuulgateway.exception.handler.ErrorHandlerController.handleTooManyRequestError - Too many request for user: shenli
28-05-2020 19:57:58.608 [http-nio-8762-exec-1] INFO  com.microservices...zuulgateway.exception.handler.ErrorHandlerController.handleTooManyRequestError - .
28-05-2020 19:57:58.610 [http-nio-8762-exec-1] INFO  com.microservices...zuulgateway.exception.handler.ErrorHandlerController.handleTooManyRequestError - body req: LockedUserRequest(refId=edbc5ce9-639f-4688-83b3-111ed26d33a1, userName=shenli)
event: com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.support.RateLimitExceededEvent[source=com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.filters.RateLimitPreFilter@5e1db27e]
RateLimitExceededEvent for user: shenli
28-05-2020 19:57:59.288 [http-nio-8762-exec-3] WARN  com.microservices...zuulgateway.exception.handler.ErrorHandlerController.handleTooManyRequestError - Too many request for user: shenli
28-05-2020 19:57:59.312 [http-nio-8762-exec-3] INFO  com.microservices...zuulgateway.exception.handler.ErrorHandlerController.handleTooManyRequestError - .
28-05-2020 19:57:59.315 [http-nio-8762-exec-3] INFO  com.microservices...zuulgateway.exception.handler.ErrorHandlerController.handleTooManyRequestError - body req: LockedUserRequest(refId=edbc5ce9-639f-4688-83b3-111ed26d33a1, userName=shenli)
event: com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.support.RateLimitExceededEvent[source=com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.filters.RateLimitPreFilter@5e1db27e]

After forcefully shutdown the app, the console continue to print this stacktrace:

28-05-2020 18:05:34.709 [http-nio-8762-exec-51] WARN  com.microservices...zuulgateway.exception.handler.ErrorHandlerController.returnError - failed when handle Too Many Request error 
org.springframework.web.client.HttpClientErrorException$Unauthorized: 401 null
	at org.springframework.web.client.HttpClientErrorException.create(HttpClientErrorException.java:81) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:122) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:102) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:778) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:736) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:710) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:463) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at com.microservices...zuulgateway.exception.handler.ErrorHandlerController.handleTooManyRequestError(ErrorHandlerController.java:93) ~[classes/:na]
	at com.microservices...zuulgateway.exception.handler.ErrorHandlerController.returnError(ErrorHandlerController.java:66) ~[classes/:na]
	at sun.reflect.GeneratedMethodAccessor190.invoke(Unknown Source) ~[na:na]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_121]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_121]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189) [spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) [spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) [spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892) [spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) [spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) [spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038) [spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) [spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) [spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) [spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]

(also on repeat/many many times)

when looking at line 93 this is the code on that line:
ResponseEntity result = restTemplate.postForEntity(uri, request, String.class);

I keep getting exception "org.springframework.web.client.HttpClientErrorException$Unauthorized: 401 null"
but I think I already set the authorization with correct bearer token before line of restTemplate.postForEntity

Is this normal behaviour? any help is really appreciated

Hi @shenlihartono, unfortunately, I don't know exactly why you're facing this issue, but I can tell this loop seems off.

Also, the 401 you're getting is unlikely to be related to this library. I do believe that will be easier to help you out if you can share a sample project reproducing the error.

Thanks for the feedback, @marcosbarbero

Unfortunately I cannot provide sample code at this moment.

But I think after debugging the code last night (setting breakpoint in many places, one of them is on the pre filter method, also on eventListener for RateLimitExceeded, etc)

I think I have a hint why the loop happened. Apparently it's issue with my local config.