CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

28
CERL 谈谈“ Boost.ASIO Erlang 谈谈谈谈谈谈” 谈谈谈 [email protected] 2009 谈 9 谈

description

CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”. 许式伟 [email protected] 2009 年 9 月. 内容提要. 服务器编程模型 A simple server Boost ASIO Light-weight processes 什么是 Erlang Style Concurrency? 基于 Actor / Message passing Light-weight processes 我之于 Erlang Style Concurrency 的不同观点 CERL CERL 2.0 CERL Vision. - PowerPoint PPT Presentation

Transcript of CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

Page 1: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

CERL谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

许式伟[email protected]

2009 年 9 月

Page 2: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

内容提要• 服务器编程模型

– A simple server– Boost ASIO– Light-weight processes

• 什么是 Erlang Style Concurrency?– 基于 Actor / Message passing– Light-weight processes– 我之于 Erlang Style Concurrency 的不同观点

• CERL• CERL 2.0• CERL Vision

Page 3: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

服务器编程模型• A simple server

• Boost ASIO

• Light-weight processes

Page 4: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

A simple server

• Listen (ip, port);

• Loop:– Accept & Read a request;– Handle the request:

• …• (maybe) Post requests to other servers and wait

the responses;• …• Write response;

Page 5: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

Problem of simple servers

• IO 并发程度不够– Post requests to other servers and wait the

responses. Here, other servers can be:• Database• Local file system• Other TCP/UDP servers• …

– 如何解决?• ASIO: Asynchronous I/O• Light-weight processes/threads

Page 6: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

ASIO

• Reactor 模式– select– epoll– kqueue

• Proactor 模式– IOCP (Completion queues/ports)

• 注: Reactor/Proactor 只是一种粗浅的划分方式,从实现的相似程度来说,个人认为 kqueue 和 IOCP 更接近。

Page 7: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

Boost.ASIO

• Boost.ASIO 是一种编程模型(或框架)。– 而上面提到的 select/epoll/kqueue/iocp 等只是

一种 IO 机制,不足以称为编程框架。– Boost.ASIO 屏蔽了繁琐的 IO 细节。

Page 8: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

A Boost.ASIO Server

• Listen (ip, port);• async_accept(HandleAccept):

– async_accept(HandleAccept);– async_read(HandleRequestHeader);

• HandleRequestHeader:– async_read(HandleRequestBody);

• HandleRequestBody:– …– (maybe) async_read/write to Other servers;– …– async_write response;

• io_service.run():– Get IO events & process;

Page 9: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

Boost.ASIO 优缺点• 评价:

– 基于状态机的服务器编程模型的最佳典范。• 优点:

– 很好的 Performance 。• 缺点:

– 完整的应用程序业务逻辑被强制分拆到很多个handle 函数。

• 这个分拆不是基于业务需要,而是 IO 需要,因此程序的阅读体验并不好,看上去不那么优雅。

Page 10: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

ASIO 小结• ASIO 并不提升单个 Request 的响应时间。

只是由于 IO 操作被重叠 (Overlapped) 进行,使得多个 Request 看起来被并行地处理。

Page 11: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

Light-weight processes

• 对比 ASIO:– ASIO 通过提升单个 Process 的 IO 吞吐量来提

升 Performance 。– Light-weight processes 模型则是通过创建多

个“ Process” 来提升 IO 吞吐量。• Light-weight processes 的典范

– Erlang

Page 12: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

Light-weight processes

• 核心概念: Process– 这只是一个逻辑上的概念。实现上可能是:

• 虚拟机中的一个 context 结构体,由虚拟机进行调度。• 一个协程(纤程)。• 操作系统的进程或线程(如果操作系统对进程 / 线程创建进行

了优化)。

• 优点– 简单

• 每个 Process 仍然只需要按照前面的 simple server 的逻辑编码。

– 代码体现自然的业务逻辑,容易理解和维护。

Page 13: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

什么是 Erlang Style Concurrency ?

• 基于 Actor / Message passing

• Light-weight processes

• 我之于 Erlang Style Concurrency 的不同观点

Page 14: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

Actor model

• The Actor model is about the semantics of message passing.– http://en.wikipedia.org/wiki/Actor_model

Page 15: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

Erlang Style Concurrency

• Ulf Wiger– http://ulf.wiger.net/weblog/2008/02/06/what-is-

