SpringCloud极简入门|zuul智能路由回退、认证、转发功能demo 第五讲

╄→гoц情女王★ 提交于 2019-12-01 14:17:16

  开篇点题 

  在微服务架构中,需要几个基础的服务治理组件,包括服务注册与发现、服务消费、负载均衡、断路器、智能路由、配置管理等,由这几个基础组件相互协作,共同组建了一个简单的微服务系统。

本章将讲解zuul(路由)这个组件,希望大家可以有个简单的入门。

Zuul简介

Zuul的主要功能是路由转发和过滤器。路由功能是微服务的一部分,比如/api/user转发到到user服务,/api/shop转发到到shop服务。zuul默认和Ribbon结合实现了负载均衡的功能。

zuul有以下功能:

Authentication
Insights
Stress Testing
Canary Testing
Dynamic Routing
Service Migration
Load Shedding
Security
Static Response handling
Active/Active traffic management


本章要点

1.学会配置zuul和eureka集成

2.zuul常用配置介绍

3.zuul调用方式介绍

...评论区内所有解答(有问必有答)

好了我们先开始个简单的入门

(今天2019.1.6 晚上10:40简单记录下)

Demo开始

本章节所有代码以springcloud-02-getway-zuul模块进行讲解(文末共享代码)

模块构建:

构建两个生产者、注册中心、路由

spring-cloud-producter1-002(生产者1)
spring-cloud-producter2-002(生产者2)

spring-cloud-eureka-002(注册中心)

spring-cloud-zuul-002(智能路由,本章讲解内容)

操作流程启动 注册中心(自然第一个先启动)、之后再启动两个生产者

验证是否启动成功,怎么验证?好了,别闹,访问注册中心不就可以了吗

通过下图我们可以看到生产者已经注册进来了,可以看到相应的启动端口

至于生产者和注册中心的代码在前面已讲解,本篇不再重复。

路由zuul构建 

pom引入

        <dependency> 			<groupId>org.springframework.retry</groupId> 			<artifactId>spring-retry</artifactId> 		</dependency>  		<dependency> 			<groupId>org.springframework.cloud</groupId> 			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> 		</dependency> 		<dependency> 			<groupId>org.springframework.cloud</groupId> 			<artifactId>spring-cloud-starter-netflix-zuul</artifactId> 		</dependency>

启动类 加注解@EnableZuulProxy

@Bean注入了token认证的一个bean(演示其他功能使用)

 @SpringBootApplication @EnableZuulProxy public class SpringCloudZuul002Application {  	public static void main(String[] args) { 		SpringApplication.run(SpringCloudZuul002Application.class, args); 		System.out.println("/***************success  zuul 6001 启动成功******************/");  	} 	@Bean 	public TokenFilter tokenFilter() { 		return new TokenFilter(); 	}  }

配置文件:

 spring:   application:     name: spring-cloud-zuul-002 server:   port: 6001 eureka:   client:     service-url:       defaultZone: http://localhost:7001/eureka  zuul:   retryable: false   routes:     producer:       path: /api1/**       serviceId: spring-cloud-producter1-002     baidu:       path: /bd/**       url: http://www.baidu.com  

