Zuul API路由網關服務簡介java
如圖:這裏的API 路由網關服務 由Zuul實現,主要就是對外提供服務接口的時候,起到了請求的路由和過濾做用,也所以可以隱藏內部服務的接口細節,歷來有利於保護系統的安全性web
Zuul 路由配置spring
咱們新建一個module microservice-zuul-3001apache
這裏咱們的zuul也註冊到eureka服務裏,端口3001;json
咱們修改下Hosts,專門爲zuul搞個本地域名映射 瀏覽器
hosts文件 加下:安全
127.0.0.1 zuul.lingerqi.comapp
pom依賴:maven
<?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>testSpringcloud</artifactId> <groupId>com.lingerqi</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>microservice-zuul-3001</artifactId> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>com.lingerqi</groupId> <artifactId>microservice-common</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <!-- actuator監控 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- hystrix容錯 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <!--zuul網關--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
修改application.yml:ide
server: port: 3001 context-path: / spring: application: name: microservice-zuul eureka: instance: instance-id: microservice-zuul:3001 prefer-ip-address: true client: service-url: defaultZone: http://eureka2001.lingerqi.com:2001/eureka/,http://eureka2002.lingerqi.com:2002/eureka/,http://eureka2003.lingerqi.com:2003/eureka/ info: groupId: com.lingerqi.testSpringcloud artifactId: microservice-zuul-3001 version: 1.0-SNAPSHOT userName: http://lingerqi.com phone: 123456
啓動類加註解:
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class}) @EnableZuulProxy
測試:
啓動三個eureka 而後再啓動下一個1001服務,以及 zuul網關服務;
咱們直接請求:http://localhost:1001/student/list 能獲取到數據;
咱們用 http://zuul.lingerqi.com:3001/microservice-student/student/list 域名+端口+服務名稱+請求地址 也能請求到數據;
說明咱們的路由配置基本OK
上面是zuul的簡單使用,從接口地址很輕易的就暴露了服務提供者的惟一標識名microservice-student;有安全風險,咱們須要將其隱藏;
ignored-services的做用是將原來的服務提供者惟一標識名禁用;
Prefix的做用是給服務加前綴
yml文件中添加如下配置:
zuul: routes: studentServer.serviceId: microservice-student studentServer.path: /studentServer/** ignored-services: "*" prefix: /lingerqi
對應的配置會出現下面的錯誤頁面,這是正常現象。
配置完畢後可經過如下連接作測試
http://zuul.lingerqi.com:3001/microservice-student/student/list
http://zuul.lingerqi.com:3001/studentServer/student/list
http://zuul.lingerqi.com:3001/lingerqi/microservice-student/student/list
http://zuul.lingerqi.com:3001/lingerqi/studentServer/student/list
好比咱們登陸某個系統 須要身份驗證,用戶名密碼啥的;
咱們請求服務,也能夠來設置身份驗證,也就是過濾非法請求;Zuul經過ZuulFilter過濾器實現;
通常具體實現的話 每次通過Zuul服務網關 咱們都對帶來的token進行有效性驗證;
咱們先定義一個 AccessFilter類:
package com.lingerqi.microservicezuul3001.filter; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import org.apache.log4j.Logger; import javax.servlet.http.HttpServletRequest; /** * @author xyls * @blog name & blog address 027@0030 * @create 2019-12-05 15:40 */ public class AccessFilter extends ZuulFilter { Logger logger=Logger.getLogger(AccessFilter.class); /** * 判斷該過濾器是否要被執行 */ @Override public boolean shouldFilter() { return true; } /** * 過濾器的具體執行邏輯 */ @Override public Object run() throws ZuulException { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); String parameter = request.getParameter("accessToken"); logger.info(request.getRequestURL().toString()+" 請求訪問"); if(parameter==null){ logger.error("accessToken爲空!"); ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(401); ctx.setResponseBody("{\"result\":\"accessToken is empty!\"}"); return null; } // token判斷邏輯 logger.info(request.getRequestURL().toString()+" 請求成功"); return null; } /** * 過濾器的類型 這裏用pre,表明會再請求被路由以前執行 */ @Override public String filterType() { return "pre"; } /** * 過濾器的執行順序 */ @Override public int filterOrder() { return 0; } }
而後再開啓下 Filter配置:
package com.lingerqi.microservicezuul3001.config; import com.lingerqi.microservicezuul3001.filter.AccessFilter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ZuulConfig { @Bean public AccessFilter accessFilter(){ return new AccessFilter(); } }
Zuul做爲服務網關爲了保證本身不被服務拖垮,自己已經集成了Hystrix對路由轉發進行隔離。 爲了方便開發人員對服務短路進行自定義處理,
ZuulFallbackProvider :Zuul 提供了 ZuulFallbackProvider 接口,開發人員能夠經過實現該接口來完成自定義Hystrix Fallback
FallbackProvider :Spring Cloud Zuul 提供了 FallbackProvider替代了ZuulFallbackProvider接口。
package com.javaxl.microservicezuul3001.fallback; import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.client.ClientHttpResponse; import org.springframework.stereotype.Component; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; @Component public class ZuulFallBack implements ZuulFallbackProvider { @Override public String getRoute() { return "*"; } /** * 在給zuul整合回退功能時,只要類實現ZuulFallbackProvider接口,而且註冊bean便可。 * * 不過須要注意的時,這個回退只有服務掉線或者超時的狀況下才會觸發(Camden.SR4版本測試是這樣), * 若是服務程序出現異常,此回退程序是不能處理的,異常會直接返回給調用者,好比頁面。 * * @return */ @Override public ClientHttpResponse fallbackResponse() { return new ClientHttpResponse() { @Override public HttpHeaders getHeaders() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON_UTF8);//application/json;charset=UTF-8 return headers; } @Override public InputStream getBody() throws IOException { String msg = "服務繁忙,請稍後....."; //new ByteArrayInputStream("{\"code\":-1,\"msg\":\"服務暫不可用\"}".getBytes(StandardCharsets.UTF_8)) return new ByteArrayInputStream(msg.getBytes()); } @Override public String getStatusText() throws IOException { return HttpStatus.BAD_REQUEST.getReasonPhrase();//400 } @Override public HttpStatus getStatusCode() throws IOException { return HttpStatus.BAD_REQUEST; } @Override public int getRawStatusCode() throws IOException { return HttpStatus.BAD_REQUEST.value();//"Bad Request" } @Override public void close() { } }; } }
瀏覽器輸入地址進行測試
http://zuul.lingerqi.com:3001/lingerqi/studentServer/student/list
http://zuul.lingerqi.com:3001/lingerqi/studentServer/student/list?accessToken=1
測試結果以下: