传送门:SpringCloud版本Hoxton SR5 --- 第一讲:认识 先看Zuul可以完成的功能,或者说他在项目中的定位和作用。

上篇文章主要讲:功能和作用都是用大白话,主要是通俗易懂的,推荐先看看

上面那篇文章也说了,路由 、过滤、容错与回退的三个功能。

这里就不多解释了,几乎每段配置都是有注释的。

后面有Zuul的集群说明。

简单提一句:zuul是什么?

Zuul包含了对请求的路由和过滤两个最主要的功能:

其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础而过滤器功能则负责对请求的处理过程进行干预,是实现请求校验、服务聚合等功能的基础.

Zuul和Eureka进行整合,将Zuul自身注册为Eureka服务治理下的应用,同时从Eureka中获得其他微服务的消息,也即以后的访问微服务都是通过Zuul跳转后获得。

注意:Zuul服务最终还是会注册进Eureka。

单机版:

依赖: springboot: 2.2.8.BUILD-SNAPSHOT<properties><java.version>1.8</java.version><spring-cloud.version>Hoxton.SR5</spring-cloud.version></properties><dependencies><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></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>
配置:#################################################### 基础公共配置 #######################################################
server:port: 7004  # 配置项目访问端口tomcat:uri-encoding: UTF-8   # 配置tomcat启动编码方式max-threads: 1000     # 配置 tomcat最大访问数 默认200min-spare-threads: 30 # 配置 tomcat 最小访问数 默认10#################################################### eureka客户端配置 ####################################################
eureka: # 注意下面的时间设置,是在网络不稳定的时候生效,但是如果是手动关闭eureka的客户端实例,会直接给eureka服务端发送信息,直接关闭在eureka中注册的服务client:serviceUrl:defaultZone: http://localhost:6004/eureka/  #单机配置 eureka服务端提供的注册地址,参考服务端配置的defaultZone属性值(就是将eureka客户端注册给eureka服务端)#      defaultZone: http://wangqinmin.com:6001/eureka  #集群配置   我建议使用这种,但是服务端的配置中,需要打开自我注册,默认也是打开的。#      defaultZone: http://wangqinmin.com:6001/eureka,http://127.0.0.1:6002/eureka,http://localhost:6003/eureka  #集群配置# 将本项目的客服端注册到所有的服务端中,为了防止服务端不注册自己的情况#(一般情况下不会出现这种问题,就是怕有些人不懂eureka,胡乱配置集群服务端,所以这是一个最稳妥的方式,如果就按照我服务端的配置来,就不会出现这样的问题。)# 其实会出问题的原因就是:手动的把自我注册的配置关闭了。# 这种配置还有一个缺点,没有连上的服务会不停的在日志中报错instance:instance-id: client-zuul-1 #此实例注册到eureka服务端的唯一的实例ID(也就是给当前项目指定一个ID,当当前项目运行起来后,就会将这个ID注册到eureka的服务端)prefer-ip-address: true #是否显示IP地址leaseRenewalIntervalInSeconds: 30 #eureka客户需要多长时间发送心跳给eureka服务器,表明它仍然活着,默认为30 秒 (与下面配置的单位都是秒)leaseExpirationDurationInSeconds: 90 #Eureka服务器在接收到实例的最后一次发出的心跳后,需要等待多久才可以将此实例删除,默认为90秒spring:application:name: zuul #实例注册到eureka服务端的name (集群模式下:相同功能的微服务名字必须相同,因为负载均衡调用的时候,直接使用此名字调用所有微服务)#################################################### zuul 配置 ####################################################
zuul:prefix: /api # 设置一个访问地址前缀。
#  strip-prefix: false # (默认true)当配置了prefix就是定义一个前缀, 每次访问都要加/api的前缀,但是有个问题: /api前缀出现在微服务调用接口的前缀上。如果这里设置为true,就会把微服务调用接口上的前缀清除,所以这里配置false,不清除ignored-services: "*"  # 禁止使用服务名来调用微服务。 还可以配置单个微服务名 :server-orderroutes:myitem:  # 为需要路由的微服务,自定义的一个名字serviceId: server-item  # 配置一个要路由的服务ID,在Eureka注册中心拿到的。path: /item/**  # /**表示,访问的后面不管有多少层级,都可以访问成功。myorder:   # 为需要路由的微服务,自定义的一个名字serviceId: server-order  # 配置一个要路由的服务ID,在Eureka注册中心拿到的。path: /order/**mylogin:serviceId: server-loginpath: /login/**
代码启动:package com.springcloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;/*** @author: wangqinmin* @date : 2020/6/14* <p>** 这里不用加 @EnableEurekaClient注解,因为zuul会自己整合。* zuul还会自己整合 Hystrix  和 Ribbon 整合。** @EnableZuulProxy简单理解为@EnableZuulServer的增强版,* 当Zuul与Eureka、Ribbon等组件配合使用时,我们使用@EnableZuulProxy*/
@SpringBootApplication
@EnableZuulProxy
//@EnableZuulServer
public class ZuulServerApplication {/*** 当对zuul的yml仅仅只做eureka和端口号的配置,这时zuul就可以使用了:* yml中其他配置也是有注释的。* 主要就是些路由功能。*/public static void main(String[] args) {SpringApplication.run(ZuulServerApplication.class);}
}

配置zuul自定义过滤器 (看需求使用)

package com.springcloud.config;import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;/*** @author: wangqinmin* @date : 2020/6/14* @description: 仰天大笑出门去,我辈岂是蓬蒿人* <p>* <p>* 过滤器(filter)是zuul的核心组件 zuul大部分功能都是通过过滤器来实现的。* <p>* zuul中定义了4种标准过滤器类型,这些过滤器类型对应于请求的典型生命周期如下:* PRE:这种过滤器在请求被路由之前调用。可利用这种过滤器实现身份验证、在 集群中选择请求的微服务、记录调试信息等。* ROUTING:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服 务的请求,并使用 Apache HttpCIient或 Netfilx Ribbon请求微服务* POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准 的 HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。* ERROR:在其他阶段发生错误时执行该过滤器。*/
@Component
public class LoggerFilter extends ZuulFilter {Logger logger = LoggerFactory.getLogger(LoggerFilter.class);/*** 这里就是选择过滤器的类型:* 具体使用谁,主要就是考虑需要在哪个生命周期下,修改代码。** @return*/@Overridepublic String filterType() {return FilterConstants.PRE_TYPE;}/*** 过滤器的优先级: 数值越小越优先。* 比如我写两个PRE类型的过滤器,这就可以指定,先执行谁 。* 当然如果过滤器类型不同,还是要遵循zuul过滤器当中的四种生命周期顺序。** @return*/@Overridepublic int filterOrder() {// return 0;/*** 默认pre级别为5:* 什么意思呢 ?* 就是zuul他自己本身就实现了zuul的过滤器,如果你还要添加新的功能,就要考虑是在zuul默认过滤器执行之前执行,还是之后执行。** 我本身这里写代码也是测试,我是为了获取ip地址,然后打印日志。* ip地址的获取呢,zuul自己也有实现,正好就是zuul的过滤器执行时保存了起来。* 所以我优先级,在默认的情况下 + 1。*/return FilterConstants.PRE_DECORATION_FILTER_ORDER + 1;}/*** 生命是否启用当前过滤器 (默认false)** @return*/@Overridepublic boolean shouldFilter() {return true;}/*** 这里就是具体的过滤逻辑。* 有没有发现这里没有传入request ? 那我们怎么写过滤逻辑 ?* <p>* 在源码中,有:RequestContext currentContext = RequestContext.getCurrentContext() 这段代码,* 在线程中,这个是存在的,所有可以直接拿。这里面就有我们需要的几乎所有东西。* 源码里面也写了过滤器,但是他把所有信息,都put到了RequestContext里面。** @return* @throws ZuulException*/@Overridepublic Object run() throws ZuulException {RequestContext currentContext = RequestContext.getCurrentContext();String requestURI = currentContext.getRequest().getRequestURI();String remoteAddr = currentContext.getRequest().getRemoteAddr();logger.warn("请求URI地址:[{}],远程访问地址:{}", requestURI, remoteAddr);
// 2020-06-14 23:36:34.506  WARN 53856 --- [nio-7004-exec-1] com.springcloud.config.LoggerFilter      : 请求URI地址:[/api/login/getFeignOrderInfo],远程访问地址:0:0:0:0:0:0:0:1return null;}
}

配置zuul的容错与回退 (差不多就是降级功能)只不过这里是单独的类,重写降级方法。

package com.springcloud.config;import com.netflix.hystrix.exception.HystrixTimeoutException;
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;/*** @author: wangqinmin* @date : 2020/6/15* @description: 仰天大笑出门去,我辈岂是蓬蒿人*/
@Component
public class ZuulFallbackProvide implements FallbackProvider {@Overridepublic String getRoute() {//制定为哪个微服务提供回退(这里写微服务名 写*代表所有微服务)return "*";}/*** 此方法需要返回一个ClientHttpResponse对象, ClientHttpResponse是一个接口,具体的回退逻辑要实现此接口** @param route 出错的微服务名* @param cause 出错的异常* @return*/@Overridepublic ClientHttpResponse fallbackResponse(String route, final Throwable cause) {//这里可以判断根据不同的异常来做不同的处理, 也可以不判断//完了之后调用response方法并根据异常类型传入HttpStatusif (cause instanceof HystrixTimeoutException) {return response(HttpStatus.GATEWAY_TIMEOUT); // 504} else {return response(HttpStatus.INTERNAL_SERVER_ERROR); // 500}}/*** 这个是自己写的,可以自己定义。** @param status* @return*/private ClientHttpResponse response(final HttpStatus status) {//这里返回一个ClientHttpResponse对象 并实现其中的方法,关于回退逻辑的详细,便在下面的方法中return new ClientHttpResponse() {@Overridepublic HttpStatus getStatusCode() throws IOException {//返回一个HttpStatus对象 这个对象是个枚举对象, 里面包含了一个status code 和reasonPhrase信息return status;}@Overridepublic int getRawStatusCode() throws IOException {//返回status的code  比如 404,500等return status.value();}@Overridepublic String getStatusText() throws IOException {//返回一个HttpStatus对象的reasonPhrase信息return status.getReasonPhrase();}@Overridepublic void close() {//close的时候调用的方法, 讲白了就是当降级信息全部响应完了之后调用的方法}/*** 这里测试的时候,我没有打开 item的微服务,直接调用item的地址:* http://localhost:7004/api/item/query** 然后页面就会返回这里配置的降级信息。* @return* @throws IOException*/@Overridepublic InputStream getBody() throws IOException {//把降级信息响应回前端return new ByteArrayInputStream("降级信息,系统繁忙,稍后再试".getBytes());}@Overridepublic HttpHeaders getHeaders() {//需要对响应报头设置的话可以在此设置HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);return headers;}};}
}

当你使用SpringCloud之后,你一定会有一个疑问。

就是以前没有Zuul的时候,我们怎么调用微服务 ?

举个例子 :

User微服务      配置  3台机器

Order微服务    配置   3台机器

比如说,我们用户必须要先登录,登录成功之后就可以查询我这个用户的订单信息了。

想想,当使用了Eureka,注册了User、Order。

User里面有Ribbon负载均衡的配置,这时候User微服务内部调用Order微服务,Order微服务被调用,使用了负载均衡。

可是User没有被负载均衡啊,对不对 ?User有3个服务,怎么用一个地址,调用3个User的ip呢 ?

User有3台机器,比如:他们的内网ip分别是: 192.168.2.11;192.168.2.12;192.168.2.13;

那么前端调用会出一个问题,我用着3个ip都是可以调用的。但是没有负载均衡的功能。

这时候就会出现一个问题,比如,我不用nginx做反向代理,我就用zuul做代理。

这时候就可以解决了上面的问题,可以直接调用zuul,然后zuul路由,但是接着问题又来了。

比如服务比较多,一个zuul不够吧,为了高可用,我要做个zuul集群。

接下来,就配置了3个zuul,分别是3台服务器。 这时候3个zuul ? 我调用哪个zuul 才能真正的高可用、负载均衡 ?

所以这种情况,就需要再来一个zuul,这个zuul路由 那3个zuul 。 还有个解决方案,用nginx做反向代理,代理那3个zuul。

我也没有具体测试过,zuul或nginx这两个做网关路由,谁的性能好。不过,网络上倒是有很多人做这种测试,结果下来:其实都是差不多的,主要都是说,如果服务器性能好,java就跑的快,zuul预热一下后,会访问更快。所以在nginx与zuul的选择上,还是要看自己喜欢哪种,毕竟没有一个明确的界限。

接下来就搭集群: 用zuul 路由 2个zuul  (为了用zuul 路由集群zuul测试了很久,不知道为什么就是不行。我成功的自闭了。)

但是一定可以的。我再找解决方案。


还是用nginx做反向代理把。nginx使用还是很简单的。就不贴配置文件了。

集群的zuul配置都是一样的,唯一不同的就是 :

访问端口号不同。

instance-Id :配置自己的名字,且不相同。

下面的Spring.application.name 必须相同。   其他配置都是一样的,启动就好了。

#################################################### 基础公共配置 #######################################################
server:port: 7002  # 配置项目访问端口#################################################### eureka客户端配置 ####################################################
eureka: # 注意下面的时间设置,是在网络不稳定的时候生效,但是如果是手动关闭eureka的客户端实例,会直接给eureka服务端发送信息,直接关闭在eureka中注册的服务client:serviceUrl:defaultZone: http://localhost:6004/eureka/  #单机配置 eureka服务端提供的注册地址,参考服务端配置的defaultZone属性值(就是将eureka客户端注册给eureka服务端)#      defaultZone: http://wangqinmin.com:6001/eureka  #集群配置   我建议使用这种,但是服务端的配置中,需要打开自我注册,默认也是打开的。#      defaultZone: http://wangqinmin.com:6001/eureka,http://127.0.0.1:6002/eureka,http://localhost:6003/eureka  #集群配置# 将本项目的客服端注册到所有的服务端中,为了防止服务端不注册自己的情况#(一般情况下不会出现这种问题,就是怕有些人不懂eureka,胡乱配置集群服务端,所以这是一个最稳妥的方式,如果就按照我服务端的配置来,就不会出现这样的问题。)# 其实会出问题的原因就是:手动的把自我注册的配置关闭了。# 这种配置还有一个缺点,没有连上的服务会不停的在日志中报错instance:instance-id: client-zuul-2 #此实例注册到eureka服务端的唯一的实例ID(也就是给当前项目指定一个ID,当当前项目运行起来后,就会将这个ID注册到eureka的服务端)prefer-ip-address: true #是否显示IP地址leaseRenewalIntervalInSeconds: 30 #eureka客户需要多长时间发送心跳给eureka服务器,表明它仍然活着,默认为30 秒 (与下面配置的单位都是秒)leaseExpirationDurationInSeconds: 90 #Eureka服务器在接收到实例的最后一次发出的心跳后,需要等待多久才可以将此实例删除,默认为90秒spring:application:name: server-zuul #实例注册到eureka服务端的name (集群模式下:相同功能的微服务名字必须相同,因为负载均衡调用的时候,直接使用此名字调用所有微服务)#################################################### zuul 配置 ####################################################
zuul:
#  prefix: /api # 设置一个访问地址前缀。
#  strip-prefix: false # (默认true)当配置了prefix就是定义一个前缀, 每次访问都要加/api的前缀,但是有个问题: /api前缀出现在微服务调用接口的前缀上,如果这里设置为true,就会把微服务调用接口上的前缀清除,所以这里配置false,不清除ignored-services: '*'  # 禁止使用服务名来调用微服务。 还可以配置单个微服务名 :server-orderroutes:mylogin:serviceId: server-loginpath: /login/**myitem:  # 为需要路由的微服务,自定义的一个名字serviceId: server-item  # 配置一个要路由的服务ID,在Eureka注册中心拿到的。path: /item/**  # /**表示,访问的后面不管有多少层级,都可以访问成功。myorder:   # 为需要路由的微服务,自定义的一个名字serviceId: server-order  # 配置一个要路由的服务ID,在Eureka注册中心拿到的。path: /order/**

自闭了。

SpringCloud版本Hoxton SR5 --- 第五讲:zuul 路由、过滤、容错与回退、集群、高可用相关推荐

