<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>kafka0102的边城客栈 &#187; 服务器模型</title>
	<atom:link href="http://www.kafka0102.com/tag/%e6%9c%8d%e5%8a%a1%e5%99%a8%e6%a8%a1%e5%9e%8b/feed" rel="self" type="application/rss+xml" />
	<link>http://www.kafka0102.com</link>
	<description>要有最朴素的生活与最遥远的梦想，即使明日天寒地冻、路远马亡。</description>
	<lastBuildDate>Sat, 18 Jun 2011 04:20:42 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>SEDA介绍与分析</title>
		<link>http://www.kafka0102.com/2010/02/34.html</link>
		<comments>http://www.kafka0102.com/2010/02/34.html#comments</comments>
		<pubDate>Sun, 07 Feb 2010 13:12:48 +0000</pubDate>
		<dc:creator>kafka0102</dc:creator>
				<category><![CDATA[framework]]></category>
		<category><![CDATA[SEDA]]></category>
		<category><![CDATA[Staged Event-Driven Architecture]]></category>
		<category><![CDATA[服务器模型]]></category>

		<guid isPermaLink="false">http://www.kafka0102.com/?p=34</guid>
		<description><![CDATA[	SEDA（Staged Event-Driven Architecture）并不是很新的技术，但它总会在我阅读的资料里出现些许影子，所以就拿出一些时间看了一下与它相关的论文资料。SEDA的目标很远大，它要构建支持大并发的互联网系统，并克服多线程及事件驱动的服务器端模型的缺点。但SEDA来源于学术界，并且这个东西还是有些复杂了，所以至今工业级的应用不是很多。它的官网是http://www.eecs.harvard.edu/~mdw/proj/seda/，上面的一些论文还是很不错的，值得拜读。]]></description>
			<content:encoded><![CDATA[<p>SEDA（Staged Event-Driven Architecture）并不是很新的技术，但它总会在我阅读的资料里出现些许影子，所以就拿出一些时间看了一下与它相关的论文资料。SEDA的目标很远大，它要构建支持大并发的互联网系统，并克服多线程及事件驱动的服务器端模型的缺点。但SEDA来源于学术界，并且这个东西还是有些复杂了，所以至今工业级的应用不是很多。它的官网是<a href="http://www.eecs.harvard.edu/~mdw/proj/seda/">http://www.eecs.harvard.edu/~mdw/proj/seda/</a>，上面的一些论文还是很不错的，值得拜读。</p>
<p>对于服务端端处理模型，目前广泛使用的有两种：</p>
<p>1、多线程处理模型。这种模型由一个主线程和多个work线程构成，主线程负责接收请求，并将接收到的请求分发给合适的work线程处理，work线程处理完请求后直接将响应返回给客户端。这种模型很简单，也有着广泛的应用，尤其是通常的后端模块，处理逻辑在work线程里是阻塞进行的。这个模型的缺点也很明显，如果大量的work线程因为某种原因被堵住（比如连接的DB响应太慢、从磁盘获取文件数据等），将使得后续的请求得不到处理，而最经典的例子莫不过apache了。</p>
<p>2、事件驱动（Event-Driven）处理模型。这种模型克服了多线程模型的并发量缺点，对请求采用事件驱动方式处理，这里的事件通常是IO事件，其底层的实现依赖于非阻塞IO和IO多路复用。事件驱动模型很适合于IO密集型的应用，这种应用对CPU消耗代价甚至要小于线程间的切换代价，比如各种proxy。而现在的proxy，基本都标配Epoll，使得能支持的并发请求数在万级别。像lightty、nginx，是事件驱动模型的经典应用，请求的处理流程是由状态机驱动的，每次状态的切换经由一次事件触发，这样单线程就够用了（当然，如果需要支持更高的处理能力，可以采用多进程的事件驱动模型）。事件驱动的缺点在于：1）单个处理阶段不能阻塞太长，如果有这方面的问题，一般可采用专门的线程处理，处理完了再触发事件让主线程接着处理。2）整个事件驱动流程通常是固定的，在一个线程内由调度器完成，这使得它很难做的通用，使应用可以自定义流程。</p>
<p>基于上面提到的两种模型的优缺点，SEDA被提出来，它的核心思路是：一个请求被分成多个stage进行处理，每个stage彼此间独立，一个请求的多个stage可以串行化也可以并行化。stage内部使用Event-Driven，新到的请求放到event queue中，系统从thread pool中的选择一个线程经由Event Handler处理，Event Handler处理完后将请求派发到下一个stage。下面的是假想的一个Web server的SEDA的处理流程：</p>
<p style="text-align: center;"><a href="http://www.kafka0102.com/wp-content/uploads/2010/02/total1.jpg"><img class="aligncenter size-full wp-image-41" title="SEDA处理流程图" src="http://www.kafka0102.com/wp-content/uploads/2010/02/total1.jpg" alt="SEDA处理流程图" width="558" height="117" /></a></p>
<p>对于SEDA中的每个stage，它由下面的三部分组成：</p>
<p>1）输入的event queue。SEDA中的event queue的大小是有限制的。所以，如果event queue 达到阈值，新到的event可能会被拒绝或者转发到特定的stage（比如错误处理stage）。</p>
<p>2）thread pool：这个线程池对应用是透明的，并且每个stage的线程池是彼此独立的。针对请求量及特点，线程池可以动态的调整大小，不至于某个stage的线程池耗尽所有的资源。</p>
<p>3）event handler，event handler接收系统给予的event，做具体的逻辑处理后将event分发到其他stage。event handler通常需要应用开发者编写。</p>
<div id="attachment_36" class="wp-caption aligncenter" style="width: 530px"><a href="http://www.kafka0102.com/wp-content/uploads/2010/02/aaa.jpg"><img class="size-full wp-image-36" title="SEDA stage内部结构图" src="http://www.kafka0102.com/wp-content/uploads/2010/02/aaa.jpg" alt="SEDA stage内部结构图" width="520" height="274" /></a><p class="wp-caption-text">SEDA stage内部结构图</p></div>
<p>针对各个stage运行时的状态，SEDA引入resource controller来调整stage的资源分配和调度参数等。核心的两个Controller是thread pool controller和batching controller。thread pool controller用来控制thread pool的运行时大小，比如当event queue很大时，就多分配些线程，反之则减少线程数。batching controller用来控制event handler同时处理的event的并发量（batching factor），当batching factor增大时，增加了吞吐量但event平均响应时间会变长，当batching factor变小时，情况相反。batching controller的控制效果使得batching factor的上下波动来控制吞吐量和响应时间。</p>
<div id="attachment_37" class="wp-caption aligncenter" style="width: 543px"><a href="http://www.kafka0102.com/wp-content/uploads/2010/02/ddd.jpg"><img class="size-full wp-image-37" title="SEDA controller结构图" src="http://www.kafka0102.com/wp-content/uploads/2010/02/ddd.jpg" alt="SEDA controller结构图" width="533" height="222" /></a><p class="wp-caption-text">SEDA controller结构图</p></div>
<p>SEDA的一个实现框架是Sandstorm，开发者可以基于它开发应用。限于精力，没有对它做实战，但使用上来说，它还是很简单的。可以想象的是，Sandstorm提供了一些编程接口做事件处理，并通过XML文件（Java的固有风格）来配置stage策略等。对于使用这样分阶段事件驱动框架来说，编程中需要注意stage间不要共享数据，并合理的划分stage策略。</p>
<p>就应用来说，SEDA的多stage处理模型，能够将应用组件化、模块化，解耦了处理的不同阶段，这可能很适合于如工作流等企业业务流程场景。但像通常简单的后端模块，对一个请求可能很难划分出多个职责明确的stage，并且这种分stage策略也增加了处理流程的复杂度，性能上也会受到损失。所以，针对不同的应用特点，SEDA的实用性仍值得商榷。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kafka0102.com/2010/02/34.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

