SpringCloud学习笔记

一、Eureka
    1、Register:服务注册
    当Eureka客户端向Eureka Server注册时,它提供自身的元数据,比如IP地址、端口,运行状况指示符URL,主页等。

    2、Renew:服务续约
    Eureka客户会每隔30秒发送一次心跳来续约。 通过续约来告知Eureka Server该Eureka客户仍然存在,没有出现问题。 正常情况下,如果Eureka Server在90秒没有收到Eureka客户的续约,它会将实例从其注册表中删除。 建议不要更改续约间隔。

    3、Fetch Registries:获取注册列表信息
    Eureka客户端从服务器获取注册表信息,并将其缓存在本地。客户端会使用该信息查找其他服务,从而进行远程调用。该注册列表信息定期(每30秒钟)更新一次。每次返回注册列表信息可能与Eureka客户端的缓存信息不同, Eureka客户端自动处理。如果由于某种原因导致注册列表信息不能及时匹配,Eureka客户端则会重新获取整个注册表信息。 Eureka服务器缓存注册列表信息,整个注册表以及每个应用程序的信息进行了压缩,压缩内容和没有压缩的内容完全相同。Eureka客户端和Eureka 服务器可以使用JSON / XML格式进行通讯。在默认的情况下Eureka客户端使用压缩JSON格式来获取注册列表的信息。

    4、Cancel:服务下线
    Eureka客户端在程序关闭时向Eureka服务器发送取消请求。 发送请求后,该客户端实例信息将从服务器的实例注册表中删除。该下线请求不会自动完成,它需要调用以下内容:
    DiscoveryManager.getInstance().shutdownComponent();

    5、Eviction 服务剔除
    在默认的情况下,当Eureka客户端连续90秒没有向Eureka服务器发送服务续约,即心跳,Eureka服务器会将该服务实例从服务注册列表删除,即服务剔除。
 
二、Feign
    1、首先通过@EnableFeignClients,开启FeignClient
    2、根据Feign的规则实现接口,并添加FeignClient注解
    3、程序启动时,会进行包扫描,扫描所有的@FeginClient注解类,并将这些信息注入到IOC容器中
    4、当接口被调用时,通过jdk动态代理来生成具体的RequestTemplate
    5、RequestTemplate在生成Request
    6、Request交给Client去处理,其中客户端可以使httpUrlConnetion,httpClient,okhttp
    7、最后Client被封在到loadBalanceClient类,这个类结合Ribbon做到了负载均衡
    
三、Ribbon

