1 為什么需要微服務(wù)網(wǎng)關(guān)
????不同的微服務(wù)一般有不同的網(wǎng)絡(luò)地址,而外部的客戶端可能需要調(diào)用多個(gè)服務(wù)的接口才能完成一個(gè)業(yè)務(wù)需求裳瘪。比如一個(gè)電影購(gòu)票的收集APP,可能回調(diào)用電影分類微服務(wù)落君,用戶微服務(wù),支付微服務(wù)等煮嫌。
如果客戶端直接和微服務(wù)進(jìn)行通信丢间,會(huì)存在以下問(wèn)題:
- 客戶端會(huì)多次請(qǐng)求不同微服務(wù),增加客戶端的復(fù)雜性
- 存在跨域請(qǐng)求亩鬼,在一定場(chǎng)景下處理相對(duì)復(fù)雜
- 認(rèn)證復(fù)雜殖告,每一個(gè)服務(wù)都需要獨(dú)立認(rèn)證
- 難以重構(gòu),隨著項(xiàng)目的迭代辛孵,可能需要重新劃分微服務(wù)丛肮,如果客戶端直接和微服務(wù)通 信,那么重構(gòu)會(huì)難以實(shí)施
- 某些微服務(wù)可能使用了其他協(xié)議魄缚,直接訪問(wèn)有一定困難
上述問(wèn)題宝与,都可以借助微服務(wù)網(wǎng)關(guān)解決。微服務(wù)網(wǎng)關(guān)是介于客戶端和服務(wù)器端之間的中間層冶匹,所有的外部請(qǐng)求都會(huì)先經(jīng)過(guò)微服務(wù)網(wǎng)關(guān)再由網(wǎng)關(guān)進(jìn)行轉(zhuǎn)發(fā)习劫。
我們?cè)趛ml zuu: routes:配置一些微服務(wù)模塊需要指定攔截路徑到指定的微服務(wù)模塊,
這要求我們
1.網(wǎng)關(guān)和微服務(wù)模塊必須注冊(cè)到eureka,相互通信的條件下才可以找到各模塊進(jìn)行路由轉(zhuǎn)發(fā)
2.當(dāng)然對(duì)應(yīng)的必須指定微服務(wù)模塊和微服務(wù)模塊的name(Zuul不依賴于ip,端口,它依賴于我們配置的微服務(wù)模塊name)
Zuul路由轉(zhuǎn)發(fā)快速體驗(yàn)
(1)創(chuàng)建子模塊zyh_manager,pom.xml引入eureka-client 和zuul的依賴
<dependencies>
<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>
</dependencies>
(2 )編寫(xiě)啟動(dòng)類
@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
public class WebApplication {
public static void main(String[] args){
SpringApplication.run(WebApplication.class,args);
}
}
(3) 編寫(xiě)配置文件 主要就是這個(gè)地方
server:
port: 9012
spring: #這里不寫(xiě)也行,寫(xiě)spring application name 只有一個(gè)作用就是供別人調(diào)用時(shí)候指定
application:
name: zyh-web
#eureka配置 目的使該微服務(wù)注冊(cè)到eureka統(tǒng)一管理
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:6868/eureka/
instance:
prefer-ip-address: true #部署導(dǎo)線上時(shí),可以使模塊之間跨域訪問(wèn)
#網(wǎng)關(guān)配置 使所有請(qǐng)求經(jīng)過(guò)網(wǎng)關(guān)進(jìn)行路由轉(zhuǎn)發(fā),無(wú)需再記一個(gè)個(gè)的端口
zuul:
routes: #下面三步,即指定訪問(wèn)路徑是/base下的都轉(zhuǎn)發(fā)導(dǎo)tensquare-base微服務(wù)下
zyh-base:
path: /base/** #攔截所有/base/路徑下的請(qǐng)求到 tensquare-base去
serviceId: zyh-base
zyh-user:
path: /user/**
serviceId: zyh-user
zyh-qa:
path: /qa/**
serviceId: zyh-qa
Zuul 過(guò)濾器
Zuul過(guò)濾器快速體驗(yàn)
Zuul過(guò)濾器屬于Zuul無(wú)需新加配置,只需要?jiǎng)?chuàng)建一個(gè)過(guò)濾器類實(shí)現(xiàn)ZuulFilter并指定規(guī)則
我們現(xiàn)在在zyh_web網(wǎng)關(guān)里 創(chuàng)建一個(gè)簡(jiǎn)單的zuul過(guò)濾器
@Component//將過(guò)濾器交給spring容器
public class ManagerFilter extends ZuulFilter {//集成ZuulFilter并實(shí)現(xiàn)它的方法
@Override
public String filterType() {//指定該過(guò)濾器什么時(shí)候使用
return "pre"; //pre代表請(qǐng)求處理前,post代表請(qǐng)求處理后
}
@Override
public int filterOrder() { //我們可以子啊這個(gè)filter包下寫(xiě)N多個(gè)過(guò)濾器,那么這么多過(guò)濾器我們就要指定優(yōu)先級(jí)別了,這個(gè)方法就是指定過(guò)濾器優(yōu)先級(jí)
return 0;//指定過(guò)濾器優(yōu)先級(jí)別,數(shù)字越小越優(yōu)先
}
@Override
public boolean shouldFilter() {//當(dāng)前過(guò)濾器是否開(kāi)啟
return true;//true代表開(kāi)啟 false代表關(guān)閉
}
@Override
public Object run() throws ZuulException {
//過(guò)濾器規(guī)則
//過(guò)濾器內(nèi)執(zhí)行的操作return任何ojbect的值都表示繼續(xù)執(zhí)行
//只有setsendzullResnnonse(false)表示不再繼續(xù)執(zhí)行
System.out.println("經(jīng)過(guò)后臺(tái)網(wǎng)關(guān)過(guò)濾器了");
return null;
}
}
這樣一個(gè)過(guò)濾器就做完了,那么我們來(lái)詳細(xì)說(shuō)一下各個(gè)配置
filterType:返回一個(gè)字符串代表過(guò)濾器的類型嚼隘,在zuul中定義了四種不同生命周期的過(guò) 濾器類型诽里,具體如下:
- pre :可以在請(qǐng)求被路由之前調(diào)用
- route :在路由請(qǐng)求時(shí)候被調(diào)用
- post :在route和error過(guò)濾器之后被調(diào)用
- error :處理請(qǐng)求時(shí)發(fā)生錯(cuò)誤時(shí)被調(diào)用
filterOrder :通過(guò)int值來(lái)定義過(guò)濾器的執(zhí)行順序
shouldFilter :返回一個(gè)boolean類型來(lái)判斷該過(guò)濾器是否要執(zhí)行,所以通過(guò)此函數(shù)可實(shí)現(xiàn)過(guò)濾器的開(kāi)關(guān)飞蛹。在上例中谤狡,我們直接返回true,所以該過(guò)濾器總是生效
run :過(guò)濾器的具體邏輯卧檐。