Spring Cloud API網關服務 5.2

爲何須要API網關

  經過前面內容的學習,咱們已經能夠構建一個簡單的微服務架構系統。這個系統可使用Spring Boot實現微服務的開發,使用Spring Cloud Eureka實現註冊中心以及服務的註冊與發現,使用Spring Cloud Ribbon實現服務間的負載均衡,使用Spring Cloud Hystrix實現線程的隔離和斷路器功能。經過這些技術,能夠設計出如圖5-11所示的基礎架構。

  在圖5-11中,集羣包含了Service A和Service B兩種服務,它們會向Eureka Server註冊和訂閱服務,Open Service是一個對外的RESTful API服務,客戶端會經過負載均衡技術(如Nginx)實現對Open Service的調用,同時服務之間也會經過Ribbon技術實現服務之間負載均衡的調用。
雖然經過這種方式實現系統功能是沒有問題的,但在實際使用時,客戶端與微服務進行直接的交互仍是存在着一些困難和限制的,具體表現以下。

  1. 增長開發和維護成本
  在大多數狀況下,爲了保證對外服務的安全性,開發人員在服務端實現的服務接口會有必定的權限校驗機制(如用戶登陸狀態校驗等),而且爲了防止客戶端在發起請求時被篡改等安全方面的考慮,還會編寫一些簽名校驗功能。在微服務中,咱們會將原來處於一個應用中的多個模塊拆分紅多個應用服務,而這些拆分出來的應用服務接口也須要原來的校驗邏輯,這就致使咱們不得不在這些應用中所有實現這樣的一套邏輯。隨着微服務規模的不斷擴大,這些校驗邏輯的冗餘將愈來愈多,一旦校驗規則有了變化或者出了問題,咱們將不得不去每個應用中修改這些邏輯。

  2. 微服務重構困難
  隨着時間的推移,咱們可能須要改變系統服務目前的拆分方案(如將兩個服務合併或將一個服務拆分爲多個),但若是客戶端直接與微服務交互,那麼這種重構就很難實施。

  3. 微服務協議限制
  客戶端直接請求的微服務可能使用的是與Web無關的協議。一個服務多是用Thrift的RPC協議,而另外一個服務多是用AMQP消息協議,兩種協議都不是特別適合瀏覽器或防火牆,最好是內部使用。應用應該在防火牆外採用HTTP或者WEBSocket之類的協議。

  因爲上述緣由,客戶端直接與服務器端通訊的方式幾乎不會在實際應用中使用。那麼咱們要如何解決上面這些問題呢?
  一般來講,一個很好的解決辦法就是採用API Gateway(網關)的方式。API Gateway是一個服務器,也能夠說是進入系統的惟一節點,它封裝了內部系統的架構,而且提供了API給各個客戶端。它還能夠有其餘功能,如受權、監控、負載均衡、緩存、請求分片和管理、靜態響應處理等。

 

  圖5-12展現了一個適應當前架構的API Gateway。

  在圖5-12中,API Gateway負責請求轉發、合成和協議轉換。全部來自客戶端的請求都要先通過API Gateway,而後負載均衡這些請求到對應的微服務。
API Gateway的一個最大好處是封裝了應用的內部結構,與調用指定的服務相比,客戶端直接跟Gateway交互會更簡單。API Gateway提供給每個客戶端一個特定API,這樣減小了客戶端與服務器端的通訊次數,也簡化了客戶端代碼。API Gateway還能夠在Web協議與內部使用的非Web協議間進行轉換,如HTTP協議、WebSocket協議。
  API Gateway能夠有不少實現方法,如Nginx、Zuul、Node.js等。本書中使用的是Spring Cloud Netflix中的Zuul,下一小節咱們將對Spring Cloud Zuul的使用進行詳細講解。

如何使用Zuul構建API網關服務

  Zuul原是Netflix公司開發的基於JVM的路由器和服務器端負載均衡器,後來被加入到了Spring Cloud中。Zuul屬於邊緣服務,能夠用來執行認證、動態路由、服務遷移、負載均衡、安全和動態響應處理等操做。
瞭解了Zuul的概念和做用後,接下來經過一個具體的應用案例來說解如何在微服務中使用Zuul。
  本案例主要涉及到3個工程,其做用分別以下。
  ·xcservice-eureka-server工程:服務註冊中心,端口爲8761。
  ·xcservice-eureka-order工程:服務提供者,須要啓動一個訂單實例,其端口號爲7900。
  ·xcservice-gateway-zuul工程:使用Zuul實現的APIGateway,端口號爲8050。
  上面3個工程中,註冊中心和服務提供者可使用前面所建立的工程,而網關服務須要從新建立,其實現過程以下。
  (1)建立工程,添加依賴。在父工程xcservice-spring-cloud下建立子模塊xcservice-gateway-zuul工程,並在其pom.xml中添加eureka和Zuul的依賴,如文件5-8所示。
  文件5-8 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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.xc</groupId>
        <artifactId>xcservice-springcloud</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <groupId>com.xc</groupId>
    <artifactId>xcservice-gateway-zuul</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>xcservice-gateway-zuul</name>
    <description>網關服務</description>

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

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

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

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

</project>

 

  (2)編輯配置文件。在配置文件中編寫Eureka服務實例的端口號、服務端地址等信息,如文件5-9所示。
  文件5-9 application.yml
server:
  port: 8050 # 指定該Eureka實例的端口號

eureka:
  instance:
    prefer-ip-address: true  # 是否顯示主機的IP
    #instance-id: ${spring.cloud.client.ipAddress}:${server.port} #將Status中的顯示內容也以「IP:端口號」的形式顯示
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/ # 指定Eureka服務端地址

spring:
  application:
    name: xcservice-gateway-zuul # 指定應用名稱

zuul:
  routes:
    order-serviceId: # zuul的惟一標識
      path: /order/**   # 須要映射的路徑
      service-id: xcservice-eureka-order  # Eureka中的serviceId

  在上述配置信息中,zuul就是API網關服務的路由配置。其中order-serviceId爲Zuul的惟一標識,能夠任意設置名稱,但必須惟一,若是該值與service-id的名稱相同時,service-id的值能夠省略。path屬性後面的值表示須要映射的路徑,service-id後面的值爲Eureka中的serviceId,應用在運行時,全部符合映射路徑的URL都會被轉發到xcservice-eureka-order中。java

  須要注意的是,Zuul的配置方式有不少,這裏只是針對本案例實現的一種方式。若是讀者想要了解更多的配置方式,能夠參考官方文檔中Zuul的配置進一步學習。spring


  (3)在工程主類Application中使用@EnableZuulProxy註解開啓Zuul的API網關功能,其代碼如文件5-10所示。
package com.xc.xcservicegatewayzuul;

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

/**
 * http://localhost:8050/xcservice-eureka-order/order/1
 */
@EnableZuulProxy
@SpringBootApplication
@EnableEurekaClient
public class XcserviceGatewayZuulApplication {

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

}

 

  (4)分別啓動註冊中心、服務提供者和網關服務後,註冊中心已註冊的服務如圖5-13所示。

  此時能夠經過地址http://localhost:7900/order/1單獨訪問訂單服務   下面經過Zuul來驗證路由功能,經過網關服務來訪問訂單信息。在瀏覽器地址欄中輸入地址http://localhost:8050/xcservice-eureka-order/order/1後,瀏覽器已經顯示出來所要訪問的訂單信息。這說明使用Zuul配置的路由功能已經生效,經過服務ID映射的方式已能夠進行跳轉。 
相關文章
相關標籤/搜索