【Spring Cloud】Spring Cloud服務網關Spring Cloud Zuul

Zuul作爲微服務系統的網關組件,用於構建邊界服務(Edge Service),致力於動態路由、過濾、監控、彈性伸縮和安全。其在微服務架構中有着重要的作用,主要體現在以下六個方面:

  • Zull、Ribbon以及Eureka相結合可以實現智能路由和負載均衡的功能,Zull可以按照某種策略將請求分發到不同的實例上;
  • 網關作爲邊界服務,將內部服務的API接口進行聚合並統一對外暴露接口。保護內部服務的API接口,防止內部服務被外界調用泄露敏感信息;
  • 網關可以對用戶的身份權限進行認證,防止非法請求API接口;
  • 網關可以實現監控功能,實時日誌輸出,對請求進行記錄;
  • 網關可以用來實現流量監控,在高流量的情況下,對服務進行降級;
  • API接口從內部服務分離出來,便於測試

 

springBoot使用的是2.0.2.RELEASE版本 springCloud使用的是Finchley.RELEASE版本。


                <dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-config</artifactId>
		</dependency>
		<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>

配置文件

zuul:
  routes:
  # /myProduct/product/list -> /product/product/list
  #aaaaa 表示這個名字可以隨便寫,下面是簡潔的寫法
    aaaaa: 
      path: /myProduct/**
      serviceId: product
      
  #簡潔寫法
#    product: /myProduct/**

啓動類

@SpringBootApplication
@EnableZuulProxy
public class ApiGatewayApplication {

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

 

面向服務的路由 

Spring Cloud Zuul 與 Spring Cloud Eureka 可以實現無縫對接實現面向服務的路由。我們讓路由的path映射到具體的服務上,而具體的url交由Eureka的服務發現機制去自動維護。面向服務的路由默認實現了負載均衡。

 

商品服務原來的訪問地址是:http://localhost:8080/product/list

使用zuul網關也可以實現路由功能:http://localhost:8002/product/product/list或者http://localhost:8002/myProduct/product/list

都可以進行服務的訪問。

其中productmyProduct(自定義)爲微服務的名稱,可以任意定義。根據配置從註冊中心拿到真實的路由地址。

/product/list 表示的是服務的真實的請求地址。

 

由於默認情況下所有Eureka上的服務都會被Zuul自動創建映射關係進行路由,這會使得一些我們不希望對外開放的服務也被外部訪問到。這個時候我們可以配置zuul.ignored-services參數來設置一個服務名匹配表達式進行判斷,如果服務名匹配表達式,那麼Zull將跳過這個服務,不爲其創建路由規則。例如:zuul.ignored-services=*表示對所有的服務不自動創建路由規則,這樣我們就需要爲每個服配置路由規則。

#排除某些路由
#  ignored-patterns:
#    - /**/product/listForOrder 

 

Zuul的過濾器

Zull有請求過濾的功能,其過濾器可以在Http請求的發起和響應返回期間執行一系列的過濾器。Zuul包擴以下四種過濾器:

  • PRE: 該類型的filters在Request routing到源web-service之前執行。可以進行一些權限認證,日誌記錄,或者額外給Request增加一些屬性供後續的filter使用;
  • ROUTING:該類型的filters用於把Request routing到源web-service,源web-service是實現業務邏輯的服務。這裏使用HttpClient請求web-service;
  • POST:該類型的filters在ROUTING返回Response後執行。用來實現對Response結果進行修改,收集統計數據以及把Response傳輸會客戶端;
  • ERROR:上面三個過程中任何一個出現錯誤都交由ERROR類型的filters進行處理。

Zuul過濾器具有以下關鍵特性:

  • Type(類型):Zuul過濾器的類型,這個類型決定過濾器在哪個階段執行,例如:pre,post等階段;
  • Execution Order(執行順序):規定了過濾器的執行順序,Order的值越小,越先執行;
  • Criteria(標準):Filters執行所需條件
  • Action(行動):如果符合執行條件,則執行Action(具體邏輯代碼)

Zuul請求的生命週期如圖所示:

 

 

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

@Component
public class TokenFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return PRE_DECORATION_FILTER_ORDER - 1;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();

        //這裏從url參數裏獲取, 也可以從header裏獲取
        String token = request.getParameter("token");
        if (StringUtils.isEmpty(token)) {
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
            requestContext.setResponseBody("token is undefined...");
        }
        return null;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章