1. Zuul 路由網關介紹
其實我們可以吧zuul看成,是公司的前臺,我在在做使用zureka做完分佈式操作之後呢,我們會發現這些端口我們都可以直接連接,那麼既然能直接連接肯定不行,所以我們需要統一管理這些端口,用一個端口去調用這些端口,而Zuul就是解決這個問題的.
具體功能:
- 外部訪問統一入口
- 過濾功能
也即以後的訪問微服務都是通過Zuul跳轉後獲得
所以我們也需要把zuul註冊Eureka
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-zl5ykcm9-1570769868038)(8D8C02577D8145C5AD0DCE9889147BFC)]
2.統一管理功能
2.1 依賴配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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>
2.2 application.yml配置
server:
port: 9000
#註冊到eureka上的服務名
spring:
application:
name: ms-zuul
eureka:
client:
#表示是否從註冊中心抓取服務
fetch-registry: true
# 是否將我這個服務註冊到註冊中心
register-with-eureka: false
# 表示註冊中心的地址(自己的eureka)
service-url:
defaultZone: http://localhost:7961/eureka/
2.3 啓動類配置
加上 @EnableZuulProxy 這個註解
@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication {
public static void main( String[] args ) {
SpringApplication.run(ZuulApplication.class, args);
}
}
接下來我們就可以直接通過zuul的端口去調用euerka註冊的類了
具體流程↓
http://localhost:9000/shop-provider/ticket/23
記得端口後面跟註冊的服務名,接着註冊的網名
從上面的結果我們可看出zuul基本配置成功,但是同時會有一個問題,就是服務名暴露出來了,所以下面我們來看看統一網關設置
3 網關過濾
3.1 application.yml配置
server:
port: 9000
#註冊到eureka上的服務名
spring:
application:
name: ms-zuul
eureka:
client:
#表示是否從註冊中心抓取服務
fetch-registry: true
# 是否將我這個服務註冊到註冊中心
register-with-eureka: false
# 表示註冊中心的地址
service-url:
defaultZone: http://localhost:7961/eureka/
#過濾部分↓
zuul:
routes:
shop-provider: #這個名字可以隨便命名,通常定義爲每個微服務中的spring.application.name的值
serviceId: shop-provider #該值必須爲spring.application.name的值
path: /tk/** #可以通過該路徑訪問服務
shop-consumer:
serviceId: shop-consumer
path: /us/**
prefix: /v1 #前綴
ignored-services: "*" #通過該服務名訪問不了
3.2 實現方法
寫一個類 繼承 ZuulFilter 實現具體過濾方法
注意: 我這裏給了一個判斷值需要在headers 中給定這個token 不然一樣還是會被拒絕
@Component
public class ZuulFilterImpl extends ZuulFilter {
/**
* pre 在達到具體的服務之前
* post 在達到具體的服務之後
* error 拋出異常
* route 具體服務在執行的過程中
*/
@Override
public String filterType() {
return "pre";
}
/**
* 執行順序 越小越前
*
* @return
*/
@Override
public int filterOrder() {
return 0;
}
/**
* 是否開啓過濾
*
* @return
*/
@Override
public boolean shouldFilter() {
return true;
}
/**
* 過濾具體內容
*
* @return
* @throws ZuulException
*/
@Override
public Object run() throws ZuulException {
// token
//獲取RequestContext對象,目的是隻能通過該對象來獲取 request、response對象
RequestContext context = RequestContext.getCurrentContext();
HttpServletRequest request = context.getRequest();
HttpServletResponse response = context.getResponse();
String token = request.getHeader("token");
if(token == null || "".equals(token.trim())) {
// 如果判斷滿足就false, 目的是用我們自己定義的響應格式
context.setSendZuulResponse(false);
// 返回的數據 可以是json數據 用來回復
context.setResponseBody("一個不合法的請求.");
// 返回狀態碼 例如 404 500 等等
context.setResponseStatusCode(HttpStatus.FORBIDDEN.value());
//修改編碼方式 (可有可無 如果有亂碼建議可以來一個,但是不一定有用 ( =A =~ ) )
response.setCharacterEncoding("gbk");
}
return null;
}
}