微服務網關Gateway


微服務網關概述

不同的微服務一般會有不同的網絡地址,而外部客戶端可能需要調用多個服務的接口才能完成一個業務需求,如果讓客戶端直接與各個微服務通信,會有以下的問題:

  • 客戶端會多次請求不同的微服務,增加了客戶端的復雜性
  • 存在跨域請求,在一定場景下處理相對復雜
  • 認證復雜,每個服務都需要獨立認證
  • 難以重構,隨着項目的迭代,可能需要重新划分微服務。例如,可能將多個服務合並成一個或者將一個服務拆分成多個。如果客戶端直接與微服務通信,那么重構將會很難實施

以上這些問題可以借助網關解決。

網關是介於客戶端和服務器端之間的中間層,所有的外部請求都會先經過 網關這一層。也就是說,API 的實現方面更多的考慮業務邏輯,而安全、性能、監控可以交由 網關來做,這樣既提高業務靈活性又不缺安全性,典型的架構圖如圖所示:

優點如下:

  • 安全 ,只有網關系統對外進行暴露,微服務可以隱藏在內網,通過防火牆保護。
  • 易於監控。可以在網關收集監控數據並將其推送到外部系統進行分析。
  • 易於統一認證授權。可以在網關上進行認證,然后再將請求轉發到后端的微服務,而無須在每個微服務中進行認證。
  • 減少了客戶端與各個微服務之間的交互次數

總結:微服務網關就是一個系統,通過暴露該微服務網關系統,方便我們進行相關的鑒權,安全控制,日志統一處理,易於監控的相關功能。

實現微服務網關的技術有很多,

  • nginx Nginx (engine x) 是一個高性能的HTTP反向代理web服務器,同時也提供了IMAP/POP3/SMTP服務
  • zuul ,Zuul 是 Netflix 出品的一個基於 JVM 路由和服務端的負載均衡器。
  • spring-cloud-gateway, 是spring 出品的 基於spring 的網關項目,集成斷路器,路徑重寫,性能比Zuul好。

我們使用gateway這個網關技術,無縫銜接到基於spring cloud的微服務開發中來。

gateway官網:

https://spring.io/projects/spring-cloud-gateway

微服務網關微服務搭建

由於我們開發的系統 有包括前台系統和后台系統,后台的系統給管理員使用。那么也需要調用各種微服務,所以我們針對管理后台搭建一個網關微服務。分析如下:

搭建步驟:

(1)在changgou_gateway工程中,創建changgou_gateway_system工程,pom.xml:

       <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

(2)創建包com.changgou.system, 創建引導類:GatewayApplication

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

(3)在resources下創建application.yml

spring:
  application:
    name: sysgateway
  cloud:
    gateway:
      routes:
      - id: goods
        uri: lb://goods
        predicates:
        - Path=/goods/**
        filters:
        - StripPrefix= 1
      - id: system
        uri: lb://system
        predicates:
        - Path=/system/**
        filters:
        - StripPrefix= 1
server:
  port: 9101
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:6868/eureka
  instance:
    prefer-ip-address: true

參考官方手冊:

https://cloud.spring.io/spring-cloud-gateway/spring-cloud-gateway.html#_stripprefix_gatewayfilter_factory

微服務網關跨域

修改application.yml ,在spring.cloud.gateway節點添加配置

      globalcors:
        cors-configurations:
          '[/**]': # 匹配所有請求
            allowedOrigins: "*" #跨域處理 允許所有的域
            allowedMethods: # 支持的方法
            - GET
            - POST
            - PUT
            - DELETE

最終配置文件如下:

spring:
  application:
    name: sysgateway
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]': # 匹配所有請求
            allowedOrigins: "*" #跨域處理 允許所有的域
            allowedMethods: # 支持的方法
            - GET
            - POST
            - PUT
            - DELETE
      routes:
      - id: goods
        uri: lb://goods
        predicates:
        - Path=/goods/**
        filters:
        - StripPrefix= 1
server:
  port: 9101
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:6868/eureka
  instance:
    prefer-ip-address: true

微服務網關過濾器

我們可以通過網關過濾器,實現一些邏輯的處理,比如ip黑白名單攔截、特定地址的攔截等。下面的代碼中做了兩個過濾器,並且設定的先后順序,只演示過濾器與運行效果。(具體邏輯處理部分學員實現)

(1)changgou_gateway_system創建IpFilter

@Component
public class IpFilter implements GlobalFilter, Ordered {
​
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
​
        System.out.println("經過第1個過濾器IpFilter");
        ServerHttpRequest request = exchange.getRequest();
        InetSocketAddress remoteAddress = request.getRemoteAddress();
        System.out.println("ip:"+remoteAddress.getHostName());
        return chain.filter(exchange);
    }
​
    @Override
    public int getOrder() {
        return 1;
    }
}

(2)changgou_gateway_system創建UrlFilter

@Component
public class UrlFilter implements GlobalFilter, Ordered {
​
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("經過第2個過濾器UrlFilter");
        ServerHttpRequest request = exchange.getRequest();
        String url = request.getURI().getPath();
        System.out.println("url:"+url);
        return chain.filter(exchange);
    }
​
    @Override
    public int getOrder() {
        return 2;
    }
}

測試,觀察控制台輸出。


免責聲明!

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



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