zuul of spring cloud application

Article directory

zuul of spring cloud application

Reading tips

Please read first. hystrix

What is zuul

zuul is a component provided by netflix with routing, filtering and fault-tolerant fallback functions

The routing function is responsible for forwarding external requests to specific microservice instances, which is the basis for the realization of external access uniform entry

The filter function is responsible for intervening the request processing, which is the basis of request verification, service aggregation and other functions

Zuul and Eureka integrate, register zuul as an application under Eureka service governance, and get other micro service messages from Eureka,
That is to say, access to microservices in the future is obtained through Zuul jump.
Note: Zuul service will eventually register with Eureka

Why zuul is needed

We used to visit the user microservice directly before, and then the user microservice calls the order, so it's not safe to expose all the microservices, and it's not convenient for unified management, so zuul is responsible for the entrance of all the microservices. After zuul, all the requests are routed to their microservices by zuul

Single zuul construction

First, build an eureka client project. For suggestions that won't be built, see my previous blog series. My cloud is a special series. Then eureka talks about how to build a project

Start class plus @ EnableZuulProxy
pom file

		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>

yml file

# Service name
spring:
  application:
    name: zuul
# Service port number
server:
  port: 8200
#Eureka related configuration
eureka:
  instance:
    instance-id: zuul
    prefer-ip-address: true
  client:
    service-url:
      defaultZone: http://server7000:7000/eureka,http://server7001:7001/eureka,http://server7002:7002/eureka

zuul:
  #prefix: /api #Prefix access path
  #strip-prefix: false #Prevent api and prefix conflicts on requestMapping
  ignored-services: "*" #Direct access to other microservice clients except zuul
  routes:
    user:
      serviceId: user8100 # serviceId is the application name of user microservice
      path: /user/**
    order:
      serviceId: order
      path: /order/**

After that, we can visit localhost:8200/user/testFeignAndHystrix
routes may not be added, but the access path must be changed to localhost:8200/user8100/testFeignAndHystrix

zuul construction of load balance

If zuul hangs up, the whole cluster will crash, so zuul has to do the cluster
Two more zuul-server-8201 and zuul-server-8202
Modify pom file and startup class
zuul-8200
zuul-server-8201
zuul-server-8202
The three yml files are as follows:

zuul-8200

# Service name
spring:
  application:
    name: zuul
# Service port number
server:
  port: 8200
#Eureka related configuration
eureka:
  instance:
    instance-id: zuul
    prefer-ip-address: true
  client:
    service-url:
      defaultZone: http://server7000:7000/eureka,http://server7001:7001/eureka,http://server7002:7002/eureka

zuul:
  #prefix: /api #Prefix access path
  #strip-prefix: false #Prevent api and prefix conflicts on requestMapping
  ignored-services: "*" #Direct access to other microservice clients except zuul
  routes:
    zuul: #Part of the access path
      serviceId: zuul-server #application name of 8201 and 8202
      path: /**

zuul-server-8201

# Service name
spring:
  application:
    name: zuul-server
# Service port number
server:
  port: 8201
#Eureka related configuration
eureka:
  instance:
    instance-id: zuul-server-1
    prefer-ip-address: true
  client:
    service-url:
      defaultZone: http://server7000:7000/eureka,http://server7001:7001/eureka,http://server7002:7002/eureka

zuul:
  #prefix: /api #Prefix access path
  #strip-prefix: false #Prevent api and prefix conflicts on requestMapping
  ignored-services: "*" #Direct access to other microservice clients except zuul
  routes:
    user:
      serviceId: user8100 # serviceId is the application name of user microservice
      path: /user/**
    order:
      serviceId: order
      path: /order/**

zuul-server-8202

# Service name
spring:
  application:
    name: zuul-server
# Service port number
server:
  port: 8202
#Eureka related configuration
eureka:
  instance:
    instance-id: zuul-server-2
    prefer-ip-address: true
  client:
    service-url:
      defaultZone: http://server7000:7000/eureka,http://server7001:7001/eureka,http://server7002:7002/eureka

zuul:
  #prefix: /api #Prefix access path
  #strip-prefix: false #Prevent api and prefix conflicts on requestMapping
  ignored-services: "*" #Direct access to other microservice clients except zuul
  routes:
    user:
      serviceId: user8100 # serviceId is the application name of user microservice
      path: /user/**
    order:
      serviceId: order
      path: /order/**

Zuul cluster is set up. Visit http://localhost:8200/zuul/user/testFeignAndHystrix

So far, our project is a little complicated. We need to draw a picture to understand

zuul filtering

Filter is zuul's core component. Most of zuul's functions are implemented through filters.
Four standard filter types are defined in zuul, which correspond to the typical life cycle of the request.

PRE: this filter is called before the request is routed. This filter can be used to implement authentication, select requested microservices in the cluster, record debugging information, etc.

ROUTING: this filter routes requests to microservices. This filter is used to build requests to the microservice and use Apache HttpCIient or Netfilx Ribbon to request the microservice

POST: this filter is executed after routing to the microservice. This filter can be used to add standard HTTP headers for responses, collect statistics and metrics, send responses from microservices to clients, and so on.

ERROR: this filter is executed when an ERROR occurs in another phase.

If you want to write a filter, you need to inherit ZuulFilter class to implement its methods:
Just put the following classes in zuul8200

@Component
public class LogFilter extends ZuulFilter {

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override public int filterOrder() {
        return FilterConstants.PRE_DECORATION_FILTER_ORDER+1;
    }

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

    @Override public Object run() throws ZuulException {
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        String remoteAddr = request.getRemoteAddr();
        String url = currentContext.get(FilterConstants.REQUEST_URI_KEY).toString();
        System.out.println("Visitor IP: "+remoteAddr+"Access address:"+request.getRequestURI()+"  Address after routing"+url);
        return null;
    }
}

fault-tolerant

zuul8200 join

@Component
class MyFallbackProvider implements FallbackProvider {

    @Override
    public String getRoute() {
        return "*"; //For all microservices, you can also specify
    }
    //When the time-out or hang up, it's fallbackResponse. The microservice will not enter if it throws an exception. At the beginning, I was stuck here
    @Override
    public ClientHttpResponse fallbackResponse(String route, final Throwable cause) {
        if (cause instanceof HystrixTimeoutException) {
            return response(HttpStatus.GATEWAY_TIMEOUT);
        } else {
            return response(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    private ClientHttpResponse response(final HttpStatus status) {
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return status;
            }

            @Override
            public int getRawStatusCode() throws IOException {
                return status.value();
            }

            @Override
            public String getStatusText() throws IOException {
                return status.getReasonPhrase();
            }

            @Override
            public void close() {
            }

            @Override
            public InputStream getBody() throws IOException {
                return new ByteArrayInputStream("fallback".getBytes());
            }

            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                return headers;
            }
        };
    }
}

Stop the user microservice and visit http://localhost:8200/user/testFeignAndHystrix. It is found that fallback is returned, and Firefox returns json parsing exception, because fallback itself is just a string, just replace it with Google

152 original articles published, 75 praised, 90000 visitors+
Private letter follow

Tags: Spring Load Balance Apache Firefox

Posted on Tue, 10 Mar 2020 01:32:57 -0700 by allspiritseve