Open glmapper opened 3 years ago
实时性:
现在的版本是检测节点变化,然后读取数据。但是消费者消费了之后是不能同步到dashboard上面,要重新部署dashboard才能获取,我们可以设置一个定时任务,进行同步数据。
可视化:
可以增加一个服务状态(正常使用、已停止、已过期等)、服务调用次数用来进行负载调优等。服务新增时间(gmt_create)、服务修改时间(gmt_modified),给服务备别名或前端新增备注行。
服务状态
服务插入、修改时间
服务别名(备注)
提供服务的作者
给服务分组(类似收藏夹的功能)
可以用ECharts完成图表显示模块
兼容性:
我们可以制作一个下拉框来让用户选择使用哪个注册中心,增加兼容性。
高性能:
使用Nosql数据库进行缓存,比如redis。
易管理:
对服务的增删改查。
增:现在都是用sofa-rpc进行服务的发布,以后是否可以考虑把这一步骤,也合并到sofaDashboard上?不过这样要解决一个问题,就是对java代码的检查,相当于要写一个类似头歌(educoder)那样的编译器。
删:移除服务或停用服务?
改:修改服务信息(备注、分组、权限、状态)。
查:通过多个维度(比如应用名、服务名、作者、分组名...)
权限设置:
可以对服务进行权限限制,比如A这个服务提供给甲客人和乙客人,对于甲可以调用A中的get方法和set方法,但是对于乙客人只能调用get方法。
需要修复的问题:
1、如果先点上面的应用维度进行搜索,然后再切回服务维度,会出现额外多处几行空白的。
2、当生产者停止提供某一服务时,应当给予用户明显的提醒,告知该服务已停用。
1、可以暂时不考虑对于 ark 部分的支持,如果在实际的开发过程中,有影响,可以将 ark 部分能力关闭掉(功能要支持插件化) 2、权限部分不需要具体实现,可以基于 Oauth2、spring security 搭一个框架出来,后续托管社区来实现对接具体平台 3、注册中心部分是重点需要关注的,由于 zk 和 sofaregistry 在模型上是不同的,所以在定义模型时,可以适当考虑冗余,由一个模型来呈现 4、重点是对 sofaregistry 的集成,现在的注册信息是通过 rest api 获取的,当数据量变大时,同步获取会有一定延迟,异步去拉则存在一定的时效性问题;这块需要和 sofaregistry 同学一块看下,基于事件方式,由服务端直接推过来是不是更合理。
目前的服务信息数据是从SOFARegistry中通过rest api获取数据,然后存入缓存中。
当运行时和检测到数据变化时,都会再通过rest api再获取一次然后存入缓存中。
这个缓存的大概实现是用3个ConcurrentHashMap实现
private Map<String, RpcService> serviceMap = new ConcurrentHashMap<>();
private Map<String, List<RpcConsumer>> consumerMap = new ConcurrentHashMap<>();
private Map<String, List<RpcProvider>> providerMap = new ConcurrentHashMap<>();
也就是说当前的实现方法是直接把 数据存储到项目内存里面。
好处是:存取速度快 吞吐量大
坏处是:
原先的数据流向示意图:
现在的数据流向示意图:
保留通过 rest api 从SOFARegistry获取数据,在此基础上,抛弃了之前存入ConcurrentHashMap的方法。我们可以直接把数据封装后存入redis里面。
采用jemeter 对/api/service/all-service?query接口进行测试,该接口是获取所有的服务列表。
测试分别采用了1个服务1个生产者1个消费者和1个服务1000个生产者1000个消费者的模式。
未使用redis:
使用了redis:
未使用redis:
使用了redis:
在第一个1个服务1个消费者1个生产者模型中,可以看到两者的异常率和吞吐量是差不多的,原先内存缓存级别的会比用了redis的速度稍微更快一点
在第二个模型中,两者的差别明显变大了。在吞吐量中,原先的缓存比采用redis的高了10倍左右。我的测试环境用的是redis单机测试的,如果采用redis集群可能会更好,而且redis跟项目是一起运行的,电脑带不动2个。但我们也非常明显看得出原先的缓存方法确实在速度上是远超redis。
总结: 本次提出的将数据迁移到redis上,想法的初衷是想着当数据量越来越大的时候,使用ConcurrentHashMap存储数据,无疑是在项目里面装了个小型数据库一样,迁移出来能给系统做到一个瘦身的效果,但这同时也意味着失去了原先的高吞吐量,高响应的性能,但是能得到减轻系统、对于数据易管理、易分析等好处。
@ashlee618 我的意见是不绑定到具体的实现上去,可以在接口层面提供好扩展,redis 作为存储的一种实现,基本 map 的 mem 存储也是一种实现,当然也可以扩展其他存储
实现高并发、消息实时性地从SofaDashboard Client中把应用和实例消息推送到SoDashboard,进行展示。
这套技术体系参考与京东的京东到家中打印小票流程的实现,和抖音上用户关注的作者视频消息推送的实现。
1、采用WebSocket长连接的特点,实现消息实时性推送。 2、采用Netty作为WebSocket的容器,比较主流的有netty、tomcat、socketIO 三个框架。 3、 采用RabbitMq作为消息队列,也可以用其他优秀的MQ框架比如Kafuka、RocketMq等。
生产者、消费者、消息队列这三个部分任何一个部分出问题都会导致消息丢失。
1、消息队列发生故障
在RabbitMq中,消息默认是以内存的方式存储,当Mq出现宕机时,消息就会全部丢失,这是我们不想看到的。以RabbitMq为例子,具体操作:对交换机(Exchange)、队列(Queue)、消息(Message)进行可持久化存储。
2、消费者发生故障
当消费者消费逻辑复杂时间太长的消息、超时、消费者被停机或网络问题,会导致消息无法传递到消费者手中。
具体操作:设置手动Ack模式。
3、生产者发生故障
生产者会遇到一个问题,就是不知道消息是否到达Mq中。
具体操作:设置Confirm机制和Return机制。如果没有到达可以做重试和异常处理。
当生产者正在把消息发送给Mq途中宕机,或者是Mq正在把消息进行可持久化存储时宕机,都会导致消息”胎死腹中“。
因此我们可以设置一个消息补偿机制,对这些异常的消息进行重新发送或者判定为放弃该消息的发送。
具体操作:需要把消息不断地都存储在db中,然后设置一个定时任务一直去读取db里面的消息,判断是否需要进行补偿重发,如果补偿次数过多,就把该消息判定为异常消息放弃发送。
这套技术体系不仅可以应用在这里,也可以为后面SofaRegistry和SofaDashboard服务信息的传递。
https://summer.iscas.ac.cn/#/org/prodetail/210170198