  1. SpringCloud版本Hoxton SR5 --- 第一讲:认识

    什么是SpringCloud ?我用好理解的方式作比喻: 这里我们拿京东的网站做解释,京东不一定这么搞得,但是思想是一致的.首先SpringCloud一种微服务架构的实现:首先京东支持14亿人访问,这 ...

  2. SpringCloud版本Hoxton SR5 --- 第七讲:SpringCloud Config 分布式配置中心+整合bus、rabbitmq、actuator

    传送门:SpringCloud版本Hoxton SR5 --- 第一讲:认识 先看SpringCloud Config 可以完成的功能,或者说他在项目中的定位和作用. SpringCloud conf ...

  3. SpringCloud版本Hoxton SR5 --- 第三讲:Ribbon 、Ribbon与Feign配合使用

    传送门:SpringCloud版本Hoxton SR5 --- 第一讲:认识 先看Ribbon.Fegin可以完成的功能,或者说他在项目中的定位和作用. 上篇文章主要讲:功能和作用都是用大白话,主要是 ...

  4. SpringCloud版本Hoxton SR5 --- 第八讲:Sleuth 分布式链路跟踪 整合Zipkin + Elasticsearch持久化

    传送门:SpringCloud版本Hoxton SR5 --- 第一讲:认识 先看Sleuth.Zipkin.Elasticsearch 可以完成的功能,或者说他在项目中的定位和作用. Sleuth比 ...

