SpringCloud之閘道器Zuul的使用以及簡介
阿新 • • 發佈:2018-12-15
說明:
Spring Cloud Zuul是SpringClud的閘道器,我們知道,閘道器一般是應用的入口,做一些公共的和業務無關的校驗工作,例如加驗籤、加解密等一些操作,而zuul作為微服務的閘道器,有如下原因:
1、作為系統的統一入口,遮蔽了微服務內部的實現細節;
2、與服務治理框架相結合(例如:Eureka),實現自動化的例項維護、以及負載均衡的路由轉發;
3、實現介面的校驗與微服務業務邏輯的解耦;
4、通過zuul中的各種過濾器,在各生命週期去校驗請求內容,將原本對外服務層做的校驗前移,保證了微服務的無狀態性,同時降低了微服務的測試難度,讓微服務更加關注本身的業務邏輯的處理;
好了,接下來我們開始一個zuul閘道器服務:
一、引入zuul的pom以來:
<?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.ck.springcloud</groupId> <artifactId>hello-service-api</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.7.RELEASE</version> <relativePath/> </parent> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Brixton.SR5</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> </project>
因為Zuul要結合Eureka使用,所以也要引入Eureka的依賴,下面會講解Zuul怎麼和Eureka的結合使用;
二、增加啟動類,增加Zuul的啟動配置註解@EnableZuulProxy:
package controller; import com.netflix.zuul.FilterLoader; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; import org.springframework.context.annotation.Bean; @SpringBootApplication @EnableZuulProxy @EnableConfigurationProperties(FilterConfiguration.class) public class Application { FilterConfiguration filterConfiguration; public static void main(String[] args) { new SpringApplicationBuilder(Application.class).run(args); } @Bean public AccessFilter getAccessFilter(){ return new AccessFilter(); } @Bean public FilterConfiguration filterLoader(FilterConfiguration filterConfiguration){ this.filterConfiguration = filterConfiguration; System.out.println(filterConfiguration.getInterval()+filterConfiguration.getRoot()); return filterConfiguration; } }
三、增加配置檔案application.yml檔案:
spring:
application:
name: api-gateway
server:
port: 5555
eureka:
client:
serviceUrl:
defaultZone: http://localhost:1111/eureka/
zuul:
routes:
api-a:
path: /api-a/**
url: http://localhost:8080
api-b:
path: /api-b/**
serviceId: feign-consumer
AccessFilter:
pre:
disable: true
zuuls:
filter:
root: filter
interval: 5
在上面的配置中,我們配置了2個路由規則:
1、是/api-a/**的請求都會轉發到http://localhost:8080
2、/api-b/**的請求都會通過Ribbon負載均衡隨機轉發到微服務名feign-consumer(通過與Eureka註冊中心結合,動態的獲取所有微服務例項)的例項上;
通過簡單的配置,現在一個簡單的Spring Cloud Zuul閘道器就實現了!
Zuul中還可以增加過濾器,在轉發請求到微服務之前做攔截過濾,實現過濾器很簡單,只要整合ZuulFilter父類;
例子:
package controller;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import javax.servlet.http.HttpServletRequest;
public class AccessFilter extends ZuulFilter {
//表明這是一個前置過濾器,在轉發到微服務之前執行
@Override
public String filterType() {
return "pre";
}
//多個過濾器之前,通過返回的order判斷過濾器的執行順序
@Override
public int filterOrder() {
return 0;
}
//這個過濾器是否執行,true表示執行
@Override
public boolean shouldFilter() {
return true;
}
//具體的攔截執行邏輯,過去邏輯是如果請求引數中沒有accessToken就攔截此次請求
//否則通過
@Override
public Object run() {
System.out.println("access token start");
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest httpServletRequest = requestContext.getRequest();
Object accessToken = httpServletRequest.getParameter("accessToken");
if(accessToken == null){
requestContext.setSendZuulResponse(false);
requestContext.setResponseStatusCode(401);
return null;
}
System.out.println("access token ok");
return null;
}
}
最後別忘記了,在Application啟動類中將AccessFilter註冊成bean:
@Bean
public AccessFilter getAccessFilter(){
return new AccessFilter();
}