springboot~zuul Implementation Gateway

Keywords: Java Spring Redis

The Role of Gateway in Microservices

Gateway is a very important link in the architecture of micro-service. It mainly realizes the unified processing of some functions, including:

  1. Unified authorization
  2. Unified exception handling
  3. Route guidance
  4. Cross domain processing
  5. Current limiting

Practice

1 Adding dependencies

dependencies {
    implementation('org.springframework.cloud:spring-cloud-starter-netflix-eureka-client')
    implementation('org.springframework.cloud:spring-cloud-starter-netflix-zuul')
    testImplementation('org.springframework.boot:spring-boot-starter-test')
    implementation('com.marcosbarbero.cloud:spring-cloud-zuul-ratelimit:1.3.2.RELEASE')
}

2 add yml

server:
  port: 8300
spring:
  application:
    name: microservice-gateway-zuul
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:6761/eureka
  instance:
    ip-address: true

zuul:
 routes:
    users:
       path: /lind/** #The path starting with lind is redirected to lind service
       serviceId: lind
 add-host-header: true #Display real http headers
 retryable: false #Turn off the retry function of Hystrix
 ratelimit:
    enabled: true
   #  repository: REDIS
    behind-proxy: true
    policies:
       users:
         limit: 5 #Limit current, request 5 times per minute
         refresh-interval: 60
         type:
           - user
           - origin
           - url
         #       url-type current limiting is distinguished by request path
         #       origin is distinguished by client IP address
         #       user is differentiated by authorized users, including anonymous users

3 Add implementation code
http interceptor, get user ID, transfer for sub-service

public class PreRequestLogFilter extends ZuulFilter {
  private static final Logger logger = LoggerFactory.getLogger(PreRequestLogFilter.class);
  private final RateLimiter rateLimiter = RateLimiter.create(1000.0);

  @Override
  public Object run() {

    try {
      RequestContext currentContext = RequestContext.getCurrentContext();
      HttpServletResponse response = currentContext.getResponse();
      HttpServletRequest reqeust = currentContext.getRequest();

      currentContext.addZuulRequestHeader("userId","123");//Write data to subsystem http header
      currentContext.addZuulRequestHeader("userName","test");

      PreRequestLogFilter.logger.info(
          String.format("send %s request to %s",
              reqeust.getMethod(),
              reqeust.getRequestURL().toString()));

      if (!rateLimiter.tryAcquire()) {
        HttpStatus httpStatus = HttpStatus.TOO_MANY_REQUESTS;
        response.setContentType(MediaType.TEXT_PLAIN_VALUE);
        response.setStatus(httpStatus.value());
        response.getWriter().append(httpStatus.getReasonPhrase());
        currentContext.setSendZuulResponse(false);
        throw new ZuulException(
            httpStatus.getReasonPhrase(),
            httpStatus.value(),
            httpStatus.getReasonPhrase()
        );
      }
    } catch (java.lang.Exception e) {
      ReflectionUtils.rethrowRuntimeException(e);
    }
    return null;

  }

  @Override
  public boolean shouldFilter() {

    // Determine whether filtering is necessary
    return true;

  }


  @Override

  public String filterType() {

    return FilterConstants.PRE_TYPE;

  }


  @Override

  public int filterOrder() {

    return Ordered.HIGHEST_PRECEDENCE;

  }


}

Inject this filter into the process

  @Bean
  public PreRequestLogFilter preRequestLogFilter() {
    return new PreRequestLogFilter();
  }

4 use it
Under the home controller of lind service through localhost:8300/users/home on the URL, the key pairs userid and username are written on the http header.

Posted by gaspower on Wed, 30 Jan 2019 12:54:15 -0800