  5. SpringCloud版本Hoxton SR5 --- 第四讲:Hystrix 熔断、限流(线程)、降级

    传送门:SpringCloud版本Hoxton SR5 --- 第一讲:认识 先看Hystrix 可以完成的功能,或者说他在项目中的定位和作用. 上篇文章主要讲:功能和作用都是用大白话,主要是通俗易懂 ...

  6. SpringCloud(第 051 篇)EurekaServer集群高可用注册中心以及简单的安全认证

    SpringCloud(第 051 篇)EurekaServer集群高可用注册中心以及简单的安全认证 - 一.大致介绍 1.前面章节分析了一下 Eureka 的源码,我们是不是在里面注意到了 Peer ...

  7. SpringCloud 微服务工具集 SpringCloud 版本: Hoxton SR6

    SpringCloud 微服务工具集v1.1 SpringCloud版本: Hoxton SR6 SpringBoot版本: 2.2.x --2.3.x 1.什么是微服务 官网: https://ww ...

  8. SpringCloud(第 025 篇)Zuul 路由后面的微服务挂了后,Zuul 提供了一种回退机制来应对熔断处理...

    2019独角兽企业重金招聘Python工程师标准>>> SpringCloud(第 025 篇)Zuul 路由后面的微服务挂了后,Zuul 提供了一种回退机制来应对熔断处理 一.大致 ...

