1. 程式人生 > >SpringCloud之閘道器Zuul的使用以及簡介

SpringCloud之閘道器Zuul的使用以及簡介

說明:

Spring Cloud Zuul是SpringClud的閘道器,我們知道,閘道器一般是應用的入口,做一些公共的和業務無關的校驗工作,例如加驗籤、加解密等一些操作,而zuul作為微服務的閘道器,有如下原因:

1、作為系統的統一入口,遮蔽了微服務內部的實現細節;

2、與服務治理框架相結合(例如:Eureka),實現自動化的例項維護、以及負載均衡的路由轉發;

3、實現介面的校驗與微服務業務邏輯的解耦;

4、通過zuul中的各種過濾器,在各生命週期去校驗請求內容,將原本對外服務層做的校驗前移,保證了微服務的無狀態性,同時降低了微服務的測試難度,讓微服務更加關注本身的業務邏輯的處理;

好了,接下來我們開始一個zuul閘道器服務:

一、引入zuul的pom以來:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.ck.springcloud</groupId>
    <artifactId>hello-service-api</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.7.RELEASE</version>
        <relativePath/>
    </parent>

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

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Brixton.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>


</project>

因為Zuul要結合Eureka使用,所以也要引入Eureka的依賴,下面會講解Zuul怎麼和Eureka的結合使用;

二、增加啟動類,增加Zuul的啟動配置註解@EnableZuulProxy:

package controller;

import com.netflix.zuul.FilterLoader;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableZuulProxy
@EnableConfigurationProperties(FilterConfiguration.class)
public class Application {
    FilterConfiguration filterConfiguration;

    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).run(args);

    }

    @Bean
    public AccessFilter getAccessFilter(){
        return new AccessFilter();
    }


    @Bean
    public FilterConfiguration filterLoader(FilterConfiguration filterConfiguration){
        this.filterConfiguration = filterConfiguration;
        System.out.println(filterConfiguration.getInterval()+filterConfiguration.getRoot());
        return filterConfiguration;
    }
}

三、增加配置檔案application.yml檔案:

spring:
  application:
    name: api-gateway
server:
  port: 5555
eureka:
  client:
    serviceUrl:
        defaultZone: http://localhost:1111/eureka/
zuul:
  routes:
    api-a:
      path: /api-a/**
      url: http://localhost:8080
    api-b:
      path: /api-b/**
      serviceId: feign-consumer
  AccessFilter:
    pre:
      disable:  true
zuuls:
  filter:
     root: filter
     interval: 5

在上面的配置中,我們配置了2個路由規則:

1、是/api-a/**的請求都會轉發到http://localhost:8080

2、/api-b/**的請求都會通過Ribbon負載均衡隨機轉發到微服務名feign-consumer(通過與Eureka註冊中心結合,動態的獲取所有微服務例項)的例項上;

通過簡單的配置,現在一個簡單的Spring Cloud Zuul閘道器就實現了!

Zuul中還可以增加過濾器,在轉發請求到微服務之前做攔截過濾,實現過濾器很簡單,只要整合ZuulFilter父類;

例子:

package controller;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;

import javax.servlet.http.HttpServletRequest;

public class AccessFilter extends ZuulFilter {

    //表明這是一個前置過濾器,在轉發到微服務之前執行
    @Override
    public String filterType() {
        return "pre";
    }

    //多個過濾器之前,通過返回的order判斷過濾器的執行順序
    @Override
    public int filterOrder() {
        return 0;
    }

   //這個過濾器是否執行,true表示執行
    @Override
    public boolean shouldFilter() {
        return true;
    }


    //具體的攔截執行邏輯,過去邏輯是如果請求引數中沒有accessToken就攔截此次請求
   //否則通過
    @Override
    public Object run() {
        System.out.println("access token start");
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest httpServletRequest = requestContext.getRequest();
        Object accessToken = httpServletRequest.getParameter("accessToken");
        if(accessToken == null){
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(401);
            return null;
        }
        System.out.println("access token ok");
        return null;
    }
}

最後別忘記了,在Application啟動類中將AccessFilter註冊成bean:

    @Bean
    public AccessFilter getAccessFilter(){
        return new AccessFilter();
    }