八:Spring Cloud 之服務路由網關-zuul

1. 簡介

Zuul is the front door for all requests from devices and web sites to the backend of the Netflix streaming application. As an edge service application, Zuul is built to enable dynamic routing, monitoring, resiliency and security. It also has the ability to route requests to multiple Amazon Auto Scaling Groups as appropriate.


Zuul 是在雲平臺上提供動態路由,監控,彈性,安全等邊緣服務的框架。Zuul 相當於是設備和 Netflix 流應用的 Web 網站後端所有請求的前門。

2. 代碼實現

2.1涉及的模塊及關係圖譜

2.1.1 涉及的模塊

  • eureka-server-singleton:服務註冊中心,端口8761
  • eureka-service: 服務提供者,通過profile指定不同端口模擬一組微服務,端口8762、8763
  • eureka-service-feign:通過Feign調用服務提供者提供的服務
  • eureka-service-ribbon:通過Feign調用服務提供者提供的服務
  • eureka-service-zuul:服務路由功能,實現請求路由,網關功能

2.1.2 模塊關係圖譜

模塊關係圖

2.2 源代碼

2.2.1 Github地址

https://github.com/andyChenHuaYing/spring-cloud-demo

2.2.2 切換

通過tag切換git tag -d v1.0,若想修改,可根據此tag創建新的分支。

2.3 eureka-server-singleton

Spring Cloud 之服務發現與調用-Ribbon#2.3 eureka-server-singleton 沒有任何區別

2.4 eureka-service

Spring Cloud 之服務發現與調用-Ribbon#2.4 eureka-service 沒有任何區別

2.5 eureka-service-feign

五:Spring Cloud 之服務發現與調用-Feign#2.5 eureka-service-feign沒有任何區別

2.6 eureka-service-ribbon

四:Spring Cloud 之服務發現與調用-Ribbon#2.5 eureka-service-ribbon 沒有任何區別

2.7 eureka-service-zuul

2.7.1 整體實現

  1. pom.xml中引入spring-cloud-starter-netflix-eureka-clientspring-cloud-starter-netflix-zuul依賴
  2. application.yml中指定配置項
    1. 端口:8768
    2. 應用名稱:eureka-serivce-zuul
    3. 指定路由規則:
      1. /api-ribbon/**請求轉發到eureka-service-ribbon處理
      2. /api-feign/**請求轉發到eureka-serivce-feign處理
  3. SpringBoot 啓動類添加啓用Zuul的註解@EnableZuulProxy
  4. 添加繼承ZuulFilter的Filter,並指定filterType實現請求過濾
  5. 根據路由規則訪問訪問API網關,觀察請求是否正確傳遞到真正服務提供者處理並返回

2.7.2 pom.xml

<?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">
    <parent>
        <artifactId>spring-cloud-finchley-demo</artifactId>
        <groupId>org.oscar.scd</groupId>
        <version>1.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>eureka-service-zuul</artifactId>

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

2.7.3 application.yml

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

server:
  port: 8768

spring:
  application:
    name: eureka-serivce-zuul

zuul:
  routes:
    api-ribbon:
      path: /api-ribbon/**
      serviceId: eureka-service-ribbon
    api-feign:
      path: /api-feign/**
      serviceId: eureka-serivce-feign

2.7.4 EurekaServiceZuulApplication

package org.oscar.scd.eureka.service.ribbon.zuul;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@EnableZuulProxy
@EnableEurekaClient
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaServiceZuulApplication {

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

2.7.5 PreFilter

使用了lombok插件,IDEA需要安裝一下lombok插件。見補充部分
package org.oscar.scd.eureka.service.ribbon.zuul.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;

@Slf4j
@Service
public class PreFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        return "yes".equals(request.getParameter("shouldFilter"));
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String token = request.getParameter("token");
        log.info("Token:{}", token);
        return null;
    }
}

3. 驗證

3.1 創建SpringBoot啓動類

3.1.1 EurekaServerSingletonApplication

四:Spring Cloud 之服務發現與調用-Ribbon#3.1.1 EurekaServerSingletonApplication 完全一致

3.1.2 EurekaServiceApplication-8762

四:Spring Cloud 之服務發現與調用-Ribbon#3.1.2 EurekaServiceApplication-8762 完全一致

3.1.3 EurekaServiceApplication-8763

四:Spring Cloud 之服務發現與調用-Ribbon#3.1.3 EurekaServiceApplication-8763完全一致

3.1.4 EurekaServiceFeignApplication

最簡單的方式添加一個SpringBoot啓動類型的啓動類就行。

3.1.5 EurekaServiceRibbonApplication

最簡單的方式添加一個SpringBoot啓動類型的啓動類就行。

###3.1.6 EurekaServiceZuulApplication
最簡單的方式添加一個SpringBoot啓動類型的啓動類就行。

3.2 啓動

  • EurekaServerSingletonApplication
  • EurekaServiceApplication-8762
  • EurekaServiceApplication-8763
  • EurekaServiceFeignApplication
  • EurekaServiceRibbonApplication
  • EurekaServiceZuulApplication

啓動完成後Run Dashboard界面:
這裏寫圖片描述

3.3 訪問服務信息界面

這裏寫圖片描述

3.4 調用服務

3.4.1 訪問 /api-ribbon/


這裏寫圖片描述

3.4.2 訪問 /api-feign/


這裏寫圖片描述

3.4.3 驗證過濾器生效

3.4.3.1 不生效

訪問:http://localhost:8768/api-ribbon/ribbon/print?name=oscar&shouldFilter=no

這裏寫圖片描述

3.4.3.2 生效

訪問:http://localhost:8768/api-ribbon/ribbon/print?name=oscar&shouldFilter=yes

這裏寫圖片描述

4. 思考

  • zuul過濾器使用場景
  • 如何做分流
  • 能不能動態指定路由規則
  • 處理請求的整體流程
  • 如何做高可用

5. 補充

5.1 資料

5.2 Zuul的Filter類型

  • pre:可以在請求被路由之前調用
  • route:在路由請求時候被調用
  • post:在route和error過濾器之後被調用
  • error:處理請求時發生錯誤時被調用

5.2 lombok插件安裝

打開IDEA的settings,按下圖所示搜索並安裝Lombok Plugin:
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章