对于一个7*24小时无间断的线上服务来说,在服役时间内难免会遇到一些fail,例如db断开连接且短暂连接不上了, 下游的某个节点忽然挂了,运维部署上依赖的某一个东西不存在了等等场景。本文主要来讨论一下这些场景使用怎样的策略会比较好。

  最简单的方法,While(true) + sleep(固定时间)  不断的重试,直到成功为止。这个方法的优点就是简单,可依赖。缺点就是对于感知延迟要求比较严格的程序,会消耗大量的CPU,甚至因为一些不合理的逻辑导致CPU满载等等情况发生.这种简单粗暴的方法应用广泛,并且能解决实际问题,在很多场合还是非常可取. 我们暂且叫这种策略为”粗暴法”.

  我曾经在一个实时文件抓取程序中(类似于scribe这样的实时日志传输方案),使用了这样的策略,当fstat源文件发现文件不存在的时候,我会重试1000次,每次间隔sleep 10ms, 其间程序会输出很多warnning信息来支持一些报警等,重试完1000次之后(10s之后),将sleep间隔设置为固定时间,例如1s,在降低程序对CPU的消耗的同时,保证了一定的实时性,源文件无论什么时候出现都能够确保在1s内cover进来,而且这样的策略对于日志切分场景也非常实用,普通的日志切分(如切分nginx为每小时一个文件,crontab每小时mv access.log access.log.$date再 kill -USR1等)程序能够立马感知到并作出相应的策略调整。我们暂且叫这种策略为”重试N次后,将间隔时间调整为最大的可接受值”.

  再看看另外一种方法,最近看了下facebook scribe的源码(感兴趣的自己google,大家可以姑且的认为是一个多下游的日志转发工具),他在下游死掉了之后选择对sleep时间循序渐进的策略,每次将retryInterval *1.414; (sqrt(2)),再加上一个范围随机数(如1-100ms),同时来设定了一个最大值的方式来相对动态的判断下游状态. 为什么一定要设置最大值呢?因为这个策略在异常时间久了之后,滞后性会非常大,当一场恢复时,可能不能及时感知,所以需要一个最大值做保证。我们暂且叫这种策略为“重试时间循序渐进, 且确保不大于最大可接受值“.

  近两年来使用zookeeper(以下简称zk)的公司越来越多,很多公司都用zk来做大型分布式系统的协调,他的模式类似于:下游通过在zk上注册一个临时节点,告诉大家,我活着呢, 上游通过watch这个节点的变化来感知下游的变化。模式很简单,但是大家都是用zk是因为他提供了很多额外的东西,例如下游注册的临时节点在下游宕机,或者网络不可达(反正就是挂了)等等情况下会自动清除,并且通过回调函数实时让上游程序感知,作出相应变化,当下游活了之后,又注册一个临时节点宣称自己活了,上游程序也能通过回调函数实时感知。上游程序依赖zookeeper的一个Lib库。对于上游程序来说,他是一个观察者,套进设计模式就是观察者模式,好莱坞有句名言. “不要给我打电话, 我会给你打电话”.我们暂且叫这种策略为“被动实时感知下游变化”

  先写到这里(也只想到了这些),后续有所想法再补充吧,也欢迎各位看官留言,过去的博文都长篇大论,以后尽量做到简约不简单吧。毕竟时间精力有限。

