5.1 学习总结 Eureka,Zuul 自定义过滤器,Hystrix 熔断,Apahe ab http性能测试,Turbine 聚合监控

学习链接

问题

  1. Eureka 是什么

  2. Eureka 自我保护机制是什么?

  3. ribbon 的主要参数是什么?
    MaxAutoRetries 一台服务器的重试次数
    MaxAutoRetriesNextServer 更换服务器的次数
    ReadTimeout 等待后台服务响应的超时时间

  4. Ribbon 的重试

  5. Feign 是什么

  6. 网关 功能

  7. ZuulFilter

  8. zuul 集成Hystrix

1. Eureka 简介

1.1 Eureka 是什么

基于REST服务,用于定位服务,以实现云端中间层服务发现和故障转移

百科介绍:
Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,
主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。
SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能

1.2 两个组件:Eureka Server 和 Eureka Client

Eureka Server(提供注册服务)
提供服务注册服务,各个微服务节点通过配置启动后,会在EurekaServer中进行注册,
这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,
服务节点的信息可以在界面中直观看到。

EurekaClient(JAVA客户端,负责发送心跳)
通过注册中心进行访问,是一个java客户端,用于简化Eureka Server的交互,
客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。
在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒),如果Eureka Server多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中吧这个服务节点移除(默认90秒)。

在这里插入图片描述
服务注册:将服务信息注册进注册中心

服务发现:从注册中心上获取服务信息

实质:存key服务名,取value调用地址

1.3 Eureka的四条运行机制

1.注册

客户端会一次一次的反复注册,直到注册成功为止

2.拉取

客户端每隔30秒,重复的拉取,刷新本地缓存的注册表

3.心跳

客户端每隔30秒向服务器发送心跳,如果服务器连续3次收不到一个服务的心跳,

就会删除该服务的注册信息

4.自我保护模式

网络不稳定,或网络中断时,15分钟内85%的服务器心跳都出现异常,会进入自动

保护模式
这种特殊情况下,会保护所有的注册信息不被删除
等待网络恢复正常时,可以自动退出保护模式
开发调试期间应该禁用保护模式,避免影响测试

2 Feign

Feign可以把Rest的请求进行隐藏,伪装成类似SpringMVC的Controller一样。
不用再自己拼接url ,拼接参数等操作,都交给Feign

Feign只是一个便利的rest框架,简化调用,最后还是通过ribbon在注册服务器中找到服务实例,然后对请求进行分配。

Feign可以把例如上面这样的远程请求给隐藏起来,让别人看不到,看起来好像是在访问本地服务一样,有一种伪装功能。Feign替我们解决这件事的时候,我们也应该去告诉他 请求路径、请求参数、请求方式、返回结果,仔细想想这四个东西springmvc的注解就可以搞定,我们的controller方法,有@RequestMapping(method属性)、@PathVariable、return返回值。所以Feign就可以利用springmvc的注解识别这些信息,帮我们远程调用,不用我们写。

2.1 注解

启动类

在这里插入图片描述

FeignClient

在这里插入图片描述
这个注解类,其实就是Feign的一个客户端
@FeignClient(“user-service”):这个注解时指定服务名,去eureka拉取服务列表,然后底层利用ribben进行负载均衡挑选任意一个服务。访问@GetMapping(“user/findById/{id}”)路径,参数为id,返回一个User对象的json字符串,全部自动完成。

2.2 Feign 集成 Ribbon

Feign 是集成工具: 集成了远程调用, Ribbon

Ribbon 提供负载均衡和重试的功能

Ribbon的重试

调用后台服务失败(异常、超时、宕机),可以自动发起重试调用

  • ribbon.MaxAutoRetries
    单台服务器的重试次数,默认 0
  • ribbon.MaxAutoRetriesNextServer
    更换服务器的次数,默认 1
  • ribbon.ReadTimeout
    超时时间,默认 1000
  • ribbon.ConnectTimeout
    与后台服务器建立连接的超时时间,默认 1000
  • ribbon.OkToRetryOnAllOperations
    是否对所有类型请求都重试,默认只对 GET 请求重试

3 Zuul API网关

3.1 统一的权限校验

模拟登陆检查

http://localhost:3001/item-service/u4y544yy45 没有登录,不允许访问