erlang-style-concurrency/

Page 16: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

我之于 Erlang Style Concurrency 的不同观点

• 从更高层次看 Erlang Style Concurrency ,其本质的理念在于:– 用最简单自然、易于维护的模式,写最高效的服务器程序。

Page 17: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

Erlang Style Concurrency 要素

• 简单自然– 进程是一个执行体,串行化地响应请求。这是“简单自然”原则的重要体现。

• 进程执行中如果需要过多考虑同步与互斥之类的问题,无疑增加开发人员的心智负担。

• 易于维护– 所有服务器以相同的方式编写(易于交流);– 一个服务器可以干净地剥离在同一个源代码单元(易于

模块化)。– 一个完整的业务逻辑应该可以在一个函数内完成,当然

也支持按逻辑拆分成若干子函数(易于编码)。– 所有服务器可以以简单且一致的方式进行调用(易于重

用)。

Page 18: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

CERL

• TODO:– 这一节介绍 CERL 对 Erlang Style

Concurrency 在传统语言中的实现

Page 19: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

CERL 2.0

• Erlang Style Concurrency 是我们的终点吗?– Light-weight processes 缺陷

• 新编程模式的尝试– Light-weight processes + 状态机?

Page 20: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

Erlang Style Concurrency 是我们的终点吗?

• 回头看服务器编程模型– Boost.ASIO ( 基于状态机 )– Light-weight processes ( 基于轻量级进程 )

• Erlang Style Concurrency

Page 21: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

Light-weight processes 缺陷• 令人尴尬的“死锁”• 进程内 IO阻塞

Page 22: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

令人尴尬的“死锁”• 令人尴尬的“死锁”

– A 向 B 发送一个同步消息,等待 B 回复;而与此同时 B 向 A 也发送了一个同步消息,也在等待状态。这时 A 、 B 两个进程都不能完成自己当前的任务,形成“死锁”。

– 当然由于网络通讯的特殊性,最终 A 和 B 这种死锁是以超时表现出来。

• 怎么办?– 为了避开这点限制,我们在编程手法上禁止了 A 、 B 两个服务

器互发同步请求的设计,改成同步请求只出现在单个方向如 A -> B ,而 B -> A 的同步请求改用两次异步请求来完成。

– 但是这样一来, B 的一个完整逻辑就被打破,使得 B 服务器多了一个临时状态,导致 B 服务器的逻辑分支变多,不利于维护。

有更好的方案吗?

Page 23: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

进程内 IO阻塞• 问题来由

– Light-weight processes 的本质是通过创建足够多的 Process 来提升 IO 吞吐量。

– 为了简化 Process 的编码, Process 是串行执行请求的。– 这两条原则有时是相悖的。

• 例如,当 Process属于“资源进程”(即该 Process“拥有”某个资源)时,为了串行化执行对资源的请求,事实上 Process 的数量并不是由请求数决定的,而是由资源数决定的。

• 所以对于资源进程,就可能发生某个请求阻塞其他请求的情况。• 解决方案

– 将资源进程中费时的同步调用改为异步调用。– 问题:给开发人员带来的额外的心智负担:他得小心地决定调用

应该是同步还是异步的。

Page 24: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

问题的实质• Light-weight processes 这两个问题的实质

在于,在一些复杂逻辑中, Process 内部其实还是避免不了对 ASIO 状态机的需求。

Page 25: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

Light-weight processes + 状态机?

• Light-weight processes–胜在编码简单,性能也很好。但“小有瑕疵”。

• Boost.ASIO ( 基于状态机 )–胜在性能绝佳,编码形式“颇为丑陋”,但是习惯了模式比较简单,无心智负担。

• 这一结论并没有经过严谨的推理。 Boost.ASIO 无心智负担,主要是指 Boost.ASIO 中没有同步调用概念,尽管繁琐,但是概念一致性非常好。

Page 26: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

CERL 2.0

• 目标–象 Erlang 那样简单地编写服务器程序,并消除其中的不协调。

• 本质的问题:我们需要进一步对同步调用和异步调用的概念进行一致化。

Page 27: CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”

CERL Vision

• CERL 的愿景–让传统语言的开发者获得最佳的分布式编程体

验。• 我们可以和 Erlang 程序员一样愉悦(甚至更好)地

进行分布式程序的开发。