  9. Redis~集群(分布理论、一致性哈希分区、虚拟槽分区、节点握手、集群通信、集群伸缩、请求路由、故障转移、集群维护)

    文章目录 分布理论 集群的分布式存储 简单哈希 一致性哈希分区 虚拟槽分区 Redis集群功能限制 节点握手 分配槽 集群通信 Gossip消息 集群伸缩 集群扩容 集群收缩 请求路由 MOVED重定 ...

  10. Spring Cloud Zuul网关 Filter、熔断、重试、高可用的使用方式

    时间过的很快,写springcloud(十):服务网关zuul初级篇还在半年前,现在已经是2018年了,我们继续探讨Zuul更高级的使用方式. 上篇文章主要介绍了Zuul网关使用模式,以及自动转发机制 ...

最新文章

  1. 【第一道计算几何题】 UVA11178 Morley‘s Theorem (二维几何,旋转直线求求交点)
  2. 世界名画 | 陌上花开,可缓缓归矣
  3. 垃圾热解气化工艺的电气、仪表及控制系统设计
  4. maven依赖管理的概念
  5. 简约易收录的导航网站源码
  6. 金立旗下18辆车产被司法拍卖 成交额近500万元
  7. windows挂载linux共享,永久挂载 Windows 共享
  8. MySQL数据库中如何选择VARCHAR和CHAR类型
  9. mysql 变量 视图_MySQL – 无法使用SET变量创建视图
  10. 侧栏广告 image flash
  11. Astute Graphics for Mac(ai创意插件合集)
  12. Luogu P2525题解
  13. c语言程序基础设计题,《C语言程序设计基础》习题集(含答案)
  14. vos3000配置与通讯测试(一)
  15. csb反编译_GitHub - lyzz0612/csb2csd: cocostudio csb反编成csd
  16. spark.jars.packages使用镜像源加速
  17. 传智播客传智汇与华为联合举办主题沙龙,解读网络安全解决方案
  18. 中国历史上十大经典遗言
  19. Android前端判断敏感词汇
  20. ssh mysql jsp码头船只出行及配套货柜码放管理系统的设计与实现

热门文章

  1. 骚操作!那些富有感情的影视台词截图都是哪来的?
  2. css轻松写出梦幻西游动画效果
  3. CF1312E Array Shrinking(区间dp模板)
  4. 广告算法,反作弊,机器学习研发工程师
  5. word打开文档很久很慢_win7系统打开word文档很慢需要等待很长时间的五种解决方法...
  6. java duration 时间差_Java Duration toDays()用法及代码示例
  7. 中南大学计算机大一学什么时候发,中南大学计算机学院2019年夏令营
  8. php 与 html 的混合编程
  9. 什么是网站PR值?如何提高网站pr值?网站pr值查询!
  10. 支付公司如何赚钱?支付网关如何设计?