SpringCloudNetflix之Hystrix(熔断器)、Zull(网关)、Feign完整使用(三)

简介: SpringCloudNetflix之Hystrix(熔断器)、Zull(网关)、Feign完整使用(三)

面向服务的路由


在刚才的路由规则中,我们把路径对应的服务地址写死了!如果同一服务有多个实例的话,这样做显然就不合理了。

我们应该根据服务的名称,去Eureka注册中心查找 服务对应的所有实例列表,然后进行动态路由才对!


添加Eureka客户端依赖


<!--添加eureka客户端-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

微信图片_20220527125757.png

开启Eureka客户端发现功能


package com.czxy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableZuulProxy         //开启zuul代理
@EnableEurekaClient     //开启eureka客户端
public class ZuulApplication {
    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication.class,args);
    }
}

添加Eureka配置 获取服务信息


#eureka配置
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka
    registry-fetch-interval-seconds: 5
  instance:
    prefer-ip-address: true   #是否注册ip地址
    ip-address: 127.0.0.1     #注册的IP地址

修改映射配置 通过服务名获取


因为已经有了Eureka客户端,我们可以从Eureka获取服务的地址信息,因此映射时无需指定IP地址,而是通过服务名称来访问

1.#路由配置
zuul:
  routes:
    service:
      path: /service/**   #zuul拦截的路径
#      url: http://localhost:9010
      serviceId: service  #将要访问的服务名

启动测试微信图片_20220527125841.png

简化的路由配置


在刚才的配置中,我们的规则是这样的:


  • zuul.routes.<route>.path=/xxx/**: 来指定映射路径。<route>是自定义的路由名
  • zuul.routes.<route>.serviceId=service:来指定服务名。

而大多数情况下,我们的<route>路由名称往往和 服务名会写成一样的。因此Zuul就提供了一种简化的配置语法:zuul.routes.<serviceId>=<path>


比方说上面我们关于user-service的配置可以简化为一条:

# zuul 网关配置路由配置
zuul:
  routes:
    classes-service: /classes-service/**

省去了对服务名称的配置。微信图片_20220527125820.png

默认的路由规则


在使用Zuul的过程中,上面讲述的规则已经大大的简化了配置项。但是当服务较多时,配置也是比较繁琐的。因此Zuul就指定了默认的路由规则:


默认情况下,一切服务的映射路径就是服务名本身。

例如服务名为:service,则默认的映射路径就是:/service/**

也就是说,刚才的映射规则我们完全不配置也是OK的,不信就试试看

微信图片_20220527125831.png

路由前缀


配置示例:

1.#路由配置
zuul:
  prefix: /api
  routes:
    service: /service/**   #zuul拦截的路径

微信图片_20220527125836.png

我们通过zuul.prefix=/api来指定了路由的前缀,这样在发起请求时,路径就要以/api开头。

路径/api/student-service/student将会被代理到/student-service/student

微信图片_20220527125841.png

过滤器


Zuul作为网关的其中一个重要功能,就是实现请求的鉴权。而这个动作我们往往是通过Zuul提供的过滤器来实现的。


ZullFilter

ZuulFilter是过滤器的顶级父类。在这里我们看一下其中定义的4个最重要的方法:

public abstract ZuulFilter implements IZuulFilter{
     abstract public String filterType(); //过滤器类型
     abstract public int filterOrder(); //执行顺序
     boolean shouldFilter(); //是否需要执行
     Object run() throws ZuulException; //具体业务逻辑
}
  • shouldFilter:返回一个Boolean值,判断该过滤器是否需要执行。返回true执行,返回false不执行。
  • run:过滤器的具体业务逻辑。
  • filterType:返回字符串,代表过滤器的类型。包含以下4种:
  • pre:请求在被路由之前执行
  • routing:在路由请求时调用
  • post:在routing和errror过滤器之后调用
  • error:处理请求时发生错误调用
  • filterOrder:通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高。


过滤器执行生命周期


这张是Zuul官网提供的请求生命周期图,清晰的表现了一个请求在各个过滤器的执行顺序。

微信图片_20220527125848.png

  • 正常流程:

请求到达首先会经过pre类型过滤器,而后到达routing类型,进行路由,请求就到达真正的服务提供者,执行请求,返回结果后,会到达post过滤器。而后返回响应。


  • 异常流程:

整个过程中,pre或者routing过滤器出现异常,都会直接进入error过滤器,再error处理完毕后,会将请求交给POST过滤器,最后返回给用户。

如果是error过滤器自己出现异常,最终也会进入POST过滤器,而后返回。

如果是POST过滤器出现异常,会跳转到error过滤器,但是与pre和routing不同的时,请求不会再到达POST过滤器了。

所有内置过滤器列表:微信图片_20220527125854.png

使用场景


场景非常多:


请求鉴权:一般放在pre类型,如果发现没有访问权限,直接就拦截了

异常处理:一般会在error类型和post类型过滤器中结合来处理。

服务调用时长统计:pre和post结合使用。


自定义过滤器


接下来我们来自定义一个过滤器,模拟一个登录的校验。基本逻辑:如果请求中有authorization请求头,则认为请求有效,放行。


定义过滤器类

package com.czxy.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.http.HttpStatus;
import javax.servlet.http.HttpServletRequest;
/**
 * Created by liangtong.
 */
