基于mina的cs通信,含内存cache,mongodb持久化案例【第一篇】
2014-01-24 17:04
232 查看
由于项目太紧,原本打算把整个开发过程总结出来的,但是现在确实没时间完成饿了,所以本文仅作为技术探讨,并没有源码共享。
同时,我总结了mina的使用心得,作为本文的补充吧。主要探讨mina的正常关闭,避免异常发生。MINA总结
先简单描述一下需求和设计思路吧。
1、需求:设计出来一套NIO的CS,client提供发送某种格式的数据;server提供接受数据并缓存同时提供持久化,用于提供实时查询和离线查询分析。
2、NIO选择:我在看了关于NIO框架的讨论分析后,决定选择mina,这个完全是自己的个人爱好。当然其他NIO如neety或者基于mina的openfire,也是不错的选择。
3、缓存:目前缓存有很多成熟的框架可以用,考虑我们的需求和服务器问题决定自己设计一套简单的缓存。server在接受多个client消息的时候,缓存数据过程势必会遇到同步问题,于是采用了ReadWriteLock、synchronized以及volatile等安全策略设计缓存,当然你也可以使用concurrent包来设计同步策略。其中一个特殊问题就是缓存数据的更新问题,每天有很多数据进入缓存,那么怎么清空过期的数据保证缓存不会爆掉?同时,client的设计呢?对于一个应用来说是分配一个client还是多个client呢,每个client是长连接还是短连接?
4、数据持久化:采用mongodb作为持久化存储db,封装了mongodb的操作,为了减少最终的jar体积,并没有使用spring的mongodb模块。在计算时采用mongodb的mapreduce进行聚合计算,这并不是最优的,因为用过mapreduce的人就会发现通常count、group速度比它要快。
5、整体流程介绍:多个client并发访问server,server解码数据并缓存,同时启动对缓存的守护进程进行轮询维护或批量持久化,调用server的接口访问缓存数据或mongodb中的离线数据。
然后说说在开发之前分析流程,设计方案,梳理出可能会存在的问题,以及应对的方案或选择的策略。
1、mina提供了handler来处理消息,但是不适合我的需求,我需要建立连接后主动去发送消息,那就需要在建立连接之后获取连接句柄,mina中其实就是iosession。解决方法是在handler中把iosession缓存起来,这样就完事了吗?事实并不这么简单,一个需要连接server的app中假如维护一个client长连接,那么这个app中可能有多个地方调用了client发送消息,这个iosession需要同步。
2、缓存的守护线程定时维护方案怎么设计?其实我并不想多讨论缓存,因为很多人可能用的是第三方的缓存框架了,但是既然提到了就简单说说吧。我考虑这个问题时分析了Timer、Quartz、JcronTab 等,首先放弃了Timer,因为timer不能保证准时触发job,同时如果发生异常Timer将会推出后续任务都放弃了,这太不安全了;Quartz和JcronTab非常棒,遗憾的是他们和外部环境的上下文隔离,这就意味着你不能访问缓存对象,显然不适合我的场景。最终考虑使用线程完成调度,daemon
thread通过计算每一次任务执行点到当前时间点的时间间隔来进行sleep,时间结束后(定时点到达)启动一个新的线程(我称为jod-thread)来执行cache的维护任务,特别提醒这个daemon thread不要访问任何状态可变的共享变量,这样daemon thread必然准时触发,而jod-thread会慢慢执行自己的任务,如果job耗时太久,不会影响daemon thread,这时如果上一个jod thread 没执行完,daemon thread 会新启动一个jod thread 处理新任务, 也就是说会出现多个job-thread在并发处理任务,所以你要考虑你的业务场景在这种情况下的资源共享问题了,比如是否对共享变量加锁来同步等等。
在经过多线程测试后,目前版本已算稳定。 期待过年的心情无法安静,先用maven生成出API,年后把项目拿出来讨论吧。
同时,我总结了mina的使用心得,作为本文的补充吧。主要探讨mina的正常关闭,避免异常发生。MINA总结
先简单描述一下需求和设计思路吧。
1、需求:设计出来一套NIO的CS,client提供发送某种格式的数据;server提供接受数据并缓存同时提供持久化,用于提供实时查询和离线查询分析。
2、NIO选择:我在看了关于NIO框架的讨论分析后,决定选择mina,这个完全是自己的个人爱好。当然其他NIO如neety或者基于mina的openfire,也是不错的选择。
3、缓存:目前缓存有很多成熟的框架可以用,考虑我们的需求和服务器问题决定自己设计一套简单的缓存。server在接受多个client消息的时候,缓存数据过程势必会遇到同步问题,于是采用了ReadWriteLock、synchronized以及volatile等安全策略设计缓存,当然你也可以使用concurrent包来设计同步策略。其中一个特殊问题就是缓存数据的更新问题,每天有很多数据进入缓存,那么怎么清空过期的数据保证缓存不会爆掉?同时,client的设计呢?对于一个应用来说是分配一个client还是多个client呢,每个client是长连接还是短连接?
4、数据持久化:采用mongodb作为持久化存储db,封装了mongodb的操作,为了减少最终的jar体积,并没有使用spring的mongodb模块。在计算时采用mongodb的mapreduce进行聚合计算,这并不是最优的,因为用过mapreduce的人就会发现通常count、group速度比它要快。
5、整体流程介绍:多个client并发访问server,server解码数据并缓存,同时启动对缓存的守护进程进行轮询维护或批量持久化,调用server的接口访问缓存数据或mongodb中的离线数据。
然后说说在开发之前分析流程,设计方案,梳理出可能会存在的问题,以及应对的方案或选择的策略。
1、mina提供了handler来处理消息,但是不适合我的需求,我需要建立连接后主动去发送消息,那就需要在建立连接之后获取连接句柄,mina中其实就是iosession。解决方法是在handler中把iosession缓存起来,这样就完事了吗?事实并不这么简单,一个需要连接server的app中假如维护一个client长连接,那么这个app中可能有多个地方调用了client发送消息,这个iosession需要同步。
2、缓存的守护线程定时维护方案怎么设计?其实我并不想多讨论缓存,因为很多人可能用的是第三方的缓存框架了,但是既然提到了就简单说说吧。我考虑这个问题时分析了Timer、Quartz、JcronTab 等,首先放弃了Timer,因为timer不能保证准时触发job,同时如果发生异常Timer将会推出后续任务都放弃了,这太不安全了;Quartz和JcronTab非常棒,遗憾的是他们和外部环境的上下文隔离,这就意味着你不能访问缓存对象,显然不适合我的场景。最终考虑使用线程完成调度,daemon
thread通过计算每一次任务执行点到当前时间点的时间间隔来进行sleep,时间结束后(定时点到达)启动一个新的线程(我称为jod-thread)来执行cache的维护任务,特别提醒这个daemon thread不要访问任何状态可变的共享变量,这样daemon thread必然准时触发,而jod-thread会慢慢执行自己的任务,如果job耗时太久,不会影响daemon thread,这时如果上一个jod thread 没执行完,daemon thread 会新启动一个jod thread 处理新任务, 也就是说会出现多个job-thread在并发处理任务,所以你要考虑你的业务场景在这种情况下的资源共享问题了,比如是否对共享变量加锁来同步等等。
在经过多线程测试后,目前版本已算稳定。 期待过年的心情无法安静,先用maven生成出API,年后把项目拿出来讨论吧。
相关文章推荐
- ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第一篇:准备工作
- ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第一篇:准备工作
- ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第一篇:准备工作
- 深度剖析Byteart Retail案例:基于MongoDB的仓储实现
- Android开发之基于MINA框架的聊天通信功能实现
- 用Spring Data JPA 基于内存存储pojo的简单案例
- ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第一篇:准备工作
- ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第一篇:准备工作
- ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第一篇:准备工作
- 基于Mina框架的 socket网络通信
- java语言基于万准衡器(吊钩秤)的串口通信案例
- ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第一篇:准备工作
- ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第一篇:准备工作 【转】
- java: java mina ——基于TCP/IP、UDP/IP协议栈的通信框架
- 基于内存的通信之一 “内核共享内存”
- 深度剖析Byteart Retail案例:基于MongoDB的仓储实现
- 基于C# Winform的简易聊天程序[第一篇-两端通信](转链接)
- MongoDB内存配置 --wiredTigerCacheSizeGB
- 基于内存的通信之一 “内核共享消息队列”
- Hive数据分析——Spark是一种基于rdd(弹性数据集)的内存分布式并行处理框架,比于Hadoop将大量的中间结果写入HDFS,Spark避免了中间结果的持久化