在上一個項目的
configCenter
父項目中新增maven Module
子項目zuul_gateway
;
該服務(wù)為網(wǎng)關(guān)服務(wù),所有請求先經(jīng)過該網(wǎng)關(guān)后,由網(wǎng)關(guān)負責(zé)去注冊中心獲取對應(yīng)服務(wù)真實地址,然后在本地做負載均衡請求真實服務(wù)器地址争群。
本網(wǎng)關(guān)服務(wù)對外端口:8102
app-member會員服務(wù)端口:8101
app-order訂單服務(wù)端口:8103
該網(wǎng)關(guān)服務(wù)需要將自己注冊到eureka注冊中心,所以需要EurekaServer服務(wù)。
pom.xml文件內(nèi)容:
<?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">
<parent>
<artifactId>configCenter</artifactId>
<groupId>configCenter</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>zuul_gateway</artifactId>
<dependencies>
<!--spring-cloud2.0比較支持zuul網(wǎng)關(guān) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
</dependencies>
</project>
application.yml 文件內(nèi)容:
server:
port: 8102
###服務(wù)別名--該服務(wù)注冊到服務(wù)中心的名稱
spring:
application:
name: service-zuul
zuul:
routes:
### 定義轉(zhuǎn)發(fā)規(guī)則座韵,這里的api-a是自定義的,也可以修改為api-member
api-a:
### 客戶端請求http://127.0.0.1/api-member開頭的,都會轉(zhuǎn)發(fā)到會員服務(wù)
path: /api-member/**
#這里的app-member是會員服務(wù)在注冊中信中的別名
#zuul網(wǎng)關(guān)默認整合ribbon,自動實現(xiàn)負載均衡輪訓(xùn)效果
serviceId: app-member
api-b:
path: /api-order/**
serviceId: app-order
eureka:
client:
serviceUrl:
###當前會員服務(wù)注冊到eureka服務(wù)中心(所有eureka集群地址)
defaultZone: http://eureka-server1:7100/eureka
項目啟動 ZuulGatewayApplication.java
package zuul_gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
//@EnableEurekaClient 將當前服務(wù)注冊到Eureka
@EnableEurekaClient
//開啟Zuul網(wǎng)關(guān)代理
@EnableZuulProxy
public class ZuulGatewayApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(ZuulGatewayApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ZuulGatewayApplication.class);
}
}
啟動網(wǎng)關(guān)服務(wù)并測試
- 啟動網(wǎng)關(guān)服務(wù)之前踢京,需要先啟動如下服務(wù):
-
springcloud-eureka-service
注冊中心服務(wù)誉碴。端口:7100
-
api-member-service-impl
會員服務(wù).端口:8101
-
api-order-service-impl
訂單服務(wù), 端口:8103
-
- 啟動本網(wǎng)關(guān)
zuul_gateway
服務(wù),端口:8102
- 訪問EurekaServer:http://127.0.0.1:7100,可以看到
會員服務(wù)
瓣距,訂單服務(wù)
黔帕,網(wǎng)關(guān)服務(wù)
,三個服務(wù)均已經(jīng)注入到注冊中心蹈丸。
image.png -
直接訪問訂單服務(wù)(不通過網(wǎng)關(guān)):http://127.0.0.1:8103:
image.png -
直接訪問會員服務(wù)(不通過網(wǎng)關(guān)):http://127.0.0.1:8101:
image.png - 通過網(wǎng)關(guān)訪問會員服務(wù):http://127.0.0.1:8102/api-member/
image.png - 通過網(wǎng)關(guān)訪問訂單服務(wù):http://127.0.0.1:8102/api-order/
image.png
在zuul_gateway網(wǎng)關(guān)項目中添加過濾器
- 在網(wǎng)關(guān)中添加過濾器,過濾規(guī)則: 獲取參數(shù)
userToken
, 如果該參數(shù)為空則直接返回.當然這是是一個演示,也可以過濾一些其他規(guī)則. - 在zuul_gateway項目中添加
TokenFilter.java
過濾器.
package zuul_gateway;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/**
* 網(wǎng)關(guān)token過濾器
* @author liangxifeng
* @date 2020-08-09
*/
@Component
public class TokenFilter extends ZuulFilter {
//過濾器類型pre,表示請求之前執(zhí)行
@Override
public String filterType() {
return "pre";
}
//過濾器執(zhí)行順序,當一個請求在同一階段存在多個過濾器的時候,多個過濾器執(zhí)行順序
@Override
public int filterOrder() {
return 0;
}
//判斷過濾器是否生效,這里return true生效
@Override
public boolean shouldFilter() {
return true;
}
/**
* 攔截業(yè)務(wù)邏輯代碼
* 所有通過網(wǎng)關(guān)的請求,都必須通過該方法驗證,才能繼續(xù)放行
* 如果驗證失敗,則返回401
*/
@Override
public Object run() throws ZuulException {
//案例:攔截所有服務(wù)接口,判斷服務(wù)接口上是否有傳遞userToken參數(shù)
//1. 獲取上下文
RequestContext currentContext = RequestContext.getCurrentContext();
//2. 獲取Request
HttpServletRequest request = currentContext.getRequest();
//3. 獲取token
String userToken = request.getParameter("userToken");
if (StringUtils.isEmpty(userToken)) {
//如果token為空,則網(wǎng)關(guān)直接返回
currentContext.setSendZuulResponse(false);
currentContext.setResponseBody("userToken is null");
currentContext.setResponseStatusCode(401);
return null;
}
//正常調(diào)用其他服務(wù)接口
return null;
}
}
- 此時重啟zuul_gateway服務(wù), 再次通過網(wǎng)關(guān)訪問會員服務(wù), http://127.0.0.1:8102/api-member, 如果沒有
userToken
參數(shù),回直接返回:
image.png - 在請求中添加
userToken
參數(shù), 就可以直接訪問到 會員服務(wù)了. http://127.0.0.1:8102/api-member?userToken=123456
image.png
動態(tài)Zuul網(wǎng)關(guān)路由轉(zhuǎn)發(fā)
以上Zuul路由轉(zhuǎn)發(fā)規(guī)則只配置兩兩個
api-member
和api-order
, 如果網(wǎng)關(guān)項目正在運行,需要新增路由規(guī)則,就需要修改配置文件,重啟網(wǎng)關(guān)服務(wù)了. 這里配置一下動態(tài)讀取配置文件. 不需要重啟服務(wù).-
也就是將路由配置信息作為配置文件
service-zuul-dev.yml
放到git版本庫中,在git中新增zuul_config
目錄作為網(wǎng)關(guān)服務(wù)配置文件存儲目錄, 內(nèi)容如下: git地址: https://github.com/liangxifeng833/gkconfig/blob/master/zuul-config/service-zuul-dev.ymlzuul: routes: ### 定義轉(zhuǎn)發(fā)規(guī)則蹬屹,這里的api-a是自定義的,也可以修改為api-member api-a: ### 客戶端請求http://127.0.0.1/api-member開頭的侣背,都會轉(zhuǎn)發(fā)到會員服務(wù) path: /api-member/** #這里的app-member是會員服務(wù)在注冊中心中的別名 #zuul網(wǎng)關(guān)默認整合ribbon,自動實現(xiàn)負載均衡輪訓(xùn)效果 serviceId: app-member api-b: path: /api-order/** serviceId: app-order
-
修改pom.xml文件,新增分布式配置中心相關(guān)依賴
<!-- 分布式配置中心相關(guān)依賴#################################start --> <!-- springCloud整合config-server分布式配置中心client --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-client</artifactId> </dependency> <!--actuaor監(jiān)控中心,手動觸發(fā)刷新本地讀取git中配置文件緩存所用--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- 分布式配置中心相關(guān)依賴#################################end -->
-
然后將
zuul_gateway
網(wǎng)關(guān)項目application.yml
修改為bootstrap.yml
, 因為SpringCloud
里面有個“啟動上下文”,主要是用于加載遠端的配置
,也就是加載ConfigServer
里面的配置,默認加載順序為:加載bootstrap.里面的配置 --> 連接configserver,加載遠程配置 --> 加載application.里面的配置; 總結(jié):這里需要借助于“啟動上下文”來處理加載遠程配置;bootstrap.yml
內(nèi)容如下:server: port: 8102 ###服務(wù)別名--該服務(wù)注冊到服務(wù)中心的名稱 spring: application: #這里的服務(wù)別名=要讀取git的配置文件的服務(wù)名稱 #配置文件命名規(guī)范:服務(wù)名-環(huán)境.yml(service-zuul-dev.yml) name: service-zuul cloud: config: #讀取配置文件的環(huán)境(service-zuul-dev.yml)中的dev profile: dev #讀取配置文件服務(wù)的config-server環(huán)境 #也就是配置中心服務(wù)端在eureka注冊的服務(wù)別名 discovery: service-id: config-server #開啟讀取權(quán)限 enabled: true #actuaor監(jiān)控中心慨默,開啟所有端點贩耐,手動觸發(fā)刷新本地緩存讀取最新git配置文件所用 management: endpoints: web: exposure: include: "*" # * 在yaml 文件屬于關(guān)鍵字,所以需要加引號 eureka: client: serviceUrl: ###當前會員服務(wù)注冊到eureka服務(wù)中心(所有eureka集群地址) defaultZone: http://eureka-server1:7100/eureka/
-
修改項目入口文件
ZuulGatewayApplication
, 新增方法如下:
作用是修改git中配置文件信息后, 手動調(diào)用接口刷新網(wǎng)關(guān)讀取遠程配置文件信息所用.// zuul配置使用git中config實現(xiàn)實時更新 @RefreshScope @ConfigurationProperties("zuul") public ZuulProperties zuulProperties() { return new ZuulProperties(); }
重啟該項目后, 訪問: http://127.0.0.1:8202/api-member?userToken=12, 如果能夠正常訪問就代表配置成功了.
-
此時我們后端,開啟兩個member服務(wù), 作為集群.
zuul
可以自動實現(xiàn)ribbon負載均衡. 以下兩次請求代表分別請求到了兩個會員服務(wù)(默認負載均衡為: 輪訓(xùn)算法)
image.png
image.png
我的視頻總結(jié)地址:https://www.bilibili.com/video/BV1z64y1F727/
我的源代碼地址:https://github.com/liangxifeng833/springcloud/tree/master/configCenter/zuul_gateway