老树新花-Java异步服务开发

内容来源:2017年5月13日,饿了么资深Java工程师朱杰在“Java开发者大会 | Java之美【上海站】”进行《老树新花-Java异步服务开发》演讲分享。IT大咖说作为独家视频合作方,经主办方和讲者审阅授权发布。

阅读字数:1901 用时: 13分钟

摘要

饿了么资深Java工程师朱杰从同步异步概念介绍、使用Java来开发异步化服务、回调监听模式所遇到的问题和解决这三方面来我们全面解读Java异步服务开发。

嘉宾演讲视频回顾及PPT:http://suo.im/4rwo2Y

同步模型

以前在并发量很低的情况下,是通过线程去收取数据并发送数据给客户端。但是当并发量和客户端连接数比较高的时候,服务器会出现明显的瓶颈。

阻塞模型比较符合人的思考逻辑,但它会有线程阻塞的问题。阻塞模型会让出CPU,不适用于高并发。

线程池或连接池只能解决一部分问题。因为线程池和连接池的本质作用并不是能直接提高QPS,而是减少或销毁线程的连接处以及开销。

我们平时调用阻塞API的一个问题就在于单机的线程数是有限的。所以如果要提高服务端性能的话,首先就要去阻塞。

异步模型

异步阻塞模型处理I/O时大部分时间是非阻塞的(监听时除外),它调用的API会立即返回,这点是需要注意的。此外,处理结果的程序并不保证调用API当前的线程,这点在处理线程安全的问题上尤其要注意。

Java中很多API都是基于操作系统底层API的模型,并没有做更高层次的封装。

Java把一层阻塞异部I/O做了封装,这些就是Java或C语言异步模型的基石。

少数线程等待事件发生,再根据对应类型处理相关事件。

最近“协程”这个词比较火,看上去能解决异步模型的大部分问题。它是一个轻量级线程,可以直接当作线程来用。还能阻塞I/O API,阻塞的是协程而非线程。

协程是用户态资源,用户态调度,消耗极低,可以启动数十万个协程。

它的实现和线程不是1对1 的关系,难点在于编程语言的内部实现。

Python虽然支持协程,但是由于全局解释锁的关系,同一时刻只有单个CPU在运行。所以python选择多进程+协程的做法。

Go语言完美解决了支持不阻塞线程的I/O操作,并支持多线程。

要能像同步I/O一样编写代码,不会创造过多数量的线程。尽量让CPU处于忙碌状态而非等待,并寻找满足以上条件的Java库。但是Java由于本身语言的问题,即使是Java协程三方库也只能部分支持协程。

退而求其次,我们只能使用Java异步工具库。如果要提高并发量,可以使用异步JDBC和异步HTTP CLIENT,这个库基于NETTY。

做到服务异步化,要查看接口是否可支持异步。还可以使用Java的异步工具库,比如Java的异步数据访问方式和异步HTTP CLIENT。如果使用的是三方框架,可以修改调用方式,有的框架支持异步回调和事件监听。最重要的是要注意线程安全问题。

异步化的优势就是极大提高了I/O密集型业务的性能,保守估计有10~100倍,也就解决了线程数创建过多的问题。

而它的缺点是增加了编程难度,包括状态保存、回调处理以及线程安全等。也存在压垮下游服务的问题:)

老树新花-基于Netty的Java模型

Netty是基于原生的异步模型,封装并优化。它修复JDK中的一些BUG,提供了多种辅助类方便开发。编程模型高效简单,开发者只需关心具体实现逻辑即可,基本不用花精力做Java网络层面的优化。此外,Netty成熟稳定,业界使用多,我们能够相信,使用它不会遇到难以解决的大问题。

Netty基于事件连接,如果有数据传入以及连接上有异常事件或自定义事件,只需复写它的回调函数就能做相应的处理。

Netty所有I/O API全都是消除阻塞异步化。线程模式也非常好,它单个连接上的所有I/O事件都由同一个线程执行,避免了线程安全问题。

Netty的单个链接绑定一个线程,EVENTLOOP即一个线程,EVENTLOOPGROUP是一个线程组。

Netty任何的I/O API都是产生一个任务,放入该连接对应的线程里执行,做到局部串行化。

Netty一切操作都是以事件驱动来执行,所有I/O API都是用异步+回调监听的方式来处理消息。单一的连接处理都在一个线程里,来避免线程安全问题。

案例-饿了么数据库中间件

我们是一个实现了MYSQL协议的中间代理服务。上游至少要支持上万客户端的连接,下游要支持上千数据库连接。

为了快速实现功能,我们最早是找了一个基于GITHUB阻塞I/O开源库,首要任务是把同步改为了异步。

线程模型的上下游各有Netty的一个线程组,中间件内部还有一个处理业务的线程组。

但有一个最本质的问题在于这三个线程组之间的线程安全得不到保证。

因为这个中间件前后端都是异步的,所以按正常流程是由协议来保证顺序执行,而异常中断是并发执行的。

参考Netty,我们把每一个连接绑定到一个单线程池,保证Task串行执行。

前后端异步的好处在于模型简单,便于后续修改。

我个人认为,在程序里过多的使用WAIT/NOTIFY/LOCK不一定代表良好的多线程编程能力,却可能代表这是不够优雅的设计。

除了前后端异步和信号量控制异步,在中间件中我们还用到了日志异步、心跳异步、JOB异步和配置变更异步。

在饿了么数据库中间件开发过程中,异步化所有API以去除阻塞,局部串行化解决线程安全问题,模型简单,易于修改和理解。

今天的分享就到这里,谢谢大家!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,561评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,218评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,162评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,470评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,550评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,806评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,951评论 3 407
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,712评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,166评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,510评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,643评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,306评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,930评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,745评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,983评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,351评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,509评论 2 348

推荐阅读更多精彩内容