负载均衡器是从EurekaClient获取服务信息,并根据IRule去路由,并且根据IPing去判断服务的可用性。
   负载均衡器多久一次去获取一次从Eureka Client获取注册信息呢,即每10秒钟,向EurekaClient发送一次"ping"。
   由此可见,LoadBalancerClient是在初始化的时候,会向Eureka回去服务注册列表,并且向通过10s一次向EurekaClient发送“ping”,
   来判断服务的可用性,如果服务的可用性发生了改变或者服务数量和之前的不一致,
   则更新或者重新拉取。LoadBalancerClient有了这些服务注册列表,就可以根据具体的IRule来进行负载均衡。

  综上所述:
  1、Ribbon的负载均衡,主要通过LoadBalancerClient来实现的
  2、而LoadBalancerClient具体交给了ILoadBalancer来处理
  3、ILoadBalancer通过配置IRule、IPing等信息,并向EurekaClient获取注册列表的信息,并默认10秒一次向EurekaClient发送“ping”,
  进而检查是否更新服务列表。
  4、最后,得到注册列表后,ILoadBalancer根据IRule的策略进行负载均衡。
  5、而RestTemplate 被@LoadBalance注解后,能过用负载均衡,主要是维护了一个被@LoadBalance注解的RestTemplate列表,
  并给列表中的RestTemplate添加拦截器,进而交给负载均衡器去处理。
  private static Map<String, LoadBalancerHttpClient> instanceMap = Maps.newConcurrentMap();

  public static LoadBalancerHttpClient getInstance(String clientName) {
    clientName = EnvironmentHolder.get().resolvePlaceholders(clientName);

    LoadBalancerHttpClient instance = instanceMap.get(clientName);
    if (instance == null) {
        synchronized (instanceMap) {
            instance = instanceMap.get(clientName);
            if (instance == null) {
                instance = new LoadBalancerHttpClient();
                instance.clientName = clientName;
                instanceMap.put(clientName, instance);
            }
        }
    }
    instance.initRequestContext();
    return instance;
}
四、Hystrix

    1、Hystrix的设计原则
        a、防止单个服务的故障,耗尽整个系统服务的容器(比如tomcat)的线程资源。
        b、减少负载并快速失败,而不是排队。
        c、在可行的情况下提供回退以保护用户免受故障。
        d、使用隔离技术(如隔板,泳道和断路器模式)来限制任何一个依赖的影响。
        e、通过近乎实时的指标,监控和警报来优化发现故障的时间。
        f、通过配置更改的低延迟传播优化恢复时间,并支持Hystrix大多数方面的动态属性更改,
            从而允许您使用低延迟反馈循环进行实时操作修改。
        g、保护整个依赖客户端执行中的故障,而不仅仅是在网络流量上进行保护降级、限流。 
        
    2、Hystrix是怎么工作的?
        1)、构建一个HystrixCommand或者HystrixObservableCommand 对象。
        2)、执行Command
            通过使用Hystrix命令对象的以下四种方法之一,可以执行该命令有四种方法(前两种方法仅适用于简单的HystrixCommand对象
            并不适用于HystrixObservableCommand):
            a、execute()–阻塞,然后返回从依赖关系接收到的单个响应(或者在发生错误时抛出异常)
            b、queue()–返回一个可以从依赖关系获得单个响应的future 对象
            c、observe()–订阅Observable代表依赖关系的响应,并返回一个Observable,该Observable会复制该来源Observable
            d、toObservable() --返回一个Observable,当您订阅它时,将执行Hystrix命令并发出其响应
            
    3.响应是否有缓存?
        如果为该命令启用请求缓存,并且如果缓存中对该请求的响应可用,则此缓存响应将立即以“可观察”的形式返回。
        
    4.断路器是否打开?
        当您执行该命令时,Hystrix将检查断路器以查看电路是否打开。

        如果电路打开(或“跳闸”),则Hystrix将不会执行该命令,但会将流程路由到(8)获取回退。

        如果电路关闭,则流程进行到(5)以检查是否有可用于运行命令的容量。    
        
    5.线程池/队列/信号量是否已经满负载?
        如果与命令相关联的线程池和队列(或信号量,如果不在线程中运行)已满,则Hystrix将不会执行该命令,但将立即将流程路由到(8)获取回退。
        
    6.HystrixObservableCommand.construct() 或者 HystrixCommand.run()
        在这里,Hystrix通过您为此目的编写的方法调用对依赖关系的请求,其中之一是:

        HystrixCommand.run() - 返回单个响应或者引发异常

        HystrixObservableCommand.construct() - 返回一个发出响应的Observable或者发送一个onError通知
        
    7.计算Circuit 的健康
        Hystrix向断路器报告成功,失败,拒绝和超时,该断路器维护了一系列的计算统计数据组。

        它使用这些统计信息来确定电路何时“跳闸”,此时短路任何后续请求直到恢复时间过去,在首次检查某些健康检查之后,它再次关闭电路。

    8.获取Fallback
        当命令执行失败时,Hystrix试图恢复到你的回退:当construct()或run()
        (6.)抛出异常时,当命令由于电路断开而短路时(4.),
        当 命令的线程池和队列或信号量处于容量(5.),或者当命令超过其超时长度时。

        编写Fallback ,它不一依赖于任何的网络依赖,从内存中获取获取通过其他的静态逻辑。
        如果你非要通过网络去获取Fallback,你可能需要些在获取服务的接口的逻辑上写一个HystrixCommand。
    9.返回成功的响应
    
    如果 Hystrix command成功,如果Hystrix命令成功,它将以Observable的形式返回对呼叫者的响应或响应。
    根据您在上述步骤2中调用命令的方式,此Observable可能会在返回给您之前进行转换:
    execute() - 以与.queue()相同的方式获取Future,然后在此Future上调用get()来获取Observable发出的单个值
    queue() - 将Observable转换为BlockingObservable,以便将其转换为Future,然后返回此未来
    observe() - 立即订阅Observable并启动执行命令的流程; 返回一个Observable,当您订阅它时,重播排放和通知
    toObservable() - 返回Observable不变; 您必须订阅它才能实际开始导致命令执行的流程
五、zuul


    在zuul中, 整个请求的过程如下:
    1、首先将请求httpRequest给zuulservlet处理,zuulservlet中有一个zuulRunner对象。
    2、该对象中初始化了RequestContext:作为存储整个请求的一些数据,并被所有的zuulfilter共享。
3、zuulRunner中还有 FilterProcessor,FilterProcessor作为执行所有的zuulfilter的管理器。
    4、FilterProcessor从filterloader 中获取zuulfilter,而zuulfilter是被filterFileManager所加载,并支持groovy热加载,采用了轮询的方式热加载。
    5、有了这些filter之后,zuulservelet首先执行的Pre类型的过滤器,再执行route类型的过滤器,最后执行的是post 类型的过滤器
    6、如果在执行这些过滤器有错误的时候则会执行error类型的过滤器。执行完这些过滤器,最终将请求的结果返回给客户端。
    不同类型过滤器:
        过滤器的order值越小,就越先执行,并且在执行过滤器的过程中,
        它们共享了一个RequestContext对象,该对象的生命周期贯穿于请求,
        可以看出优先执行了pre类型的过滤器,并将执行后的结果放在RequestContext中,供后续的filter使用,
        比如在执行PreDecorationFilter的时候,决定使用哪一个route,它的结果的是放在RequestContext对象中,
        后续会执行所有的route的过滤器,如果不满足条件就不执行该过滤器的run方法。最终达到了就执行一个route过滤器的run()方法。

        而error类型的过滤器,是在程序发生异常的时候执行的。

        post类型的过滤,在默认的情况下,只注入了SendResponseFilter,该类型的过滤器是将最终的请求结果以流的形式输出给客户单。
 
 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值