http://localhost:3001/item-service/u4y544yy45?token=uyt343t3 已经登录,可以访问

  1. 新建过滤器,继承 ZuulFilter
  2. 按照规则实现 ZuulFilter
  3. 添加注解:@Component
  • zuul的自动配置类,会自动配置过滤器
package cn.tedu.sp06.filter;

import cn.tedu.web.util.JsonResult;
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.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

@Component
//统一的权限校验
public class AccessFilter extends ZuulFilter {
    //设置过滤器类型:pre,routing,post,error
    @Override
    public String filterType() {
//        return "pre";
        return FilterConstants.PRE_TYPE;//设置成前置过滤器
    }

    //设置过滤器的顺序号
    @Override
    public int filterOrder() {
        return 6;
    }

    //针对当前请求,是否执行过滤代码
    @Override
    public boolean shouldFilter() {
        //调用 item-service 需要判断权限
        //否则,不判断权限直接跳过代码
        /*
            1.获取请求上下文对象
            2.从上下文对象获取调用的服务id
            3.如果服务ID是item-service,返回true,否则false
         */
        //1.获取请求上下文对象
        RequestContext ctx = RequestContext.getCurrentContext();
        //2.从上下文对象获取调用的服务id
        String serviceId = (String) ctx.get(FilterConstants.SERVICE_ID_KEY);//("serviceId")
        //3.如果服务ID是item-service,返回true,否则false
        //IgnoreCase 忽略大小写
        return "item-service".equalsIgnoreCase(serviceId);
    }

    //过滤代码
    @Override
    public Object run() throws ZuulException {
        //
        //1.获取请求上下文对象
        RequestContext ctx = RequestContext.getCurrentContext();
        //2.从上下文获得request 对象
        HttpServletRequest request = ctx.getRequest();
        //3.从request 取出token参数
        String token = request.getParameter("token");
        //4.如果没有token null ""
        if (StringUtils.isBlank(token)){
            //阻止继续调用  发送zuul响应 禁用
            ctx.setSendZuulResponse(false);
            //直接向客户端返回响应
            String json = JsonResult.build().code(400).msg("未登录!").toString();
            ctx.addZuulResponseHeader("Content-Type","application/json;charset=UTF-8");
            ctx.setResponseBody(json);
        }

        return null;//当前zuul版本中这个返回值不起作用
    }
}

测试效果
在这里插入图片描述

Zuul 集成 Ribbon

  • 默认启用了负载均衡
  • 默认不启用重试
    一般不在网关添加重试功能,否则可能造成后台服务压力翻倍,出现大面积故障。
    重试功能应该尽量靠后添加

zuul启用重试

  1. 添加依赖: spring-retry
  2. yml配置: zuul.retryable=true

重试默认参数:

  • MaxAutoRetries: 0
  • MaxAutoRetriesNextServer: 1

4 Hystrix 断路器

容错和限流工具

  • 容错: 降级
  • 限流: 熔断

在这里插入图片描述

在这里插入图片描述

4.1 zuul 集成Hystrix

  1. 新建降级类,实现 FallbackProvider 接口
  2. 按接口规则进行实现
  3. 添加注解:@Component
  • zuul的自动配置类可以完成自动配置

item-service 业务降级
在这里插入图片描述

package cn.tedu.sp06.fb;

import cn.tedu.web.util.JsonResult;
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
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 ItemFB implements FallbackProvider {
    /*
    zuul+Hystrix降级

    getRoute 设置当前降级类,是针对哪个服务进行降级
        - item-service: 只针对商品降级
        - * :       对所有服务都应用当前降级类
        - null :    对所有服务都应用当前降级类

     */
    @Override
    public String getRoute() {
        return "item-service";
    }

    /*
    向客户端返回的响应

     */
    @Override
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.INTERNAL_SERVER_ERROR;
            }

            @Override
            public int getRawStatusCode() throws IOException {
                return HttpStatus.INTERNAL_SERVER_ERROR.value();
            }

            @Override
            public String getStatusText() throws IOException {
                return HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase();
            }

            @Override
            public void close() {
                //用来关闭下面方法中的流
                //ByteArrayInputStream 不占用任何底层系统资源 所以不需要关闭
            }

            @Override
            public InputStream getBody() throws IOException {

                String json = JsonResult.build().code(500).msg("调用后台服务出错").toString();
                //把json封装到ByteArrayInputStream   字符串转成数组封装到流
                return new ByteArrayInputStream(json.getBytes("UTF-8"));
            }

            @Override
            public HttpHeaders getHeaders() {
                //协议头 返回json格式

                HttpHeaders h = new HttpHeaders();
                h.add("Content-Type","application/json;charset=UTF-8");
                return h;
            }
        };
    }
}

