• Spring Cloud 学习笔记(2)--Greenwich.SR4


    上一节我们讲到了Eureka 注册中心服务端的配置,接下来我们进行Eureka客户端的配置

    服务提供者和服务消费者两个工程都属于客户端(这就好比滴滴出行的司机端和用户端,都是客户端)需要把他们分别注册到Eureka中

    这里也是参考服务端的pom那样,把版本统一管理两个pom.xml本次加的内容一样,故这里只截图其中一个

     

     provider的配置文件

     provider引导类:

     

     测试

     

     在开发环境如何实现高可用测试呢?了解内容

    因为一个运行实例就是一个tomcat,所以我们只需要拷贝一下运行实例即可,

     把配置文件中的 server.port去掉,将它配置到vm参数中,如上图,然后注册地址改成对方地址

    改的是同一个项目的配置文件哦,改了之后启动,然后紧接着再改,改了再启动另一个实例

    也可以这样改这段【-Dspring.profiles.active=peer2 -Dserver.port=8762】配置指定了Eureka Server实例启动时使用的配置文件、端口号,peer2就是配置文件的名称,下一步会创建这个配置文件。

    https://blog.csdn.net/lihailin9073/article/details/100712996 (具体看这篇文章)

     

     

    服务提供者

    在启动时,会检测配置属性中的:eureka.client.register-with-eureka=true参数是否正确,事实上默认就是true。如果值确实为true,则会向EurekaServer发起一个Rest请求,并携带自己的元数据信息,Eureka Server会把这些信息保存到一个双层Map结构中。

    • 第一层Map的Key就是服务id,一般是配置中的spring.application.name属性

    • 第二层Map的key是服务的实例id。一般host+ serviceId + port,例如:locahost:service-provider:8081

    • 值则是服务的实例对象,也就是说一个服务,可以同时启动多个不同实例,形成集群。

    在注册服务完成以后,服务提供者会维持一个心跳(定时向EurekaServer发起Rest请求),告诉EurekaServer:“我还活着”。这个我们称为服务的续约(renew)

    有两个重要参数可以修改服务续约的行为:


    eureka:
    instance:
      lease-expiration-duration-in-seconds: 90
      lease-renewal-interval-in-seconds: 30
    • lease-renewal-interval-in-seconds:服务续约(renew)的间隔,默认为30秒

    • lease-expiration-duration-in-seconds:服务失效时间,默认值90秒

    也就是说,默认情况下每个30秒服务会向注册中心发送一次心跳,证明自己还活着。如果超过90秒没有发送心跳,EurekaServer就会认为该服务宕机,会从服务列表中移除,这两个值在生产环境不要修改,默认即可

    但是在开发时,这个值有点太长了,经常我们关掉一个服务,会发现Eureka依然认为服务在活着。所以我们在开发阶段可以适当调小。


    eureka:
    instance:
      lease-expiration-duration-in-seconds: 10 # 10秒即过期
      lease-renewal-interval-in-seconds: 5 # 5秒一次心跳

    服务消费者

    启动时,会检测eureka.client.fetch-registry=true参数的值,如果为true,则会拉取Eureka Server服务的列表只读备份,然后缓存在本地。并且每隔30秒会重新获取并更新数据。我们可以通过下面的参数来修改:


    eureka:
    client:
      registry-fetch-interval-seconds: 5

    生产环境中,我们不需要修改这个值。

    负载均衡 Ribbon

    Eureka中已经帮我们集成了负载均衡组件 Ribbon,

    Ribbon是Netfiix发布的负载均衡器,它有助于控制HTTP和TCP客户端的行为,为Ribbon配置服务提供者地址列表后,Ribbon就可基于某种负载均衡算法,自动帮助服务消费者去请求。它默认提供了多种算法,如轮询/随机,当然也可以自定义算法。

    如何使用Ribbon呢?

    1,首先我们用上面同样的方法,将服务提供者拷贝一份,在8082端口上启动,这样服务端才有了两个;

    2,然后我们再在消费者端使用负载均衡器,默认情况下 Eureka已经集成了Ribbon,可以在Eureka的包中看到

    3,无需覆盖消费者的默认配置,加注解(这里比较特殊,不是加在引导类上,而是在RestTemplate方法上 @LoadBalanced

    4,修改Controller的调用方式,这里直接使用服务名调用,注释掉上次那个Host+Port的拼接。

     

     通过断点跟踪发现,执行的是如下代码

     下来我们可以写个测试来,来观察系统提供的负载均衡策略。(默认是轮询, 系统还提供了随机)

     

     i%count,来决定用哪一个

    如果你要想实现负载均衡器,实现接口IRule. 

     更改Consumer的配置文件负载均衡策略,并运行测试类看结果

     

    Hystix也是Netflix公司的组件

    Hystix是Netflix开源的一个延迟和容错库,用于隔离访问远程服务、第三方库、防止出现级联失败。

    雪崩问题: 看这篇文章的图解 https://cloud.tencent.com/developer/article/1445716

    Hystix解决雪崩问题的手段两种  线程隔离,服务熔断

    Hystrix为每个依赖服务调用分配一个小的线程池,如果线程池已满调用将被立即拒绝,默认不采用排队.加速失败判定时间。

    用户的请求将不再直接访问服务,而是通过线程池中的空闲线程来访问服务,如果线程池已满,或者请求超时,则会进行降级处理,什么是服务降级?

          服务降级:优先保证核心服务,而非核心服务不可用或弱可用。

    用户的请求故障时,不会被阻塞,更不会无休止的等待或者看到系统崩溃,至少可以看到一个执行结果(例如返回友好的提示信息) 。

    服务降级虽然会导致请求失败,但是不会导致阻塞,而且最多会影响这个依赖服务对应的线程池中的资源,对其它服务没有响应。

    触发Hystix服务降级的情况

    • 线程池已满

    • 请求超时 

    在服务调用方(消费者方)配置 Hystix

     

     我们测试超时情况的熔断,关掉服务提供者服务,重启消费者端,然后浏览器访问

    上面是在方法上的熔断,如果每个方法都写熔断不太现实,此时我们可以在类上加熔断

    请求在超过1秒后都会返回错误信息,这是因为Hystix的默认超时时长为1,我们可以通过配置修改这个值:

    我们可以通过hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds来设置Hystrix超时时间。毫秒值。

     

     如果要测试这个效果,就把服务提供者开启来,然后在它的方法里面睡眠一段时间,睡眠时间值大于设置的超时时间.

    
    
    @SpringCloudApplication组合注解,它相当于 @SpringBootApplication @EnableDiscoveryClient @EnableCircuitBreaker

     

    熔断器,也叫断路器,其英文单词为:Circuit Breaker

    ‘生活中典型的例子 就是 电路保险丝

    熔断状态机3个状态:

    • Closed:关闭状态,所有请求都正常访问

    • Open:打开状态,所有请求都会被降级。Hystix会对请求情况计数,当一定时间内失败请求百分比达到阈值,则触发熔断,断路器会完全打开。默认失败比例的阈值是50%,请求次数最少不低于20次。

    • Half Open:半开状态,open状态不是永久的,打开后会进入休眠时间(默认是5S)。随后断路器会自动进入半开状态。此时会释放部分请求通过,若这些请求都是健康的,则会完全关闭断路器,否则继续保持打开,再次进行休眠计时

    不过,默认的熔断触发要求较高,休眠时间窗较短,为了测试方便,我们可以通过配置修改熔断策略

    circuitBreaker.requestVolumeThreshold=10               触发熔断的最小请求次数,默认20
    circuitBreaker.sleepWindowInMilliseconds=10000     触发熔断的失败请求最小占比,默认50%
    circuitBreaker.errorThresholdPercentage=50            休眠时长,默认是5000毫秒

    为了能够精确控制请求的成功或失败,我们在consumer的调用业务中加入一段逻辑

    @GetMapping("{id}")
    @HystrixCommand
    public String queryUserById(@PathVariable("id") Long id){
    if(id == 1){
    throw new RuntimeException("太忙了");
    }
    String user = this.restTemplate.getForObject("http://service-provider/user/" + id, String.class);
    return user;
    }

    这样如果参数是id为1,一定失败,其它情况都成功。

    我们准备两个请求窗口:

    当我们疯狂访问id为1的请求时(超过20次),就会触发熔断。断路器会断开,一切请求都会被降级处理。

    此时你访问id为2的请求,会发现返回的也是失败,而且失败时间很短,只有几毫秒左右

  • 相关阅读:
    PHP学习(一)----变量及字符串
    swith
    重写和重载的区别
    静态对象与非静态对象
    继承
    面向对象
    五个对面向对象的实例
    双色球 36选7
    菱形java代码
    双色球代码
  • 原文地址:https://www.cnblogs.com/xin1006/p/11919079.html
Copyright © 2020-2023  润新知