Spring-Cloud-Netflix-Zuul網關


Spring-Cloud-Netflix-Zuul網關

API網關

  1. API網關,顧名思義,是統一管理API的一個網絡關口、通道,是整個微服務平台所有請求的唯一入口
  2. 所有的客戶端和消費端都通過統一的網關接入微服務,在網關層處理所有的非業務功能
    有網關和沒有網關:
  1. 沒有:沒有網關的時候, 用戶可以隨意訪問一台微服務
  2. 有:有了網關后, 請求必須得要先經過網關, 確定這個請求是否合法,如果合法, zuul會對其做出判斷 , 轉發到指定的微服務,也會自動幫助做負責均衡

Zuul概述

  1. Zuul是Netflix出品的一個基於JVM路由和服務端的負載均衡器(網關)
  2. Zuul包含了對請求的路由和過濾兩個最主要的功能:
  1. 路由功能負責將外部請求轉發到具體的微服務實例上,是實現外部訪問統一入口的基礎
  2. 過濾器功能則負責對請求的處理過程進行干預,是實現請求校驗、服務聚合等功能的基礎
  1. Zuul也作為一個客戶端注冊進Eureka
    將Zuul自身注冊為Eureka服務治理下的應用
    同時從Eureka中獲得其他微服務的消息,也即以后的訪問微服務都是通過Zuul跳轉后獲得。

Zuul使用

1. 在工程當中創建一個網關微服務

在這里插入圖片描述

2. 導入zuul相關依賴

在這里插入圖片描述

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

3.創建啟動類,在啟動類上添加@EnableZuulProxy

在這里插入圖片描述

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

4 .創建application/yml

在這里插入圖片描述

server:
  port: 8001
eureka:
  client:
    serviceUrl:
      #eureka服務端提供的注冊地址 參考服務端配置的這個路徑
      defaultZone: http://eureka:3000/eureka,http://eureka1:3001/eureka,http://eureka2:3000/eureka2
  instance:
    instance-id: zull-0 #此實例注冊到eureka服務端的唯一的實例ID
    prefer-ip-address: true #是否顯示IP地址
    #eureka客戶需要多長時間發送心跳給eureka服務器,表明它仍然活着,默認為30 秒 (與下面配置的單位都是秒)
    leaseRenewalIntervalInSeconds: 1
    #Eureka服務器在接收到實例的最后一次發出的心跳后,需要等待多久才可以將此實例刪除,默認為90秒
    leaseExpirationDurationInSeconds: 3

spring:
  application:
    name: client-zuul #此實例注冊到eureka服務端的name
  1. 啟動 根據zull的端口號+服務名稱 訪問
    在這里插入圖片描述

zuul配置路由

  1. 在zuul的配置文件當中添加如下配置
    在這里插入圖片描述
zuul:
  routes:
    goods: #自己定義的名稱  商品服務
      serviceId: client-goods
      path: /goods/**   #/* 是一級   /** 是多級
    order: #訂單服務
      serviceId: client-order
      path: /order/**

配置完成后,再訪問地址http://localhost:8003/goods/getGoods.do
在這里插入圖片描述

  1. 禁用通過微服務的名稱直接調用
    在這里插入圖片描述
    在這里插入圖片描述
  2. prefix 前綴: 訪問網關時需要加上prefix
    在這里插入圖片描述
    訪問時:http://localhost:8001/api/goods/getGoods.do
    在這里插入圖片描述

過濾器

過濾器(filter)是zuul的核心組件 zuul大部分功能都是通過過濾器來實現的

zuul中定義了4種標准過濾器類型:

  1. PRE
    這種過濾器在請求被路由之前調用。 可利用這種過濾器實現身份驗證、在 集群中選擇請求的微服務、記錄調試信息等。
  2. ROUTING
    這種過濾器將請求路由到微服務。 這種過濾器用於構建發送給微服 務的請求,並使用 Apache HttpCIient或 Netfilx
  3. POST:
    這種過濾器在路由到微服務以后執行。
    這種過濾器可用來為響應添加標准 的 HTTP Header、收集統計信息和指標、將響應從微服務發送給客戶端等
  4. ERROR:
    在其他階段發生錯誤時執行該過濾器。

自定義過濾器: 寫一個類繼承 ZuulFilter類
在這里插入圖片描述

@Component
public class zfilter extends ZuulFilter {
    /*返回過濾器的類型*/
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE; //前置過濾器
    }
    /*返回指定過濾器的執行順序 越小越靠前*/
    @Override
    public int filterOrder() {
        //+1 在此過濾器之后執行
        return FilterConstants.PRE_DECORATION_FILTER_ORDER+1;
    }
    /*判斷該過濾器是否要執行, true表示執行, false表示不執行。*/
    @Override
    public boolean shouldFilter() {
        return true;
    }
    /*過濾器的具體邏輯*/
    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String remoteAddr = request.getRemoteAddr();
        System.out.println("訪問者IP:"+remoteAddr+"訪問地址:"+request.getRequestURI());
        //可以通過strip-prefix: true/false確定是否要移除前綴
        System.out.println("路由后的地址:"+ctx.get(FilterConstants.REQUEST_URI_KEY));
        return null;
    }
}

zuul容錯與回退

zuul默認是整合了hystrix和ribbon的, 提供降級回退,當服務訪問不通的時候,會調用自己提供的方法,是服務級別的

實現步驟:

  1. 編寫一個類,實現FallbackProvider
    在這里插入圖片描述
@Component
public class ZuulFallBackProvider implements FallbackProvider {
    //制定為哪個微服務提供回退(這里寫微服務名 寫*代表所有微服務)
    @Override
    public String getRoute() {
        return "*";
    }

    //此方法需要返回一個ClientHttpResponse對象
    // ClientHttpResponse是一個接口,具體的回退邏輯要實現此接口
    @Override
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        //這里可以判斷根據不同的異常來做不同的處理, 也可以不判斷
        //完了之后調用response方法並根據異常類型傳入HttpStatus
        if (cause instanceof HystrixTimeoutException) {
            return response(HttpStatus.GATEWAY_TIMEOUT);
        } else {
            return response(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    private ClientHttpResponse response(final HttpStatus status) {
        //這里返回一個ClientHttpResponse對象 並實現其中的方法,關於回退邏輯的詳細,便在下面的方法中
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode() throws IOException {
                //返回一個HttpStatus對象 這個對象是個枚舉對象, 里面包含了一個status code 和reasonPhrase信息
                return status;
            }
            @Override
            public int getRawStatusCode() throws IOException {
                //返回status的code  比如 404,500等
                return status.value();
            }
            @Override
            public String getStatusText() throws IOException {
                //返回一個HttpStatus對象的reasonPhrase信息
                return status.getReasonPhrase();
            }
            @Override
            public void close() {
                //close的時候調用的方法, 講白了就是當降級信息全部響應完了之后調用的方法
                System.out.println("close調用");
            }
            @Override
            public InputStream getBody() throws IOException {
                //把降級信息響應回前端
                return new ByteArrayInputStream("系統繁忙,請稍后再試".getBytes());
            }
            @Override
            public HttpHeaders getHeaders() {
                //需要對響應報頭設置的話可以在此設置
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                return headers;
            }
        };
    }
}

zuul集群

新創建創建兩個zuul服務
修改8001的zullsever代理的配置
在這里插入圖片描述
8002的zuul服務端:
在這里插入圖片描述
8003的zull服務
在這里插入圖片描述

開啟所有的服務:
在這里插入圖片描述
在這里插入圖片描述
訪問goods服務:
http://localhost:8002/api/goods/getGoods.do
在這里插入圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM