一、 描述
Spring Cloud Zuul是基于Netflix開源的Zuul項(xiàng)目構(gòu)建而成,它作為微服務(wù)架構(gòu)中的網(wǎng)關(guān)服務(wù),主要用于實(shí)現(xiàn)動(dòng)態(tài)路由、負(fù)載均衡和請求過濾等功能。
-
動(dòng)態(tài)路由:Zuul根據(jù)預(yù)設(shè)的路由規(guī)則將進(jìn)來的請求路由到相應(yīng)的服務(wù)實(shí)例上。路由規(guī)則可以通過配置文件或代碼進(jìn)行定義,接收到請求后,Zuul會(huì)解析請求的URL,并根據(jù)配置的路由規(guī)則找到對應(yīng)的服務(wù)地址,將請求轉(zhuǎn)發(fā)到目標(biāo)服務(wù)。
-
負(fù)載均衡:Zuul內(nèi)置了Ribbon負(fù)載均衡器,可以對請求進(jìn)行負(fù)載均衡。當(dāng)一個(gè)服務(wù)有多個(gè)實(shí)例時(shí),Zuul可以使用負(fù)載均衡算法將請求均勻地分發(fā)到不同的實(shí)例上,以提高系統(tǒng)的性能和可擴(kuò)展性。
-
請求過濾:Zuul支持自定義過濾器,在請求被路由之前或之后對請求進(jìn)行處理。過濾器可以用于在路由前進(jìn)行身份驗(yàn)證、請求統(tǒng)計(jì)、參數(shù)校驗(yàn)等操作,也可以在路由后處理響應(yīng)結(jié)果,比如修改返回?cái)?shù)據(jù)、添加自定義的響應(yīng)頭等。開發(fā)者可以根據(jù)需求創(chuàng)建不同類型的過濾器,并定義過濾器的執(zhí)行順序。
-
整合服務(wù)注冊中心:Zuul可以與服務(wù)注冊中心(如Zookeeper、Eureka)進(jìn)行整合,實(shí)現(xiàn)動(dòng)態(tài)路由和負(fù)載均衡。通過與服務(wù)注冊中心交互,Zuul能夠動(dòng)態(tài)地獲取服務(wù)實(shí)例的信息,并根據(jù)需要進(jìn)行路由和負(fù)載均衡。
-
高可用和容錯(cuò):Zuul支持配置多個(gè)實(shí)例運(yùn)行在不同的機(jī)器上,以實(shí)現(xiàn)高可用性。當(dāng)一個(gè)Zuul實(shí)例發(fā)生故障時(shí),其他實(shí)例可以接管請求處理,確保系統(tǒng)的穩(wěn)定性和容錯(cuò)性。
Spring Cloud Zuul通過動(dòng)態(tài)路由、負(fù)載均衡和請求過濾等機(jī)制,提供了一個(gè)強(qiáng)大且靈活的網(wǎng)關(guān)服務(wù)。它能夠統(tǒng)一管理微服務(wù)的入口,實(shí)現(xiàn)請求的轉(zhuǎn)發(fā)和過濾,簡化了微服務(wù)架構(gòu)中的通信和調(diào)用方式,提高了系統(tǒng)的可伸縮性和可維護(hù)性。
????? 下面是使用Spring Cloud Zuul的一般實(shí)踐步驟
二、添加依賴
引入zuul的依賴spring-cloud-starter-netflix-zuul


1 <dependency> 2 <groupId>org.springframework.cloud</groupId> 3 <artifactId>spring-cloud-starter-netflix-zuul</artifactId> 4 </dependency>
三、創(chuàng)建啟動(dòng)類:
????? 創(chuàng)建一個(gè)啟動(dòng)類,并使用@EnableZuulProxy
注解開啟Zuul代理功能。


1 @SpringBootApplication 2 @EnableZuulProxy 3 public class GatewayApplication { 4 5 public static void main(String[] args) { 6 SpringApplication.run(GatewayApplication.class, args); 7 } 8 9 }
四、 配置
在配置文件(如application.yml
)中定義Zuul的路由規(guī)則??梢允褂肸uul的zuul.routes
前綴來配置不同的路由規(guī)則。


