cerl 谈谈“ boost.asio 、 erlang 与服务器编程”
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 PresentationTRANSCRIPT
内容提要• 服务器编程模型
– 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
服务器编程模型• A simple server
• Boost ASIO
• Light-weight processes
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;
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
ASIO
• Reactor 模式– select– epoll– kqueue
• Proactor 模式– IOCP (Completion queues/ports)
• 注: Reactor/Proactor 只是一种粗浅的划分方式,从实现的相似程度来说,个人认为 kqueue 和 IOCP 更接近。
Boost.ASIO
• Boost.ASIO 是一种编程模型(或框架)。– 而上面提到的 select/epoll/kqueue/iocp 等只是
一种 IO 机制,不足以称为编程框架。– Boost.ASIO 屏蔽了繁琐的 IO 细节。
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;
Boost.ASIO 优缺点• 评价:
– 基于状态机的服务器编程模型的最佳典范。• 优点:
– 很好的 Performance 。• 缺点:
– 完整的应用程序业务逻辑被强制分拆到很多个handle 函数。
• 这个分拆不是基于业务需要,而是 IO 需要,因此程序的阅读体验并不好,看上去不那么优雅。
ASIO 小结• ASIO 并不提升单个 Request 的响应时间。
只是由于 IO 操作被重叠 (Overlapped) 进行,使得多个 Request 看起来被并行地处理。
Light-weight processes
• 对比 ASIO:– ASIO 通过提升单个 Process 的 IO 吞吐量来提
升 Performance 。– Light-weight processes 模型则是通过创建多
个“ Process” 来提升 IO 吞吐量。• Light-weight processes 的典范
– Erlang
Light-weight processes
• 核心概念: Process– 这只是一个逻辑上的概念。实现上可能是:
• 虚拟机中的一个 context 结构体,由虚拟机进行调度。• 一个协程(纤程)。• 操作系统的进程或线程(如果操作系统对进程 / 线程创建进行
了优化)。
• 优点– 简单
• 每个 Process 仍然只需要按照前面的 simple server 的逻辑编码。
– 代码体现自然的业务逻辑,容易理解和维护。
什么是 Erlang Style Concurrency ?
• 基于 Actor / Message passing
• Light-weight processes
• 我之于 Erlang Style Concurrency 的不同观点
Actor model
• The Actor model is about the semantics of message passing.– http://en.wikipedia.org/wiki/Actor_model
Erlang Style Concurrency
• Ulf Wiger– http://ulf.wiger.net/weblog/2008/02/06/what-is-
erlang-style-concurrency/
我之于 Erlang Style Concurrency 的不同观点
• 从更高层次看 Erlang Style Concurrency ,其本质的理念在于:– 用最简单自然、易于维护的模式,写最高效的服务器程序。
Erlang Style Concurrency 要素
• 简单自然– 进程是一个执行体,串行化地响应请求。这是“简单自然”原则的重要体现。
• 进程执行中如果需要过多考虑同步与互斥之类的问题,无疑增加开发人员的心智负担。
• 易于维护– 所有服务器以相同的方式编写(易于交流);– 一个服务器可以干净地剥离在同一个源代码单元(易于
模块化)。– 一个完整的业务逻辑应该可以在一个函数内完成,当然
也支持按逻辑拆分成若干子函数(易于编码)。– 所有服务器可以以简单且一致的方式进行调用(易于重
用)。
CERL
• TODO:– 这一节介绍 CERL 对 Erlang Style
Concurrency 在传统语言中的实现
CERL 2.0
• Erlang Style Concurrency 是我们的终点吗?– Light-weight processes 缺陷
• 新编程模式的尝试– Light-weight processes + 状态机?
Erlang Style Concurrency 是我们的终点吗?
• 回头看服务器编程模型– Boost.ASIO ( 基于状态机 )– Light-weight processes ( 基于轻量级进程 )
• Erlang Style Concurrency
Light-weight processes 缺陷• 令人尴尬的“死锁”• 进程内 IO阻塞
令人尴尬的“死锁”• 令人尴尬的“死锁”
– A 向 B 发送一个同步消息,等待 B 回复;而与此同时 B 向 A 也发送了一个同步消息,也在等待状态。这时 A 、 B 两个进程都不能完成自己当前的任务,形成“死锁”。
– 当然由于网络通讯的特殊性,最终 A 和 B 这种死锁是以超时表现出来。
• 怎么办?– 为了避开这点限制,我们在编程手法上禁止了 A 、 B 两个服务
器互发同步请求的设计,改成同步请求只出现在单个方向如 A -> B ,而 B -> A 的同步请求改用两次异步请求来完成。
– 但是这样一来, B 的一个完整逻辑就被打破,使得 B 服务器多了一个临时状态,导致 B 服务器的逻辑分支变多,不利于维护。
有更好的方案吗?
进程内 IO阻塞• 问题来由
– Light-weight processes 的本质是通过创建足够多的 Process 来提升 IO 吞吐量。
– 为了简化 Process 的编码, Process 是串行执行请求的。– 这两条原则有时是相悖的。
• 例如,当 Process属于“资源进程”(即该 Process“拥有”某个资源)时,为了串行化执行对资源的请求,事实上 Process 的数量并不是由请求数决定的,而是由资源数决定的。
• 所以对于资源进程,就可能发生某个请求阻塞其他请求的情况。• 解决方案
– 将资源进程中费时的同步调用改为异步调用。– 问题:给开发人员带来的额外的心智负担:他得小心地决定调用
应该是同步还是异步的。
问题的实质• Light-weight processes 这两个问题的实质
在于,在一些复杂逻辑中, Process 内部其实还是避免不了对 ASIO 状态机的需求。
Light-weight processes + 状态机?
• Light-weight processes–胜在编码简单,性能也很好。但“小有瑕疵”。
• Boost.ASIO ( 基于状态机 )–胜在性能绝佳,编码形式“颇为丑陋”,但是习惯了模式比较简单,无心智负担。
• 这一结论并没有经过严谨的推理。 Boost.ASIO 无心智负担,主要是指 Boost.ASIO 中没有同步调用概念,尽管繁琐,但是概念一致性非常好。
CERL 2.0
• 目标–象 Erlang 那样简单地编写服务器程序,并消除其中的不协调。
• 本质的问题:我们需要进一步对同步调用和异步调用的概念进行一致化。
CERL Vision
• CERL 的愿景–让传统语言的开发者获得最佳的分布式编程体
验。• 我们可以和 Erlang 程序员一样愉悦(甚至更好)地
进行分布式程序的开发。