4.2 Hystrix 熔断

限制访问流量
流量过大,出现故障,可以熔断,断开链路,减轻后台服务的压力

  • 熔断的触发条件:
    • 10秒20次请求(必须首先满足)
    • 50%请求出错
  • 断路器打开后一段时间,会进入“半开状态”
    • 半开状态下,会尝试发送一次客户端调用
      • 调用成功,关闭断路器恢复正常
      • 调用失败,继续保持打开状态

4.3 使用 Actuator 暴露 Hystrix 监控日志

http://localhost:3001/actuator

4.3.1 Hystrix利用Actuator来暴露自己的监控日志

添加 Actuator

Actuator是springboot 提供的一个项目指标工具

  • 健康状态
  • spring容器中所有的对象
  • springmvc 映射的所有路径
  • java虚拟机堆内存镜像
  1. actuator依赖
    zuul的依赖包已包含
  2. 暴露监控日志
    在这里插入图片描述

4.3.2 暴露所有监控日志

在zuul的yml文件添加

m.e.w.e.i="*"  暴露所有监控日志
m.e.w.e.i=health, beans, mappings
m.e.w.e.i=hystrix.stram

在这里插入图片描述

  1. 访问 http://localhost:3001/actuator

4.3.3 暴露hystrix的监控值 http://localhost:3001/actuator/hystrix.stream

暴露hystrix的监控值
在这里插入图片描述

4.4 hystrix-dashbord 仪表盘搭建

Hystrix数据监控 - Hystrix Dashboard

  1. 新建 spring 模块: sp07-hystrix-dashboard

  2. 添加依赖: hystrix dashboard

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>
  1. yml配置:
server:
  port: 4001
hystrix:
  dashboard:
    proxy-stream-allow-list: localhost  # 允许抓取的服务器列表

  1. 启动类注解: @EnablueHystrixDashboard
  • 访问: http://localhost:4001/hystrix
    在这里插入图片描述

4.5 Apache ab进行http性能测试

ab -n 20000 -c 100 http://localhost:3001/user-service/8
ab -n 20000 -c 100 http://localhost:3001/item-service/asd213?token=asd21as

ab的参数说明
-n 需要执行的请求次数
-c 并发的数量
-t 等待返回的最长时间
-b TCP收发缓冲区的大小,单位(byte)
-p 使用post (同时需要定义-T参数)
-u 使用put (同时需要定义-T参数)
-T content-type, 例如application/x-www-form-urlencoded, 默认为text/plain
-w 把结果打印在html的表格里
-x 表格的属性
-y tr行属性
-z td列属性
-C 设置cookie 例如Apach=1234
-H header行, 例如Accept-Encoding:gzip
-k 是否标示位HTTP Keep Alive

在这里插入图片描述

6网关高可用

  1. 运行下拉菜单 – edit configuration
  2. 编辑 06 启动配置
    • 名称:Sp06Zuul-3001
    • program arguments: --server.port=3001
  3. 左侧点复制按钮,修改成 3002

在这里插入图片描述

5 Turbine 聚合监控

Turbine
从多台服务器抓取日志,进行聚合

  1. 新建 spring 模块 :sp08-turbine
  2. 添加依赖
    <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-turbine</artifactId>
        </dependency>
    </dependencies>
  1. yml配置
spring:
  application:
    name: turbine

server:
  port: 5001

eureka:
  client:
    service-url:
      defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka

turbine:
  app-config: zuul
  cluster-name-expression: new String("default") #名字表达式
  1. 启动类注解
    在这里插入图片描述
  2. 测试 : 访问聚合日志: http://localhost:5001/turbine.stream

测试

http://localhost:5001/turbine.stream
http://localhost:3001/actuator/hystrix.stream
http://localhost:3002/actuator/hystrix.stream

ab -n 20000 -c 100 http://localhost:3001/user-service/8
ab -n 20000 -c 100 http://localhost:3002/user-service/8

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值