使用Vertx重构系统小结

背景java

前几个月,使用Vertx重构了公司的一个子系统,该系统负责公司核心数据subscriber的采集、处理、存储和搜索。这里介绍下重构该系统时的一些关键点。web

架构redis

重构前系统部署图:数据库

重构前系统主要有2部分组成,这2部分都会对Subscriber数据操做:缓存

Java APP: 是个定时任务触发的APP,每2小时跑一次,每次启动后作如下的事情:网络

  1. 从MongoDB里加载已有的数据到内存。
  2. 读取准备好的Data文件,处理文件中的数据,和已加载的数据作合并,这个处理的过程会致使Subscriber数据有添加、删除和更新操做。
  3. 处理完Data文件后,将数据持久化到MongoDB和Elasticsearch。

JBoss服务:架构

  1. 从Kafka中来的消息数据,批量处理Kafka消息,会添加和更新Subscriber数据到MongoDB和Elasticsearch中。
  2. 从其余系统触发的API调用,接收一些API请求,这些请求也会增长、删除和更新Subscriber数据。在更新的时候,由于查询条件的多样性,为了提升查询Subscriber的速度,对MongoDB的Subscriber Collection建了各类索引。

重构缘由并发

  1. 对同一种的数据的操做在2个不一样的服务中,一种是war一种是jar,不利于维护。代码在不一样的Rep和Project下,维护也不方便。
  2. Jboss如今是单实例部署,Jboss中还部署有其余的服务,Jboss的稳定性直接影响了该服务。为了提升查询速度,对数据创建了多种不一样的索引,更新数据增长了数据库的负担。
  3. 定时任务JavaAPP每次在处理某个客户的Subscriber数据时候,都要从MongoDB加载数据到内存,耗时没有效率。由于是定时任务,对数据更新不够及时,会影响其余依赖Subscriber数据的服务。
  4. 数据更新冲突:在定时任务把数据加载到内存,正在处理时,此时若是Jboss也在更新数据会致使数据更新冲突(如今采用了一个很tricky的方式解决)。

重构后系统部署图app

重构后,系统组件介绍和说明:异步

Adapter服务:

  1. 数据适配服务,统一接收来自文件、Kafka和API调用的数据,对数据进行预处理,发送相应的业务消息到Event Bus。
  2. 由于对Adapter的触发方式只有2种,一种是REST API,另外一种是链接Kafka读取消息,因此Adapter服务能够经过部署多个实例来增长可用性,也顺便提升了总体性能。

Mapper服务:

  1. 数据处理服务,按数据分片进行部署,分片规则能够按客户大小来分,好比把10个大客户的数据部署在一个实例上,200个小客户的数据部署在另外一个实例上,也能够按数据量平均分。
  2. 初始启动时候加载所属该实例的全部Subscriber数据到内存,从EventBus上接收来自Adapter的业务请求,处理请求并对数据进行更新。
  3. 数据更新策略:
    1. 来自API的请求都会实时的更新到MongoDB和Elasticsearch中。
    2. 来自文件和Kafka的数据更新量比较大,为了不每次对数据更新的时候都去操做DB和ES,经过一个队列缓存全部的更新。触发队列持久化条件:一种是当缓存Size达到阈值时候触发,另外一种是定时触发,触发后批量更新数据到MongoDB和Elasticsearch中。
    3. 内存、MongoDB和Elasticsearch中数据一致性:由于如今数据在内存中,使用了Vertx的MongoClient的异步回调机制,保证只有更新到MongoDB成功后才去更新Elasticsearch,保证MongoDB里数据的准确性是第一位的。而ElasticSearch中数据的准确性是经过“定时补偿机制”去保证:有其余定时执行的脚本去定时检查,并决定是否从新对某个客户的数据重建索引。

重构以后的可改进项:

  1. 耗内存,全部的Subscriber数据都分片加载到了JVM里。这部分能够把数据放到其余的存储中,好比redis,但就算是放到redis,也是耗内存。
  2. 若是系统出错,会致使数据在MongoDB和ElasticSearch之间不一致,须要其余方式去作“数据一致性补偿”。若是资源容许,能够把数据更新同步单独拿出来实现,使用相似处理“分布式系统数据一致性”的方式来改善这一点。

小结

一些技术关键点

1 异步非阻塞

    Vertx的异步非阻塞机制有很好的并发性能。网络IO依赖了Netty,Java NIO的特性。

2 Vert.x-Web

    Vertx-web能够很方便的去实现一个web app,很容易实现一些REST APIs。

3 Data access client

    Vertx提供了访问各类存储的Client,这些client的API都是异步的,能够很方便的去访问MongoDB,JDBC,Redis等。

4 Event Bus

    Vertx的一个核心功能,重构这个子系统时也很依赖这个功能。Event Bus可用于不一样Verticle之间的通讯,也能够用于Vertx cluster之间的通讯。

5 功能解耦

    系统中各个子功能能够按不一样的Verticle去实现,不一样的Verticle能够经过EventBus去通讯解耦。Vertx支持动态的加载和卸载Verticle,也就能够实如今运行时动态的加载卸载某些功能。

6 集群模式

    Adapter服务和Mapper服务经过Vertx的Cluster模式组成集群,集群中节点发现和通讯经过Hazelcast管理。使用Vertx实现的服务,能够单实例部署,也能够组成集群提供服务。

 

参考

相关文章
相关标签/搜索