failover机制的小讨论的更多相关文章

  1. Apche Kafka 的生与死 – failover 机制详解

    Kafka 作为 high throughput 的消息中间件,以其性能,简单和稳定性,成为当前实时流处理框架中的主流的基础组件. 当然在使用 Kafka 中也碰到不少问题,尤其是 failover ...

  2. Apche Kafka 的生与死 – failover 机制详解

    转自:http://www.cnblogs.com/fxjwind/p/4972244.html Kafka 作为 high throughput 的消息中间件,以其性能,简单和稳定性,成为当前实时流 ...

  3. tomcat集群的failover机制

    集群要提供高可用性就必须要有某种机制去保证,常用的机制为failover(故障转移),简单说就是通过一定的heartbeat检测是否有故障,一旦故障发生备份节点则接管故障节点的工作. tomcat使用 ...

  4. 第1节 flume:11、flume的failover机制实现高可用

    1.4 高可用Flum-NG配置案例failover 在完成单点的Flume NG搭建后,下面我们搭建一个高可用的Flume NG集群,架构图如下所示: 图中,我们可以看出,Flume的存储可以支持多 ...

  5. 理解Django 中Call Stack 机制的小Demo

    1.工作流程 request/response模式下,request并不是直接到达view方法,view方法也不是将返回的response直接发送给浏览器的,而是request由外到里的层层通过各种m ...

  6. python垃圾回收机制与小整数池

    python垃圾回收机制 当引用计数为0时,python会删除这个值. 引用计数 x = 10 y = x del x print(y) 10 引用计数+1,引用计数+1,引用计数-1,此时引用计数为 ...

  7. python的代码块缓存机制,小数据池机制。

    同一代码块的缓存机制 在python中一个模块,一个函数,一个类,一个文件等都是一个代码块. 机制内容:Python在执行同一个代码块的初始化对象的命令时,会检查是否其值是否已经存在,如果存在,会将其 ...

  8. 关于java中自增,自减,和拓展运算符的小讨论

    java中运算符很多,但是能深入讨论的不算太多.这里我仅仅以++,*=为例做讨论. 例:++ i=0; i=i++ + ++i;//i=1 i=++i+i++;//i=2 i=i++ -++i;//i ...

  9. C# Note34: 异常机制相关小点

    1.使用throw和throw ex抛出异常的区别 通常,我们使用try/catch/finally语句块来捕获异常,那么在抛出异常的时候,使用throw和throw ex有什么区别呢? 假如,按顺序 ...

随机推荐

  1. Javascript基础回顾 之(三) 面向对象

    本来是要继续由浅入深表达式系列最后一篇的,但是最近团队突然就忙起来了,从来没有过的忙!不过喜欢表达式的朋友请放心,已经在写了:) 在工作当中发现大家对Javascript的一些基本原理普遍存在这里或者 ...

  2. 避免Castle Windsor引起的内存泄露

    原文地址: http://nexussharp.wordpress.com/2012/04/21/castle-windsor-avoid-memory-leaks-by-learning-the-u ...

  3. 接口自动化测试的"开胃小菜"---简单黑客攻击手段

    Web应用系统的小安全漏洞及相应的攻击方式 接口自动化测试的"开胃小菜" 1   写作目的 本文讲述一个简单的利用WebAPI来进行一次基本没有破坏力的“黑客”行为. 主要目的如下 ...

  4. Microsoft Azure Web Sites应用与实践【2】—— 通过本地IIS 远程管理Microsoft Azure Web Site

    Microsoft Azure Web Sites应用与实践 系列: [1]—— 打造你的第一个Microsoft Azure Website [2]—— 通过本地IIS 远程管理Microsoft ...

  5. Hibernate 延迟加载原理

        如何简单的理解延迟加载?开发中常见的org.hibernate.LazyInitializationException no session错误又是怎么产生的?下面通过一个简单的例子来解析一下 ...

  6. AutoMapper 最佳实践

    AutoMapper 是一个基于命名约定的对象->对象映射工具. 只要2个对象的属性具有相同名字(或者符合它规定的命名约定),AutoMapper就可以替我们自动在2个对象间进行属性值的映射.如 ...

  7. Visual Studio Code 调试 nodeJS

    Step 1: 点击Debug按钮,调出launch.json文件,更改program的路径为目标js文件. 生成的luanch.json文件在.vscode文件下 step2:接下来就可以加断点调试 ...

  8. 《Entity Framework 6 Recipes》中文翻译系列 (44) ------ 第八章 POCO之POCO中使用值对象和对象变更通知

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 8-4  POCO中使用值对象(Complex Type--也叫复合类型)属性 问题 ...

  9. PHP钩子机制

    什么是钩子 大家想必听过插件,wordpress插件特别多,这个就是用钩子机制实现的. 当代码在运行的过程中,我们预先在运行的几个特殊点里执行一些特殊方法:例如在运行方法(例如Blog::add的ad ...

  10. JVM字节码指令

    invokevirtual 调用实例方法 invokespecial 调用父类构造,实例初始化方法,私有方法 dup 复制栈顶数值,并且复制值进栈,pop/pop2为栈顶值出栈 aload_0 加载第 ...