单点登录更新不了缓存_[开源]Sentinel控制台集群方案(使用Ignite解决单点故障问题)...

目录

一、前言

二、总体设计方案

1、什么是Ignite2、Ignite构建控制台集群3、拉取客户端流量数据方案4、客户端心跳方案5、控制台集群登录方案

三、具体实现与改造

1、Ignite集群实现2、登录实现3、选举实现4、规则存储实现

四、开源信息

1、开源地址2、如何启动3、登录界面

五、惯例

21acf2bdd3095b924034e8fff1c52dcd.png 一、前言 最近在项目中使用到了Sentinel来做限流与降级,并封装了一套切合项目的自动限流降级框架。在使用Sentinel的过程中发现如下两个问题: 1、Sentinel提供的控制台只能够支持单机部署,存在单点故障的问题 2、Sentinel默认只支持单机限流,如果需要支持集群限流则要自己实现并提供Token Server。 为了让Sentinel能够完美的应用到项目中,因此我们必须要解决这两个棘手的问题。经过分析选型我们最终设计出了如下方案: 1、使用Ignite来解决控制台故障的问题 2、使用Raft协议来构建高可用性能的Token Server 当前项目已经完成了Ignite协议的控制台集群方案的设计与开发,而Token Server方案还在开发中。因此文本先介绍基于Ignite的控制台集群方案。
该项目已经开源,开源信息在文章末尾。后续Token Server完成之后也将为大家开源。
二、总体设计方案 1、什么是Ignite Ignite是以内存为中心的分布式数据库、缓存和处理平台,用于事务性、分析性和流式工作负载,提供内存速度在PB级规模。
Ignite 为应用和不同的数据源之间提供一个高性能、分布式内存中数据组织管理的框架。它包含如下组件: 1.高级的集群化 2.数据网格(JCache) 3.流计算和CEP 4.计算网格 5.服务网格 6.Ignite文件系统 7.分布式数据结构 8.分布式消息 9.分布式事件 10.Hadoop加速器 11.Spark共享RDD 总的来说其功能很强大,但是为了实现控制台集群,我们只需要知道Ignite可以做分布式缓存系统并且提供集群节点发现功能,且能够支持通过SQL查询缓存数据即可。 如果大家想要深入了解Ignite这个强大的组件。请访问其官网:https://ignite.apache.org/ 2、Ignite构建控制台集群 由于Ignite提供集群发现功能,且能够支持基于内存的分布式缓存(Ignite的分布式缓存支持持久化,只是我们这里没有使用)。因此就可以用Ignite来构建控制台集群,同时将所有控制台需要临时数据都存到分布式集群中即可。整体架构图如下:

16bc23d55da24ee5e04e7d764605afb8.png

