异步化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 ...
随机推荐
- JAVA中运用数组的四种排序方法
JAVA中在运用数组进行排序功能时,一般有四种方法:快速排序法.冒泡法.选择排序法.插入排序法. 快速排序法主要是运用了Arrays中的一个方法Arrays.sort()实现. 冒泡法是运用遍历数组进 ...
- Codeforces Round #143 (Div. 2) (ABCD 思维场)
题目连链接:http://codeforces.com/contest/231 A. Team time limit per test:2 seconds memory limit per test: ...
- Swift 2.0初探:值得注意的新特性
转眼间,Swift已经一岁多了,这门新鲜.语法时尚.类型安全.执行速度更快的语言已经渐渐的深入广大开发者的心.我同样也是非常喜爱这门新的编程语言. 今年6月,一年一度的WWDC大会如期而至,在大会上A ...
- Play Framework Web开发教程(33): 结构化页面-组合使用模板
和你编写代码相似,你编写的页面也能够由多个小的片段组合而成,这些小的片段本身也能够由更小的片段构成.这些小片段一般是能够在其他页面反复使用的:有些部分能够用在全部页面,而有些部分是某些页面特定的.本篇 ...
- HashSet的分析(转)
一. HashSet概述: HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持.它不保证set 的迭代顺序:特别是它不保证该顺序恒久不变.此类允许使用null元素. 二. ...
- MySQL Replication Error 处理一例
故障现象 MySQL slave status详情 mysql> show slave status\G *************************** 1. row ********* ...
- 使用堆栈结构进行字符串表达式("7*2-5*3-3+6/3")的计算
问题: 给定字符串String str = "7*2-5*3-3+6/3", 求出字符串里面表达式的结果? 像javascript有自带的eval()方法,可以直接计算.但java ...
- Jsp request
<%@ page language="java" import="java.util.*" pageEncoding="GB18030" ...
- SQLSERVER内核架构剖析 (转)
我们做管理软件的,主要核心就在数据存储管理上.所以数据库设计是我们的重中之重.为了让我们的管理软件能够稳定.可扩展.性能优秀.可跟踪排错. 可升级部署.可插件运行,我们往往研发自己的管理软件开发平台. ...
- MS-DOS命令列表
以下是微软的DOS操作系统(MS-DOS)的DOS命令列表.其它DOS的命令和用法可能类似. 后期版本的 DOS 可以通过help命令来得到命令与参数列表,通过help <命令>或者< ...