1 server: 2 port: 9000 3 management: 4 endpoints: 5 web: 6 exposure: 7 include: '*' 8 server: 9 port: 12345 10 zuul: 11 routes: 12 configserver: 13 path: /myConfig/** 14 serviceId: config 15 user: 16 path: /myUser/** 17 serviceId: provider 18 ignored-patterns: #忽略指定的路由 19 - /config/** 20 - /gateway/** 21 sensitive-headers: 22 # ignore-local-service: true # 忽略原來自身的路由。比如,true: 原來的config/xxx/xxx不可再訪問
上述配置將/myConfig/**的請求轉(zhuǎn)發(fā)到config服務(wù),將/myUser/**的請求轉(zhuǎn)發(fā)到provider服務(wù)。
還可以將網(wǎng)關(guān)注冊到注冊中心實(shí)現(xiàn)高可用。創(chuàng)建bootstrap.yml文件


1 spring: 2 application: 3 name: gateway 4 cloud: 5 zookeeper: 6 discovery: 7 register: true 8 enabled: true 9 connect-string: 192.168.3.100:2181 10 config: 11 discovery: 12 service-id: config 13 enabled: true
五、配置過濾器
?通過zuul添加過濾器,對請求進(jìn)行攔截或校驗(yàn)等等


1 package com.mike.study.gateway.fiter; 2 3 import com.netflix.zuul.ZuulFilter; 4 import com.netflix.zuul.context.RequestContext; 5 import com.netflix.zuul.exception.ZuulException; 6 import org.apache.commons.lang.StringUtils; 7 import org.springframework.http.HttpStatus; 8 import org.springframework.stereotype.Component; 9 10 import javax.servlet.http.HttpServletRequest; 11 12 import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER; 13 import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; 14 15 /** 16 * @Classname ParameterFilter 17 * @Created by Michael 18 * @Date 2023/7/12 19 * @Description 自定義過濾器 20 */ 21 @Component 22 public class ParameterFilter extends ZuulFilter { 23 /** 24 * 前置過濾 25 * @return 26 */ 27 @Override 28 public String filterType() { 29 return PRE_TYPE; 30 } 31 32 /** 33 * 數(shù)值越小,優(yōu)先級越高 34 * @return 35 */ 36 @Override 37 public int filterOrder() { 38 return PRE_DECORATION_FILTER_ORDER - 1; 39 } 40 41 @Override 42 public boolean shouldFilter() { 43 return true; 44 } 45 46 @Override 47 public Object run() throws ZuulException { 48 49 // 獲取請求對象 50 RequestContext context = RequestContext.getCurrentContext(); 51 HttpServletRequest request = context.getRequest(); 52 // 獲取地址欄傳入的參數(shù) 53 String token = request.getParameter("token"); 54 System.out.println("token ===>"+token); 55 //模擬校驗(yàn)token,沒有token則終止轉(zhuǎn)發(fā) 56 if (StringUtils.isEmpty(token)) { 57 context.setSendZuulResponse(false); 58 context.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value()); 59 } 60 return null; 61 } 62 }
以上代碼時(shí)在轉(zhuǎn)發(fā)請求服務(wù)前,對參數(shù)進(jìn)行校驗(yàn),如果沒有token參數(shù),則停止轉(zhuǎn)發(fā),并且返回401錯(cuò)誤
六、測試
測試網(wǎng)關(guān)轉(zhuǎn)發(fā)主要需要請求發(fā)起方,網(wǎng)關(guān)和請求處理方。這里在原來demo的基礎(chǔ)上,增加網(wǎng)關(guān),所以看到有配置中心,以往的文章有項(xiàng)目的搭建介紹。如果不想那么復(fù)雜,可以去掉配置中心,將配置放置各個(gè)module即可,項(xiàng)目組如下
?文章來源:http://www.zghlxwxcb.cn/news/detail-554069.html
準(zhǔn)備請求發(fā)起方,即consumer,controller通過feign框架請求網(wǎng)關(guān),網(wǎng)關(guān)轉(zhuǎn)發(fā)請求provider。consumer的controller如下


1 import com.mike.study.orderconsumer.client.UserClient; 2 import com.mike.study.orderconsumer.vo.UserVo; 3 import org.springframework.web.bind.annotation.GetMapping; 4 import org.springframework.web.bind.annotation.PathVariable; 5 import org.springframework.web.bind.annotation.RequestParam; 6 import org.springframework.web.bind.annotation.RestController; 7 8 import javax.annotation.Resource; 9 10 /** 11 * @Classname UserRuttingController 12 * @Created by Michael 13 * @Date 2023/7/9 14 * @Description feign框架調(diào)用provider api 15 */ 16 @RestController 17 public class UserRuttingController { 18 @Resource 19 private UserClient userClient; 20 21 @GetMapping("warp/user/2.1/{id}") 22 public UserVo getUser(@PathVariable("id") Integer userId, @RequestParam("token") String token) { 23 System.out.println("使用feign框架調(diào)用provide的api"); 24 return userClient.getUser(userId, token); 25 } 26 }
Feign接口


1 import com.mike.study.orderconsumer.vo.UserVo; 2 import org.springframework.cloud.openfeign.FeignClient; 3 import org.springframework.web.bind.annotation.GetMapping; 4 import org.springframework.web.bind.annotation.PathVariable; 5 import org.springframework.web.bind.annotation.RequestParam; 6 7 /** 8 * @Classname UserFeigClient 9 * @Created by Michael 10 * @Date 2023/7/9 11 * @Description feign client 12 */ 13 14 @FeignClient("gateway") 15 public interface UserClient { 16 17 @GetMapping("myUser/user/{id}") 18 public UserVo getUser(@PathVariable("id") Integer userId,@RequestParam("token") String token); 19 }
以上Feign接口配合注冊中心zookeeper使用,訪問的網(wǎng)關(guān)地址,而不是直接請求服務(wù)提供者的api。
provider module簡單提供一個(gè)api查詢用戶信息。
六、測試結(jié)果
positive case:token參數(shù)有值
?negative case:token參數(shù)i為空
?
總結(jié),就是consumer不再直接請求provider server,而是通過zuul作為中轉(zhuǎn)站,這樣做的好處很多,比如,對consumer的請求進(jìn)行攔截過濾,驗(yàn)證,降流等等。文章來源地址http://www.zghlxwxcb.cn/news/detail-554069.html
到了這里,關(guān)于spring cloud zuul實(shí)踐的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!