异步化DAO的设计和实践
目前,公司技术规划要求未来所有的服务要全面实现异步化接口,使得每个服务能达到1万/秒的单机性能。我们知道,在一个服务请求中,可能会调用其他服务,还会使用memcache、kv以及mysql等。目前,大众点评的使用的服务框架、kv和cache框架均有异步化调用的接口,但是唯独缺少异步调用数据库的框架支持。这就意味着,如果业务代码一旦其他的请求都异步化了,但是唯独数据库还是同步的,那么就没有达成完全的异步化。在这种情况下,就要求必须有异步化数据库调用的框架支持。zebra-dao就是在这种情况下开发的。
目录[-]
异步化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接口方式,对于每一个异步接口,必须要有相应的同步方法定义,因为其实所有的异步接口最后还是在线程池中调用的同步接口。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
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);} |
业务如果使用的是回调接口,那么在使用的时候必须定义回调方法,在回调方法中,通常做的是把结果放到服务框架的异步回调方法中,这样才能做到一个服务的全部异步化。在下面的例子的回调方法中,隐去了使用服务异步调用接口的具体实现,仅仅展示如何定义回调方法。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
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一样,没有额外特别之处。
|
1
2
3
|
Future<UserEntity> future = dao.findUserById1(1);UserEntity user = future.get();System.out.println(user); |
更详细的使用方法,请参考这里。
4. 总结
目前,公司的价格服务等一系列的服务使用的这个框架去访问数据库,这些服务也因此实现了异步化。未来,公司会将越来越多的服务使用这个框架。目前,这个框架还额外实现了物理分页的功能。这个功能的API的设计也很多为了兼容已有业务代码考虑的。
异步化DAO的设计和实践的更多相关文章
- 商品详情页系统的Servlet3异步化实践
http://jinnianshilongnian.iteye.com/blog/2245925 博客分类: 架构 在京东工作的这一年多时间里,我在整个商品详情页系统(后端数据源)及商品详情页统一 ...
- 使用异步任务降低API延迟_实践总结
之前在想如何降低API的延迟,这些API里有几个比较耗时的操作且是串行执行,那通过异步执行的方式理论上可以降低运行的时间,如下图所示: 具体的实现比较简单,例如这样: public class Par ...
- 唯品会API网关设计与实践--转
原文地址:https://609518.kuaizhan.com/86/70/p4108366952248f 刘璟宇Leo 唯品会资深研发工程师,在大型高性能分布式系统设计和开发方面有丰富的经验.目前 ...
- Apache Beam实战指南 | 大数据管道(pipeline)设计及实践
Apache Beam实战指南 | 大数据管道(pipeline)设计及实践 mp.weixin.qq.com 策划 & 审校 | Natalie作者 | 张海涛编辑 | LindaAI 前 ...
- vivo商城促销系统架构设计与实践-概览篇
一.前言 随着商城业务渠道不断扩展,促销玩法不断增多,原商城v2.0架构已经无法满足不断增加的活动玩法,需要进行促销系统的独立建设,与商城解耦,提供纯粹的商城营销活动玩法支撑能力. 我们将分系列来介绍 ...
- RESTful API 设计最佳实践
背景 目前互联网上充斥着大量的关于RESTful API(为了方便,以后API和RESTful API 一个意思)如何设计的文章,然而却没有一个"万能"的设计标准:如何鉴权?API ...
- AppBox升级进行时 - 扁平化的权限设计
AppBox 是基于 FineUI 的通用权限管理框架,包括用户管理.职称管理.部门管理.角色管理.角色权限管理等模块. AppBox v2.0中的权限实现 AppBox v2.0中权限管理中涉及三个 ...
- ****RESTful API 设计最佳实践(APP后端API设计参考典范)
http://blog.jobbole.com/41233/ 背景 目前互联网上充斥着大量的关于RESTful API(为方便,下文中“RESTful API ”简写为“API”)如何设计的文章,然而 ...
- RESTful API 设计最佳实践(转)
摘要:目前互联网上充斥着大量的关于RESTful API(为了方便,以后API和RESTful API 一个意思)如何设计的文章,然而却没有一个”万能“的设计标准:如何鉴权?API格式如何?你的API ...
随机推荐
- 充分发挥 JavaScript 语言的优势
尽管我在生产环境中使用 JavaScript 长达 8 年之久了,但是,直到最近 2 年,我才开始学习如何正确地编写 JavaScript 代码,根据我对人们的理解,很多开发者都有类似经历.我们有相当 ...
- ServerSocketChannel实现多Selector高并发server
参考hbase RpcServer,编写了一个简洁版多Selector server,对nio怎么用,Selector如何选择事件会有更深入的认识. client端发送消息:内容长度 + 内容,200 ...
- 第21/22讲 UI_布局 之 线性布局
第21/22讲 UI_布局 之 线性布局 布局管理就是组件在activity中呈现方式,包括组件的大小,间距和对齐方式等. Android提供了两种布局的实现方式: 1.在xml配置文件中声明:这种方 ...
- python StringIO标准库基础学习
#标准库:StringIO提供类文件API文本缓冲区#作用:可以处理内存中的文本,有2种不同的实现:cStringIP版本用c编写提高速度,StringIO用python来提供可移植性,与其他字符串连 ...
- (转)A drop-in universal solution for moving text fields out of the way of the keyboard
There are a hundred and one proposed solutions out there for how to move UITextField andUITextView o ...
- 【转】WCF、WebAPI、WCFREST、WebService之间的区别
在.net平台下,有大量的技术让你创建一个HTTP服务,像Web Service,WCF,现在又出了Web API.在.net平台下,你有很多的选择来构建一个HTTP Services.我分享一下我对 ...
- [Regex Expression] Use Shorthand to Find Common Sets of Characters
In this lesson we'll learn shorthands for common character classes as well as their negated forms. v ...
- hdu-1573 Robot Motion
Robot Motion Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 10219 Accepted: 4977 Des ...
- 使用DataReader
string sqlStr="select * from tb_news"; SqlCommand myCmd=new SqlCommand(sqlStr,myConn); myC ...
- Android-----------打开手机上的应用
##判断手机上是否存在应用,存在则打开 package com.funs.openApp.utils; import java.util.List; import android.c ...