Services Gateway Spring Cloud Zuul

Spring Cloud Zuul

Development environment

  • idea 2019.1.2
  • jdk1.8.0_201
  • Spring Boot 2.1.9.RELEASE
  • Spring Cloud Greenwich SR3

Zuul Introduction

Zuul is a Netflix developed to provide dynamic routing, monitoring, flexible, secure gateway services, he can and Eureka, Ribbon, Hystrix and other components used in conjunction. It can also provide support for checking the filter by creating a filter, so that the micro-service applications and more focus on developing business logic.

The benefits of using Zuul gateway service is to bring out a unified system provides REST API, and additionally provides access control, load balancing and other functions, and these functions are pulled out from the original service and there is a separate.

Zuul offers different types of filter for processing the request, the filter allows us to achieve the following functions

  • And reject the request information for identifying the authentication condition is not satisfied may be required: access control and security
  • Monitoring: Monitoring request information
  • Dynamic routing: request to the background of different service clusters as needed dynamically route
  • Stress Test: the flow rate is gradually increased to the cluster, for performance evaluation
  • Load balancing: the capacity to allocate for each type of request and discards the request exceeds limit
  • Limiting
  • Black and white list filtering
  • Static resource handling: directly in response zuul dealing with static resources without the need to forward the request to the internal cluster

filter

ZuulFilter is a base abstract class defines the abstract methods

  • filterType method: filter types, there are "pre", "route", "post", "error", "static"
    • pre: performed before the request is routed
    • route: executed when the request is routed
    • post: performed after the request is routed
    • error: error occurred when requesting execution
    • static: Special Filter can be seen particularly StaticResponseFilter, which allows the generation of a response from the Zuul itself, instead of forwarding the request to the source
  • filterOrder Method: the priority, the higher the level, the faster is performed (smaller value indicates a higher level)

  • shouldFilter method: switch, if it is true, run method will be executed, or not executed

  • run method: filter logic operations performed

Code

1. Create a service registry

Creating zuul-eureka-server project, the introduction of eureka-server-dependent, you can view the complete source project: the Spring Cloud Zuul sample source code

The following paragraphs paste the key code

pom add dependencies

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

Start class increase @EnableEurekaServer comment

@EnableEurekaServer
@SpringBootApplication
public class ZuulEurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ZuulEurekaServerApplication.class, args);
    }
}

yml Configuration

server:
  port: 8761

spring:
  application:
    name: zuul-eureka-server

eureka:
  instance:
    hostname: localhost   # eureka 实例名称
  client:
    register-with-eureka: false # 不向注册中心注册自己
    fetch-registry: false       # 是否检索服务
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/  # 注册中心访问地址

2. Create a service provider 1

Creating zuul-server-provider program, the introduction of eureka-client-dependent, you can view the complete source project: the Spring Cloud Zuul sample source code

The following paragraphs paste the key code

pom add dependencies

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

Write HelloController Service

@RestController
@Slf4j
public class HelloController {

    @RequestMapping("/hello")
    public String index(@RequestParam String name) {
        log.info("request one  name is " + name);
        return "hello " + name + ",this is first messge";
    }
}

Start class increase @EnableDiscoveryClient comment

@SpringBootApplication
@EnableDiscoveryClient
public class ZuulServerProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(ZuulServerProviderApplication.class, args);
    }
}

yml Configuration

spring:
  application:
    name: zuul-server-provider
server:
  port: 9000
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka

3. Create a service provider 2

Creating zuul-server-provider2 project, the introduction of eureka-client dependency with other service providers 1 project, the project can view the complete source code: the Spring Cloud Zuul sample source code

The difference of the code posted

Write the service, to do service degradation test here, set up a long dormant period for the current thread

@RestController
@Slf4j
public class HelloController {
    @RequestMapping("/hello")
    public String index(@RequestParam String name) {
        log.info("request two name is " + name);
        try{
            //为做服务降级测试,设置一个超长休眠时间,故意导致该服务访问超时
            Thread.sleep(1000000);  
        }catch ( Exception e){
            log.error(" hello two error",e);
        }
        return "hello " + name + ",this is two messge";
    }
}

4. Create zuul Services Gateway

