Zuul 路由网关
Posted chenziyue
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Zuul 路由网关相关的知识,希望对你有一定的参考价值。
为什么需要zuul?
Zuul Ribbon 以及Eureka 相结合 可以实现智能路由和负载均衡的功能
网关将所有服务的API 接口统一聚合 并统一对外暴露
网关服务可以做用户身份认证和权限认证 防止非法请求操作API 接口 对服务器起到保护作用。
Zuul过滤器的类型
PRE 过滤器:请求路由到具体的服务之前执行 可以做安全验证,例如身份验证、参数验证等。
ROUTING 过滤器:将请求路由到具体的微服务实例
POST 过滤器:请求己被路由到微服务后执行 用作收集统计信息、指标,以及将响应传输到客户端
ERROR过滤器 :在其他过滤器发生错误时执行
过滤器之间不能直接相互通信 而是通过RequestContext 对象来共享数据, 每个请求都会创建一个RequestContext 对象
执行流程
案例
创建新工程(继承父工程)
导入依赖
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
启动类
@SpringBootApplication // 开启Zuul功能 @EnableZuulProxy @EnableEurekaClient public class ZuulApp { public static void main( String[] args ) { SpringApplication.run(ZuulApp.class); } }
配置文件
server: port: 8009 eureka: instance: hostname: service-zuul client: service-url: defaultZone: http://eureka01:8001/eureka/ register-with-eureka: true spring: application: name: service-zuul zuul: routes: hiapi: # 将以/hiapi 开头的路由到 eureka-client 服务 path: /hiapi/** serviceId: eureka-client ribbonapi: path: /ribbonapi/** serviceId: ribbon-client feignapi: path: /feignapi/** serviceId: feign-client
修改host文件
127.0.0.1 eureka01 eureka02 eureka-client ribbon-client feign-client
启动服务
打开浏览器输入
http://localhost:8009/hiapi/hi/aa
刷新
Zuul 在路由转发做了负载均衡 如果不需要用Ribbon 做负载均衡 可以指定服务实例的Url一旦指定了Uri Zuul 就不能做负载均衡了 而是直接访问指定的Uri 在实际的开发中这种做法是不可取的
zuul: routes: hiapi: path: /hiapi/** # serviceId: eureka-client url: http://eureka-client:8006 ribbonapi: path: /ribbonapi/** serviceId: ribbon-client feignapi: path: /feignapi/** serviceId: feign-client
重启服务后 继续刷新 可以看到不负载了
在Zuul 上配置API 接口的版本号
zuul: routes: hiapi: path: /hiapi/** # serviceId: eureka-client url: http://eureka-client:8006 ribbonapi: path: /ribbonapi/** serviceId: ribbon-client feignapi: path: /feignapi/** serviceId: feign-client # 版本号前缀 prefix: /v3
访问要加V3前缀
Zuul 上配置熔断器
实现ZuulFallbackProvider 接口
@Component public class ZuulError implements ZuulFallbackProvider { @Override public String getRoute() { // 如果要将所有服务加熔断器 加* // returen "*" return "eureka-client"; } @Override public ClientHttpResponse fallbackResponse() { 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("eureka-client error".getBytes()); } @Override public HttpHeaders getHeaders() { HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setContentType(MediaType.APPLICATION_JSON); return httpHeaders; } }; } }
配置文件
zuul: routes: hiapi: path: /hiapi/** serviceId: eureka-client ribbonapi: path: /ribbonapi/** serviceId: ribbon-client feignapi: path: /feignapi/** serviceId: feign-client
重启服务 关闭eureka_client服务
打开浏览器访问
zuul过滤器
打开工程
在controller层 新增
@RequestMapping("/test") public String test(@RequestParam("name") String name){ return "有name参数"; }
打开工程
新建ZuulFilterDemo类 实现zuulFilter接口
@Component public class ZuulFilterDemo extends ZuulFilter { @Override public String filterType() { //PRE 过滤器:请求路由到具体的服务之前执行 可以做安全验证,例如身份验证、参数验证等。 // ROUTING 过滤器:将请求路由到具体的微服务实例 // POST 过滤器:请求己被路由到微服务后执行 用作收集统计信息、指标,以及将响应传输到客户端 // ERROR过滤器 :在其他过滤器发生错误时执行 return "pre"; } @Override public int filterOrder() { // 过滤顺序 值越小 越早过滤 return 0; } @Override public boolean shouldFilter() { // true执行run false不执行 return true; } @Override public Object run() { // 判断是否有name参数 RequestContext currentContext = RequestContext.getCurrentContext(); HttpServletRequest request = currentContext.getRequest(); HttpServletResponse response = currentContext.getResponse(); String name = request.getParameter("name"); if(StringUtils.isEmpty(name)){ try { response.setCharacterEncoding("utf-8"); response.getWriter().write("error"); currentContext . setSendZuulResponse(false) ; currentContext . setResponseStatusCode(401) ; } catch (IOException e) { e.printStackTrace(); } } return null; } }
启动服务器
访问http://localhost:8009/hiapi/test 此时没有携带参数 返回error
携带name参数后
以上是关于Zuul 路由网关的主要内容,如果未能解决你的问题,请参考以下文章