(五)api網關服務 zuul-路由

路由是微服務架構中必須的一部分,好比,「/」 可能映射到你的WEB程序上,」/api/users 「可能映射到你的用戶服務上,「/api/shop」可能映射到你的商品服務商。(註解:我理解這裏的這幾個映射就是說經過Zuul這個網關把服務映射到不一樣的服務商去處理,從而變成了微服務!)java

這裏只列舉zuul一些配置,headers,client等等不作考慮。web

經過Zuul咱們能夠完成如下功能:正則表達式

  • 動態路由
  • 監控與審查
  • 身份認證與安全
  • 壓力測試: 逐漸增長某一個服務集羣的流量,以瞭解服務性能;
  • 金絲雀測試
  • 服務遷移
  • 負載剪裁: 爲每個負載類型分配對應的容量,對超過限定值的請求棄用;
  • 靜態應答處理

構建網關

在Idea裏,新建項目,選擇Spring initializer.spring

 

下面的pomapi

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

  

配置properties文件參數;瀏覽器

server.port=8887

spring.application.name=zuul-proxy

eureka.client.service-url.defaultZone=http://localhost:8882/eureka

 

啓動類以下:安全

@EnableZuulProxy	// 啓動Zuul的路由服務
@SpringBootApplication
public class SpringCloundZuulDemoApplication {

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

  

代碼基本編寫完成,下面咱們來啓動項目;Eureka,service-hello(兩個 + 一個實例),最後啓動zuul-proxy;架構

 

瀏覽器輸入:(可見,zuul也實現了負載均衡)app

 

 可見,zuul-proxy已經幫咱們路由到相應的微服務。負載均衡

自定義微服務訪問路徑

zuul.routes.service-hello = /hello/**
zuul.routes.service-hello-2 = /hello2/**

所要配置的路徑能夠指定一個正則表達式來匹配路徑,所以,/hello/*只能匹配一級路徑,可是經過/hello/**能夠匹配全部以/hello/開頭的路徑。

 

忽略指定微服務

配置格式爲: zuul.ignored-services=微服務Id1,微服務Id2...,多個微服務之間使用逗號分隔。

zuul.ignored-services = service-hello-2

可見,自定義路由依舊能夠訪問。

還有其餘形式的路由配置,不在此一一列舉。

 

spring-cloud-starter-zuul自己已經集成了hystrix和ribbon,因此Zuul天生就擁有線程隔離和斷路器的自我保護能力,以及對服務調用的客戶端負載均衡功能。可是,咱們須要注意,當使用path與url的映射關係來配置路由規則時,對於路由轉發的請求則不會採用HystrixCommand來包裝,因此這類路由請求就沒有線程隔離和斷路器保護功能,而且也不會有負載均衡的能力。所以,咱們在使用Zuul的時候儘可能使用path和serviceId的組合進行配置,這樣不只能夠保證API網關的健壯和穩定,也能用到Ribbon的客戶端負載均衡功能。

 咱們來看看zuul是否集成hystrix,在以前feign已經集成了hystrix,這裏很少作說明。

 請注意,Zuul的Hystrix監控的粒度是微服務,而不是某個API,也就是全部通過Zuul的請求都會被Hystrix保護起來。假如,咱們如今把service-hello-2服務關閉,再來訪問會出現什麼結果呢?結果可能不是咱們所想那樣,以下:

那麼如何爲Zuul實現容錯與回退呢?

Zuul提供了一個ZuulFallbackProvider(新版:FallbackProvider接口,經過實現該接口就能夠爲Zuul實現回退功能。那麼讓咱們改造以前的Zuul-proxy

package com.example.zuul.fallback;

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.IOException;
import java.io.InputStream;

/**
 * @author sky.javaweb@qq.com
 * @version 1.0
 * @date 2018-12-28
 */
@Component
public class ServiceFallbackProvider implements FallbackProvider {
    @Override
    public String getRoute() {
        // 代表是爲哪一個微服務提供回退,*表示爲全部微服務提供回退
        return "*";
    }

    @Override
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.OK;
            }

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

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

            @Override
            public void close() {

            }

            @Override
            public InputStream getBody() throws IOException {
                return new ByteArrayInputStream((route + "服務暫不可用,請稍後重試!" + cause.getMessage()).getBytes());
            }

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

 再打開service-hello-2服務接口

相關文章
相關標籤/搜索