异步化DAO的设计和实践
2016-03-07 10:14
246 查看
摘要: 目前,公司技术规划要求未来所有的服务要全面实现异步化接口,使得每个服务能达到1万/秒的单机性能。我们知道,在一个服务请求中,可能会调用其他服务,还会使用memcache、kv以及mysql等。目前,大众点评的使用的服务框架、kv和cache框架均有异步化调用的接口,但是唯独缺少异步调用数据库的框架支持。这就意味着,如果业务代码一旦其他的请求都异步化了,但是唯独数据库还是同步的,那么就没有达成完全的异步化。在这种情况下,就要求必须有异步化数据库调用的框架支持。zebra-dao就是在这种情况下开发的。
2. 技术选型
调研了目前所有的异步化方案,考虑到有以下的实现:
业务使用时自己将每一次的dao调用放到异步线程池中去。优点是,不需要架构支持什么。缺点是,因为是业务迁移,迁移的代价比较大。
使用google的async-mysql-connector。优点是:背后实现是基于NIO的方式,性能更高。缺点是,异步的jdbc接口上层没有任何的DAO框架支持,公司业务基本无法使用。
所以,笔者主要考虑到业务的易用性和方便迁移,决定将方案定为在MyBatis-Spring的基础上进行封装,背后实现是线程池的方式。
3. API
zebra-dao目前支持两种方式的异步API:回调和Future接口方式,对于每一个异步接口,必须要有相应的同步方法定义,因为其实所有的异步接口最后还是在线程池中调用的同步接口。
业务如果使用的是回调接口,那么在使用的时候必须定义回调方法,在回调方法中,通常做的是把结果放到服务框架的异步回调方法中,这样才能做到一个服务的全部异步化。在下面的例子的回调方法中,隐去了使用服务异步调用接口的具体实现,仅仅展示如何定义回调方法。
对于使用的Future接口,就和使用Future一样,没有额外特别之处。
更详细的使用方法,请参考这里。
4. 总结
目前,公司的价格服务等一系列的服务使用的这个框架去访问数据库,这些服务也因此实现了异步化。未来,公司会将越来越多的服务使用这个框架。目前,这个框架还额外实现了物理分页的功能。这个功能的API的设计也很多为了兼容已有业务代码考虑的。
异步化DAO的设计和实践
1. 背景
目前,公司技术规划要求未来所有的服务要全面实现异步化接口,使得每个服务能达到1万/秒的单机性能。我们知道,在一个服务请求中,可能会调用其他服务,还会使用memcache、kv以及mysql等。目前,大众点评的使用的服务框架、kv和cache框架均有异步化调用的接口,但是唯独缺少异步调用数据库的框架支持。这就意味着,如果业务代码一旦其他的请求都异步化了,但是唯独数据库还是同步的,那么就没有达成完全的异步化。在这种情况下,就要求必须有异步化数据库调用的框架支持。zebra-dao就是在这种情况下开发的。2. 技术选型
调研了目前所有的异步化方案,考虑到有以下的实现:业务使用时自己将每一次的dao调用放到异步线程池中去。优点是,不需要架构支持什么。缺点是,因为是业务迁移,迁移的代价比较大。
使用google的async-mysql-connector。优点是:背后实现是基于NIO的方式,性能更高。缺点是,异步的jdbc接口上层没有任何的DAO框架支持,公司业务基本无法使用。
所以,笔者主要考虑到业务的易用性和方便迁移,决定将方案定为在MyBatis-Spring的基础上进行封装,背后实现是线程池的方式。
3. API
zebra-dao目前支持两种方式的异步API:回调和Future接口方式,对于每一个异步接口,必须要有相应的同步方法定义,因为其实所有的异步接口最后还是在线程池中调用的同步接口。public interface UserMapper { /** * Normal synchronization dao method. */ public UserEntity findUserById(@Param("userId") int userId); /** * Asynchronous callback method. Return void and only one * callback method required. */ public void findUserById(@Param("userId") int userId, AsyncDaoCallback<UserEntity> callback); /** * Asynchronous future method. Return future and must have the * same params as synchronization method. */ @TargetMethod(name = "findUserById") public Future<UserEntity> findUserById1(@Param("userId") int userId); }
业务如果使用的是回调接口,那么在使用的时候必须定义回调方法,在回调方法中,通常做的是把结果放到服务框架的异步回调方法中,这样才能做到一个服务的全部异步化。在下面的例子的回调方法中,隐去了使用服务异步调用接口的具体实现,仅仅展示如何定义回调方法。
dao.findUserById(1, new AsyncDaoCallback<UserEntity>() { @Override public void onSuccess(UserEntity user) { System.out.println(user); //another asynchronous invoke in the asynchronous invoke dao.findUserById(2, new AsyncDaoCallback<UserEntity>() { @Override public void onSuccess(UserEntity user) { System.out.println(user); } @Override public void onException(Exception e) { } }); //synchronization invoke in the asynchronous invoke UserEntity entity = dao.findUserById(3); System.out.println(entity); } @Override public void onException(Exception e) { } });
对于使用的Future接口,就和使用Future一样,没有额外特别之处。
Future<UserEntity> future = dao.findUserById1(1); UserEntity user = future.get(); System.out.println(user);
更详细的使用方法,请参考这里。
4. 总结
目前,公司的价格服务等一系列的服务使用的这个框架去访问数据库,这些服务也因此实现了异步化。未来,公司会将越来越多的服务使用这个框架。目前,这个框架还额外实现了物理分页的功能。这个功能的API的设计也很多为了兼容已有业务代码考虑的。
相关文章推荐
- Android之获取手机上的图片和视频缩略图thumbnails
- 数据库链接字符串查询网站
- DB2实例管理
- DB2实例管理
- 保障MySQL数据安全的14个最佳方法
- mysql问答汇集
- 第三章 数据库备份和还原
- 创建一个空的IBM DB2 ECO数据库的方法
- Access 2000 数据库 80 万记录通用快速分页类
- 开通一个数据库失败的原因的和解决办法
- 一个简单的asp数据库操作类
- CentOS下DB2数据库安装过程详解
- EasyASP v1.5发布(包含数据库操作类,原clsDbCtrl.asp)第1/2页
- sql2008 还原数据库解决方案
- Oracle 数据库自动存储管理-安装配置
- Oracle数据库执行脚本常用命令小结
- Oracle 数据库 临时数据的处理方法
- 数据库分页查询语句数据库查询
- 最近比较流行的数据库挂马