springCloud Zuul閘道器
阿新 • • 發佈:2018-12-22
1.springboot 僅2.0.x 支援,在此選擇 2.0.7
2.新建Module eureka-zuul-client
3.匯入依賴
<?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"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.hc</groupId> <artifactId>demoparent</artifactId> <version>0.0.1-SNAPSHOT</version> <relativePath/> <!-- lookup parent from repository --> </parent> <artifactId>eureka-zuul-client</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--引入關於 eureka-server的依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> <version>2.0.2.RELEASE</version> </dependency> <!--引入閘道器 zuul依賴--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> <version>2.0.2.RELEASE</version> </dependency> <!--執行狀態監控--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--mybatis配置 start--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.2.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.39</version> </dependency> <!--mybatis配置 end--> </dependencies> </project>
4.啟動類加上註解
@EnableEurekaClient
@EnableZuulProxy
5.增加配置檔案application.yml
server: port: 8767 spring: main: allow-bean-definition-overriding: true datasource: url: jdbc:mysql://192.168.9.1:3306/test1?useUnicode=true&characterEncoding=utf8 username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver application: name: eureka-zuul-client eureka: client: #改變eureka server的檢查方式,使用actuator 的health進行檢查,可能會檢查到資料庫 healthcheck: enabled: true service-url: defaultZone: http://localhost:8761/eureka/ instance: prefer-ip-address: true instanceId: ${spring.application.name}:${server.port} # 每隔10s傳送一次心跳 lease-renewal-interval-in-seconds: 10 # 告知服務端30秒還未收到心跳的話,就將該服務移除列表 lease-expiration-duration-in-seconds: 30 #改變eureka 服務端的 status 狀態跳轉檢視頁面 status-page-url-path: /actuator/health management: endpoints: web: exposure: include: "*" server: port: 10116 servlet: context-path: / ssl: enabled: false endpoint: health: show-details: always zuul: routes: zuulHello: path: /zuulHello/** serviceId: eureka-client ribbonHello: path: /ribbonHello/** serviceId: eureka-ribbon-client feignHello: path: /feignHello/** serviceId: eureka-feign-client prefix: /v1
6.增加zuul熔斷器
程式碼:
package com.example.eurekazuulclient.hystrixList; import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; 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 MyFallbackProvider implements FallbackProvider { @Override public String getRoute() { //return "eureka-client"; return "*"; } @Override public ClientHttpResponse fallbackResponse(String route, Throwable cause) { return new ClientHttpResponse() { @Override public HttpStatus getStatusCode() throws IOException { return HttpStatus.OK; } @Override public int getRawStatusCode() throws IOException { return 200; } @Override public String getStatusText() throws IOException { return "OK"; } @Override public void close() { } @Override public InputStream getBody() throws IOException { return new ByteArrayInputStream("fallback".getBytes()); } @Override public HttpHeaders getHeaders() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); return headers; } }; } }//end
7.增加zuul 過濾器
pre
package com.example.eurekazuulclient.filter; 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; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Component public class MyFilter_pre extends ZuulFilter { @Override public String filterType() { /** * pre 代表請求被路由前執行 */ return "pre"; } @Override public int filterOrder() { /** * 過濾器執行的順序 越小越靠前 */ return 0; } @Override public boolean shouldFilter() { /** * 判斷過濾器是否執行 */ return true; } @Override public Object run() throws ZuulException { RequestContext currentContext = RequestContext.getCurrentContext(); HttpServletRequest request = currentContext.getRequest(); System.out.println("pre send " + request.getMethod() + " Request to " + request.getRequestURL().toString()); //int i = 1 / 0; String token = request.getParameter("token"); if (StringUtils.isBlank(token)) { System.out.println("access token is empty"); currentContext.setSendZuulResponse(false); currentContext.setResponseStatusCode(401); try { HttpServletResponse response = currentContext.getResponse(); response.setCharacterEncoding("utf-8"); //設定字符集 response.setContentType("text/html; charset=utf-8"); //設定相應格式 response.getWriter().write("token 驗證失敗"); } catch (IOException e) { System.out.println("response io異常"); e.printStackTrace(); } return null; } return null; } }//end
post
package com.example.eurekazuulclient.filter; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; @Component public class MyFilter_post extends ZuulFilter { @Override public String filterType() { /** * post 它是在請求己被路由到微服務後執行的 般情況下,用作收集統計 * 資訊、指標,以及將響應傳輸到客戶端 */ return "post"; } @Override public int filterOrder() { /** * 過濾器執行的順序 越小越靠前 */ return 0; } @Override public boolean shouldFilter() { /** * 判斷過濾器是否執行 */ return true; } @Override public Object run() throws ZuulException { RequestContext currentContext = RequestContext.getCurrentContext(); HttpServletRequest request = currentContext.getRequest(); System.out.println("post send " + request.getMethod() + " Request to " + request.getRequestURL().toString()); return null; } }//end
error
package com.example.eurekazuulclient.filter; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Component public class MyFilter_error extends ZuulFilter { @Override public String filterType() { /** * error 在其他過濾器發生錯誤時執行 */ return "error"; } @Override public int filterOrder() { /** * 過濾器執行的順序 越小越靠前 */ return 0; } @Override public boolean shouldFilter() { /** * 判斷過濾器是否執行 */ return true; } @Override public Object run() throws ZuulException { RequestContext currentContext = RequestContext.getCurrentContext(); HttpServletRequest request = currentContext.getRequest(); System.out.println("error send " + request.getMethod() + " Request to " + request.getRequestURL().toString()); try { HttpServletResponse response = currentContext.getResponse(); response.setCharacterEncoding("utf-8"); //設定字符集 response.setContentType("text/html; charset=utf-8"); //設定相應格式 response.getWriter().write("error 驗證失敗"); } catch (IOException e) { System.out.println("response io異常"); e.printStackTrace(); } return null; } }//end
routing
package com.example.eurekazuulclient.filter; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; @Component public class MyFilter_routing extends ZuulFilter { @Override public String filterType() { /** * routing 它用於將請求路由到具體的微服務例項。在預設情況下,它使用 * Http Client 進行網路請求。 */ return "routing"; } @Override public int filterOrder() { /** * 過濾器執行的順序 越小越靠前 */ return 0; } @Override public boolean shouldFilter() { /** * 判斷過濾器是否執行 */ return true; } @Override public Object run() throws ZuulException { RequestContext currentContext = RequestContext.getCurrentContext(); HttpServletRequest request = currentContext.getRequest(); System.out.println("routing send " + request.getMethod() + " Request to " + request.getRequestURL().toString()); return null; } }//end
7.依次啟動,eureka-server eureka-client-01 eureka-client eureka-feign-client eureka-ribbon-client eureka-zuul-client
訪問 http://192.168.9.6:8767/v1/zuulHello/hello?token=123 顯示
訪問 http://192.168.9.6:8767/v1/ribbonHello/hello?token=123 顯示
訪問 http://192.168.9.6:8767/v1/feignHello/hello 顯示