springcloud的網關zuul概念

前言

本章相對於之前的學習,我們第一是要轉變一個思想概念。

概念

本章的代碼內容並不多,可重要要學習的就只有一個:思想的轉變!!!

爲什麼說是思想的轉變呢?

之前:消費者A對於服務者B而言,消費者A確實是消費者A,因爲是相對而言,消費者A在服務者那裏進行了一個服務的消費,所以消費者A才被稱之爲消費者。消費者A其實也可以是一個服務者A,因爲對於C來說:消費者C也可以在服務者A中進行一個服務的消費。
在這裏插入圖片描述

現在:其實所有的A,B,C相對於zuul網關而言都是一個個擁有自己功能的微服務項目。在現在所有的客戶端可以通過網關來發送請求,而那個請求(ip+端口)
還要加上我們微服務的名字(比如之前的microservice-student)才能指定要訪問的微服務,當然還是要通過服務註冊中心來獲取每一個在註冊中心註冊過的微服務地址。
在這裏插入圖片描述

小結:之前的案例講解中的消費者和服務者實際上都是一個個微服務,都能進行自己模塊的功能提供。每一個微服務之間的資源調用都是像我們之前的案例一樣進行,而如今是zuul網關去調用每一個微服務的資源。

如果不能理解,也就是這樣
在這裏插入圖片描述


zuul的簡單部署

增加一個zuul項目: microservice-zuul-3001

在這裏插入圖片描述

pom.xml增加了:

	 	 <!--zuul網關-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
        </dependency>

全部的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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <!--保持使用版本的一致1.0-SNAPSHOT-->
    <parent>
        <groupId>com.liwangwang</groupId>
        <artifactId>springcloud</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>microservice-zuul-3001</artifactId>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--相當於全局的一個依賴關係,這個導入能確保整個項目使用的包版本一致
            比如全局中的: spring-cloud-dependencies
                           spring-boot-dependencies
                           druid-spring-boot-starter

        -->
        <dependency>
            <groupId>com.liwangwang</groupId>
            <artifactId>microservice-common</artifactId>
        </dependency>
        <!--處理web請求-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--test測試的包-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- actuator監控引入,點擊後的追責 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--添加註冊中心Eureka相關配置,就是說這個是客戶端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <!--Hystrix相關依賴,用來處理服務處理異常情況-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>
        <!--zuul網關-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
        </dependency>
        
        <!-- Hystrix,Feign是基於Hystrix的 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

yml文件的配置

server:
  port: 3001
  context-path: /

spring:
  application:
    name: microservice-zuul

eureka:
  instance:
    instance-id: microservice-zuul:3001 #客戶端實例名稱
    prefer-ip-address: true #是否顯示IP
  client:
    service-url:
      #設置與Eureka註冊中心交互的地址,是所有註冊中心
      defaultZone: http://eureka2001.javawwl.com:2001/eureka/,http://eureka2002.javawwl.com:2002/eureka/,http://eureka2003.javawwl.com:2003/eureka/   #把服務註冊到eureka註冊中心

info:
  groupId: com.liwangwang.springcloud
  artifactId: microservice-zuul-3001
  version: 1.0-SNAPSHOT
  userName: http://www.javawwl.com
  phone: 123456


啓動類:
在這裏插入圖片描述

ok,可以直接輸入:
http://zuul.javawwl.com:3001/microservice-student/student/hystrix
記得要修改host
在這裏插入圖片描述
在這裏插入圖片描述


提高zuul安全措施

1、隱藏真實請求路徑

在yml文件中加上:

zuul:
  routes: # 所有的路由都要配置在這裏
    studentServer.serviceId: microservice-student
    studentServer.path: /studentServer/**
  ignored-services: "*"
  prefix: /javawwl

這樣就行了

在這裏插入圖片描述

那麼我的一個請求就變成了:http://zuul.javawwl.com:3001/javawwl/studentServer/student/hystrix
在這裏插入圖片描述

2、定義過濾規則

在這裏插入圖片描述
AccessFilter

package com.liwangwang.microservicezuul3001.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.log4j.Logger;

import javax.servlet.http.HttpServletRequest;

/**
 * @author 李旺旺
 * @site www.javawwl.com
 * @company
 * @create  2019-04-30 16:05
 */
public class AccessFilter extends ZuulFilter {

    Logger logger=Logger.getLogger(AccessFilter.class);

    /**
     * 判斷該過濾器是否要被執行
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 過濾器的具體執行邏輯
     */
    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String parameter = request.getParameter("accessToken");
        logger.info(request.getRequestURL().toString()+" 請求訪問");
        if(parameter==null){
            logger.error("accessToken爲空!");
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);
            ctx.setResponseBody("{\"result\":\"accessToken is empty!\"}");
            return null;
        }
        //  token判斷邏輯
        logger.info(request.getRequestURL().toString()+" 請求成功");
        return null;
    }

    /**
     * 過濾器的類型 這裏用pre,代表會再請求被路由之前執行
     */
    @Override
    public String filterType() {
        return "pre";
    }

    /**
     * 過濾器的執行順序
     */
    @Override
    public int filterOrder() {
        return 0;
    }

}