核心实现如下: 利用Ignite构建分布式内存集群,所有数据都存到内存集群中 在控制台集群前部署负载均衡,让浏览器通过负载均衡随机访问到控制台机器。 3、拉取客户端流量数据方案 熟悉Sentinel原生控制台原理的同学应该都知道,控制台上可以展示客户端的资源限流详情,如下图。而这个流量信息是控制台定时通过Http接口从客户端拉取过来的。当我们将控制台修改成集群之后,默认所有机器都会去拉取流量数据并存到Ignite分布式缓存中,这样就会导致流量数据不准。因此我们需要选举一台机器出来复制拉取数据。我们的方案是:利用Ignite自带的简单选举功能实现选举(官方文档:https://apacheignite.readme.io/docs/leader-election )。通过这个功能,我们可以得到当前集群中最新或者最老的节点作为Leader。有了这个功能,我们能轻松的从集群中选举出Leader。 a1bd2dc2142d7ecff3268f713db23e48.png 4、客户端心跳方案 由于默认的客户端心跳会发送到一个控制台。并且不会处理控制台失联宕机等场景。因此我们需要修改客户端的心跳发送逻辑,具体方案是采用随机选择控制台的方案。即随机选择配置控制台集群中的一台发送心跳,如果发送失败则自动选择下一台控制台机器。 5、控制台集群登录方案 默认控制台登录通过jsessionid实现,并将登录信息存储到session中。在集群方案中,我们使用UUID为用户生成一个唯一id作为其用户ID,并存储到cookie中。同时将其登录信息存储到分布式缓存集群中。这样每次访问只需要从cookie中获取用户ID,然后根据ID从分布式缓存集群获取到登录信息即可。 三、具体实现与改造 1 、 Ignite 集群实现 基于Ignite分布式缓存,我们主要设计了三个缓存:Machine:用于存储客户端机器信息。每次客户端发送心跳之后就会更新该缓存。Metrics:用户存储客户端的流量信息。当Leader拉取到客户端的流量信息之后,就存储到该缓存中。缓存有效时间5分钟(因为控制台默认只展示过去5分钟的流量数据)。Authority:用户登录信息,用户登录之后就存储到该缓存中。每次校验就从缓存中获取数据。缓存有效时间10分钟(10分钟后重新登录)。
2 、登录实现 前面已经介绍过基本实现,本身实现也比较简单。这里直接贴代码吧。登录成功后,创建cookie,并写入用户信息到缓存: e14361478c2a27e46c9a2ae1a3443a9d.png 访问时从缓存中拉取数据判断用户登录状态是否有效: c39234398b1210f488f0311eb1e83071.png 3 、选举实现 前面原理篇我们已经介绍过了,选举是通过获取集群中最新或者最老的节点作为Leader实现的。我的方案中使用最老的节点,这样可以防止在启动的过程中Leader不断变化。 那我们只需要在Ignite节点启动时候判断一下自己是否为Leader(最老节点)就OK了么?当然不是。因为如果Leader节点宕机了,集群中其他节点还必须要选举出一个新的Leader来。因此我们需要对集群中的节点进行监听。好在Ignite本身提供了事件机制。其可以监听Ignite内部的各类事件,如:节点变更,缓存变更,任务变更等等。所以我们可以利用其节点变更来得到当前节点Leader失联的消息即可。 该方案的选举过程和普通的选举过程有些区别。普通的选举是判断Leader节点挂了,自己启动选举流程。而Ignite的选举是判断到某个节点挂了,然后判断一下自己是否变成了最老的节点,如果是,则标记自己为Leader节点。下面是节点收到节点变更事件后的选举机制核心代码: a8c7050191a0b8b033723d527d7f911b.png 当机器变成Leader之后,其需要做如下两件事情:a、不停从客户端机器拉取流量数据
b、将控制台集群所有地址通知给客户端。我们在实际项目中使用的统一配置中心通知。而开源代码中则没有提供具体实现。如有需要可以自行实现,具体实现请查看类:DashboardNodeRegister。如下是为大家预留的控制台地址注册逻辑,如果需要实现,可修改该代码逻辑即可。
4、规则存储实现 默认的控制台中,每次查询到规则信息都存储在内存中由InMemoryRuleRepositoryAdapter实现。而在集群方案中,我们则将所有的规则数据存储到对应的缓存(流控,降级,系统等)中。为此我们重写了InMemoryRuleRepositoryAdapter,实现了其所有接口方法,让所有的操作都基于分布式缓存实现。该实现类为IgniteRuleRepositoryAdapter。同时每个规则都继承IgniteRuleRepositoryAdapter。结构关系如下图:
四、开源信息 1 、开源地址 https://github.com/lifeofcoder/AutoLimiter 49e4c0cf0ac8a4f7ef336b7560bbdf38.png 2 、如何启动 集群控制台只需要直接打包部署autolimiter-dashboard-cluster工程即可。 application.properties文件中只需要修改配置ignite.register.addresses。填上控制台集群中所有机器的IP即可。其他配置和Sentinel的默认控制台完全一样。 默认的用户名和密码为:sentinel/ sentinel。
3 、登录界面 由于没有对页面和功能做任何修改,因此其界面和原生的Sentinel控制台界面没有差别。 20142f045508d31a3b842ca4f2951cea.png 五、惯例 如果你喜欢这篇文章,请点击右下角的“在看”图标支持下。 如果你对本文有任何疑问或者高见,欢迎添加公众号"Life of Coder"共同交流探讨(添加公众号可以获得”Java高级架构“上10G的视频和图文资料哦)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值