Spring Zuul Header based routing hangs when downstream is not responsive for some time

Viewed 235

I have implemented the below code to route requests based on headers to the respective downstreams. When the downstream are unresponsive for sometime Zuul stops forwarding the requests, it does not forward the request when the downstream is up again.

There are no errors in the logs.

package com.uk.proxy.filter;

import ai.cuddle.sift.dataapi.proxy.Application;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ROUTE_TYPE;

@Component
public class RoutingFilter extends ZuulFilter {

    private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);

    private static final String DEFAULT_DOWNSTREAM_GROUP = "SYSTEM";
    public static final String HEADER_ORIGIN = "";

    @Autowired
    @Qualifier(value = "downstreamConfig")
    private Map<String, String> downstreamMap;

    @Override
    public String filterType() {
        return ROUTE_TYPE;
    }

    @Override
    public int filterOrder() {
        return FilterConstants.PRE_DECORATION_FILTER_ORDER - 100;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String inputURI = request.getRequestURI();
        String header = request.getHeader(HEADER_ORIGIN);
        try {
            String downstreamHost = getDownstreamHost(header);
            LOGGER.info(" Header "+header+ " Downstream Host "+downstreamHost);

            ctx.setRouteHost(new URL(downstreamHost));
            ctx.put("requestURI", inputURI);
        } catch (MalformedURLException e) {
            LOGGER.error(e.getMessage(), e);
        }
        return null;

    }

    private String getDownstreamHost(String header) {

        if(header == null || header.isEmpty()){
            LOGGER.warn("Header is null or empty");
        }

        String downstreamGroup = (header == null || header.isEmpty()) ? DEFAULT_DOWNSTREAM_GROUP : header.toUpperCase();

        String downstreamHost;
        if (downstreamMap.containsKey(downstreamGroup)) {
            downstreamHost = downstreamMap.get(downstreamGroup);
        } else {
            LOGGER.error("Header "+header+" not found in config. DownstreamMap "+downstreamMap);
            downstreamHost = downstreamMap.get(DEFAULT_DOWNSTREAM_GROUP);
        }

        return downstreamHost;
    }
}

application.yaml

    zuul:
  ignoredPatterns:
    - /manage/**
  routes:
    yourService:
      path: /**
      stripPrefix: false
      serviceId: customServiceId
  host:
    connect-timeout-millis: 300000
    socket-timeout-millis: 300000
ribbon:
  eureka:
    enabled: false

Spring cloud version: Hoxton.SR8.

Please let me know if anyone has faced this issue.

0 Answers
Related