ZuulConfig

package com.liwangwang.microservicezuul3001.config;

import com.liwangwang.microservicezuul3001.filter.AccessFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ZuulConfig {

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

那麼請求路徑就爲
http://zuul.javawwl.com:3001/javawwl/studentServer/student/hystrix?accessToken=1

有的時候
在這裏插入圖片描述
沒有的時候
在這裏插入圖片描述

zuul的服務斷路處理

這個有兩種方法:

Zuul作爲服務網關爲了保證自己不被服務拖垮,本身已經集成了Hystrix對路由轉發進行隔離。 爲了方便開發人員對服務短路進行自定義處理,

ZuulFallbackProvider :Zuul 提供了 ZuulFallbackProvider 接口,開發人員可以通過實現該接口來完成自定義Hystrix Fallback

FallbackProvider :Spring Cloud Zuul 提供了 FallbackProvider替代了ZuulFallbackProvider接口。

但是本次本次只使用ZuulFallbackProvider接口來演示
在這裏插入圖片描述

package com.liwangwang.microservicezuul3001.fallback;

import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider;
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.IOException;
import java.io.InputStream;

/**
 * @authorliwangwang
 * @site www.liwangwang.com
 * @company xxx公司
 * @create 2019-11-26 14:18
 */
@Component
public class ZuulFallBack implements ZuulFallbackProvider {

    @Override
    public String getRoute() {
        return "*";
    }

    /**
     * 在給zuul整合回退功能時,只要類實現ZuulFallbackProvider接口,並且註冊bean即可。
     *
     * 不過需要注意的時,這個回退只有服務掉線或者超時的情況下才會觸發(Camden.SR4版本測試是這樣),
     * 如果服務程序出現異常,此回退程序是不能處理的,異常會直接返回給調用者,比如頁面。
     *
     * @return
     */
    @Override
    public ClientHttpResponse fallbackResponse() {
        return new ClientHttpResponse() {
            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON_UTF8);//application/json;charset=UTF-8
                return headers;
            }

            @Override
            public InputStream getBody() throws IOException {
                String msg = "服務繁忙,請稍後";
                //new ByteArrayInputStream("{\"code\":-1,\"msg\":\"服務暫不可用\"}".getBytes(StandardCharsets.UTF_8))
                return new ByteArrayInputStream(msg.getBytes());
            }

            @Override
            public String getStatusText() throws IOException {
                return HttpStatus.BAD_REQUEST.getReasonPhrase();//400
            }

            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.BAD_REQUEST;
            }

            @Override
            public int getRawStatusCode() throws IOException {
                return HttpStatus.BAD_REQUEST.value();//"Bad Request"
            }

            @Override
            public void close() {

            }
        };
    }
}

方法名 說明
getRoute() 該Provider應用的Route ID,例如:testservice,如果設置爲 * ,那就對所有路由生效
fallbackResponse() 快速回退失敗/響應,即處理異常並返回對應輸出/響應內容。

在這裏插入圖片描述

後記

整理整理:
本章的代碼內容並不多,可重要要學習的就只有一個:思想的轉變!!!

爲什麼說是思想的轉變呢?

之前:消費者A對於服務者B而言,消費者A確實是消費者A,因爲是相對而言,消費者A在服務者那裏進行了一個服務的消費,所以消費者A才被稱之爲消費者。消費者A其實也可以是一個服務者A,因爲對於C來說:消費者C也可以在服務者A中進行一個服務的消費。

現在:其實所有的A,B,C相對於zuul網關而言都是一個個擁有自己功能的微服務項目。在現在所有的客戶端可以通過網關來發送請求,而那個請求(ip+端口)
還要加上我們微服務的名字(比如之前的microservice-student)才能指定要訪問的微服務,當然還是要通過服務註冊中心來獲取每一個在註冊中心註冊過的微服務地址。

小結:之前的案例講解中的消費者和服務者實際上都是一個個微服務,都能進行自己模塊的功能提供。每一個微服務之間的資源調用都是像我們之前的案例一樣進行,而如今是zuul網關去調用每一個微服務的資源。

一、 zuul簡單配置

1、 導入pom.xml
2、 配置yml文件
3、 爲啓動類加上註解:@EnableZuulProxy

二、 zuul網關安全措施
1、 改變路由真實路徑

2、 加上過濾條件認證

① 寫好一個AccessFilter extends(實現)ZuulFilter接口
② 實現過濾類的Bean注入(config)

三、 zuul的服務斷路處理
Zuul作爲服務網關爲了保證自己不被服務拖垮,本身已經集成了Hystrix對路由轉發進行隔離。 爲了方便開發人員對服務短路進行自定義處理,
ZuulFallbackProvider :Zuul 提供了 ZuulFallbackProvider 接口,開發人員可以通過實現該接口來完成自定義Hystrix Fallback
FallbackProvider :Spring Cloud Zuul 提供了 FallbackProvider替代了ZuulFallbackProvider接口。

在pom依賴中導入依賴

寫好一個回調類繼承上面的兩個接口之一就行

φ(* ̄0 ̄)這樣就差不多了

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