filter:token拦截

 public class TokenFilter  extends ZuulFilter{     private Logger logger= LoggerFactory.getLogger(TokenFilter.class);     @Override     public String filterType() {         return "pre"; // 可以在请求被路由之前调用     }      @Override     public int filterOrder() {         // filter执行顺序,通过数字指定 ,优先级为0,数字越大,优先级越低         return 0;     }      @Override     public boolean shouldFilter() {         // 是否执行该过滤器,此处为true,说明需要过滤         return true;     }      @Override     public Object run() throws ZuulException {         RequestContext ctx = RequestContext.getCurrentContext();         HttpServletRequest request = ctx.getRequest();          logger.info("--->>> TokenFilter {},{}", request.getMethod(), request.getRequestURL().toString());          String token = request.getParameter("token");// 获取请求的参数          if (StringUtils.isNotBlank(token)) {             ctx.setSendZuulResponse(true); //对请求进行路由             ctx.setResponseStatusCode(200);             ctx.set("isSuccess", true);             return null;         } else {             ctx.setSendZuulResponse(false); //不对其进行路由             ctx.setResponseStatusCode(400);             ctx.setResponseBody("token is empty");             ctx.set("isSuccess", false);             return null;         }     } }
 FallbackProvider
 @Component public class ProviderFallBack   implements FallbackProvider{     private Logger logger= LoggerFactory.getLogger(ProviderFallBack.class);     //指定要处理的 service。     @Override     public String getRoute() { //        api服务id,如果需要所有调用都支持回退,则return "*"或return null         return "spring-cloud-producter2-002";     }     /**      * 如果请求用户服务失败,返回什么信息给消费者客户端      */      @Override     public ClientHttpResponse fallbackResponse(String route, Throwable cause) {         return new ClientHttpResponse() {             /**              * 网关向api服务请求是失败了,但是消费者客户端向网关发起的请求是OK的,              * 不应该把api的404,500等问题抛给客户端              * 网关和api服务集群对于客户端来说是黑盒子              */             @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 {                 logger.info("/***********获取getBody  *******************/");                 Map r = new HashMap();                 r.put("state", "9999");                 r.put("msg", "系统错误,请求失败");                 //返回异常信息                 return new ByteArrayInputStream("The service is unavailable.".getBytes("UTF-8"));              }              @Override             public HttpHeaders getHeaders() {                 HttpHeaders headers = new HttpHeaders();                 //和body中的内容编码一致,否则容易乱码 //                headers.setContentType(MediaType.APPLICATION_JSON);                 headers.setContentType(MediaType.APPLICATION_JSON_UTF8);                 return headers;             }         };     }  }

内容比较多我们现在开始测试讲解

测试过程

启动zuul服务后,我们同样访问注册中心页面,发现已注册成功。

1. token认证实现

在我们构建接口的时候往往会有认证,此时怎么实现呢?

结合 filter:token拦截 代码(需要注册成组件,在启动类或者加注解可以)

我们可以看到程序对参数进行了token参数值的一个获取,很简单,验证是否为空即可(一般放在header里进行传递,有不明白的可以留言)

要是没有token会怎样呢?服务进行拦截,不再进行转发到生产者

无token访问

有token访问 

2.测试一中spring-cloud-producter1-002?这个是啥

解答:zuul路由注册到注册中心后通过服务的名称是可以直接调用生产者的,也就是spring-cloud-producter1-002是生产者1的名称

3.换种访问方式,猜猜api1是什么? 

 

我们可以看到测试1中返回的结果是一样的,自然api1就代表着生产者1的服务

在zuul的配置文件中指定即可

访问百度的时候  localhost:6001/bd?token=1  也是可以跳转的。

4.重点

一、zuul:开启重试机制

pom引入

 <dependency>    <groupId>org.springframework.retry</groupId>    <artifactId>spring-retry</artifactId> </dependency>

配置文件可以配置如下重试策略(结合文档看) 

二、api服务网关zuul回退fallback hystrix有fallback回退能力,及如果服务调用出现了异常,则执行指定的fallback方法。

     zuul对api服务集群进行了反向代理,集成了hystrix,那zuul也能fallback了。

  我们访问生产者2

为什么或这样,可以看到信息是在ProviderFallBack类定义的,说明生产者2没有调通,所有zuul回退返回了上面信息

 

生产者2controller如下:sleep很长时间,所以zuul调用超时,触发回退机制

 

End:

  zuul的讲解就结束了,比较简单,但是很重要!很重要!智能路由在服务中发挥着直观重要的作用

 我们现在zuul换成了spring cloud gateway,正在不断地开发新的功能,关于gateway的相关知识我们会用很多篇介绍也是整个微服务课程的重点(主要着做智能路由这块业务),有机会会开源相关插件,供大家参考

回到原点,即使springcloud不打算集成zuul2.x,但是简单了解下,面试或者工作还是有好处的,你说对吧?

编程之路期待你的参与 ,欢迎小伙伴加入 @架构师速成记

 下载:https://github.com/shinians/springcloud-demos

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!