Zuul 的官方介紹是
“Zuul is the front door for all requests from devices and web sites to the backend of the Netflix streaming application. As an edge service application, Zuul is built to enable dynamic
routing, monitoring, resiliency and security. It also has the ability to route requests to multiple Amazon Auto Scaling Groups as appropriate.”
大致是說zuul是設備和網站到Netflix後臺應用程序的所有的請求的前門,是一個邊緣化應用程序,它的創建是爲了實現動態路由,監控,彈性,和安全性, 它還能夠根據需要將請求路由到多個Amazon Auto Scaling組。
其實zuul主要實現的功能就是API Gateway(api網關)的功能,爲什麼使用api gateway:
- 客戶端會多次請求不同的微服務,導致客戶端複雜度增加,使用網關時客戶端只與網關交互,降低客戶端的調用邏輯的複雜度,同時網關也可以實現認證邏輯簡化內部服務的之間相互調用的複雜度。
- 對不同客戶端的支持及數據的聚合,如一個網站有web端,手機端,頁面所需的數據有同有異,可以將數據整合或者裁剪,減少客戶端的請求次數,比如BFF架構。
- 可以更好的對項目的微服務封裝,可將項目的微服務統一封裝在一個內網環境中,只通過網關提供服務,同時網關也可以對安全,認證,監控,防禦單獨強化。
在springcloud使用zuul:
1:除了添加eureka依賴外,添加zuul依賴包:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
2:在啓動類上使用@EnableZuulProxy 啓用zuul
@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication {
public static void main(String[]
args) {
SpringApplication.run(ZuulApplication.class, args);
}
}
3:配置文件application.yml
spring:
application:
name: micoserice-gateway-zuul
server:
port: 8090
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
instance-id: ${spring.application.name}:${server.port}
啓動運行:
如圖我這裏啓動了三個服務,zuul註冊到Eureka-service爲服務後默認情況下是構建PAI-GATEWAY,訪問時只要zuul-host/appname/api
如我這裏訪問:http://localhost:8090/micoserice-user/user/getuser,當調用服務有多個時,zuul是實現了負載均衡的。
zuul中使用hystrix的回退:
代碼如下
/**
*
@author
wxy
* zuul中使用hystrix的回退
*/
@Component
public class
MyFallbackProvider
implements
ZuulFallbackProvider {
@Override
public
String
getRoute() {
//路由配置micoserice-user,如果全部用"*"代替
return
"micoserice-user";
}
@Override
public
ClientHttpResponse
fallbackResponse() {
return
new ClientHttpResponse() {
@Override
public
HttpStatus
getStatusCode()
throws
IOException {
//回退的狀態碼
return
HttpStatus.OK;
}
@Override
public int
getRawStatusCode()
throws
IOException {
//數字類型狀態碼
return
200;
}
@Override
public
String
getStatusText()
throws
IOException {
//狀態文本
return
"ok";
}
@Override
public void
close() { }
@Override
public
InputStream
getBody()
throws
IOException {
//回退響應體
return new
ByteArrayInputStream("服務不可用稍後再試".getBytes());
}
@Override
public
HttpHeaders
getHeaders() {
//header設置
HttpHeaders headers =
new
HttpHeaders();
MediaType mediaType =
new
MediaType("application","json",
Charset.forName("UTF-8"));
headers.setContentType(mediaType);
return
headers;
}
};
}
}
添加回退後當訪問micoserice-user
微服務失敗後將會返回“服務不可用稍後再試”。
zuul過濾器:
/**
*
@author
wxy
* zuul過濾器
* zuul中定義了四種標準過濾類型,這些過濾類型對應請求的生命週期
*
* PRE:這種過濾類型在請求被路由之前調用。可利用這種過濾器實現身份驗證,在集羣中選擇請求的微服務,記錄調試信息等。
*
* ROUTING:這種過濾器將請求路由到微服務。這種過濾用於構建發送給微服務的請求,
*
並可以使用Apache HttpClient,Fegin,Ribbon請求微服務。
*
* POST:這種過濾器在路由到微服務以後執行。這種過濾器可用來微響應添加標準的http
header,
*
蒐集統計信息和指標,將響應發送給客戶端。
*
* ERROR:在其他階段發生錯誤時執行該過濾器。
*
*/
public class
RequestLogFilter
extends
ZuulFilter {
private static
Logger
logger = LoggerFactory.getLogger(RequestLogFilter.class);
@Override
public
String
filterType() {
return
PRE_TYPE;
}
@Override
public int
filterOrder() {
return
1;
}
@Override
public boolean
shouldFilter() {
return
true;
}
@Override
public
Object
run() {
RequestContext
requestContext =RequestContext.getCurrentContext();
HttpServletRequest
request = requestContext.getRequest();
logger.info(String.format("send
%s request to %s",request.getMethod(),request.getRequestURL().toString()));
return
null;
}
}
//在啓動類下添加Bean
@Bean
public
RequestLogFilter
getRequestLogFilter(){
return new
RequestLogFilter();
}
本文參考