@Component
public class LoginFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return "pre";       //路由之前执行
    }
    @Override
    public int filterOrder() {
        return 1;           //排序
    }
    @Override
    public boolean shouldFilter() {
        return true;        //是否进行过滤,true将执行run()方法
    }
    @Override
    public Object run() throws ZuulException {
        //1 获得上下文对象
        RequestContext requestContext = RequestContext.getCurrentContext();
        //2 获得请求对象
        HttpServletRequest request = requestContext.getRequest();
        //3 获得指定的请求头
        String token = request.getHeader("authorization");
        //如果没有token返回401
        if(token == null || "".equals(token)) {
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
        }
        return null;
    }
}

测试


没有token微信图片_20220527125901.png


有token微信图片_20220527125907.png

负载均衡和熔断


Zuul中默认就已经集成了Ribbon负载均衡和Hystix熔断机制。但是所有的超时策略都是走的默认值,比如熔断超时时间只有1S,很容易就触发了。因此建议我们手动进行配置:微信图片_20220527125916.png

#网关配置
zuul:
  retryable: true   #开启重试(注意:检查之前是否配置zuul,如果配置需要合并配置项)
#全局负载均衡配置
ribbon:
  ConnectTimeout: 250 # 连接超时时间(ms)
  ReadTimeout: 2000 # 通信超时时间(ms)
  OkToRetryOnAllOperations: true # 是否对所有操作重试
  MaxAutoRetriesNextServer: 2 # 同一服务不同实例的重试次数
  MaxAutoRetries: 1 # 同一实例的重试次数
#熔断
hystrix:
  command:
   default:
        execution:
          isolation:
            thread:
              timeoutInMillisecond: 6000 # 熔断超时时长:6000ms

后端代码


参考:

image.png

相关文章
|
1月前
服务熔断器-Hystrix
服务熔断器-Hystrix
23 2
|
7月前
|
Java 机器人 Maven
【Java用法】微服务之间的相互调用方式之一,通过FeignClient客户端调用其他微服务的方法包含熔断器(Hystrix)
【Java用法】微服务之间的相互调用方式之一,通过FeignClient客户端调用其他微服务的方法包含熔断器(Hystrix)
87 0
|
10月前
SpringCloud极简入门-Feign开启Hystrix
1.支付服务集成Hystrix 官方文档:https://cloud.spring.io/spring-cloud-static/Greenwich.SR5/single/spring-cloud.html#spring-cloud-feign-hystrix 支付服务 springcloud-pay-server-1040 之前集成了Feign,修改该工程集成Hystrix。我们除了要给Feign开启Hystrix以外还需要为Feign接口编写托底类。
106 0
|
4月前
|
Java Sentinel
【熔断限流组件resilience4j和hystrix】
【熔断限流组件resilience4j和hystrix】
|
2月前
|
监控 微服务
Hystrix熔断器设计思想(学习笔记)附(服务监控hystrixDashboard识图)
Hystrix熔断器设计思想(学习笔记)附(服务监控hystrixDashboard识图)
18 0
|
4月前
|
监控 Java Sentinel
springcloud4-服务熔断hystrix及sentinel
springcloud4-服务熔断hystrix及sentinel
26 0
|
9月前
Ribbon、Feign、Hystrix超时&重试&熔断问题
在使用Ribbon、Feign、Hystrix组合时,因为配置的问题出现以下现象,让我的大脑CPU烧的不行不行(拿我老家话说就是“脑子ran滴奥”)
105 0
|
5月前
|
监控 负载均衡 数据可视化
SpringCloud - Hystrix断路器-服务熔断与降级和HystrixDashboard
SpringCloud - Hystrix断路器-服务熔断与降级和HystrixDashboard
30 0
|
5月前
|
监控 数据可视化 Java
【使用Hystrix实现服务容错和熔断】—— 每天一点小知识
【使用Hystrix实现服务容错和熔断】—— 每天一点小知识
|
7月前
|
Java Spring
15SpringCloud - 断路器项目示例(Feign Hystrix)
15SpringCloud - 断路器项目示例(Feign Hystrix)
19 0