Creating zuul-server-gateway project, the introduction of netflix-zuul and eureka-client-dependent, you can view the complete source project: the Spring Cloud Zuul sample source code

The following paragraphs paste the key code

pom.xml configuration

        <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>

Create a filter TokenFilter.java

package com.easy.zuulServerGateway.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import javax.servlet.http.HttpServletRequest;

@Slf4j
public class TokenFilter extends ZuulFilter {

    @Override
    public String filterType() {
        //可以在请求被路由之前调用
        return "pre";
    }

    @Override
    public int filterOrder() {
        //filter执行顺序,通过数字指定 ,优先级为0,数字越大,优先级越低
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        //是否执行该过滤器,此处为true,说明需要过滤
        return true;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();

        log.info("--->>> TokenFilter {},{}", request.getMethod(), request.getRequestURL().toString());

        //获取请求的参数
        String token = request.getParameter("token");

        if (StringUtils.isNotBlank(token)) {
            //对请求进行路由
            ctx.setSendZuulResponse(true);
            ctx.setResponseStatusCode(200);
            ctx.set("isSuccess", true);
            return null;
        } else {
            //不对其进行路由
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(400);
            ctx.setResponseBody("token is empty");
            ctx.set("isSuccess", false);
            return null;
        }
    }
}

Creating zuul-server-provider services corresponding fuse (fuse here for the entire service, can do to deal with a single service interface fuse), ProviderFallback.java

package com.easy.zuulServerGateway.fallback;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

@Slf4j
@Component
public class ProviderFallback implements FallbackProvider {

    @Override
    public String getRoute() {
        return "zuul-server-provider";
    }

    @Override
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        if (cause != null) {
            String reason =cause.getMessage();
            log.info("Excption {}", reason);
        }
        return fallbackResponse();
    }

    public ClientHttpResponse fallbackResponse() {
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode() {
                return HttpStatus.OK;
            }

            @Override
            public int getRawStatusCode() {
                return 200;
            }

            @Override
            public String getStatusText(){
                return "OK";
            }

            @Override
            public void close() {

            }

            @Override
            public InputStream getBody() {
                return new ByteArrayInputStream("The service is unavailable.".getBytes());
            }

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

yml Configuration

spring:
  application:
    name: zuul-service-gateway
server:
  port: 8888

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka

  #是否开启重试功能
zuul:
  retryable: true
  #对当前服务的重试次数
ribbon:
  MaxAutoRetries: 2
  #切换相同Server的次数
  MaxAutoRetriesNextServer: 0

Increase @EnableZuulProxy startup class notes, to start the service gateway
ZuulServerGatewayApplication.java

package com.easy.zuulServerGateway;

import com.easy.zuulServerGateway.filter.TokenFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableZuulProxy
public class ZuulServerGatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(ZuulServerGatewayApplication.class, args);
    }

    @Bean
    public TokenFilter tokenFilter() {
        return new TokenFilter();
    }
}

First, an example of the four service is created, then run the sample see the effects

use

Four existing projects are as follows

zuul-eureka-server: service registry, service name: zuul-eureka-server, port: 8761
Zuul-Server-Provider: Service Provider 1. Service Name: zuul-server-provider, port: 9000
Zuul-Server-Provider2 are : service providers, service name: zuul-server-provider, port: 9001
Zuul-Server-gateway: gateway service, service name: zuul-server-gateway, port: 8888

Run the test

Respectively start zuul-eureka-server, zuul-server-gateway, zuul-server-provider three services

  • Access address: http: // localhost:? 8888 / zuul-server-provider / hello name = yuntian, return: token is empty, the request is intercepted returned.
  • Access address: http: // localhost:? 8888 / zuul-server-provider / hello name = yuntian & token = xx, return: hello yuntian, this is first messge, indicating that the request normal response.

Start zuul-server-provider2

  • Many visits to http: // localhost: 8888 / zuul-server-provider / hello name = yuntian & token = xx, this time will alternate return?
hello yuntian,this is first messge
The service is unavailable
...

As can be seen from the results returned: zuul-server-provider2 project has enabled blown return: The service is unavailable.

data

Guess you like

Origin www.cnblogs.com/tqlin/p/11670884.html