我们有很多的手段保证数据的安全备案网站,但是要保证100%安全这是不可能的宕机检测。毕竟在系统运行的过程中,服务器可以出的问题千奇百怪,只能说尽可能的让数据尽可能的出出现丢失。宕机检测,线上服务宕机时,如何保证数据100%不丢失单纯的保证数据库本身的数据不丢失的话,最直接的方式就是通过建立主从库,实现数据的热备一般情况下,小的系统我们并不会考虑数据的热备,一般只是在每天定时进行冷备而已,也就是设置一个定时器,然后到时间就同步数据。不过这样做的话,一单系统的数据库出现异常,那么我们的数据就会回滚到上一个备份的时间点,影响范围就会比较大。因此,对于数据量大一点的系统,我们就会进行主从库的设置,不过通常情况下,我们做了主从库都会做读写分离。现在不管是哪种数据库,都提供了数据库之间订阅同步的机制。以Mysql为例,我们先设置一个Master主库,然后在基于这个主库设置1个到多个Salve从主,从库通过在主库的SQLLog日志进行监听,一旦有SQL执行,就会记录一个二进制的Log,从库发现了这个Log,也会同时执行同样的操作,这样就实现了数据的热备。但是,这种热备的机制并不能100%保证数据不丢失。因为,我们在写入主库的时候如果出现异常,导致SQLLog还没有记录,那么从库是不可能有数据记录的。当然,此后的数据不会有影响,因为这是从库会变为主库来记录后续数据。同样,如果主从库一起宕机,那也只有凉凉。那么,为了让数据库的数据更加安全,就需要把数据保证的机制提前,不能单纯的依靠数据库来实现,那么我们可以加入队列来试试。队列并不是针对于数据的,队列其实是用来保证消息的安全稳定的。自然,当请求没有被写入到数据库是,都是以消息的形态存在,我们就可以考虑队列来保证数据安全。在数据库访问层,或者再靠前,到服务层,我们都可以加入MQ,让每一个请求都通过MQ来顺序的处理,一但数据库宕机了,MQ的执行就会失败,这时,失败的记录会被保存在MQ里面,并不会丢失,一但数据库重启,我们可以再次执行MQ中的消息,保证数据被成功的写入到数据库中。具体怎么做呢?首先,我们在插入数据库前,把插入的操作变为向队列对添加一个消息,然后,我们不同队列建立不同的消费者,消费者对队列的消息进行执行,再往数据库里面插入数据。对于我们的服务层,我们只要把消息插入到了队列中,即视为成功,返回成功的消息。这样,虽然我们的数据处理会有一点点的延时,并且在事务的控制上难度会变大,可能需要建立补偿机制,但是我们的数据安全就更加高了。这样是不是就安全了呢?并不是的。消息服务器也可能会宕机,消息也有可能出现丢失的情况,所以并不能保证100%的安全。如果我们还需要做的更好,我们还可以加上MongoDB来做日志MongoDB是一个非关系型数据库,在我们现在的系统中应用非常广。最多的应用场景就是用来记录日志。那么,日志就是一个帮助我们避免消息丢失的有效方式了。我们对服务层的每个请求报文,都用MongoDB记录请求的报文,再在请求处理完成返回结果的时候,记录一个消息的处理结果(成功或失败),这样,我们就能够很直观的看到每天发生的请求,处理的请求情况了。当有服务处理失败了,不管是数据库的问题还是其他的问题,我们都可以对异常进行排查,然后再根据报文进行消息的重推。这样,我们的数据就会更加的安全了。当然,即使如此,也不可能100%安全的,我们只能说尽可能的让系统更安全,只不过,安全的同时,付出的成功也是高昂的,我们需要来衡量是否有这个必要,当我们的系统确实足够大,用户量很大时,这么处理是有价值的,否则,那就是一种资源的浪费。您是说电脑死机还是? 检测一台机器是否宕机的应用场景如下:1, 工作机器宕机,总控节点需要能够检测到并且将原有服务迁移到集群中的其它节点。2, 总控节点宕机,总控节点的备份节点(一般称为Slave)需要能够检测到并替换成主节点继续对外服务。检测一台机器是否宕机必须是可靠的。 在大规模集群中,机器可能出现各种异常,比如停电,磁盘故障,过于繁忙导致假死等。对于机器假死,如果总控节点认为机器宕机并将服务迁移到其它节点,假死的机器又认为自己还可以提供服务,则会出现多个节点服务同一份数据而导致数据不一致的情况。首先必须明确,理论上检测另外一台机器是否宕机是无法做到的,有兴趣的同学可以参考Fischer的论文。 可以简单理解如下:A机器往B机器发送心跳包,如果B机器不发送响应,A无法确定B机器是宕机了还是过于繁忙,由于A和B两台机器的时钟可能不同步,B机器也无法确定多久没有收到A机器的心跳包可以认为必须停止服务。因此,A机器没有办法确定B机器已经宕机或者采取措施强制B机器停止服务。 当然,工程实践中,由于机器之间会进行时钟同步,我们总是假设A和B两台机器的本地时钟相差不大,比如相差不超过0。5秒。这样,我们可以通过Lease机制进行宕机检测。Lease机制就是带有超时时间的一种授权。假设总控节点需要检测工作节点是否宕机,总控节点可以给工作节点发放Lease授权,工作节点持有有效期内的Lease才允许提供服务,否则主动下线停止服务。 工作节点的Lease快要到期的时候向总控节点重新申请Lease(一般称为renewLease),总控节点定时检测所有工作机的Lease授权是否合法,如果发现某台工作机Lease失效,可以将工作机上的服务迁移到集群中的其它机器,这时因为工作机发现自己Lease失效会主动停止服务。 当然,这里需要注意,由于总控节点和工作机的时钟可能不一致且有网络延迟,总控节点上的Lease超时时间要长,也就是说,如果工作节点的Lease超时时间是12秒,总控节点可能需要13秒后才能确认工作节点已经停止了服务,从而避免数据不一致问题。同构节点之间的选主也有一个宕机检测问题。 比如总控节点宕机,备份节点需要能够检测并升级为主节点继续对外服务。Mysql数据库经常采用Heartbeat DRBD (Distributed Replicated Block Device) Mysql的高可用性方案,据说能够达到3个9的高可用性,主节点和备节点维持Heartbeat心跳,当提供服务的主节点出现故障时,备节点的Heartbeat检测到主节点没有心跳(例如,Ping不通主节点),备节点自动接管虚拟IP,升级为主节点提供Mysql读写服务。 由于Heartbeat检测机器主节点宕机不可靠,这个方案存在众所周知的脑裂问题,即集群中可能同时存在多个主节点同时提供服务。解决这个问题本质上还是需要引入仲裁节点,比如Heartbeat DRBD方案中引入Fence节点使出现问题的节点从集群中脱离,或者引入分布式锁服务,比如Chubby的开源实现Zookeeper服务。 分布式锁服务实现主节点选举大致如下:主节点和备节点到Chubby中抢锁,抢到锁的节点在锁的有效期(Lease期)内提供服务,当主节点锁的Lease快要到期时,主节点申请延长锁的超时时间,正常情况下分布式锁服务总是优先满足主节点的请求,当主节点出现故障时,备节点能够抢到锁切换为主节点提供服务。 最后还有一个问题,假设总控节点通过Lease机制检测工作节点是否宕机,这种方案是可靠的,不过当总控节点宕机时,如果不采取任何措施,集群中的所有工作节点都将因为无法重新申请Lease而停止服务,这就是带有总控节点的设计固有的脆弱性,某个设计或者编码的错误都有可能造成严重的影响。 解决这个问题一般会有一个叫做Grace Period的机制,工作节点Lease超时时将停止服务,但是工作节点并不一开始就重启或者下线,而是处于一种危险状态(称为Jeopardy),这种状态持续一个Grace Period,比如45秒。如果在Grace Period 内总控节点重启,工作节点和总控节点重新联系上从而可以切换为正常状态继续提供服务。 Alt Tab看是否能够切换不同页面。或者Ctrl Shift Esc看是否可以打开任务管理器。