280 likes | 599 Views
CERL 谈谈“ Boost.ASIO 、 Erlang 与服务器编程”. 许式伟 xushiweizh@gmail.com 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.
E N D
CERL谈谈“Boost.ASIO、Erlang与服务器编程” 许式伟 xushiweizh@gmail.com 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
服务器编程模型 • 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对ErlangStyleConcurrency 在传统语言中的实现
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程序员一样愉悦(甚至更好)地进行分布式程序的开发。
Q & A xushiweizh@gmail.com