spring clude ---服務網關組件Netflix Zuul

介紹:服務網關是微服務架構中一個不可或缺的部分。通過服務網關統一向外系統提供REST API的過程中,除了具備服務路由、均衡負載功能之外,它還具備了權限控制等功能。
Zuul是Netflix開源的微服務網關,他可以和Eureka,Ribbon,Hystrix等組件配合使用。Zuul組件的核心是一系列的過濾器,這些過濾器可以完成以下功能:
#身份認證和安全: 識別每一個資源的驗證要求,並拒絕那些不符的請求
#審查與監控:
#動態路由:動態將請求路由到不同後端集羣
#壓力測試:逐漸增加指向集羣的流量,以瞭解性能
#負載分配:爲每一種負載類型分配對應容量,並棄用超出限定值的請求
#靜態響應處理:邊緣位置進行響應,避免轉發到內部集羣

搭建一個Zuul服務網關


1.新建模塊ZuulGateWay,增加所需依賴包
 <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>

注意,eureka-client導包,是:spring-cloud-starter-netflix-eureka-client
不是:spring-cloud-netflix-eureka-client


2.在程序啓動類增加註解@EnableZuulProxy開啓Zuul

@SpringCloudApplication註解,通過源碼我們看到,它整合了@SpringBootApplication、@EnableDiscoveryClient、@EnableCircuitBreaker,主要目的還是簡化配置。

package com.offcn;

import com.offcn.filter.AccessFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;

@SpringCloudApplication //組合註解
@EnableZuulProxy
public class ZuulGatwayStarter {
    public static void main(String[] args) {
        SpringApplication.run(ZuulGatwayStarter.class,args);
    }

    //初始化過濾器爲bean
    @Bean
    public AccessFilter createAccessFilter(){
        return new AccessFilter();
    }
}


3.修改application.yml屬性配置文件
spring:
  application:
    name: ZUULGATEWAY
server:
  port: 80

完成上面的工作後,Zuul已經可以運行了,但是如何讓它爲我們的微服務集羣服務,還需要我們另行配置,下面詳細的介紹一些常用配置內容。



Zuul服務網關路由配置


方式一:通過url直接映射

1.修改項目ZuulGateWay的屬性配置文件application.yml
zuul:
  routes:
    userprovider001:
      path: /userprovider001/**
      url: http://localhost:9003/
    userprovider002:
      path: /userprovider002/**
      url: http://localhost:9004/  

該配置,定義了,所有到Zuul中的規則爲:/userprovider001/**的訪問都映射到http://localhost:9003/上,也就是說當我們訪問http://localhost/userprovider001/的時候,Zuul會將該請求路由到:http://localhost:9003/上
注意:配置屬性zuul.routes.userprovider001.path中的userprovider001部分爲路由的名字,可以任意定義,但是一組映射關係的path和url要相同

2測試url直接映射方式

(測試該服務的某個接口功能)
http://localhost/userprovider001/user/getAll

方式二:通過在Eureka服務註冊的serviceId進行映射

通過url映射的方式對於Zuul來說,並不是特別友好,Zuul需要知道我們所有微服務的地址,才能完成所有的映射配置。而實際上,我們在實現微服務架構時,服務名與服務實例地址的關係在eureka server中已經存在了,所以只需要將Zuul註冊到eureka server上去發現其他服務,我們就可以實現對serviceId的映射。

1.修改服務網關ZuulGateWay的屬性配置文件application.yml
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka,http://localhost:10087/eureka
zuul:
  routes:
    userprovider:
      path: /service/**   #自定義訪問規則
      service-id: USERPROVIDER  #註冊的提供服務名,就不需要再配置服務地址了
2.測試ServiceId映射方式

http://localhost/service/user/getAll

3.修改客戶端調用Zuul網關地址

使用Fegin方式實現接口的
1.修改註解FeignClient
@FeignClient(value = “ZUULGATEWAY”,configuration = feignConfig.class,fallback = UserServiceImpl.class)
2.調用方法按照Zuul定義的規則修改即可
例:
@GetMapping("/service/user/getAll")
public List getAll(…);



Zuul服務網關過濾器使用

在服務網關中定義過濾器只需要繼承ZuulFilter抽象類實現其定義的四個抽象函數就可對請求進行攔截與過濾。

比如下面的例子,定義了一個Zuul過濾器,實現了在請求被路由之前檢查請求中是否有accessToken參數,若有就進行路由,若沒有就拒絕訪問,返回401 Unauthorized錯誤。

1.編寫Zuul過濾器(在模塊ZuulGateWay下)

在這裏插入圖片描述

package com.offcn.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;

import javax.servlet.http.HttpServletRequest;

public class AccessFilter extends ZuulFilter {
   //設置過濾器的類型,決定了過濾器的執行時間
   @Override
   public String filterType() {
       //常見過濾器類型pre 路由請求轉發之前執行  routing 在路由轉發同時執行  post 在routing和error過濾器之後被調用  error:處理請求時發生錯誤時被調用
       return "pre";
   }

   @Override
   public int filterOrder() {
       return 0;  //過濾器的執行順序,數字越小越先執行
   }

   //開關
   @Override
   public boolean shouldFilter() {
       return true;  //true 表示丐蘿氯氣處於可運行狀態  false表示該過濾器不可用
   }

   //該過濾器做身份驗證
   @Override
   public Object run() throws ZuulException {
       //獲取到當前請求上下文環境
       RequestContext context = RequestContext.getCurrentContext();
       //從上下文環境獲取當前請求對象
       HttpServletRequest request = context.getRequest();
       //從請求對象獲取傳遞的憑證
       String token = request.getParameter("token");
       //判斷憑證是否存在
       if(token==null){
           //憑證不存在,禁止路由轉發
           context.setSendZuulResponse(false);
           //提示錯誤狀態碼   401 權限不足的意思
           context.setResponseStatusCode(401);
       }
       return null;
   }
}
2.實例化該過濾器

在這裏插入圖片描述

我們只需要在啓動類中增加如下內容:

	@Bean
	public AccessFilter accessFilter() {
		return new AccessFilter();
	}
3.測試過濾器

http://localhost/service/user/getAll
發現:
在這裏插入圖片描述
因爲沒有傳token的值,所以被過濾器攔截了
我們再測試:
http://localhost/service/user/getAll?token=token
可以發現能正常訪問該接口了

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