1. 程式人生 > >Spring Cloud (12) 服務網關-基礎

Spring Cloud (12) 服務網關-基礎

avi 邏輯 版本 安全 微服務 內部 [] OS 存在

通過前幾篇介紹,已經可以構建一個簡單的微服務架構了,如下圖:

技術分享圖片

通過eureka實現服務註冊中心以及服務註冊發現,通過ribbon或feign實現服務的消費以及負載均衡,通過spring cloud config實現了應用多環境的外部配置以及版本管理。為了集群更為健壯使用了Hystrix的隔斷機制來避免微服務架構中個別服務出現異常而引起的雪崩。

在該架構中,我們的服務集群包含內部服務Service A和Service B,他們都會註冊到eureka server,而open service 是一個對外的服務,通過負載均衡公開到服務調用方。

這樣的架構存在的不足:

  首先,破壞了服務無狀態特點,為了保證對外服務的安全性,我們需要實現對服務訪問的權限控制,而開放服務的權限控制機制將會貫穿並汙染整個開放服務的業務邏輯,者會帶來最直接的問題是,破壞了服務集群中REST API無狀態的特點。從具體開發和測試的角度來說,在工作中除了要考慮實際的業務之外,還需要額外可續對接口訪問的控制處理。

  其次,無法直接復用既有接口,當我們需要對一個既有的集群內訪問接口,實現外部服務訪問時,我們不得不通過在原有接口上增加校驗邏輯,或增加一個代理調用來實現權限控制,無法直接復用原有接口。

為了解決上面這些問題,我們需要將權限控制這樣的東西從我們的服務單元中抽離出去,而適合這些邏輯的地方就是處於對外訪問最前端的地方,我們需要一個更強大一些的負載均衡器->服務網關。

服務網關

  服務網關是微服務架構中不可或缺的一部分。通過服務網關統一向外系統提供REST API的過程中,除了具備服務路由、負載均衡功能外,還具備了權限控制等功能。Spring Cloud Netflix中的Zuul就擔任了這樣的一個角色,為微服務架構提供了前門保護的作用,同事還將權限控制這些較重的非業務邏輯內容遷移到服務路由層面,使得服務集群主體能夠具備更高的可復用性和可測試性。

構建服務網關

  創建一個基礎的Spring Boot項目,命名為david-gateway,並在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> <groupId>com.david</groupId> <artifactId>gateway</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>gateway</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</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> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Edgware.SR2</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>

在啟動類中使用@EnableZuulProxy開啟網關功能

@EnableZuulProxy
@SpringBootApplication
public class GatewayApplication {

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

編輯配置文件application.yml

spring:
  application:
    name: david-gateway
server:
  port: 8769
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

啟動eureka、feign、gateway 輸入網址:http://localhost:8769/david-feign/test

發現已經可以執行了 feign中的test方法了。

當我們gateway應用啟動並註冊到eureka之後,服務網關發現我們啟動的feign服務,這時候Zuul就會創建一個路由規則,每個路由規則包含兩部分,一部分是外部請求的匹配規則,另一部分是路由的服務ID,

轉發到feign服務的請求規則為 : /david-feign/**

Spring Cloud (12) 服務網關-基礎