springCloud Zuul网关
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 显示
欢迎指正:haizi2014@qq.com