<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-14949417</id><updated>2012-02-16T17:32:56.817-08:00</updated><category term='comet'/><category term='libevent'/><category term='streaming channel'/><category term='mysql'/><category term='blazeds'/><category term='erlang'/><category term='amf3'/><category term='flex'/><category term='mochiweb'/><title type='text'>digging into iT</title><subtitle type='html'>把自己的工作,生活记录下来,我爱博客</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ro4tub.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14949417/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ro4tub.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>ro4tub</name><uri>http://www.blogger.com/profile/05900229797645474112</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>6</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-14949417.post-7553694923155968727</id><published>2008-11-27T02:12:00.000-08:00</published><updated>2008-12-07T05:40:48.224-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>MYSQL 5.1 GA正式发布</title><content type='html'>&lt;span class="Apple-style-span"   style="border-collapse: collapse;   font-family:arial;font-size:13px;"&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 104, 28); font-weight: bold; white-space: nowrap; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; "&gt;&lt;a href="mailto:Timothy.Smith@sun.com"&gt;Timothy Smith&lt;/a&gt; &lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: bold; white-space: nowrap; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; "&gt;宣布&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 104, 28); font-weight: bold; white-space: nowrap; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;We are proud to present to you the MySQL Server 5.1.30 GA release, the&lt;br /&gt;first 5.1 production version of the popular open source database.&lt;br /&gt;MySQL 5.1.30 is recommended for use on production systems.&lt;br /&gt;&lt;br /&gt;MySQL 5.1 provides a number of new enhancements including:&lt;br /&gt;&lt;br /&gt;- Table and index partitioning&lt;br /&gt;- Row-based and mixed replication&lt;br /&gt;- Built-in job scheduler&lt;br /&gt;- Improved XML handling with XPath support&lt;br /&gt;- New SQL diagnostic aids and performance utilities&lt;br /&gt;- The return of the embedded library (libmysqld)&lt;br /&gt;&lt;br /&gt;For a more complete look at what's new in MySQL 5.1, please see&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;p&gt;&lt;span class="Apple-style-span"   style="border-collapse: collapse;   font-family:arial;font-size:13px;"&gt; &lt;a href="http://dev.mysql.com/doc/refman/5.1/en/mysql-nutshell.html" target="_blank" style="color: rgb(42, 93, 176); "&gt;http://dev.mysql.com/doc/refman/5.1/en/mysql-nutshell.html&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"   style="border-collapse: collapse;   font-family:arial;font-size:13px;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"   style="border-collapse: collapse;   font-family:arial;font-size:13px;"&gt;Update: &lt;a href="http://monty-says.blogspot.com/2008/11/oops-we-did-it-again-mysql-51-released.html"&gt;Oops, we did it again (MySQL 5.1 released as GA with crashing bugs)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14949417-7553694923155968727?l=ro4tub.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ro4tub.blogspot.com/feeds/7553694923155968727/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14949417&amp;postID=7553694923155968727' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14949417/posts/default/7553694923155968727'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14949417/posts/default/7553694923155968727'/><link rel='alternate' type='text/html' href='http://ro4tub.blogspot.com/2008/11/mysql-51-ga.html' title='MYSQL 5.1 GA正式发布'/><author><name>ro4tub</name><uri>http://www.blogger.com/profile/05900229797645474112</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14949417.post-964466873458778178</id><published>2008-11-12T05:44:00.000-08:00</published><updated>2008-11-13T00:11:41.103-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='flex'/><category scheme='http://www.blogger.com/atom/ns#' term='streaming channel'/><category scheme='http://www.blogger.com/atom/ns#' term='blazeds'/><category scheme='http://www.blogger.com/atom/ns#' term='amf3'/><category scheme='http://www.blogger.com/atom/ns#' term='libevent'/><title type='text'>Say goodbye to BlazeDS</title><content type='html'>&lt;a href="http://opensource.adobe.com/wiki/display/blazeds"&gt;BlazeDS&lt;/a&gt;是Adobe提供的一套与Flex进行交互的后台框架，它的最大的卖点就是开源，最大败笔是性能低。本着变腐朽为神奇的思想，我们需要大刀阔斧重整BlazeDS，最终把它丢掉。&lt;br /&gt;&lt;br /&gt;具体步骤：&lt;br /&gt;1.把Streaming Channel代码从BlazeDS中剥离出来，抛弃Endpoint/Service/MessageBroker/Destination等复杂的代码，只保留Message/AMF3。&lt;br /&gt;2.以jetty的continuation方式实现Streaming Channel。&lt;br /&gt;3.基于libevent实现amf3 gateway，并实现wireshark amf3 plugin。&lt;br /&gt;4.基于amf3 gateway(c++ 版本) + game server(java 版本)的架构重新实现整套游戏服务器。&lt;br /&gt;5.进行stress test。&lt;br /&gt;6.使amf3 gateway支持socket和http通讯。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2008年11月12日，基本上已经完成了第一步的工作，不过所有代码都在sandbox，需要integrate。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14949417-964466873458778178?l=ro4tub.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ro4tub.blogspot.com/feeds/964466873458778178/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14949417&amp;postID=964466873458778178' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14949417/posts/default/964466873458778178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14949417/posts/default/964466873458778178'/><link rel='alternate' type='text/html' href='http://ro4tub.blogspot.com/2008/11/say-goodbye-to-blazeds.html' title='Say goodbye to BlazeDS'/><author><name>ro4tub</name><uri>http://www.blogger.com/profile/05900229797645474112</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14949417.post-1189986302023746926</id><published>2008-10-29T21:56:00.000-07:00</published><updated>2008-10-29T22:09:56.953-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comet'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='mochiweb'/><title type='text'>[译]使用Mochiweb构建百万级Comet程序,第二篇</title><content type='html'>&lt;div&gt;&lt;a id="i8vb" title="使用Mochiweb构建百万级Comet程序,第一部分" href="http://www.metabrew.com/article/a-million-user-comet-application-with-mochiweb-part-2"&gt;&lt;span style="color: rgb(128, 0, 128);font-size:180%;" &gt;使用Mochiweb构建百万级Comet程序,第二篇&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;在第一篇中，我们构建了一个mochiweb comet程序（不太实用），每10秒向客户端发送一条消息。我们调整了Linux内核的若干参数，并且为了测试性能和内存的使用量，写了一个发起大量连接的工具。我们发现，每个连接约占45KB内存。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;第二篇，我们将调整程序，使其实用，且能节省内存。&lt;/div&gt; &lt;div&gt; &lt;div&gt; &lt;/div&gt;&lt;/div&gt; &lt;ul&gt;&lt;li&gt;&lt;br /&gt;通过login/logout/send API实现一个消息路由器  &lt;/li&gt;&lt;li&gt;更新mochiweb应用，使其可以从路由器接收消息  &lt;/li&gt;&lt;li&gt;建立一套分布式的erlang系统，我们可以在不同的节点/主机运行该路由器  &lt;/li&gt;&lt;li&gt;写个工具，向路由器发送大量消息  &lt;/li&gt;&lt;li&gt;图形化显示24小时内存实用情况，优化mochiweb应用，使其节省内存开销&lt;/li&gt;&lt;/ul&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;这意味着我们正在吧消息发送逻辑从mochiweb应用中剥离出来。通过第一部分的floodtest工具，我们&lt;/div&gt; &lt;div&gt;可以进行近乎产品化得性能测试。&lt;br /&gt;&lt;br /&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;&lt;span style="font-size:100%;"&gt;&lt;b&gt;实现消息路由器&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;路由器API只有3个函数：&lt;/div&gt; &lt;ul&gt;&lt;li&gt;login(Id, Pid) 注册一个进程(进程Id为Pid)，为Id接收消息  &lt;/li&gt;&lt;li&gt; &lt;div&gt;logout(Pid)停止接收消息&lt;/div&gt; &lt;/li&gt;&lt;li&gt; &lt;div&gt;send(Id, Msg)向任何以Id登陆的客户端发送消息Msg&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;注意，通过设计，一个进程可能会以多个不同得Id登陆。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;下面的路由器模块使用了2张表存放Pid和Id之间的双向映射关系（#state record中的pid2id和id2pid）。&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;router.erl:&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;ol&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;-&lt;span class="kw2"&gt;module&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;router&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;-&lt;span class="kw2"&gt;behaviour&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;gen_server&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;-&lt;span class="kw2"&gt;export&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="kw3"&gt;start_link&lt;/span&gt;/&lt;span class="nu0"&gt;0&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;-&lt;span class="kw2"&gt;export&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;[&lt;/span&gt;init/&lt;span class="nu0"&gt;1&lt;/span&gt;, handle_call/&lt;span class="nu0"&gt;3&lt;/span&gt;, handle_cast/&lt;span class="nu0"&gt;2&lt;/span&gt;, handle_info/&lt;span class="nu0"&gt;2&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;     terminate/&lt;span class="nu0"&gt;2&lt;/span&gt;, code_change/&lt;span class="nu0"&gt;3&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;-&lt;span class="kw2"&gt;export&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;[&lt;/span&gt;send/&lt;span class="nu0"&gt;2&lt;/span&gt;, login/&lt;span class="nu0"&gt;2&lt;/span&gt;, logout/&lt;span class="nu0"&gt;1&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;-define&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;SERVER&lt;/span&gt;, global:&lt;span class="me2"&gt;whereis_name&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;?&lt;span class="re0"&gt;MODULE&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;&lt;span class="co1"&gt;% will hold bidirectional mapping between id &lt;–&gt; pid&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;-record&lt;span class="br0"&gt;(&lt;/span&gt;state, &lt;span class="br0"&gt;{&lt;/span&gt;pid2id, id2pid&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;&lt;span class="kw3"&gt;start_link&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="me1"&gt;gen_server&lt;/span&gt;:&lt;span class="kw3"&gt;start_link&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;global, ?&lt;span class="re0"&gt;MODULE&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;, ?&lt;span class="re0"&gt;MODULE&lt;/span&gt;, &lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;, &lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;&lt;span class="co1"&gt;% sends Msg to anyone logged in as Id&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;send&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Id&lt;/span&gt;, &lt;span class="re0"&gt;Msg&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;    &lt;span class="me1"&gt;gen_server&lt;/span&gt;:&lt;span class="kw3"&gt;call&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;?&lt;span class="re0"&gt;SERVER&lt;/span&gt;, &lt;span class="br0"&gt;{&lt;/span&gt;send, &lt;span class="re0"&gt;Id&lt;/span&gt;, &lt;span class="re0"&gt;Msg&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;login&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Id&lt;/span&gt;, &lt;span class="re0"&gt;Pid&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; when is_pid&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Pid&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="me1"&gt;gen_server&lt;/span&gt;:&lt;span class="kw3"&gt;call&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;?&lt;span class="re0"&gt;SERVER&lt;/span&gt;, &lt;span class="br0"&gt;{&lt;/span&gt;login, &lt;span class="re0"&gt;Id&lt;/span&gt;, &lt;span class="re0"&gt;Pid&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;logout&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Pid&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; when is_pid&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Pid&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="me1"&gt;gen_server&lt;/span&gt;:&lt;span class="kw3"&gt;call&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;?&lt;span class="re0"&gt;SERVER&lt;/span&gt;, &lt;span class="br0"&gt;{&lt;/span&gt;logout, &lt;span class="re0"&gt;Pid&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;&lt;span class="co1"&gt;%%&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;init&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="co1"&gt;% set this so we can catch death of logged in pids:&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    process_flag&lt;span class="br0"&gt;(&lt;/span&gt;trap_exit, true&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="co1"&gt;% use ets for routing tables&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="br0"&gt;{&lt;/span&gt;ok, #state&lt;span class="br0"&gt;{&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;                pid2id = ets:&lt;span class="me2"&gt;new&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;?&lt;span class="re0"&gt;MODULE&lt;/span&gt;, &lt;span class="br0"&gt;[&lt;/span&gt;bag&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                id2pid = ets:&lt;span class="me2"&gt;new&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;?&lt;span class="re0"&gt;MODULE&lt;/span&gt;, &lt;span class="br0"&gt;[&lt;/span&gt;bag&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;               &lt;span class="br0"&gt;}&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="br0"&gt;}&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;handle_call&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;login, &lt;span class="re0"&gt;Id&lt;/span&gt;, &lt;span class="re0"&gt;Pid&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;, _&lt;span class="re0"&gt;From&lt;/span&gt;, &lt;span class="re0"&gt;State&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; when is_pid&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Pid&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="me1"&gt;ets&lt;/span&gt;:&lt;span class="me2"&gt;insert&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;State&lt;/span&gt;#state.pid2id, &lt;span class="br0"&gt;{&lt;/span&gt;&lt;span class="re0"&gt;Pid&lt;/span&gt;, &lt;span class="re0"&gt;Id&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    ets:&lt;span class="me2"&gt;insert&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;State&lt;/span&gt;#state.id2pid, &lt;span class="br0"&gt;{&lt;/span&gt;&lt;span class="re0"&gt;Id&lt;/span&gt;, &lt;span class="re0"&gt;Pid&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    link&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Pid&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;, &lt;span class="co1"&gt;% tell us if they exit, so we can log them out&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    io:&lt;span class="kw3"&gt;format&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="st0"&gt;"~w logged in as ~w&lt;span class="es0"&gt;\n&lt;/span&gt;"&lt;/span&gt;,&lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="re0"&gt;Pid&lt;/span&gt;, &lt;span class="re0"&gt;Id&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;    &lt;span class="br0"&gt;{&lt;/span&gt;reply, ok, &lt;span class="re0"&gt;State&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;handle_call&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;logout, &lt;span class="re0"&gt;Pid&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;, _&lt;span class="re0"&gt;From&lt;/span&gt;, &lt;span class="re0"&gt;State&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; when is_pid&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Pid&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="me1"&gt;unlink&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Pid&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="re0"&gt;PidRows&lt;/span&gt; = ets:&lt;span class="me2"&gt;lookup&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;State&lt;/span&gt;#state.pid2id, &lt;span class="re0"&gt;Pid&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;    &lt;span class="kw1"&gt;case&lt;/span&gt; &lt;span class="re0"&gt;PidRows&lt;/span&gt; &lt;span class="kw1"&gt;of&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="me1"&gt;ok&lt;/span&gt;;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        _ -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="re0"&gt;IdRows&lt;/span&gt; = &lt;span class="br0"&gt;[&lt;/span&gt; &lt;span class="br0"&gt;{&lt;/span&gt;&lt;span class="re0"&gt;I&lt;/span&gt;,&lt;span class="re0"&gt;P&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt; || &lt;span class="br0"&gt;{&lt;/span&gt;&lt;span class="re0"&gt;P&lt;/span&gt;,&lt;span class="re0"&gt;I&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt; &lt;- &lt;span class="re0"&gt;PidRows&lt;/span&gt; &lt;span class="br0"&gt;]&lt;/span&gt;, &lt;span class="co1"&gt;% invert tuples&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;            &lt;span class="co1"&gt;% delete all pid-&gt;id entries&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            ets:&lt;span class="me2"&gt;delete&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;State&lt;/span&gt;#state.pid2id, &lt;span class="re0"&gt;Pid&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="co1"&gt;% and all id-&gt;pid&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="br0"&gt;[&lt;/span&gt; ets:&lt;span class="me2"&gt;delete_object&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;State&lt;/span&gt;#state.id2pid, &lt;span class="re0"&gt;Obj&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; || &lt;span class="re0"&gt;Obj&lt;/span&gt; &lt;- &lt;span class="re0"&gt;IdRows&lt;/span&gt; &lt;span class="br0"&gt;]&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="kw1"&gt;end&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;    io:&lt;span class="kw3"&gt;format&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="st0"&gt;"pid ~w logged out&lt;span class="es0"&gt;\n&lt;/span&gt;"&lt;/span&gt;,&lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="re0"&gt;Pid&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="br0"&gt;{&lt;/span&gt;reply, ok, &lt;span class="re0"&gt;State&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;handle_call&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;send, &lt;span class="re0"&gt;Id&lt;/span&gt;, &lt;span class="re0"&gt;Msg&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;, _&lt;span class="re0"&gt;From&lt;/span&gt;, &lt;span class="re0"&gt;State&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="co1"&gt;% get pids who are logged in as this Id&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;    &lt;span class="re0"&gt;Pids&lt;/span&gt; = &lt;span class="br0"&gt;[&lt;/span&gt; &lt;span class="re0"&gt;P&lt;/span&gt; || &lt;span class="br0"&gt;{&lt;/span&gt; _&lt;span class="re0"&gt;Id&lt;/span&gt;, &lt;span class="re0"&gt;P&lt;/span&gt; &lt;span class="br0"&gt;}&lt;/span&gt; &lt;- ets:&lt;span class="me2"&gt;lookup&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;State&lt;/span&gt;#state.id2pid, &lt;span class="re0"&gt;Id&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; &lt;span class="br0"&gt;]&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="co1"&gt;% send Msg to them all&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="re0"&gt;M&lt;/span&gt; = &lt;span class="br0"&gt;{&lt;/span&gt;router_msg, &lt;span class="re0"&gt;Msg&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="br0"&gt;[&lt;/span&gt; &lt;span class="re0"&gt;Pid&lt;/span&gt; ! &lt;span class="re0"&gt;M&lt;/span&gt; || &lt;span class="re0"&gt;Pid&lt;/span&gt; &lt;- &lt;span class="re0"&gt;Pids&lt;/span&gt; &lt;span class="br0"&gt;]&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="br0"&gt;{&lt;/span&gt;reply, ok, &lt;span class="re0"&gt;State&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;&lt;span class="co1"&gt;% handle death and cleanup of logged in processes&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;handle_info&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Info&lt;/span&gt;, &lt;span class="re0"&gt;State&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="kw1"&gt;case&lt;/span&gt; &lt;span class="re0"&gt;Info&lt;/span&gt; &lt;span class="kw1"&gt;of&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="br0"&gt;{&lt;/span&gt;&lt;span class="st0"&gt;‘EXIT’&lt;/span&gt;, &lt;span class="re0"&gt;Pid&lt;/span&gt;, _&lt;span class="re0"&gt;Why&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;            &lt;span class="co1"&gt;% force logout:&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            handle_call&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;logout, &lt;span class="re0"&gt;Pid&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;, blah, &lt;span class="re0"&gt;State&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;; &lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="re0"&gt;Wtf&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="me1"&gt;io&lt;/span&gt;:&lt;span class="kw3"&gt;format&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="st0"&gt;"Caught unhandled message: ~w&lt;span class="es0"&gt;\n&lt;/span&gt;"&lt;/span&gt;, &lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="re0"&gt;Wtf&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="kw1"&gt;end&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;    &lt;span class="br0"&gt;{&lt;/span&gt;noreply, &lt;span class="re0"&gt;State&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;handle_cast&lt;span class="br0"&gt;(&lt;/span&gt;_&lt;span class="re0"&gt;Msg&lt;/span&gt;, &lt;span class="re0"&gt;State&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="br0"&gt;{&lt;/span&gt;noreply, &lt;span class="re0"&gt;State&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;terminate&lt;span class="br0"&gt;(&lt;/span&gt;_&lt;span class="re0"&gt;Reason&lt;/span&gt;, _&lt;span class="re0"&gt;State&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;    &lt;span class="me1"&gt;ok&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;code_change&lt;span class="br0"&gt;(&lt;/span&gt;_&lt;span class="re0"&gt;OldVsn&lt;/span&gt;, &lt;span class="re0"&gt;State&lt;/span&gt;, _&lt;span class="re0"&gt;Extra&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="br0"&gt;{&lt;/span&gt;ok, &lt;span class="re0"&gt;State&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;.&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-size:100%;"&gt;&lt;b&gt;更新mochiweb应用&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;让我们假设每个用户以基于连向mochiweb的URL的整形Id，用这个Id在消息路由器中注册。不是阻塞10秒钟，然后发送消息，而是mochiweb循环阻塞着从路由器接收消息。把路由器发送过来得每条消息包装成http块发送给客户端。&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;ul&gt;&lt;li&gt; &lt;div class="de1"&gt;客户端通过&lt;a href="http://localhost:8000/test/123"&gt;http://localhost:8000/test/123&lt;/a&gt;连接mochiweb&lt;/div&gt; &lt;/li&gt;&lt;li&gt; &lt;div class="de1"&gt;Mochiweb应用把该连接的pid和id '123'关联起来，注册在消息路由器&lt;/div&gt; &lt;/li&gt;&lt;li&gt; &lt;div class="de1"&gt;假如你把（目标）地址id '123'的消息发送给路由器，该消息将被转发给正确得mochiweb进程，并在那个用户的浏览器中显示。&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;这里是更新后得mochiconntest_web.erl:&lt;/div&gt;&lt;br /&gt;&lt;div class="dean_ch" style=""&gt; &lt;ol&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;-&lt;span class="kw2"&gt;module&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;mochiconntest_web&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;-&lt;span class="kw2"&gt;export&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;[&lt;/span&gt;start/&lt;span class="nu0"&gt;1&lt;/span&gt;, stop/&lt;span class="nu0"&gt;0&lt;/span&gt;, loop/&lt;span class="nu0"&gt;2&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;&lt;span class="co1"&gt;%% External API&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;start&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Options&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="br0"&gt;{&lt;/span&gt;&lt;span class="re0"&gt;DocRoot&lt;/span&gt;, &lt;span class="re0"&gt;Options1&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt; = get_option&lt;span class="br0"&gt;(&lt;/span&gt;docroot, &lt;span class="re0"&gt;Options&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="re0"&gt;Loop&lt;/span&gt; = fun &lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Req&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;                   ?&lt;span class="re0"&gt;MODULE&lt;/span&gt;:&lt;span class="me2"&gt;loop&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Req&lt;/span&gt;, &lt;span class="re0"&gt;DocRoot&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;           &lt;span class="kw1"&gt;end&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="co1"&gt;% we’ll set our maximum to 1 million connections. (default: 2048)&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    mochiweb_http:&lt;span class="me2"&gt;start&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;max, &lt;span class="nu0"&gt;1000000&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;, &lt;span class="br0"&gt;{&lt;/span&gt;name, ?&lt;span class="re0"&gt;MODULE&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;, &lt;span class="br0"&gt;{&lt;/span&gt;loop, &lt;span class="re0"&gt;Loop&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt; | &lt;span class="re0"&gt;Options1&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;stop&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="me1"&gt;mochiweb_http&lt;/span&gt;:&lt;span class="me2"&gt;stop&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;?&lt;span class="re0"&gt;MODULE&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;loop&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Req&lt;/span&gt;, &lt;span class="re0"&gt;DocRoot&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="st0"&gt;"/"&lt;/span&gt; ++ &lt;span class="re0"&gt;Path&lt;/span&gt; = &lt;span class="re0"&gt;Req&lt;/span&gt;:&lt;span class="me2"&gt;get&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;path&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;    &lt;span class="kw1"&gt;case&lt;/span&gt; &lt;span class="re0"&gt;Req&lt;/span&gt;:&lt;span class="me2"&gt;get&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;method&lt;span class="br0"&gt;)&lt;/span&gt; &lt;span class="kw1"&gt;of&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="re0"&gt;Method&lt;/span&gt; when &lt;span class="re0"&gt;Method&lt;/span&gt; =:= &lt;span class="st0"&gt;‘GET’&lt;/span&gt;; &lt;span class="re0"&gt;Method&lt;/span&gt; =:= &lt;span class="st0"&gt;‘HEAD’&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="kw1"&gt;case&lt;/span&gt; &lt;span class="re0"&gt;Path&lt;/span&gt; &lt;span class="kw1"&gt;of&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                &lt;span class="st0"&gt;"test/"&lt;/span&gt; ++ &lt;span class="re0"&gt;Id&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                    &lt;span class="re0"&gt;Response&lt;/span&gt; = &lt;span class="re0"&gt;Req&lt;/span&gt;:&lt;span class="me2"&gt;ok&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;&lt;span class="st0"&gt;"text/html; charset=utf-8"&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;                                      &lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;&lt;span class="st0"&gt;"Server"&lt;/span&gt;,&lt;span class="st0"&gt;"Mochiweb-Test"&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                                      chunked&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                    &lt;span class="co1"&gt;% login using an integer rather than a string&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                    &lt;span class="br0"&gt;{&lt;/span&gt;&lt;span class="re0"&gt;IdInt&lt;/span&gt;, _&lt;span class="br0"&gt;}&lt;/span&gt; = string:&lt;span class="me2"&gt;to_integer&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Id&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                    router:&lt;span class="me2"&gt;login&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;IdInt&lt;/span&gt;, self&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;                    feed&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Response&lt;/span&gt;, &lt;span class="re0"&gt;IdInt&lt;/span&gt;, &lt;span class="nu0"&gt;1&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                _ -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                    &lt;span class="re0"&gt;Req&lt;/span&gt;:&lt;span class="me2"&gt;not_found&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="kw1"&gt;end&lt;/span&gt;;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="st0"&gt;‘POST’&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;            &lt;span class="kw1"&gt;case&lt;/span&gt; &lt;span class="re0"&gt;Path&lt;/span&gt; &lt;span class="kw1"&gt;of&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                _ -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                    &lt;span class="re0"&gt;Req&lt;/span&gt;:&lt;span class="me2"&gt;not_found&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="kw1"&gt;end&lt;/span&gt;;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        _ -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;            &lt;span class="re0"&gt;Req&lt;/span&gt;:&lt;span class="me2"&gt;respond&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;&lt;span class="nu0"&gt;501&lt;/span&gt;, &lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;, &lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="kw1"&gt;end&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;feed&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Response&lt;/span&gt;, &lt;span class="re0"&gt;Id&lt;/span&gt;, &lt;span class="re0"&gt;N&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="kw1"&gt;receive&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;    &lt;span class="br0"&gt;{&lt;/span&gt;router_msg, &lt;span class="re0"&gt;Msg&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="re0"&gt;Html&lt;/span&gt; = io_lib:&lt;span class="kw3"&gt;format&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="st0"&gt;"Recvd msg #~w: ‘~s’"&lt;/span&gt;, &lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="re0"&gt;N&lt;/span&gt;, &lt;span class="re0"&gt;Msg&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="re0"&gt;Response&lt;/span&gt;:&lt;span class="me2"&gt;write_chunk&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Html&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="kw1"&gt;end&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    feed&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Response&lt;/span&gt;, &lt;span class="re0"&gt;Id&lt;/span&gt;, &lt;span class="re0"&gt;N&lt;/span&gt;&lt;span class="nu0"&gt;+1&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;&lt;span class="co1"&gt;%% Internal API&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;get_option&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Option&lt;/span&gt;, &lt;span class="re0"&gt;Options&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="br0"&gt;{&lt;/span&gt;proplists:&lt;span class="me2"&gt;get_value&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Option&lt;/span&gt;, &lt;span class="re0"&gt;Options&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;, proplists:&lt;span class="me2"&gt;delete&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Option&lt;/span&gt;, &lt;span class="re0"&gt;Options&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;.&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt; &lt;/div&gt;&lt;br /&gt;&lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-size:100%;"&gt;&lt;b&gt;运行起来吧&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;现在让它们跑起来吧，我们将使用两个erlang shell，一个是mochiweb，另一个是路由器。编辑用来启动mochiweb的脚本start-dev.sh，给erl添加下列额外的参数:&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;ul&gt;&lt;li&gt; &lt;div class="de1"&gt;-sname n1 命名erlang节点为'n1'&lt;/div&gt; &lt;/li&gt;&lt;li&gt; &lt;div class="de1"&gt;+K true 启用kernel-poll，处理大量连接时，似乎没有理由不启用这个选项&lt;/div&gt; &lt;/li&gt;&lt;li&gt; &lt;div class="de1"&gt;+P 134217727 默认的最大进程数目为32768；考虑到我们每个连接需要一个进程，我建议把它设为可以的最大值。通过'man erl'我们知道134,217,727是最大值。&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;现在运行make &amp;amp;&amp;amp; ./start-dev.sh，你会看到这样的提示：(&lt;a href="mailto:n1@localhost%291"&gt;n1@localhost)1&lt;/a&gt;&gt;，你得mochiweb程序正在运行，并且这个erlang节点有个名字。&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;现在运行另一个erlang shell：erl -sname n2&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;目前，那两个erlang实例彼此不知道对方，修正它：&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;(n2@localhost)1&gt; nodes().&lt;br /&gt;[]&lt;br /&gt;(n2@localhost)2&gt; net_adm:ping(n1@localhost).&lt;br /&gt;pong&lt;br /&gt;(n2@localhost)3&gt; nodes().&lt;br /&gt;[n1@localhost]&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;现在从这个shell中编译、&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;启动路由器：&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;(n2@localhost)4&gt; c(router).&lt;br /&gt;{ok,router}&lt;br /&gt;(n2@localhost)5&gt; router:start_link().&lt;br /&gt;{ok,&lt;0.38.0&gt;}&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;现在用你的浏览器访问&lt;a href="http://localhost:8000/test/123"&gt;http://localhost:8000/test/123&lt;/a&gt;（或者在控制台用lynx --source &lt;a href="http://localhost:8000/test/123"&gt;http://localhost:8000/test/123&lt;/a&gt;）。检查运行路由器得那个shell，你会看到有一位用户登录。&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;你现在可以向路由器发送消息，并能在你的浏览器中看到。目前为止，只可以发送字符串，因为在feed函数中我们使用io_lib:format的~s格式化它们，atoms会使程序崩溃。&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;n2@localhost)6&gt; router:send(123, "Hello World").&lt;br /&gt;(n2@localhost)7&gt; router:send(123, "Why not open another browser window too?").&lt;br /&gt;(n2@localhost)8&gt; router:send(456, "This message will go into the void unless you are connected as /test/456 too").&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;看一下你的浏览器，comet程序已经正常运行。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style=";font-family:Courier New;font-size:100%;"  &gt;&lt;b&gt;运行在分布式erlang系统中&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;在不同机器上运行路由器和mochiweb前端是有意义的。假定你有几台闲置的电脑进行测试，你应该以分布式节点启动erlang shell。比如使用-name &lt;a href="mailto:n1@host1.example.com"&gt;n1@host1.example.com&lt;/a&gt;替代-sname n1(同样对于n2)。通过net_adm:ping(...)确保它们互相可见。&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;注意在router.erl的16行，路由器进程的名字('router')是被全局注册的，因为在gen_server中我们使用了下列宏来识别/定位路由器，这已经适用于分布式系统：&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;-define(SERVER, global:whereis_name(?MODULE)).&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;在分布式系统中，进程的全局命名注册键是erlang天生由来的。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style=";font-family:Courier New;font-size:100%;"  &gt;&lt;b&gt;产生大量消息&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;在真实环境中，我们可能会看到长尾一样的使用模式，少些活跃用户加上大量的非活跃用户。然而，在这个测试用，我们不分青红皂白地给随机用户发送测试消息。&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;mesgen.erl：&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt;  &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;br /&gt;&lt;div class="dean_ch" style=""&gt; &lt;ol&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;-&lt;span class="kw2"&gt;module&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;msggen&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;-&lt;span class="kw2"&gt;export&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;[&lt;/span&gt;start/&lt;span class="nu0"&gt;3&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;start&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="nu0"&gt;0&lt;/span&gt;, _, _&lt;span class="br0"&gt;)&lt;/span&gt; -&gt; &lt;span class="me1"&gt;ok&lt;/span&gt;;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;start&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Num&lt;/span&gt;, &lt;span class="re0"&gt;Interval&lt;/span&gt;, &lt;span class="re0"&gt;Max&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="re0"&gt;Id&lt;/span&gt; = random:&lt;span class="me2"&gt;uniform&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Max&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    router:&lt;span class="me2"&gt;send&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Id&lt;/span&gt;, &lt;span class="st0"&gt;"Fake message Num = "&lt;/span&gt; ++ &lt;span class="re0"&gt;Num&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="kw1"&gt;receive&lt;/span&gt; &lt;span class="kw1"&gt;after&lt;/span&gt; &lt;span class="re0"&gt;Interval&lt;/span&gt; -&gt; &lt;span class="me1"&gt;start&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Num&lt;/span&gt; &lt;span class="nu0"&gt;-1&lt;/span&gt;, &lt;span class="re0"&gt;Interval&lt;/span&gt;, &lt;span class="re0"&gt;Max&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; &lt;span class="kw1"&gt;end&lt;/span&gt;.&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt; &lt;/div&gt;&lt;br /&gt;它会给1到Max之间的随机的用户Id发送Num条消息，每次发送之间会等待Interval毫秒。&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;按照如下指令，你会看到整个运行情况。运行路由器和mochiweb程序，浏览器访问&lt;a href="http://localhost:8000/test/3"&gt;http://localhost:8000/test/3&lt;/a&gt;，然后运行：&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;erl -sname test&lt;br /&gt;(test@localhost)1&gt; net_adm:ping(n1@localhost).&lt;br /&gt;pong&lt;br /&gt;(test@localhost)2&gt; c(msggen).&lt;br /&gt;{ok,msggen}&lt;br /&gt;(test@localhost)3&gt; msggen:start(20, 10, 5).&lt;br /&gt;ok&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;它给1-5之间的随机Id发送20条消息，每条消息之间有10毫秒的等待。&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;我们甚至可以并行地运行它们，模拟多个消息源。下面的例子会产生10个进程，给1-5之间的ids发送20条消息，每条消息之间等待100毫秒。&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;[ spawn(fun() -&gt; msggen:start(20, 100, 5), io:format("~w finished.\n", [self()]) end) || _ &lt;- lists:seq(1,10) ]. [&lt;0.97.0&gt;,&lt;0.98.0&gt;,&lt;0.99.0&gt;,&lt;0.100.0&gt;,&lt;0.101.0&gt;,&lt;0.102.0&gt;,&lt;br /&gt;&lt;0.103.0&gt;,&lt;0.104.0&gt;,&lt;0.105.0&gt;,&lt;0.106.0&gt;]&lt;br /&gt;&lt;0.101.0&gt; finished.&lt;br /&gt;&lt;0.105.0&gt; finished.&lt;br /&gt;&lt;0.106.0&gt; finished.&lt;br /&gt;&lt;0.104.0&gt; finished.&lt;br /&gt;&lt;0.102.0&gt; finished.&lt;br /&gt;&lt;0.98.0&gt; finished.&lt;br /&gt;&lt;0.99.0&gt; finished.&lt;br /&gt;&lt;0.100.0&gt; finished.&lt;br /&gt;&lt;0.103.0&gt; finished.&lt;br /&gt;&lt;0.97.0&gt; finished.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style=";font-family:Courier New;font-size:100%;"  &gt;&lt;b&gt;再次CK10&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt; 我想我们需要进一步大规模的测试，客户端连接mochiweb程序，并被注册到消息路由器中。我们可以在路由器上产生大量测试消息，发往任何注册的客户端。让我们再测一遍1万个并发用户的情况，但是这一次我们让客户端多连一会。&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;假定你按照第一篇中的指令对内核进行了调节，增加最大文件限制等等，这很容易的。你已经运行了mochiweb程序和路由器。接着，让我们记录所有的通讯。&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;在没有客户端连接的情况下，mochiweb beam进程使用大约40MB内存(常驻的)：&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;$ ps -o rss= -p `pgrep -f 'sname n1'`&lt;br /&gt;40156&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;我写一行可怕的代码，每隔60秒打印一次：时间戳、mochiweb当前内存实用情况(KB单位)以及当前的连接数。在一个空闲的终端跑这段脚本:&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;$ MOCHIPID=`pgrep -f 'name n1'`; while [ 1 ] ; do NUMCON=`netstat -n | awk ‘/ESTABLISHED/ &amp;amp;&amp;amp; $4==”127.0.0.1:8000″‘ | wc -l`; MEM=`ps -o rss= -p $MOCHIPID`; echo -e “`date`\t`date +%s`\t$MEM\t$NUMCON”; sleep 60; done | tee -a mochimem.log&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;现在在新的erl shell中启动第一篇中的floodtest工具：&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;erl&gt; floodtest:start("/tmp/mochi-urls.txt", 10).&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;它将每秒建立10条连接的频率建立1万条连接。&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;你会看到，很快到达1万条连接：&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;erl&gt; floodtest:start("/tmp/mochi-urls.txt", 10).&lt;br /&gt;Stats: {825,0,0}&lt;br /&gt;Stats: {1629,0,0}&lt;br /&gt;Stats: {2397,0,0}&lt;br /&gt;Stats: {3218,0,0}&lt;br /&gt;Stats: {4057,0,0}&lt;br /&gt;Stats: {4837,0,0}&lt;br /&gt;Stats: {5565,0,0}&lt;br /&gt;Stats: {6295,0,0}&lt;br /&gt;Stats: {7022,0,0}&lt;br /&gt;Stats: {7727,0,0}&lt;br /&gt;Stats: {8415,0,0}&lt;br /&gt;Stats: {9116,0,0}&lt;br /&gt;Stats: {9792,0,0}&lt;br /&gt;Stats: {10000,0,0}&lt;br /&gt;...&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;请看那行脚本的输出：&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;Mon Oct 20 16:57:24 BST 2008 1224518244 40388 1&lt;br /&gt;Mon Oct 20 16:58:25 BST 2008 1224518305 41120 263&lt;br /&gt;Mon Oct 20 16:59:27 BST 2008 1224518367 65252 5267&lt;br /&gt;Mon Oct 20 17:00:32 BST 2008 1224518432 89008 9836&lt;br /&gt;Mon Oct 20 17:01:37 BST 2008 1224518497 90748 10001&lt;br /&gt;Mon Oct 20 17:02:41 BST 2008 1224518561 90964 10001&lt;br /&gt;Mon Oct 20 17:03:46 BST 2008 1224518626 90964 10001&lt;br /&gt;Mon Oct 20 17:04:51 BST 2008 1224518691 90964 10001&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;1万条连接（加上我在firefox中打开的一条连接），大约占用90MB（90964KB）。&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;现在开始发送消息：&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt; &lt;p&gt;&lt;code&gt;erl&gt; [ spawn(fun() -&gt; msggen:start(1000000, 100, 10000) end) || _ &lt;- lists:seq(1,100) ]. [&lt;0.65.0&gt;,&lt;0.66.0&gt;,&lt;0.67.0&gt;,&lt;0.68.0&gt;,&lt;0.69.0&gt;,&lt;0.70.0&gt;,&lt;br /&gt;&lt;0.71.0&gt;,&lt;0.72.0&gt;,&lt;0.73.0&gt;,&lt;0.74.0&gt;,&lt;0.75.0&gt;,&lt;0.76.0&gt;,&lt;br /&gt;&lt;0.77.0&gt;,&lt;0.78.0&gt;,&lt;0.79.0&gt;,&lt;0.80.0&gt;,&lt;0.81.0&gt;,&lt;0.82.0&gt;,&lt;br /&gt;&lt;0.83.0&gt;,&lt;0.84.0&gt;,&lt;0.85.0&gt;,&lt;0.86.0&gt;,&lt;0.87.0&gt;,&lt;0.88.0&gt;,&lt;br /&gt;&lt;0.89.0&gt;,&lt;0.90.0&gt;,&lt;0.91.0&gt;,&lt;0.92.0&gt;,&lt;0.93.0&gt;|...]&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;&lt;/code&gt; &lt;/p&gt; &lt;p&gt;&lt;code&gt;100个进程，每个进程以每秒10条的频率随机地给1到1万之间的id发送1百万条消息。这意味着，路由器每秒发送1000条消息，平均每个客户端每10秒接收一条消息。&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;&lt;/code&gt; &lt;/p&gt; &lt;p&gt;&lt;code&gt;看一下floodtest的输出，你会看到客户端正在接收http块（记住这是{已连接的连接数，被关闭的连接数，接收到的数据块的数量}）：&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;&lt;/code&gt; &lt;/p&gt; &lt;p&gt;&lt;code&gt;...&lt;br /&gt;Stats: {10000,0,5912}&lt;br /&gt;Stats: {10000,0,15496}&lt;br /&gt;Stats: {10000,0,25145}&lt;br /&gt;Stats: {10000,0,34755}&lt;br /&gt;Stats: {10000,0,44342}&lt;br /&gt;...&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;&lt;/code&gt; &lt;/p&gt; &lt;p&gt;&lt;code&gt;每个进程以每秒10条消息的频率发送1百万条消息，需要27个小时才能完成。&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;这里是10分钟后的内存使用情况：&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;&lt;/code&gt; &lt;/p&gt; &lt;p&gt;&lt;code&gt;Mon Oct 20 16:57:24 BST 2008 1224518244 40388 1&lt;br /&gt;Mon Oct 20 16:58:25 BST 2008 1224518305 41120 263&lt;br /&gt;Mon Oct 20 16:59:27 BST 2008 1224518367 65252 5267&lt;br /&gt;Mon Oct 20 17:00:32 BST 2008 1224518432 89008 9836&lt;br /&gt;Mon Oct 20 17:01:37 BST 2008 1224518497 90748 10001&lt;br /&gt;Mon Oct 20 17:02:41 BST 2008 1224518561 90964 10001&lt;br /&gt;Mon Oct 20 17:03:46 BST 2008 1224518626 90964 10001&lt;br /&gt;Mon Oct 20 17:04:51 BST 2008 1224518691 90964 10001&lt;br /&gt;Mon Oct 20 17:05:55 BST 2008 1224518755 90980 10001&lt;br /&gt;Mon Oct 20 17:07:00 BST 2008 1224518820 91120 10001&lt;br /&gt;Mon Oct 20 17:08:05 BST 2008 1224518885 98664 10001&lt;br /&gt;Mon Oct 20 17:09:10 BST 2008 1224518950 106752 10001&lt;br /&gt;Mon Oct 20 17:10:15 BST 2008 1224519015 114044 10001&lt;br /&gt;Mon Oct 20 17:11:20 BST 2008 1224519080 119468 10001&lt;br /&gt;Mon Oct 20 17:12:25 BST 2008 1224519145 125360 10001&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;&lt;/code&gt; &lt;/p&gt; &lt;p&gt;&lt;code&gt;当连上1万个客户端后，内存使用量就从40MB增加到90MB，当运行一段时间后，变为125MB。&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;&lt;/code&gt; &lt;/p&gt; &lt;p&gt;&lt;code&gt;值得指出的是，floodtest工具占用了大部分的CPU，msggen使用了2%的CPU，而路由器和mochiweb不到1%（只有客户端模拟程序占用大量的CPU，而服务器程序本身没怎么占用CPU）。这表明我们需要在多台机器或者多核CPU机器上跑测试。&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;&lt;/code&gt; &lt;/p&gt; &lt;p&gt;&lt;code&gt;&lt;span style="font-size:100%;"&gt;&lt;b&gt;24小时后的结果&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;这个测试跑了24个小时，同时把内存使用情况记录在mochimem.log文件中。这是1万个客户端，每秒1000条消息随机发送给客户端。&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;下面的bash/awk脚本调用gnuplot把mochimem.log文件中的数据图形化：&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt; &lt;p&gt;&lt;code&gt;(echo -e "set terminal png size 500,300\nset xlabel \"Minutes Elapsed\"\nset ylabel \"Mem (KB)\"\nset title \"Mem usage with 10k active connections, 1000 msg/sec\"\nplot \"-\" using 1:2 with lines notitle" ; awk 'BEGIN{FS="\t";} NR%10==0 {if(!t){t=$2} mins=($2-t)/60; printf("%d %d\n",mins,$3)}' mochimem.log ; echo -e "end" ) | gnuplot &gt; mochimem.png&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;&lt;/code&gt; &lt;/p&gt;&lt;code&gt; &lt;/code&gt;&lt;div id="ygzn" style="padding: 1em 0px; text-align: left;"&gt;&lt;img src="http://docs.google.com/File?id=dgwzfxqf_17c94ztvcz_b" /&gt;&lt;/div&gt;&lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;图片展示了内存使用情况，24小时内基本上稳定在250MB。两个大的落差，一个是在开始的时候，另一个是在结束的时候，是因为我在mochiweb erlang进程中运行了：&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;erl&gt; [erlang:garbage_collect(P) || P &lt;- erlang:processes()].&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-family:Courier New;"&gt;这强制所有进程垃圾回收，释放了将近100MB的内存。接下来，我们一起研究如何节省内存开销。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style=";font-family:Courier New;font-size:100%;"  &gt;&lt;b&gt;在mochiweb中降低内存开销&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;mochiweb程序只是发送消息，并不会保存。内存使用量不会因为发送的消息数量增多而增多。&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;对与erlang的内存管理，我是新手。但我觉得时常地垃圾回收，会降低一部分的内存开销，最终让我们用最少的内存服务更多的用户。我们可能会牺牲一部分的CPU，但这是可以接受的。&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;深入了&lt;a id="yrhg" title="erlang文档" href="http://erlang.org/doc/man/erlang.html"&gt;erlang文档&lt;/a&gt; ，发现如下的选项：&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt; &lt;p&gt;&lt;b&gt;&lt;code&gt;erlang:system_flag(fullsweep_after, Number)&lt;/code&gt;&lt;/b&gt;&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Number is a non-negative integer which indicates how many times generational garbages collections can be done without forcing a fullsweep collection. The value applies to new processes; processes already running are not affected.&lt;br /&gt;In low-memory systems (especially without virtual memory), setting the value to 0 can help to conserve memory.&lt;br /&gt;An alternative way to set this value is through the (operating system) environment variable ERL_FULLSWEEP_AFTER.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt; &lt;div class="de1"&gt;看起来不错，不过它只适用于新的进程，并且会影响到VM中的所有进程，而不是只有我们的mochiweb进程。&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;接着：&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt; &lt;p&gt;&lt;b&gt;&lt;code&gt;erlang:system_flag(min_heap_size, MinHeapSize)&lt;/code&gt;&lt;/b&gt;&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Sets the default minimum heap size for processes. The size is given in words. The new min_heap_size only effects processes spawned after the change of min_heap_size has been made. The min_heap_size can be set for individual processes by use of spawn_opt/N or process_flag/2. &lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt; &lt;div class="de1"&gt;可能会有用，不过我确信mochiweb进程需要一个更大的堆。如果可以，我会尽可能避免修改mochiweb的源代码，增加spawn选项。&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;接着，这个映入我的眼帘：&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt; &lt;p&gt;&lt;b&gt;&lt;code&gt;erlang:hibernate(Module, Function, Args)&lt;/code&gt;&lt;/b&gt;&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Puts the calling process into a wait state where its memory allocation has been reduced as much as possible, which is useful if the process does not expect to receive any messages in the near future. &lt;/p&gt; &lt;p&gt;The process will be awaken when a message is sent to it, and control will resume in Module:Function with the arguments given by Args with the call stack emptied, meaning that the process will terminate when that function returns. Thus erlang:hibernate/3 will never return to its caller.&lt;/p&gt; &lt;p&gt;If the process has any message in its message queue, the process will be awaken immediately in the same way as described above.&lt;/p&gt; &lt;p&gt;In more technical terms, what erlang:hibernate/3 does is the following. It discards the call stack for the process. Then it garbage collects the process. After the garbage collection, all live data is in one continuous heap. The heap is then shrunken to the exact same size as the live data which it holds (even if that size is less than the minimum heap size for the process).&lt;/p&gt; &lt;p&gt;If the size of the live data in the process is less than the minimum heap size, the first garbage collection occurring after the process has been awaken will ensure that the heap size is changed to a size not smaller than the minimum heap size.&lt;/p&gt; &lt;p&gt;Note that emptying the call stack means that any surrounding catch is removed and has to be re-inserted after hibernation. One effect of this is that processes started using proc_lib (also indirectly, such as gen_server processes), should use proc_lib:hibernate/3 instead to ensure that the exception handler continues to work when the process wakes up. &lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt; &lt;div class="de1"&gt;看上去是有道理的，每条消息后进行睡眠，看看会发生什么变化。&lt;/div&gt; &lt;div class="de1"&gt;编辑mochiconntest_web.erl，进行如下更改：&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;ul&gt;&lt;li&gt; &lt;div class="de1"&gt;最后一行的fee(Response, Id, N)函数将调用hibernate而不是自身&lt;/div&gt;&lt;/li&gt;&lt;li&gt; &lt;div class="de1"&gt;登录路由器后立即调用hibernate，而不是调用feed，然后阻塞着接收&lt;/div&gt;&lt;/li&gt;&lt;li&gt; &lt;div class="de1"&gt;记住导出feed/3，那样hibernate在醒来后可以回调它&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;更新mochiconntest_web.erl：&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt; &lt;ol&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;-&lt;span class="kw2"&gt;&lt;b&gt;module&lt;/b&gt;&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;/span&gt;mochiconntest_web&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;-&lt;span class="kw2"&gt;&lt;b&gt;export&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;[&lt;/span&gt;&lt;/span&gt;start/&lt;span class="nu0"&gt;&lt;span style="color: rgb(255, 51, 255);"&gt;1&lt;/span&gt;&lt;/span&gt;, stop/&lt;span class="nu0"&gt;&lt;span style="color: rgb(255, 51, 255);"&gt;0&lt;/span&gt;&lt;/span&gt;, loop/&lt;span class="nu0"&gt;&lt;span style="color: rgb(255, 51, 255);"&gt;2&lt;/span&gt;&lt;/span&gt;, feed/&lt;span class="nu0"&gt;&lt;span style="color: rgb(255, 51, 255);"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;&lt;span class="co1"&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;%% External API&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;start&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="re0"&gt;Options&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class="re0"&gt;DocRoot&lt;/span&gt;, &lt;span class="re0"&gt;Options1&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;/span&gt; = get_option&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;/span&gt;docroot, &lt;span class="re0"&gt;Options&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="re0"&gt;Loop&lt;/span&gt; = fun &lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="re0"&gt;Req&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;                   ?&lt;span class="re0"&gt;MODULE&lt;/span&gt;:&lt;span class="me2"&gt;loop&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="re0"&gt;Req&lt;/span&gt;, &lt;span class="re0"&gt;DocRoot&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;           &lt;span class="kw1"&gt;&lt;span style="color: rgb(161, 161, 0);"&gt;end&lt;/span&gt;&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="co1"&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;% we’ll set our maximum to 1 million connections. (default: 2048)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    mochiweb_http:&lt;span class="me2"&gt;start&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;&lt;/span&gt;max, &lt;span class="nu0"&gt;&lt;span style="color: rgb(255, 51, 255);"&gt;1000000&lt;/span&gt;&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;/span&gt;, &lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;/span&gt;name, ?&lt;span class="re0"&gt;MODULE&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;/span&gt;, &lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;/span&gt;loop, &lt;span class="re0"&gt;Loop&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;/span&gt; | &lt;span class="re0"&gt;Options1&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;stop&lt;span style="color: rgb(102, 204, 102);"&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="me1"&gt;mochiweb_http&lt;/span&gt;:&lt;span class="me2"&gt;stop&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;/span&gt;?&lt;span class="re0"&gt;MODULE&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;loop&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="re0"&gt;Req&lt;/span&gt;, &lt;span class="re0"&gt;DocRoot&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="st0"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"/"&lt;/span&gt;&lt;/span&gt; ++ &lt;span class="re0"&gt;Path&lt;/span&gt; = &lt;span class="re0"&gt;Req&lt;/span&gt;:&lt;span class="me2"&gt;get&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;/span&gt;path&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;    &lt;span class="kw1"&gt;&lt;span style="color: rgb(161, 161, 0);"&gt;case&lt;/span&gt;&lt;/span&gt; &lt;span class="re0"&gt;Req&lt;/span&gt;:&lt;span class="me2"&gt;get&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;/span&gt;method&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class="kw1"&gt;&lt;span style="color: rgb(161, 161, 0);"&gt;of&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="re0"&gt;Method&lt;/span&gt; when &lt;span class="re0"&gt;Method&lt;/span&gt; =:= &lt;span class="st0"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;‘GET’&lt;/span&gt;&lt;/span&gt;; &lt;span class="re0"&gt;Method&lt;/span&gt; =:= &lt;span class="st0"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;‘HEAD’&lt;/span&gt;&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="kw1"&gt;&lt;span style="color: rgb(161, 161, 0);"&gt;case&lt;/span&gt;&lt;/span&gt; &lt;span class="re0"&gt;Path&lt;/span&gt; &lt;span class="kw1"&gt;&lt;span style="color: rgb(161, 161, 0);"&gt;of&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                &lt;span class="st0"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"test/"&lt;/span&gt;&lt;/span&gt; ++ &lt;span class="re0"&gt;IdStr&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                    &lt;span class="re0"&gt;Response&lt;/span&gt; = &lt;span class="re0"&gt;Req&lt;/span&gt;:&lt;span class="me2"&gt;ok&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class="st0"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"text/html; charset=utf-8"&lt;/span&gt;&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;                                      &lt;span style="color: rgb(102, 204, 102);"&gt;&lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class="st0"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"Server"&lt;/span&gt;&lt;/span&gt;,&lt;span class="st0"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"Mochiweb-Test"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                                      chunked&lt;span style="color: rgb(102, 204, 102);"&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                    &lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class="re0"&gt;Id&lt;/span&gt;, _&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;/span&gt; = string:&lt;span class="me2"&gt;to_integer&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="re0"&gt;IdStr&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                    router:&lt;span class="me2"&gt;login&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="re0"&gt;Id&lt;/span&gt;, self&lt;span style="color: rgb(102, 204, 102);"&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                    &lt;span class="co1"&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;% Hibernate this process until it receives a message:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;                    proc_lib:&lt;span class="me2"&gt;hibernate&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;/span&gt;?&lt;span class="re0"&gt;MODULE&lt;/span&gt;, feed, &lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;[&lt;/span&gt;&lt;/span&gt;&lt;span class="re0"&gt;Response&lt;/span&gt;, &lt;span class="re0"&gt;Id&lt;/span&gt;, &lt;span class="nu0"&gt;&lt;span style="color: rgb(255, 51, 255);"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/span&gt;;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                _ -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                    &lt;span class="re0"&gt;Req&lt;/span&gt;:&lt;span class="me2"&gt;not_found&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="kw1"&gt;&lt;span style="color: rgb(161, 161, 0);"&gt;end&lt;/span&gt;&lt;/span&gt;;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;        &lt;span class="st0"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;‘POST’&lt;/span&gt;&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="kw1"&gt;&lt;span style="color: rgb(161, 161, 0);"&gt;case&lt;/span&gt;&lt;/span&gt; &lt;span class="re0"&gt;Path&lt;/span&gt; &lt;span class="kw1"&gt;&lt;span style="color: rgb(161, 161, 0);"&gt;of&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                _ -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                    &lt;span class="re0"&gt;Req&lt;/span&gt;:&lt;span class="me2"&gt;not_found&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="kw1"&gt;&lt;span style="color: rgb(161, 161, 0);"&gt;end&lt;/span&gt;&lt;/span&gt;;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;        _ -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="re0"&gt;Req&lt;/span&gt;:&lt;span class="me2"&gt;respond&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class="nu0"&gt;&lt;span style="color: rgb(255, 51, 255);"&gt;501&lt;/span&gt;&lt;/span&gt;, &lt;span style="color: rgb(102, 204, 102);"&gt;&lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;/span&gt;, &lt;span style="color: rgb(102, 204, 102);"&gt;&lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="kw1"&gt;&lt;span style="color: rgb(161, 161, 0);"&gt;end&lt;/span&gt;&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;feed&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="re0"&gt;Response&lt;/span&gt;, &lt;span class="re0"&gt;Id&lt;/span&gt;, &lt;span class="re0"&gt;N&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;    &lt;span class="kw1"&gt;&lt;span style="color: rgb(161, 161, 0);"&gt;receive&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;/span&gt;router_msg, &lt;span class="re0"&gt;Msg&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="re0"&gt;Html&lt;/span&gt; = io_lib:&lt;span class="kw3"&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;format&lt;/span&gt;&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="st0"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"Recvd msg #~w: ‘~w’&lt;br /&gt;"&lt;/span&gt;&lt;/span&gt;, &lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;[&lt;/span&gt;&lt;/span&gt;&lt;span class="re0"&gt;N&lt;/span&gt;, &lt;span class="re0"&gt;Msg&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="re0"&gt;Response&lt;/span&gt;:&lt;span class="me2"&gt;write_chunk&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="re0"&gt;Html&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="kw1"&gt;&lt;span style="color: rgb(161, 161, 0);"&gt;end&lt;/span&gt;&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;    &lt;span class="co1"&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;% Hibernate this process until it receives a message:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    proc_lib:&lt;span class="me2"&gt;hibernate&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;/span&gt;?&lt;span class="re0"&gt;MODULE&lt;/span&gt;, feed, &lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;[&lt;/span&gt;&lt;/span&gt;&lt;span class="re0"&gt;Response&lt;/span&gt;, &lt;span class="re0"&gt;Id&lt;/span&gt;, &lt;span class="re0"&gt;N&lt;/span&gt;&lt;span class="nu0"&gt;&lt;span style="color: rgb(255, 51, 255);"&gt;+1&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;&lt;span class="co1"&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;%% Internal API&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;get_option&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="re0"&gt;Option&lt;/span&gt;, &lt;span class="re0"&gt;Options&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;/span&gt;proplists:&lt;span class="me2"&gt;get_value&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="re0"&gt;Option&lt;/span&gt;, &lt;span class="re0"&gt;Options&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;/span&gt;, proplists:&lt;span class="me2"&gt;delete&lt;/span&gt;&lt;span class="br0"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="re0"&gt;Option&lt;/span&gt;, &lt;span class="re0"&gt;Options&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;/span&gt;.&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;更改后，重新编译mochiweb，然后重新进行相同的c10k测试。&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-size:100%;"&gt;&lt;b&gt;使用proc_lib:hibernate()后的结果&lt;/b&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt; &lt;div id="xpn1" style="padding: 1em 0px; text-align: left;"&gt;&lt;img src="http://docs.google.com/File?id=dgwzfxqf_188kv2fr97_b" /&gt;&lt;/div&gt;&lt;/div&gt; &lt;div class="de1"&gt;使用hibernate后，内存使用量仅为78MB，明显好于第一篇中的450MB。CPU使用量没有明显提高。&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-size:100%;"&gt;&lt;b&gt;&lt;br /&gt;总结&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;我们基于mochiweb实现了comet程序，让我们可以通过ID任意地给客户端发送消息。经过24小时不间断地1000 msg/秒发送消息，1万个连接，使用了80MB内存，也就是每条连接占用8KB。我们还制作了精美的图表。&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;对于第一篇中的每条连接45KB来说，这是一个进步，而这一切归功于我们以一种更真实的方式进行测试，并且在消息之间使用了hibernate。&lt;br /&gt;&lt;br /&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;&lt;span style="font-size:100%;"&gt;&lt;b&gt;下一步&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;在第三篇中（不久发布），我将进行1百万连接的测试，测试程序部署在多cpu的64位服务器上，有足够的内存。&lt;/div&gt; &lt;div class="de1"&gt;看看有什么区别。我也会列出一些窍门，用来模拟1百万个客户端。&lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt;程序将以一种pub-sub系统呈现，订阅将和用户id有关，并被程序保存，而不是由客户端在连接的时候提供。我们将加载典型的社交网数据：朋友。这将允许用户用他们的id登录，并能自动接受朋友们的事件。&lt;/div&gt;&lt;div class="de1"&gt; &lt;/div&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14949417-1189986302023746926?l=ro4tub.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ro4tub.blogspot.com/feeds/1189986302023746926/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14949417&amp;postID=1189986302023746926' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14949417/posts/default/1189986302023746926'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14949417/posts/default/1189986302023746926'/><link rel='alternate' type='text/html' href='http://ro4tub.blogspot.com/2008/10/mochiwebcomet_29.html' title='[译]使用Mochiweb构建百万级Comet程序,第二篇'/><author><name>ro4tub</name><uri>http://www.blogger.com/profile/05900229797645474112</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14949417.post-4696320468801789994</id><published>2008-10-19T01:47:00.000-07:00</published><updated>2008-10-19T02:11:31.325-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blazeds'/><category scheme='http://www.blogger.com/atom/ns#' term='amf3'/><title type='text'>深入浅出AMF3</title><content type='html'>&lt;meta equiv="Content-Type" content="text/html; charset=utf-8"&gt;&lt;meta name="ProgId" content="Word.Document"&gt;&lt;meta name="Generator" content="Microsoft Word 11"&gt;&lt;meta name="Originator" content="Microsoft Word 11"&gt;&lt;!--[if !mso]&gt; &lt;style&gt; v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} &lt;/style&gt; &lt;![endif]--&gt;&lt;o:smarttagtype namespaceuri="urn:schemas-microsoft-com:office:smarttags" name="chmetcnv"&gt;&lt;/o:smarttagtype&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:worddocument&gt;   &lt;w:view&gt;Normal&lt;/w:View&gt;   &lt;w:zoom&gt;0&lt;/w:Zoom&gt;   &lt;w:punctuationkerning/&gt;   &lt;w:drawinggridverticalspacing&gt;7.8 磅&lt;/w:DrawingGridVerticalSpacing&gt;   &lt;w:displayhorizontaldrawinggridevery&gt;0&lt;/w:DisplayHorizontalDrawingGridEvery&gt;   &lt;w:displayverticaldrawinggridevery&gt;2&lt;/w:DisplayVerticalDrawingGridEvery&gt;   &lt;w:validateagainstschemas/&gt;   &lt;w:saveifxmlinvalid&gt;false&lt;/w:SaveIfXMLInvalid&gt;   &lt;w:ignoremixedcontent&gt;false&lt;/w:IgnoreMixedContent&gt;   &lt;w:alwaysshowplaceholdertext&gt;false&lt;/w:AlwaysShowPlaceholderText&gt;   &lt;w:compatibility&gt;    &lt;w:spaceforul/&gt;    &lt;w:balancesinglebytedoublebytewidth/&gt;    &lt;w:donotleavebackslashalone/&gt;    &lt;w:ultrailspace/&gt;    &lt;w:donotexpandshiftreturn/&gt;    &lt;w:adjustlineheightintable/&gt;    &lt;w:breakwrappedtables/&gt;    &lt;w:snaptogridincell/&gt;    &lt;w:wraptextwithpunct/&gt;    &lt;w:useasianbreakrules/&gt;    &lt;w:dontgrowautofit/&gt;    &lt;w:usefelayout/&gt;   &lt;/w:Compatibility&gt;   &lt;w:browserlevel&gt;MicrosoftInternetExplorer4&lt;/w:BrowserLevel&gt;  &lt;/w:WordDocument&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:latentstyles deflockedstate="false" latentstylecount="156"&gt;  &lt;/w:LatentStyles&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if !mso]&gt;&lt;object classid="clsid:38481807-CA0E-42D2-BF39-B33AF135CC4D" id="ieooui"&gt;&lt;/object&gt; &lt;style&gt; st1\:*{behavior:url(#ieooui) } &lt;/style&gt; &lt;![endif]--&gt;&lt;style&gt; &lt;!--  /* Font Definitions */  @font-face 	{font-family:Wingdings; 	panose-1:5 0 0 0 0 0 0 0 0 0; 	mso-font-charset:2; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:0 268435456 0 0 -2147483648 0;} @font-face 	{font-family:宋体; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-alt:SimSun; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 16 0 262145 0;} @font-face 	{font-family:黑体; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-alt:SimHei; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:1 135135232 16 0 262144 0;} @font-face 	{font-family:"\@宋体"; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 16 0 262145 0;} @font-face 	{font-family:"\@黑体"; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:1 135135232 16 0 262144 0;}  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-parent:""; 	margin:0cm; 	margin-bottom:.0001pt; 	text-align:justify; 	text-justify:inter-ideograph; 	mso-pagination:none; 	font-size:10.5pt; 	mso-bidi-font-size:12.0pt; 	font-family:"Times New Roman"; 	mso-fareast-font-family:宋体; 	mso-font-kerning:1.0pt;} h1 	{mso-style-next:正文; 	margin-top:17.0pt; 	margin-right:0cm; 	margin-bottom:16.5pt; 	margin-left:0cm; 	text-align:justify; 	text-justify:inter-ideograph; 	line-height:240%; 	mso-pagination:lines-together; 	page-break-after:avoid; 	mso-outline-level:1; 	font-size:22.0pt; 	font-family:"Times New Roman"; 	mso-font-kerning:22.0pt;} h2 	{mso-style-next:正文; 	margin-top:13.0pt; 	margin-right:0cm; 	margin-bottom:13.0pt; 	margin-left:0cm; 	text-align:justify; 	text-justify:inter-ideograph; 	line-height:173%; 	mso-pagination:lines-together; 	page-break-after:avoid; 	mso-outline-level:2; 	font-size:16.0pt; 	font-family:Arial; 	mso-fareast-font-family:黑体; 	mso-bidi-font-family:"Times New Roman"; 	mso-font-kerning:1.0pt;} a:link, span.MsoHyperlink 	{color:blue; 	text-decoration:underline; 	text-underline:single;} a:visited, span.MsoHyperlinkFollowed 	{color:purple; 	text-decoration:underline; 	text-underline:single;}  /* Page Definitions */  @page 	{mso-page-border-surround-header:no; 	mso-page-border-surround-footer:no;} @page Section1 	{size:595.3pt 841.9pt; 	margin:72.0pt 90.0pt 72.0pt 90.0pt; 	mso-header-margin:42.55pt; 	mso-footer-margin:49.6pt; 	mso-paper-source:0; 	layout-grid:15.6pt;} div.Section1 	{page:Section1;}  /* List Definitions */  @list l0 	{mso-list-id:1089812879; 	mso-list-type:hybrid; 	mso-list-template-ids:-1325734836 67698689 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;} @list l0:level1 	{mso-level-number-format:bullet; 	mso-level-text:; 	mso-level-tab-stop:21.0pt; 	mso-level-number-position:left; 	margin-left:21.0pt; 	text-indent:-21.0pt; 	font-family:Wingdings;} @list l1 	{mso-list-id:1446192652; 	mso-list-template-ids:67698717;} @list l1:level1 	{mso-level-text:%1; 	mso-level-tab-stop:21.25pt; 	mso-level-number-position:left; 	margin-left:21.25pt; 	text-indent:-21.25pt;} @list l1:level2 	{mso-level-text:"%1\.%2"; 	mso-level-tab-stop:49.6pt; 	mso-level-number-position:left; 	margin-left:49.6pt; 	text-indent:-1.0cm;} @list l1:level3 	{mso-level-text:"%1\.%2\.%3"; 	mso-level-tab-stop:70.9pt; 	mso-level-number-position:left; 	margin-left:70.9pt; 	text-indent:-1.0cm;} @list l1:level4 	{mso-level-text:"%1\.%2\.%3\.%4"; 	mso-level-tab-stop:99.2pt; 	mso-level-number-position:left; 	margin-left:99.2pt; 	text-indent:-35.4pt;} @list l1:level5 	{mso-level-text:"%1\.%2\.%3\.%4\.%5"; 	mso-level-tab-stop:127.55pt; 	mso-level-number-position:left; 	margin-left:127.55pt; 	text-indent:-42.5pt;} @list l1:level6 	{mso-level-text:"%1\.%2\.%3\.%4\.%5\.%6"; 	mso-level-tab-stop:163.0pt; 	mso-level-number-position:left; 	margin-left:163.0pt; 	text-indent:-2.0cm;} @list l1:level7 	{mso-level-text:"%1\.%2\.%3\.%4\.%5\.%6\.%7"; 	mso-level-tab-stop:191.35pt; 	mso-level-number-position:left; 	margin-left:191.35pt; 	text-indent:-63.8pt;} @list l1:level8 	{mso-level-text:"%1\.%2\.%3\.%4\.%5\.%6\.%7\.%8"; 	mso-level-tab-stop:219.7pt; 	mso-level-number-position:left; 	margin-left:219.7pt; 	text-indent:-70.9pt;} @list l1:level9 	{mso-level-text:"%1\.%2\.%3\.%4\.%5\.%6\.%7\.%8\.%9"; 	mso-level-tab-stop:255.1pt; 	mso-level-number-position:left; 	margin-left:255.1pt; 	text-indent:-85.0pt;} ol 	{margin-bottom:0cm;} ul 	{margin-bottom:0cm;} --&gt; &lt;/style&gt;&lt;!--[if gte mso 10]&gt; &lt;style&gt;  /* Style Definitions */  table.MsoNormalTable 	{mso-style-name:普通表格; 	mso-tstyle-rowband-size:0; 	mso-tstyle-colband-size:0; 	mso-style-noshow:yes; 	mso-style-parent:""; 	mso-padding-alt:0cm 5.4pt 0cm 5.4pt; 	mso-para-margin:0cm; 	mso-para-margin-bottom:.0001pt; 	mso-pagination:widow-orphan; 	font-size:10.0pt; 	font-family:"Times New Roman"; 	mso-ansi-language:#0400; 	mso-fareast-language:#0400; 	mso-bidi-language:#0400;} &lt;/style&gt; &lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;o:shapedefaults ext="edit" spidmax="1044"&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;o:shapelayout ext="edit"&gt;   &lt;o:idmap ext="edit" data="1"&gt;  &lt;/o:shapelayout&gt;&lt;/xml&gt;&lt;![endif]--&gt;  &lt;h1 style="text-align: center;" align="center"&gt;&lt;span style="font-family:宋体;"&gt;深入浅出&lt;/span&gt;&lt;span lang="EN-US"&gt;AMF3&lt;/span&gt;&lt;/h1&gt;  &lt;p class="MsoNormal" style="text-align: right;" align="right"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;       &lt;/span&gt;By &lt;a href="http://ro4tub.blogspot.com/"&gt;Oscar&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-align: right;" align="right"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;h1 style="margin-left: 21.25pt; text-indent: -21.25pt;"&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;1&lt;span style=";font-family:&amp;quot;;font-size:7;"  &gt;       &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span style="font-family:宋体;"&gt;不同的序列化方式&lt;/span&gt;&lt;/h1&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-family:宋体;"&gt;让我们先考虑这样一个需求：客户端发送两个整数给服务器，服务器接收数据，计算它们的和，然后把结果传回给客户端。&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-family:宋体;"&gt;我们如何序列化这两个整型数据呢？&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;h2 style="margin-left: 49.6pt; text-indent: -1cm;"&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;1.1&lt;span style=";font-family:&amp;quot;;font-size:7;"  &gt;    &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span style="font-family:黑体;"&gt;传统的序列化方式&lt;/span&gt;&lt;/h2&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-family:宋体;"&gt;首先，我们考虑传统的序列化方式，一个报头，加上具体数据，大致如下：&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;!--[if mso &amp; !supportInlineShapes &amp; supportFields]&gt;&lt;span lang="EN-US"&gt;&lt;span style="'mso-element:field-begin;mso-field-lock:yes'"&gt;&lt;/span&gt;&lt;span style="'mso-spacerun:yes'"&gt; &lt;/span&gt;SHAPE&lt;span style="'mso-spacerun:yes'"&gt;  &lt;/span&gt;\* MERGEFORMAT &lt;span style="'mso-element:field-separator'"&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]--&gt;&lt;meta equiv="Content-Type" content="text/html; charset=utf-8"&gt;&lt;meta name="ProgId" content="Word.Document"&gt;&lt;meta name="Generator" content="Microsoft Word 11"&gt;&lt;meta name="Originator" content="Microsoft Word 11"&gt;&lt;link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C06%5Cclip_filelist.xml"&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:worddocument&gt;   &lt;w:view&gt;Normal&lt;/w:View&gt;   &lt;w:zoom&gt;0&lt;/w:Zoom&gt;   &lt;w:punctuationkerning/&gt;   &lt;w:drawinggridverticalspacing&gt;7.8 磅&lt;/w:DrawingGridVerticalSpacing&gt;   &lt;w:displayhorizontaldrawinggridevery&gt;0&lt;/w:DisplayHorizontalDrawingGridEvery&gt;   &lt;w:displayverticaldrawinggridevery&gt;2&lt;/w:DisplayVerticalDrawingGridEvery&gt;   &lt;w:validateagainstschemas/&gt;   &lt;w:saveifxmlinvalid&gt;false&lt;/w:SaveIfXMLInvalid&gt;   &lt;w:ignoremixedcontent&gt;false&lt;/w:IgnoreMixedContent&gt;   &lt;w:alwaysshowplaceholdertext&gt;false&lt;/w:AlwaysShowPlaceholderText&gt;   &lt;w:compatibility&gt;    &lt;w:spaceforul/&gt;    &lt;w:balancesinglebytedoublebytewidth/&gt;    &lt;w:donotleavebackslashalone/&gt;    &lt;w:ultrailspace/&gt;    &lt;w:donotexpandshiftreturn/&gt;    &lt;w:adjustlineheightintable/&gt;    &lt;w:breakwrappedtables/&gt;    &lt;w:snaptogridincell/&gt;    &lt;w:wraptextwithpunct/&gt;    &lt;w:useasianbreakrules/&gt;    &lt;w:dontgrowautofit/&gt;    &lt;w:usefelayout/&gt;   &lt;/w:Compatibility&gt;   &lt;w:browserlevel&gt;MicrosoftInternetExplorer4&lt;/w:BrowserLevel&gt;  &lt;/w:WordDocument&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:latentstyles deflockedstate="false" latentstylecount="156"&gt;  &lt;/w:LatentStyles&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;style&gt; &lt;!--  /* Font Definitions */  @font-face 	{font-family:宋体; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-alt:SimSun; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 16 0 262145 0;} @font-face 	{font-family:"\@宋体"; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 16 0 262145 0;}  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-parent:""; 	margin:0cm; 	margin-bottom:.0001pt; 	text-align:justify; 	text-justify:inter-ideograph; 	mso-pagination:none; 	font-size:10.5pt; 	mso-bidi-font-size:12.0pt; 	font-family:"Times New Roman"; 	mso-fareast-font-family:宋体; 	mso-font-kerning:1.0pt;}  /* Page Definitions */  @page 	{mso-page-border-surround-header:no; 	mso-page-border-surround-footer:no;} @page Section1 	{size:612.0pt 792.0pt; 	margin:72.0pt 90.0pt 72.0pt 90.0pt; 	mso-header-margin:36.0pt; 	mso-footer-margin:36.0pt; 	mso-paper-source:0;} div.Section1 	{page:Section1;} --&gt; &lt;/style&gt;&lt;!--[if gte mso 10]&gt; &lt;style&gt;  /* Style Definitions */  table.MsoNormalTable 	{mso-style-name:普通表格; 	mso-tstyle-rowband-size:0; 	mso-tstyle-colband-size:0; 	mso-style-noshow:yes; 	mso-style-parent:""; 	mso-padding-alt:0cm 5.4pt 0cm 5.4pt; 	mso-para-margin:0cm; 	mso-para-margin-bottom:.0001pt; 	mso-pagination:widow-orphan; 	font-size:10.0pt; 	font-family:"Times New Roman"; 	mso-ansi-language:#0400; 	mso-fareast-language:#0400; 	mso-bidi-language:#0400;} &lt;/style&gt; &lt;![endif]--&gt;  &lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style=";font-family:宋体;font-size:9;"  &gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style=";font-family:宋体;font-size:9;"  &gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p class="MsoNormal"&gt;&lt;span style=";font-family:宋体;font-size:9;"  &gt;两个字节消息类型&lt;/span&gt;&lt;span  lang="EN-US" style="font-size:9;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style=";font-family:宋体;font-size:9;"  &gt;两个字节消息长度&lt;/span&gt;&lt;span  lang="EN-US" style="font-size:9;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style=";font-family:宋体;font-size:9;"  &gt;四个字节&lt;/span&gt;&lt;span  lang="EN-US" style="font-size:9;"&gt;value1&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style=";font-family:宋体;font-size:9;"  &gt;四个字节&lt;/span&gt;&lt;span  lang="EN-US" style="font-size:9;"&gt;value2&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p class="MsoNormal"&gt;&lt;span  lang="EN-US" style="font-size:9;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span  lang="EN-US" style="font-size:9;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;!--[if mso &amp; !supportInlineShapes &amp; supportFields]&gt;&lt;span lang="EN-US"&gt;&lt;v:shape id="_x0000_i1025" type="#_x0000_t75" style="'width:414pt;"&gt;  &lt;v:imagedata croptop="-65520f" cropbottom="65520f"&gt; &lt;/v:shape&gt;&lt;span style="'mso-element:field-end'"&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]--&gt;&lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-family:宋体;"&gt;也就是说，以这种包装数据的方式，我们需要发送&lt;/span&gt;&lt;span lang="EN-US"&gt;12&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;字节。&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;h2 style="margin-left: 49.6pt; text-indent: -1cm;"&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;1.2&lt;span style=";font-family:&amp;quot;;font-size:7;"  &gt;    &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span lang="EN-US"&gt;Java&lt;/span&gt;&lt;span style="font-family:黑体;"&gt;对象序列化方式&lt;/span&gt;&lt;/h2&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-family:宋体;"&gt;接下来，我们尝试一下&lt;/span&gt;&lt;span lang="EN-US"&gt;Java&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;对象序列化方式，我们需要定义这样的类：&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;!--[if mso &amp; !supportInlineShapes &amp; supportFields]&gt;&lt;span lang="EN-US"&gt;&lt;span style="'mso-element:field-begin;mso-field-lock:yes'"&gt;&lt;/span&gt;&lt;span style="'mso-spacerun:yes'"&gt; &lt;/span&gt;SHAPE&lt;span style="'mso-spacerun:yes'"&gt;  &lt;/span&gt;\* MERGEFORMAT &lt;span style="'mso-element:field-separator'"&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]--&gt;&lt;meta equiv="Content-Type" content="text/html; charset=utf-8"&gt;&lt;meta name="ProgId" content="Word.Document"&gt;&lt;meta name="Generator" content="Microsoft Word 11"&gt;&lt;meta name="Originator" content="Microsoft Word 11"&gt;&lt;link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C07%5Cclip_filelist.xml"&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:worddocument&gt;   &lt;w:view&gt;Normal&lt;/w:View&gt;   &lt;w:zoom&gt;0&lt;/w:Zoom&gt;   &lt;w:punctuationkerning/&gt;   &lt;w:drawinggridverticalspacing&gt;7.8 磅&lt;/w:DrawingGridVerticalSpacing&gt;   &lt;w:displayhorizontaldrawinggridevery&gt;0&lt;/w:DisplayHorizontalDrawingGridEvery&gt;   &lt;w:displayverticaldrawinggridevery&gt;2&lt;/w:DisplayVerticalDrawingGridEvery&gt;   &lt;w:validateagainstschemas/&gt;   &lt;w:saveifxmlinvalid&gt;false&lt;/w:SaveIfXMLInvalid&gt;   &lt;w:ignoremixedcontent&gt;false&lt;/w:IgnoreMixedContent&gt;   &lt;w:alwaysshowplaceholdertext&gt;false&lt;/w:AlwaysShowPlaceholderText&gt;   &lt;w:compatibility&gt;    &lt;w:spaceforul/&gt;    &lt;w:balancesinglebytedoublebytewidth/&gt;    &lt;w:donotleavebackslashalone/&gt;    &lt;w:ultrailspace/&gt;    &lt;w:donotexpandshiftreturn/&gt;    &lt;w:adjustlineheightintable/&gt;    &lt;w:breakwrappedtables/&gt;    &lt;w:snaptogridincell/&gt;    &lt;w:wraptextwithpunct/&gt;    &lt;w:useasianbreakrules/&gt;    &lt;w:dontgrowautofit/&gt;    &lt;w:usefelayout/&gt;   &lt;/w:Compatibility&gt;   &lt;w:browserlevel&gt;MicrosoftInternetExplorer4&lt;/w:BrowserLevel&gt;  &lt;/w:WordDocument&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:latentstyles deflockedstate="false" latentstylecount="156"&gt;  &lt;/w:LatentStyles&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;style&gt; &lt;!--  /* Font Definitions */  @font-face 	{font-family:宋体; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-alt:SimSun; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 16 0 262145 0;} @font-face 	{font-family:"\@宋体"; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 16 0 262145 0;}  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-parent:""; 	margin:0cm; 	margin-bottom:.0001pt; 	text-align:justify; 	text-justify:inter-ideograph; 	mso-pagination:none; 	font-size:10.5pt; 	mso-bidi-font-size:12.0pt; 	font-family:"Times New Roman"; 	mso-fareast-font-family:宋体; 	mso-font-kerning:1.0pt;}  /* Page Definitions */  @page 	{mso-page-border-surround-header:no; 	mso-page-border-surround-footer:no;} @page Section1 	{size:612.0pt 792.0pt; 	margin:72.0pt 90.0pt 72.0pt 90.0pt; 	mso-header-margin:36.0pt; 	mso-footer-margin:36.0pt; 	mso-paper-source:0;} div.Section1 	{page:Section1;} --&gt; &lt;/style&gt;&lt;!--[if gte mso 10]&gt; &lt;style&gt;  /* Style Definitions */  table.MsoNormalTable 	{mso-style-name:普通表格; 	mso-tstyle-rowband-size:0; 	mso-tstyle-colband-size:0; 	mso-style-noshow:yes; 	mso-style-parent:""; 	mso-padding-alt:0cm 5.4pt 0cm 5.4pt; 	mso-para-margin:0cm; 	mso-para-margin-bottom:.0001pt; 	mso-pagination:widow-orphan; 	font-size:10.0pt; 	font-family:"Times New Roman"; 	mso-ansi-language:#0400; 	mso-fareast-language:#0400; 	mso-bidi-language:#0400;} &lt;/style&gt; &lt;![endif]--&gt;  &lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;public class SumUpMessage implements Serializable&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;{&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;    &lt;/span&gt;private static final long serialVersionUID = 3357976281271608025L;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;    &lt;/span&gt;private int value1;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;    &lt;/span&gt;private int value2;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;    &lt;/span&gt;public int getValue1()&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;    &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;        &lt;/span&gt;return value1;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;    &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;    &lt;/span&gt;public void setValue1(int value1)&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;    &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;        &lt;/span&gt;this.value1 = value1;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;    &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;    &lt;/span&gt;public int getValue2()&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;    &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;        &lt;/span&gt;return value2;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;    &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;    &lt;/span&gt;public void setValue2(int value2)&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;    &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;        &lt;/span&gt;this.value2 = value2;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;    &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;}&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;  &lt;!--[if mso &amp; !supportInlineShapes &amp; supportFields]&gt;&lt;span lang="EN-US"&gt;&lt;v:shape id="_x0000_i1026" type="#_x0000_t75" style="'width:414pt;"&gt;  &lt;v:imagedata croptop="-65520f" cropbottom="65520f"&gt; &lt;/v:shape&gt;&lt;span style="'mso-element:field-end'"&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]--&gt;&lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-family:宋体;"&gt;测试发现，我们需要发送&lt;/span&gt;&lt;span lang="EN-US"&gt;69&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;字节。&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-family:宋体;"&gt;测试程序如下：&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;!--[if mso &amp; !supportInlineShapes &amp; supportFields]&gt;&lt;span lang="EN-US"&gt;&lt;span style="'mso-element:field-begin;mso-field-lock:yes'"&gt;&lt;/span&gt;&lt;span style="'mso-spacerun:yes'"&gt; &lt;/span&gt;SHAPE&lt;span style="'mso-spacerun:yes'"&gt;  &lt;/span&gt;\* MERGEFORMAT &lt;span style="'mso-element:field-separator'"&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]--&gt;&lt;meta equiv="Content-Type" content="text/html; charset=utf-8"&gt;&lt;meta name="ProgId" content="Word.Document"&gt;&lt;meta name="Generator" content="Microsoft Word 11"&gt;&lt;meta name="Originator" content="Microsoft Word 11"&gt;&lt;link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C08%5Cclip_filelist.xml"&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:worddocument&gt;   &lt;w:view&gt;Normal&lt;/w:View&gt;   &lt;w:zoom&gt;0&lt;/w:Zoom&gt;   &lt;w:punctuationkerning/&gt;   &lt;w:drawinggridverticalspacing&gt;7.8 磅&lt;/w:DrawingGridVerticalSpacing&gt;   &lt;w:displayhorizontaldrawinggridevery&gt;0&lt;/w:DisplayHorizontalDrawingGridEvery&gt;   &lt;w:displayverticaldrawinggridevery&gt;2&lt;/w:DisplayVerticalDrawingGridEvery&gt;   &lt;w:validateagainstschemas/&gt;   &lt;w:saveifxmlinvalid&gt;false&lt;/w:SaveIfXMLInvalid&gt;   &lt;w:ignoremixedcontent&gt;false&lt;/w:IgnoreMixedContent&gt;   &lt;w:alwaysshowplaceholdertext&gt;false&lt;/w:AlwaysShowPlaceholderText&gt;   &lt;w:compatibility&gt;    &lt;w:spaceforul/&gt;    &lt;w:balancesinglebytedoublebytewidth/&gt;    &lt;w:donotleavebackslashalone/&gt;    &lt;w:ultrailspace/&gt;    &lt;w:donotexpandshiftreturn/&gt;    &lt;w:adjustlineheightintable/&gt;    &lt;w:breakwrappedtables/&gt;    &lt;w:snaptogridincell/&gt;    &lt;w:wraptextwithpunct/&gt;    &lt;w:useasianbreakrules/&gt;    &lt;w:dontgrowautofit/&gt;    &lt;w:usefelayout/&gt;   &lt;/w:Compatibility&gt;   &lt;w:browserlevel&gt;MicrosoftInternetExplorer4&lt;/w:BrowserLevel&gt;  &lt;/w:WordDocument&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:latentstyles deflockedstate="false" latentstylecount="156"&gt;  &lt;/w:LatentStyles&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;style&gt; &lt;!--  /* Font Definitions */  @font-face 	{font-family:宋体; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-alt:SimSun; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 16 0 262145 0;} @font-face 	{font-family:"\@宋体"; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 16 0 262145 0;}  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-parent:""; 	margin:0cm; 	margin-bottom:.0001pt; 	text-align:justify; 	text-justify:inter-ideograph; 	mso-pagination:none; 	font-size:10.5pt; 	mso-bidi-font-size:12.0pt; 	font-family:"Times New Roman"; 	mso-fareast-font-family:宋体; 	mso-font-kerning:1.0pt;}  /* Page Definitions */  @page 	{mso-page-border-surround-header:no; 	mso-page-border-surround-footer:no;} @page Section1 	{size:612.0pt 792.0pt; 	margin:72.0pt 90.0pt 72.0pt 90.0pt; 	mso-header-margin:36.0pt; 	mso-footer-margin:36.0pt; 	mso-paper-source:0;} div.Section1 	{page:Section1;} --&gt; &lt;/style&gt;&lt;!--[if gte mso 10]&gt; &lt;style&gt;  /* Style Definitions */  table.MsoNormalTable 	{mso-style-name:普通表格; 	mso-tstyle-rowband-size:0; 	mso-tstyle-colband-size:0; 	mso-style-noshow:yes; 	mso-style-parent:""; 	mso-padding-alt:0cm 5.4pt 0cm 5.4pt; 	mso-para-margin:0cm; 	mso-para-margin-bottom:.0001pt; 	mso-pagination:widow-orphan; 	font-size:10.0pt; 	font-family:"Times New Roman"; 	mso-ansi-language:#0400; 	mso-fareast-language:#0400; 	mso-bidi-language:#0400;} &lt;/style&gt; &lt;![endif]--&gt;  &lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;SumUpMessage data = new SumUpMessage();&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;ByteArrayOutputStream baos = new ByteArrayOutputStream();&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;ObjectOutputStream oos = new ObjectOutputStream(baos);&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;oos.writeObject(data);&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;int storedSize = baos.size();&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;System.out.println(String.format("SumUpMessage: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;需要占用&lt;/span&gt;&lt;span lang="EN-US"&gt;%d&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;字节&lt;/span&gt;&lt;span lang="EN-US"&gt;", storedSize));&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;  &lt;!--[if mso &amp; !supportInlineShapes &amp; supportFields]&gt;&lt;span lang="EN-US"&gt;&lt;v:shape id="_x0000_i1027" type="#_x0000_t75" style="'width:414pt;"&gt;  &lt;v:imagedata croptop="-65520f" cropbottom="65520f"&gt; &lt;/v:shape&gt;&lt;span style="'mso-element:field-end'"&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]--&gt;&lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;h2 style="margin-left: 49.6pt; text-indent: -1cm;"&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;1.3&lt;span style=";font-family:&amp;quot;;font-size:7;"  &gt;    &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span lang="EN-US"&gt;AMF3&lt;/span&gt;&lt;span style="font-family:黑体;"&gt;方式&lt;/span&gt;&lt;/h2&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-family:宋体;"&gt;最后，让我们&lt;/span&gt;&lt;span lang="EN-US"&gt;AMF3&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的封包方式，我们使用&lt;/span&gt;&lt;span lang="EN-US"&gt;BlazeDS&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中的&lt;/span&gt;&lt;span lang="EN-US"&gt;amf3&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;相关&lt;/span&gt;&lt;span lang="EN-US"&gt;API&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;实现如下的测试程序：&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;!--[if mso &amp; !supportInlineShapes &amp; supportFields]&gt;&lt;span lang="EN-US"&gt;&lt;span style="'mso-element:field-begin;mso-field-lock:yes'"&gt;&lt;/span&gt;&lt;span style="'mso-spacerun:yes'"&gt; &lt;/span&gt;SHAPE&lt;span style="'mso-spacerun:yes'"&gt;  &lt;/span&gt;\* MERGEFORMAT &lt;span style="'mso-element:field-separator'"&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]--&gt;&lt;meta equiv="Content-Type" content="text/html; charset=utf-8"&gt;&lt;meta name="ProgId" content="Word.Document"&gt;&lt;meta name="Generator" content="Microsoft Word 11"&gt;&lt;meta name="Originator" content="Microsoft Word 11"&gt;&lt;link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C09%5Cclip_filelist.xml"&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:worddocument&gt;   &lt;w:view&gt;Normal&lt;/w:View&gt;   &lt;w:zoom&gt;0&lt;/w:Zoom&gt;   &lt;w:punctuationkerning/&gt;   &lt;w:drawinggridverticalspacing&gt;7.8 磅&lt;/w:DrawingGridVerticalSpacing&gt;   &lt;w:displayhorizontaldrawinggridevery&gt;0&lt;/w:DisplayHorizontalDrawingGridEvery&gt;   &lt;w:displayverticaldrawinggridevery&gt;2&lt;/w:DisplayVerticalDrawingGridEvery&gt;   &lt;w:validateagainstschemas/&gt;   &lt;w:saveifxmlinvalid&gt;false&lt;/w:SaveIfXMLInvalid&gt;   &lt;w:ignoremixedcontent&gt;false&lt;/w:IgnoreMixedContent&gt;   &lt;w:alwaysshowplaceholdertext&gt;false&lt;/w:AlwaysShowPlaceholderText&gt;   &lt;w:compatibility&gt;    &lt;w:spaceforul/&gt;    &lt;w:balancesinglebytedoublebytewidth/&gt;    &lt;w:donotleavebackslashalone/&gt;    &lt;w:ultrailspace/&gt;    &lt;w:donotexpandshiftreturn/&gt;    &lt;w:adjustlineheightintable/&gt;    &lt;w:breakwrappedtables/&gt;    &lt;w:snaptogridincell/&gt;    &lt;w:wraptextwithpunct/&gt;    &lt;w:useasianbreakrules/&gt;    &lt;w:dontgrowautofit/&gt;    &lt;w:usefelayout/&gt;   &lt;/w:Compatibility&gt;   &lt;w:browserlevel&gt;MicrosoftInternetExplorer4&lt;/w:BrowserLevel&gt;  &lt;/w:WordDocument&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:latentstyles deflockedstate="false" latentstylecount="156"&gt;  &lt;/w:LatentStyles&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;style&gt; &lt;!--  /* Font Definitions */  @font-face 	{font-family:宋体; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-alt:SimSun; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 16 0 262145 0;} @font-face 	{font-family:"\@宋体"; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 16 0 262145 0;}  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-parent:""; 	margin:0cm; 	margin-bottom:.0001pt; 	text-align:justify; 	text-justify:inter-ideograph; 	mso-pagination:none; 	font-size:10.5pt; 	mso-bidi-font-size:12.0pt; 	font-family:"Times New Roman"; 	mso-fareast-font-family:宋体; 	mso-font-kerning:1.0pt;}  /* Page Definitions */  @page 	{mso-page-border-surround-header:no; 	mso-page-border-surround-footer:no;} @page Section1 	{size:612.0pt 792.0pt; 	margin:72.0pt 90.0pt 72.0pt 90.0pt; 	mso-header-margin:36.0pt; 	mso-footer-margin:36.0pt; 	mso-paper-source:0;} div.Section1 	{page:Section1;} --&gt; &lt;/style&gt;&lt;!--[if gte mso 10]&gt; &lt;style&gt;  /* Style Definitions */  table.MsoNormalTable 	{mso-style-name:普通表格; 	mso-tstyle-rowband-size:0; 	mso-tstyle-colband-size:0; 	mso-style-noshow:yes; 	mso-style-parent:""; 	mso-padding-alt:0cm 5.4pt 0cm 5.4pt; 	mso-para-margin:0cm; 	mso-para-margin-bottom:.0001pt; 	mso-pagination:widow-orphan; 	font-size:10.0pt; 	font-family:"Times New Roman"; 	mso-ansi-language:#0400; 	mso-fareast-language:#0400; 	mso-bidi-language:#0400;} &lt;/style&gt; &lt;![endif]--&gt;  &lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;SerializationContext serializationContext = SerializationContext.getSerializationContext();&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;ByteArrayOutputStream baos = new ByteArrayOutputStream();&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;Amf3Output amf3Output = new Amf3Output(serializationContext);&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;AmfTrace trace = new AmfTrace();&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;amf3Output.setDebugTrace(trace);&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;amf3Output.setOutputStream(baos);&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;try&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;{&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;amf3Output.writeObject(new SumUpMessage());&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;amf3Output.flush();&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;int storedSize = baos.size();&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;System.out.println(String.format("SumUpMessage.amf3: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;需要占用&lt;/span&gt;&lt;span lang="EN-US"&gt;%d&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;字节&lt;/span&gt;&lt;span lang="EN-US"&gt;", storedSize));&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;amf3Output.close();&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;}&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;catch (IOException e)&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;{&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;e.printStackTrace();&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;}&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;  &lt;!--[if mso &amp; !supportInlineShapes &amp; supportFields]&gt;&lt;span lang="EN-US"&gt;&lt;v:shape id="_x0000_i1028" type="#_x0000_t75" style="'width:414pt;"&gt;  &lt;v:imagedata croptop="-65520f" cropbottom="65520f"&gt; &lt;/v:shape&gt;&lt;span style="'mso-element:field-end'"&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]--&gt;&lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-family:宋体;"&gt;我们需要发送&lt;/span&gt;&lt;span lang="EN-US"&gt;43&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;字节。&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;h2 style="margin-left: 49.6pt; text-indent: -1cm;"&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;1.4&lt;span style=";font-family:&amp;quot;;font-size:7;"  &gt;    &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span style="font-family:黑体;"&gt;总结&lt;/span&gt;&lt;/h2&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-family:宋体;"&gt;通过上述的粗糙测试，我们对于&lt;/span&gt;&lt;span lang="EN-US"&gt;AMF3&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的封包有个大概的了解。&lt;/span&gt;&lt;span lang="EN-US"&gt;AMF3&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的『压缩率』对于特别在乎网络带宽的公司，可能不是那么满意。但是它能提高我们日常的开发效率。因为&lt;/span&gt;&lt;span lang="EN-US"&gt;amf3&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;是&lt;/span&gt;&lt;span lang="EN-US"&gt;flash&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;默认的封包方式，对于&lt;/span&gt;&lt;span lang="EN-US"&gt;flash&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;程序员，可以忽略字节流的概念，所有&lt;/span&gt;&lt;span lang="EN-US"&gt;input/output&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;都是对象或者原子数据（&lt;/span&gt;&lt;span lang="EN-US"&gt;primitive type&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;）。&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-family:宋体;"&gt;让我继续吧。下一章我们将深入&lt;/span&gt;&lt;span lang="EN-US"&gt;SumUpMessage&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;被封装的过程。&lt;/span&gt;&lt;/p&gt;  &lt;h1 style="margin-left: 21.25pt; text-indent: -21.25pt;"&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;2&lt;span style=";font-family:&amp;quot;;font-size:7;"  &gt;       &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span lang="EN-US"&gt;AMF3&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;详细分析&lt;/span&gt;&lt;/h1&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-family:宋体;"&gt;上面的测试，我们并没有实现&lt;/span&gt;&lt;span lang="EN-US"&gt;Externalizable&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;接口，也就是说，整个封装过程都是按照默认方式进行的。&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-family:宋体;"&gt;接下来，我们实现&lt;/span&gt;&lt;span lang="EN-US"&gt;Externalizable&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;接口。&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;!--[if mso &amp; !supportInlineShapes &amp; supportFields]&gt;&lt;span lang="EN-US"&gt;&lt;span style="'mso-element:field-begin;mso-field-lock:yes'"&gt;&lt;/span&gt;&lt;span style="'mso-spacerun:yes'"&gt; &lt;/span&gt;SHAPE&lt;span style="'mso-spacerun:yes'"&gt;  &lt;/span&gt;\* MERGEFORMAT &lt;span style="'mso-element:field-separator'"&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]--&gt;&lt;meta equiv="Content-Type" content="text/html; charset=utf-8"&gt;&lt;meta name="ProgId" content="Word.Document"&gt;&lt;meta name="Generator" content="Microsoft Word 11"&gt;&lt;meta name="Originator" content="Microsoft Word 11"&gt;&lt;link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C10%5Cclip_filelist.xml"&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:worddocument&gt;   &lt;w:view&gt;Normal&lt;/w:View&gt;   &lt;w:zoom&gt;0&lt;/w:Zoom&gt;   &lt;w:punctuationkerning/&gt;   &lt;w:drawinggridverticalspacing&gt;7.8 磅&lt;/w:DrawingGridVerticalSpacing&gt;   &lt;w:displayhorizontaldrawinggridevery&gt;0&lt;/w:DisplayHorizontalDrawingGridEvery&gt;   &lt;w:displayverticaldrawinggridevery&gt;2&lt;/w:DisplayVerticalDrawingGridEvery&gt;   &lt;w:validateagainstschemas/&gt;   &lt;w:saveifxmlinvalid&gt;false&lt;/w:SaveIfXMLInvalid&gt;   &lt;w:ignoremixedcontent&gt;false&lt;/w:IgnoreMixedContent&gt;   &lt;w:alwaysshowplaceholdertext&gt;false&lt;/w:AlwaysShowPlaceholderText&gt;   &lt;w:compatibility&gt;    &lt;w:spaceforul/&gt;    &lt;w:balancesinglebytedoublebytewidth/&gt;    &lt;w:donotleavebackslashalone/&gt;    &lt;w:ultrailspace/&gt;    &lt;w:donotexpandshiftreturn/&gt;    &lt;w:adjustlineheightintable/&gt;    &lt;w:breakwrappedtables/&gt;    &lt;w:snaptogridincell/&gt;    &lt;w:wraptextwithpunct/&gt;    &lt;w:useasianbreakrules/&gt;    &lt;w:dontgrowautofit/&gt;    &lt;w:usefelayout/&gt;   &lt;/w:Compatibility&gt;   &lt;w:browserlevel&gt;MicrosoftInternetExplorer4&lt;/w:BrowserLevel&gt;  &lt;/w:WordDocument&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:latentstyles deflockedstate="false" latentstylecount="156"&gt;  &lt;/w:LatentStyles&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;style&gt; &lt;!--  /* Font Definitions */  @font-face 	{font-family:宋体; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-alt:SimSun; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 16 0 262145 0;} @font-face 	{font-family:"\@宋体"; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 16 0 262145 0;}  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-parent:""; 	margin:0cm; 	margin-bottom:.0001pt; 	text-align:justify; 	text-justify:inter-ideograph; 	mso-pagination:none; 	font-size:10.5pt; 	mso-bidi-font-size:12.0pt; 	font-family:"Times New Roman"; 	mso-fareast-font-family:宋体; 	mso-font-kerning:1.0pt;}  /* Page Definitions */  @page 	{mso-page-border-surround-header:no; 	mso-page-border-surround-footer:no;} @page Section1 	{size:612.0pt 792.0pt; 	margin:72.0pt 90.0pt 72.0pt 90.0pt; 	mso-header-margin:36.0pt; 	mso-footer-margin:36.0pt; 	mso-paper-source:0;} div.Section1 	{page:Section1;} --&gt; &lt;/style&gt;&lt;!--[if gte mso 10]&gt; &lt;style&gt;  /* Style Definitions */  table.MsoNormalTable 	{mso-style-name:普通表格; 	mso-tstyle-rowband-size:0; 	mso-tstyle-colband-size:0; 	mso-style-noshow:yes; 	mso-style-parent:""; 	mso-padding-alt:0cm 5.4pt 0cm 5.4pt; 	mso-para-margin:0cm; 	mso-para-margin-bottom:.0001pt; 	mso-pagination:widow-orphan; 	font-size:10.0pt; 	font-family:"Times New Roman"; 	mso-ansi-language:#0400; 	mso-fareast-language:#0400; 	mso-bidi-language:#0400;} &lt;/style&gt; &lt;![endif]--&gt;  &lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;public void writeExternal(ObjectOutput out) throws IOException&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;{&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;out.writeInt(value1);&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;out.writeInt(value2);&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;}&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;  &lt;!--[if mso &amp; !supportInlineShapes &amp; supportFields]&gt;&lt;span lang="EN-US"&gt;&lt;v:shape id="_x0000_i1029" type="#_x0000_t75" style="'width:414pt;"&gt;  &lt;v:imagedata croptop="-65520f" cropbottom="65520f"&gt; &lt;/v:shape&gt;&lt;span style="'mso-element:field-end'"&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]--&gt;&lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-family:宋体;"&gt;现在只需要&lt;/span&gt;&lt;span lang="EN-US"&gt;33&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;字节。&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-family:宋体;"&gt;接下来，我们用&lt;/span&gt;&lt;span lang="EN-US"&gt;writeObject&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;替代&lt;/span&gt;&lt;span lang="EN-US"&gt;writeInt&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，即&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;!--[if mso &amp; !supportInlineShapes &amp; supportFields]&gt;&lt;span lang="EN-US"&gt;&lt;span style="'mso-element:field-begin;mso-field-lock:yes'"&gt;&lt;/span&gt;&lt;span style="'mso-spacerun:yes'"&gt; &lt;/span&gt;SHAPE&lt;span style="'mso-spacerun:yes'"&gt;  &lt;/span&gt;\* MERGEFORMAT &lt;span style="'mso-element:field-separator'"&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]--&gt;&lt;meta equiv="Content-Type" content="text/html; charset=utf-8"&gt;&lt;meta name="ProgId" content="Word.Document"&gt;&lt;meta name="Generator" content="Microsoft Word 11"&gt;&lt;meta name="Originator" content="Microsoft Word 11"&gt;&lt;link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C11%5Cclip_filelist.xml"&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:worddocument&gt;   &lt;w:view&gt;Normal&lt;/w:View&gt;   &lt;w:zoom&gt;0&lt;/w:Zoom&gt;   &lt;w:punctuationkerning/&gt;   &lt;w:drawinggridverticalspacing&gt;7.8 磅&lt;/w:DrawingGridVerticalSpacing&gt;   &lt;w:displayhorizontaldrawinggridevery&gt;0&lt;/w:DisplayHorizontalDrawingGridEvery&gt;   &lt;w:displayverticaldrawinggridevery&gt;2&lt;/w:DisplayVerticalDrawingGridEvery&gt;   &lt;w:validateagainstschemas/&gt;   &lt;w:saveifxmlinvalid&gt;false&lt;/w:SaveIfXMLInvalid&gt;   &lt;w:ignoremixedcontent&gt;false&lt;/w:IgnoreMixedContent&gt;   &lt;w:alwaysshowplaceholdertext&gt;false&lt;/w:AlwaysShowPlaceholderText&gt;   &lt;w:compatibility&gt;    &lt;w:spaceforul/&gt;    &lt;w:balancesinglebytedoublebytewidth/&gt;    &lt;w:donotleavebackslashalone/&gt;    &lt;w:ultrailspace/&gt;    &lt;w:donotexpandshiftreturn/&gt;    &lt;w:adjustlineheightintable/&gt;    &lt;w:breakwrappedtables/&gt;    &lt;w:snaptogridincell/&gt;    &lt;w:wraptextwithpunct/&gt;    &lt;w:useasianbreakrules/&gt;    &lt;w:dontgrowautofit/&gt;    &lt;w:usefelayout/&gt;   &lt;/w:Compatibility&gt;   &lt;w:browserlevel&gt;MicrosoftInternetExplorer4&lt;/w:BrowserLevel&gt;  &lt;/w:WordDocument&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:latentstyles deflockedstate="false" latentstylecount="156"&gt;  &lt;/w:LatentStyles&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;style&gt; &lt;!--  /* Font Definitions */  @font-face 	{font-family:宋体; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-alt:SimSun; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 16 0 262145 0;} @font-face 	{font-family:"\@宋体"; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 16 0 262145 0;}  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-parent:""; 	margin:0cm; 	margin-bottom:.0001pt; 	text-align:justify; 	text-justify:inter-ideograph; 	mso-pagination:none; 	font-size:10.5pt; 	mso-bidi-font-size:12.0pt; 	font-family:"Times New Roman"; 	mso-fareast-font-family:宋体; 	mso-font-kerning:1.0pt;}  /* Page Definitions */  @page 	{mso-page-border-surround-header:no; 	mso-page-border-surround-footer:no;} @page Section1 	{size:612.0pt 792.0pt; 	margin:72.0pt 90.0pt 72.0pt 90.0pt; 	mso-header-margin:36.0pt; 	mso-footer-margin:36.0pt; 	mso-paper-source:0;} div.Section1 	{page:Section1;} --&gt; &lt;/style&gt;&lt;!--[if gte mso 10]&gt; &lt;style&gt;  /* Style Definitions */  table.MsoNormalTable 	{mso-style-name:普通表格; 	mso-tstyle-rowband-size:0; 	mso-tstyle-colband-size:0; 	mso-style-noshow:yes; 	mso-style-parent:""; 	mso-padding-alt:0cm 5.4pt 0cm 5.4pt; 	mso-para-margin:0cm; 	mso-para-margin-bottom:.0001pt; 	mso-pagination:widow-orphan; 	font-size:10.0pt; 	font-family:"Times New Roman"; 	mso-ansi-language:#0400; 	mso-fareast-language:#0400; 	mso-bidi-language:#0400;} &lt;/style&gt; &lt;![endif]--&gt;  &lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;public void writeExternal(ObjectOutput out) throws IOException&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;{&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;out.writeObject(value1);&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;out.writeObject(value2);&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;}&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;  &lt;!--[if mso &amp; !supportInlineShapes &amp; supportFields]&gt;&lt;span lang="EN-US"&gt;&lt;v:shape id="_x0000_i1030" type="#_x0000_t75" style="'width:414pt;"&gt;  &lt;v:imagedata croptop="-65520f" cropbottom="65520f"&gt; &lt;/v:shape&gt;&lt;span style="'mso-element:field-end'"&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]--&gt;&lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-family:宋体;"&gt;此时，只需占用&lt;/span&gt;&lt;span lang="EN-US"&gt;29&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;字节。&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-family:宋体;"&gt;现在的问题是，为什么这三种不同的实现方式，而带来完全不同的效果呢？&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-family:宋体;"&gt;好的，让我们继续分析吧。&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;h2 style="margin-left: 49.6pt; text-indent: -1cm;"&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;2.1&lt;span style=";font-family:&amp;quot;;font-size:7;"  &gt;    &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span style="font-family:黑体;"&gt;默认的实现&lt;/span&gt;&lt;/h2&gt;  &lt;p style="text-align: left;" class="MsoNormal"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_eD3fEmdStVI/SPr4J5VkkeI/AAAAAAAAAAc/mafsJm8HmaA/s1600-h/sumupMessage_default.JPG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_eD3fEmdStVI/SPr4J5VkkeI/AAAAAAAAAAc/mafsJm8HmaA/s400/sumupMessage_default.JPG" alt="" id="BLOGGER_PHOTO_ID_5258788363802284514" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x&lt;st1:chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="0" unitname="a" st="on"&gt;0&lt;/st1:chmetcnv&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;st1:chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="0" unitname="a" st="on"&gt;A&lt;/st1:chmetcnv&gt;: object marker&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x23: trait&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;信息，包含是否&lt;/span&gt;&lt;span lang="EN-US"&gt;externalizable&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;、&lt;/span&gt;&lt;span lang="EN-US"&gt;dynamic&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;以及&lt;/span&gt;&lt;span lang="EN-US"&gt;SumUpMessage&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;类的属性数量。&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;       &lt;/span&gt;XXXXXXXX XXXXXXXX XXXXXXXX XXXXDE11&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;       &lt;/span&gt;E: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;表示是否实现了&lt;/span&gt;&lt;span lang="EN-US"&gt;Externalizable&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;接口&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;       &lt;/span&gt;D: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;是否是动态的&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;       &lt;/span&gt;X: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;表示所含属性的数量&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;       &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;整个整型数据以&lt;/span&gt;&lt;span lang="EN-US"&gt;29-bit&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;编码方式进行优化处理，所以只占用一个字节。&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x2D: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;类名所占字节数，&lt;/span&gt;&lt;span lang="EN-US"&gt;2*&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;类名的字符数目&lt;/span&gt;&lt;span lang="EN-US"&gt;+1&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x63 &lt;st1:chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="6" unitname="F" st="on"&gt;6F&lt;/st1:chmetcnv&gt; 6D 2E &lt;st1:chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="6" unitname="F" st="on"&gt;6F&lt;/st1:chmetcnv&gt; 73 63 61 72 2E 53 75 6D 55 70 4D 65 73 73 61 67 65: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;类名的字符串&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x0D: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;属性名&lt;/span&gt;&lt;span lang="EN-US"&gt;1&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;所占字节数，也是&lt;/span&gt;&lt;span lang="EN-US"&gt;2*&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;属性名的字符数目&lt;/span&gt;&lt;span lang="EN-US"&gt;+1&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x76 61 &lt;st1:chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="6" unitname="C" st="on"&gt;6C&lt;/st1:chmetcnv&gt; 75 65 31: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;属性名&lt;/span&gt;&lt;span lang="EN-US"&gt;1&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的字符串&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x0D: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;属性名&lt;/span&gt;&lt;span lang="EN-US"&gt;2&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;所占字节数，也是&lt;/span&gt;&lt;span lang="EN-US"&gt;2*&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;属性名的字符数目&lt;/span&gt;&lt;span lang="EN-US"&gt;+1&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x76 61 &lt;st1:chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="6" unitname="C" st="on"&gt;6C&lt;/st1:chmetcnv&gt; 75 65 32: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;属性名&lt;/span&gt;&lt;span lang="EN-US"&gt;2&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的字符串&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x04: integer marker&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x00: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;属性&lt;/span&gt;&lt;span lang="EN-US"&gt;1&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的值&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x04: integer marker&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x00: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;属性&lt;/span&gt;&lt;span lang="EN-US"&gt;2&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的值&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;h2 style="margin-left: 49.6pt; text-indent: -1cm;"&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;2.2&lt;span style=";font-family:&amp;quot;;font-size:7;"  &gt;    &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span style="font-family:黑体;"&gt;实现&lt;/span&gt;&lt;span lang="EN-US"&gt;Externalizable&lt;/span&gt;&lt;span style="font-family:黑体;"&gt;接口，使用&lt;/span&gt;&lt;span lang="EN-US"&gt;writeInt&lt;/span&gt;&lt;span style="font-family:黑体;"&gt;输出&lt;/span&gt;&lt;/h2&gt;  &lt;p style="text-align: left;" class="MsoNormal"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_eD3fEmdStVI/SPr4Uws6cHI/AAAAAAAAAAk/3SsToGUKexM/s1600-h/sumupMessage_writeInt.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_eD3fEmdStVI/SPr4Uws6cHI/AAAAAAAAAAk/3SsToGUKexM/s400/sumupMessage_writeInt.JPG" alt="" id="BLOGGER_PHOTO_ID_5258788550462828658" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x&lt;st1:chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="0" unitname="a" st="on"&gt;0A&lt;/st1:chmetcnv&gt;: object marker&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x07: trait&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;信息&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x2D: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;类名所占字节数&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x63 &lt;st1:chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="6" unitname="F" st="on"&gt;6F&lt;/st1:chmetcnv&gt; 6D 2E &lt;st1:chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="6" unitname="F" st="on"&gt;6F&lt;/st1:chmetcnv&gt; 73 63 61 72 2E 53 75 6D 55 70 4D 65 73 73 61 67 65: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;类名的字符串&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x00 00 00 00: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;我们在&lt;/span&gt;&lt;span lang="EN-US"&gt;writeExternal&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中实现的，写属性&lt;/span&gt;&lt;span lang="EN-US"&gt;1&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的值&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x00 00 00 00: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;我们在&lt;/span&gt;&lt;span lang="EN-US"&gt;writeExternal&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中实现的，写属性&lt;/span&gt;&lt;span lang="EN-US"&gt;2&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的值&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;h2 style="margin-left: 49.6pt; text-indent: -1cm;"&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;2.3&lt;span style=";font-family:&amp;quot;;font-size:7;"  &gt;    &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span style="font-family:黑体;"&gt;实现&lt;/span&gt;&lt;span lang="EN-US"&gt;Externalizable&lt;/span&gt;&lt;span style="font-family:黑体;"&gt;接口，使用&lt;/span&gt;&lt;span lang="EN-US"&gt;writeObject&lt;/span&gt;&lt;span style="font-family:黑体;"&gt;输出&lt;/span&gt;&lt;/h2&gt;  &lt;p style="text-align: left;" class="MsoNormal"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_eD3fEmdStVI/SPr4eYI_4rI/AAAAAAAAAAs/Adr8iOMIpU8/s1600-h/sumupMessage_writeObject.JPG"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_eD3fEmdStVI/SPr4eYI_4rI/AAAAAAAAAAs/Adr8iOMIpU8/s400/sumupMessage_writeObject.JPG" alt="" id="BLOGGER_PHOTO_ID_5258788715668431538" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x&lt;st1:chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="0" unitname="a" st="on"&gt;0A&lt;/st1:chmetcnv&gt;: object marker&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x07: trait&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;信息&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x2D: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;类名所占字节数&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x63 &lt;st1:chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="6" unitname="F" st="on"&gt;6F&lt;/st1:chmetcnv&gt; 6D 2E &lt;st1:chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="6" unitname="F" st="on"&gt;6F&lt;/st1:chmetcnv&gt; 73 63 61 72 2E 53 75 6D 55 70 4D 65 73 73 61 67 65: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;类名的字符串&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x04: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;我们在&lt;/span&gt;&lt;span lang="EN-US"&gt;writeExternal&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中实现的，&lt;/span&gt;&lt;span lang="EN-US"&gt;integer marker&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x00: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;我们在&lt;/span&gt;&lt;span lang="EN-US"&gt;writeExternal&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中实现的，属性&lt;/span&gt;&lt;span lang="EN-US"&gt;1&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的值&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x04: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;我们在&lt;/span&gt;&lt;span lang="EN-US"&gt;writeExternal&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中实现的，&lt;/span&gt;&lt;span lang="EN-US"&gt;integer marker&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;0x00: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;我们在&lt;/span&gt;&lt;span lang="EN-US"&gt;writeExternal&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中实现的，属性&lt;/span&gt;&lt;span lang="EN-US"&gt;2&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的值&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;h2 style="margin-left: 49.6pt; text-indent: -1cm;"&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;2.4&lt;span style=";font-family:&amp;quot;;font-size:7;"  &gt;    &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span lang="EN-US"&gt;29bit&lt;/span&gt;&lt;span style="font-family:黑体;"&gt;编码&lt;/span&gt;&lt;/h2&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;29bit&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;编码的目的是尽可能使用少量的内存来表示一个&lt;/span&gt;&lt;span lang="EN-US"&gt;integer&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;数据。它把一个&lt;/span&gt;&lt;span lang="EN-US"&gt;byte&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的最高&lt;/span&gt;&lt;span lang="EN-US"&gt;bit&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;用来标记下一个&lt;/span&gt;&lt;span lang="EN-US"&gt;byte&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;是否属于这个&lt;/span&gt;&lt;span lang="EN-US"&gt;integer&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt; 32bit&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中去掉用作标记的&lt;/span&gt;&lt;span lang="EN-US"&gt;3bit&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，就剩下&lt;/span&gt;&lt;span lang="EN-US"&gt;29bit&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;用作存放实际数据。&lt;/span&gt;&lt;/p&gt;  &lt;h1 style="margin-left: 21.25pt; text-indent: -21.25pt;"&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;3&lt;span style=";font-family:&amp;quot;;font-size:7;"  &gt;       &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span style="font-family:宋体;"&gt;下一步&lt;/span&gt;&lt;/h1&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-family:宋体;"&gt;下一步，我将把&lt;/span&gt;&lt;span lang="EN-US"&gt;AMF3&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;序列化和反序列化功能添加到&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;a href="http://kasparov.skife.org/blog/src/java/grizzly-arp-basic.html"&gt;Grizzly ARP&lt;/a&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中，另外实现&lt;/span&gt;&lt;span lang="EN-US"&gt;wireshark&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;插件解析&lt;/span&gt;&lt;span lang="EN-US"&gt;AMF3&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;格式协议。敬请期待。&lt;/span&gt;&lt;/p&gt;  &lt;h1 style="margin-left: 21.25pt; text-indent: -21.25pt;"&gt;&lt;!--[if !supportLists]--&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;4&lt;span style=";font-family:&amp;quot;;font-size:7;"  &gt;       &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span style="font-family:宋体;"&gt;参考资料&lt;/span&gt;&lt;/h1&gt;  &lt;ul&gt;&lt;li&gt;&lt;!--[if !supportLists]--&gt;&lt;!--[endif]--&gt;&lt;span lang="EN-US"&gt;&lt;a href="http://www.blogger.com/1.%09http:/download.macromedia.com/pub/labs/amf/amf3_spec_121207.pdf"&gt;AMF3&lt;span  lang="EN-US" style="font-family:宋体;"&gt;&lt;span lang="EN-US"&gt;规范&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;!--[endif]--&gt;&lt;span lang="EN-US"&gt;&lt;a href="http://opensource.adobe.com/wiki/display/blazeds/Source"&gt;BlazeDS&lt;span  lang="EN-US" style="font-family:宋体;"&gt;&lt;span lang="EN-US"&gt;代码&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;    &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14949417-4696320468801789994?l=ro4tub.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ro4tub.blogspot.com/feeds/4696320468801789994/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14949417&amp;postID=4696320468801789994' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14949417/posts/default/4696320468801789994'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14949417/posts/default/4696320468801789994'/><link rel='alternate' type='text/html' href='http://ro4tub.blogspot.com/2008/10/amf3.html' title='深入浅出AMF3'/><author><name>ro4tub</name><uri>http://www.blogger.com/profile/05900229797645474112</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_eD3fEmdStVI/SPr4J5VkkeI/AAAAAAAAAAc/mafsJm8HmaA/s72-c/sumupMessage_default.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14949417.post-1528683366598794799</id><published>2008-10-17T08:36:00.000-07:00</published><updated>2008-10-29T22:04:53.982-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comet'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='mochiweb'/><title type='text'>[译]使用Mochiweb构建百万级Comet程序,第一篇</title><content type='html'>&lt;span style="font-size:180%;"&gt;&lt;a title="使用Mochiweb构建百万级Comet程序,第一部分" href="http://www.metabrew.com/article/a-million-user-comet-application-with-mochiweb-part-1/" id="i8vb"&gt;使用Mochiweb构建百万级Comet程序,第一篇&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;br /&gt;译者: &lt;a title="oscar" href="http://ro4tub.blogspot.com/" id="y1wf"&gt;oscar&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;p&gt;&lt;span style="font-size:78%;"&gt;译者注：作者Richard Jones是Last.fm的创始人之一。原文简单易懂，且最后的留言也颇有参考价值。&lt;/span&gt;&lt;/p&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;在这系列，我将向大家详细描述，我所知道的mochiweb支持那么多的连接的原因。教你们使用mochiweb构建comet程序，每个mochiweb连接都注册在给不同用户分发消息的路由器上。&lt;br /&gt;最后，我会给出一个可以运行的，且能支持百万并发连接的程序。关键之处是，我们需要知道支持那多并发连接需要占用多少内存。&lt;br /&gt;&lt;br /&gt;本作：&lt;br /&gt;&lt;ul&gt;&lt;li&gt;实现一个简单的comet mochiweb程序，每10秒向客户端发送一条消息。&lt;/li&gt;&lt;li&gt;设置linux内核参数，使其能处理更多的TCP连接。&lt;/li&gt;&lt;li&gt;实现一个压力测试工具(flood-testing tool)，不断建立连接(&lt;a title="C10K" href="http://www.kegel.com/c10k.html" id="r3hu"&gt;C10K&lt;/a&gt; 测试)。&lt;/li&gt;&lt;li&gt;检查每条连接占用的内存。&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;在续作中，我将介绍如何实现一个实时消息路由系统、降低内存使用的技巧和进一步的测试（10万、100万并发连接）。&lt;br /&gt;&lt;br /&gt;我假定，你会使用linux命令行，并且了解Erlang。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size:130%;"&gt;编译Mochiweb测试程序&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;简而言之：&lt;br /&gt;&lt;ol&gt;&lt;li&gt;安装、编译Mochiweb&lt;/li&gt;&lt;li&gt;运行: /your-mochiweb-path/scripts/new_mochiweb.erl mochiconntest&lt;/li&gt;&lt;li&gt;cd mochiconntest 然后编辑src/mochiconntest_web.erl&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;这段代码(mochiconntest_web.erl)只是接受连接，并使用块传输(chunked transfer)发送一条初始的欢迎消息，每10秒给每个客户端发送一条。&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;-&lt;span class="kw2"&gt;module&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;mochiconntest_web&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;-&lt;span class="kw2"&gt;export&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;[&lt;/span&gt;start/&lt;span class="nu0"&gt;1&lt;/span&gt;, stop/&lt;span class="nu0"&gt;0&lt;/span&gt;,  loop/&lt;span class="nu0"&gt;2&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;&lt;span class="co1"&gt;%% External API&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;start&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Options&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;    &lt;span class="br0"&gt;{&lt;/span&gt;&lt;span class="re0"&gt;DocRoot&lt;/span&gt;, &lt;span class="re0"&gt;Options1&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt; = get_option&lt;span class="br0"&gt;(&lt;/span&gt;docroot, &lt;span class="re0"&gt;Options&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="re0"&gt;Loop&lt;/span&gt; = fun &lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Req&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                   ?&lt;span class="re0"&gt;MODULE&lt;/span&gt;:&lt;span class="me2"&gt;loop&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Req&lt;/span&gt;, &lt;span class="re0"&gt;DocRoot&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;           &lt;span class="kw1"&gt;end&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="co1"&gt;% we’ll set our maximum to 1 million  connections. (default: 2048)&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;    mochiweb_http:&lt;span class="me2"&gt;start&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;max, &lt;span class="nu0"&gt;1000000&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;, &lt;span class="br0"&gt;{&lt;/span&gt;name,  ?&lt;span class="re0"&gt;MODULE&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;, &lt;span class="br0"&gt;{&lt;/span&gt;loop, &lt;span class="re0"&gt;Loop&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt; |  &lt;span class="re0"&gt;Options1&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;stop&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="me1"&gt;mochiweb_http&lt;/span&gt;:&lt;span class="me2"&gt;stop&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;?&lt;span class="re0"&gt;MODULE&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;loop&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Req&lt;/span&gt;, &lt;span class="re0"&gt;DocRoot&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="st0"&gt;"/"&lt;/span&gt; ++ &lt;span class="re0"&gt;Path&lt;/span&gt; =  &lt;span class="re0"&gt;Req&lt;/span&gt;:&lt;span class="me2"&gt;get&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;path&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="kw1"&gt;case&lt;/span&gt; &lt;span class="re0"&gt;Req&lt;/span&gt;:&lt;span class="me2"&gt;get&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;method&lt;span class="br0"&gt;)&lt;/span&gt; &lt;span class="kw1"&gt;of&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="re0"&gt;Method&lt;/span&gt; when &lt;span class="re0"&gt;Method&lt;/span&gt; =:= &lt;span class="st0"&gt;‘GET’&lt;/span&gt;; &lt;span class="re0"&gt;Method&lt;/span&gt; =:= &lt;span class="st0"&gt;‘HEAD’&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="kw1"&gt;case&lt;/span&gt; &lt;span class="re0"&gt;Path&lt;/span&gt; &lt;span class="kw1"&gt;of&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;                &lt;span class="st0"&gt;"test/"&lt;/span&gt; ++ &lt;span class="re0"&gt;Id&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                    &lt;span class="re0"&gt;Response&lt;/span&gt; = &lt;span class="re0"&gt;Req&lt;/span&gt;:&lt;span class="me2"&gt;ok&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;&lt;span class="st0"&gt;"text/html; charset=utf-8"&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                                      &lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;&lt;span class="st0"&gt;"Server"&lt;/span&gt;,&lt;span class="st0"&gt;"Mochiweb-Test"&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                                      chunked&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                    &lt;span class="re0"&gt;Response&lt;/span&gt;:&lt;span class="me2"&gt;write_chunk&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="st0"&gt;"Mochiconntest welcomes you! Your Id: "&lt;/span&gt; ++ &lt;span class="re0"&gt;Id&lt;/span&gt; ++ &lt;span class="st0"&gt;"&lt;span class="es0"&gt;\n&lt;/span&gt;"&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;                    &lt;span class="co1"&gt;%%  router:login(list_to_atom(Id), self()),&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                    feed&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Response&lt;/span&gt;, &lt;span class="re0"&gt;Id&lt;/span&gt;, &lt;span class="nu0"&gt;1&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                _ -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                    &lt;span class="re0"&gt;Req&lt;/span&gt;:&lt;span class="me2"&gt;not_found&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="kw1"&gt;end&lt;/span&gt;;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;        &lt;span class="st0"&gt;‘POST’&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="kw1"&gt;case&lt;/span&gt; &lt;span class="re0"&gt;Path&lt;/span&gt; &lt;span class="kw1"&gt;of&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                _ -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                    &lt;span class="re0"&gt;Req&lt;/span&gt;:&lt;span class="me2"&gt;not_found&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="kw1"&gt;end&lt;/span&gt;;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;        _ -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="re0"&gt;Req&lt;/span&gt;:&lt;span class="me2"&gt;respond&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;&lt;span class="nu0"&gt;501&lt;/span&gt;, &lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;, &lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="kw1"&gt;end&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;feed&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Response&lt;/span&gt;,  &lt;span class="re0"&gt;Path&lt;/span&gt;, &lt;span class="re0"&gt;N&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;  -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;    &lt;span class="kw1"&gt;receive&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="co1"&gt;%{router_msg, Msg} -&gt;&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="co1"&gt;%    Html = io_lib:format("Recvd msg #~w:  ‘~s’&lt;br /&gt;", [N, Msg]),&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="co1"&gt;%     Response:write_chunk(Html);&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="kw1"&gt;after&lt;/span&gt; &lt;span class="nu0"&gt;10000&lt;/span&gt;  -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;        &lt;span class="re0"&gt;Msg&lt;/span&gt; = io_lib:&lt;span class="kw3"&gt;format&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="st0"&gt;"Chunk ~w for id  ~s&lt;span class="es0"&gt;\n&lt;/span&gt;"&lt;/span&gt;, &lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="re0"&gt;N&lt;/span&gt;, &lt;span class="re0"&gt;Path&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="re0"&gt;Response&lt;/span&gt;:&lt;span class="me2"&gt;write_chunk&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Msg&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="kw1"&gt;end&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    feed&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Response&lt;/span&gt;,  &lt;span class="re0"&gt;Path&lt;/span&gt;, &lt;span class="re0"&gt;N&lt;/span&gt;&lt;span class="nu0"&gt;+1&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;&lt;span class="co1"&gt;%% Internal API&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;get_option&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Option&lt;/span&gt;,  &lt;span class="re0"&gt;Options&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="br0"&gt;{&lt;/span&gt;proplists:&lt;span class="me2"&gt;get_value&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Option&lt;/span&gt;,  &lt;span class="re0"&gt;Options&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;, proplists:&lt;span class="me2"&gt;delete&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Option&lt;/span&gt;,  &lt;span class="re0"&gt;Options&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;.&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size:130%;"&gt;启动你的mochiweb程序&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;make &amp;amp;&amp;amp; ./start-dev.sh&lt;br /&gt;&lt;br /&gt;默认情况下，mochiweb在所有网卡的8000端口上侦听。如果你在桌面环境下工作，那么你可以打开任何浏览&lt;br /&gt;器进行测试，输入http://localhost:8000/test/foo。&lt;br /&gt;&lt;br /&gt;而命令行测试如下:&lt;br /&gt;&lt;pre&gt;$ lynx --source "http://localhost:8000/test/foo"&lt;br /&gt;Mochiconntest welcomes you! Your Id: foo&lt;br /&gt;&lt;br /&gt;Chunk 1 for id foo&lt;br /&gt;&lt;br /&gt;Chunk 2 for id foo&lt;br /&gt;&lt;br /&gt;Chunk 3 for id foo&lt;br /&gt;&lt;br /&gt;^C&lt;br /&gt;&lt;br /&gt;好的，让我们继续吧。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size:130%;"&gt;设置Linux内核参数，以支持更多连接&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;为节省你的时间，在进行大规模测试之前，我们先调节内核的tcp设置。否则，你的测试将会失败，你会看到许&lt;br /&gt;多『out of socket memory』的消息(最后将是nf_conntrack: table&lt;br /&gt;full, dropping packet.)&lt;br /&gt;&lt;br /&gt;下面是最终的sysctl设置（你的配置可能不一样，但应该差不多）：&lt;br /&gt;&lt;br /&gt;# General gigabit tuning:&lt;br /&gt;net.core.rmem_max = 16777216&lt;br /&gt;net.core.wmem_max = 16777216&lt;br /&gt;net.ipv4.tcp_rmem = 4096 87380 16777216&lt;br /&gt;net.ipv4.tcp_wmem = 4096 65536 16777216&lt;br /&gt;net.ipv4.tcp_syncookies = 1&lt;br /&gt;# this gives the kernel more memory for tcp&lt;br /&gt;# which you need with many (100k+) open socket connections&lt;br /&gt;net.ipv4.tcp_mem = 50576   64768   98152&lt;br /&gt;net.core.netdev_max_backlog = 2500&lt;br /&gt;# I was also masquerading the port comet was on, you might not need this&lt;br /&gt;net.ipv4.netfilter.ip_conntrack_max = 1048576&lt;br /&gt;&lt;br /&gt;在/etc/sysctl.conf中配置，然后运行-p。不需要重启电脑，现在你的内核可以处理大量的连接了。&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;创建大量连接&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:85%;"&gt;有多种实现方法。&lt;a title="Tsung" href="http://tsung.erlang-projects.org/" id="pq1r"&gt;Tsung&lt;/a&gt; 是其中最为不错的，其他不错的还有ab、httperf、httpload等等。不过对于测试&lt;br /&gt;comet程序，们都显得不那么理想化&lt;/span&gt;&lt;span style="font-size:85%;"&gt;。正好&lt;/span&gt;&lt;span style="font-size:85%;"&gt;我也想&lt;/span&gt;&lt;span style="font-size:85%;"&gt;找个借口尝试一下Erlang http客户端，所以我写了个简单&lt;br /&gt;的测试程序，进行大量的连接。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;在这里一个连接一个进程确实有点浪费。所以，我用一个进程从文件中加载URL，另一个进程建立连接、接收&lt;br /&gt;数据（还有一个进程每10秒定时打印报告）。&lt;br /&gt;&lt;br /&gt;服务器不处理接收到的数据，直接丢弃，但是会增加计数器，所以我们可以跟踪http块(HTTP chunks)的传输&lt;br /&gt;量。&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;floodtest.erl&lt;/p&gt; &lt;div class="dean_ch"&gt; &lt;ol&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;-&lt;span class="kw2"&gt;module&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;floodtest&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;-&lt;span class="kw2"&gt;export&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;[&lt;/span&gt;start/&lt;span class="nu0"&gt;2&lt;/span&gt;, timer/&lt;span class="nu0"&gt;2&lt;/span&gt;, recv/&lt;span class="nu0"&gt;1&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;start&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Filename&lt;/span&gt;,  &lt;span class="re0"&gt;Wait&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;    &lt;span class="me1"&gt;inets&lt;/span&gt;:&lt;span class="me2"&gt;start&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    spawn&lt;span class="br0"&gt;(&lt;/span&gt;?&lt;span class="re0"&gt;MODULE&lt;/span&gt;,  timer, &lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="nu0"&gt;10000&lt;/span&gt;, self&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="re0"&gt;This&lt;/span&gt; = self&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    spawn&lt;span class="br0"&gt;(&lt;/span&gt;fun&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;-&gt; &lt;span class="me1"&gt;loadurls&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Filename&lt;/span&gt;, fun&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;U&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;-&gt; &lt;span class="re0"&gt;This&lt;/span&gt; ! &lt;span class="br0"&gt;{&lt;/span&gt;loadurl, &lt;span class="re0"&gt;U&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt; &lt;span class="kw1"&gt;end&lt;/span&gt;, &lt;span class="re0"&gt;Wait&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; &lt;span class="kw1"&gt;end&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    recv&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;&lt;span class="nu0"&gt;0&lt;/span&gt;,&lt;span class="nu0"&gt;0&lt;/span&gt;,&lt;span class="nu0"&gt;0&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;recv&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Stats&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="br0"&gt;{&lt;/span&gt;&lt;span class="re0"&gt;Active&lt;/span&gt;, &lt;span class="re0"&gt;Closed&lt;/span&gt;, &lt;span class="re0"&gt;Chunks&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt; =  &lt;span class="re0"&gt;Stats&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="kw1"&gt;receive&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="br0"&gt;{&lt;/span&gt;stats&lt;span class="br0"&gt;}&lt;/span&gt;  -&gt; &lt;span class="me1"&gt;io&lt;/span&gt;:&lt;span class="kw3"&gt;format&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="st0"&gt;"Stats: ~w&lt;span class="es0"&gt;\n&lt;/span&gt;"&lt;/span&gt;,&lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="re0"&gt;Stats&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;        &lt;span class="kw1"&gt;after&lt;/span&gt; &lt;span class="nu0"&gt;0&lt;/span&gt;  -&gt; &lt;span class="me1"&gt;noop&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="kw1"&gt;end&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="kw1"&gt;receive&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="br0"&gt;{&lt;/span&gt;http,&lt;span class="br0"&gt;{&lt;/span&gt;_&lt;span class="re0"&gt;Ref&lt;/span&gt;,stream_start,_&lt;span class="re0"&gt;X&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt; -&gt;  &lt;span class="me1"&gt;recv&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;&lt;span class="re0"&gt;Active&lt;/span&gt;&lt;span class="nu0"&gt;+1&lt;/span&gt;,&lt;span class="re0"&gt;Closed&lt;/span&gt;,&lt;span class="re0"&gt;Chunks&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="br0"&gt;{&lt;/span&gt;http,&lt;span class="br0"&gt;{&lt;/span&gt;_&lt;span class="re0"&gt;Ref&lt;/span&gt;,stream,_&lt;span class="re0"&gt;X&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt; -&gt;           &lt;span class="me1"&gt;recv&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;&lt;span class="re0"&gt;Active&lt;/span&gt;, &lt;span class="re0"&gt;Closed&lt;/span&gt;,  &lt;span class="re0"&gt;Chunks&lt;/span&gt;&lt;span class="nu0"&gt;+1&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;        &lt;span class="br0"&gt;{&lt;/span&gt;http,&lt;span class="br0"&gt;{&lt;/span&gt;_&lt;span class="re0"&gt;Ref&lt;/span&gt;,stream_end,_&lt;span class="re0"&gt;X&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt; -&gt;  &lt;span class="me1"&gt;recv&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;&lt;span class="re0"&gt;Active&lt;/span&gt;&lt;span class="nu0"&gt;-1&lt;/span&gt;, &lt;span class="re0"&gt;Closed&lt;/span&gt;&lt;span class="nu0"&gt;+1&lt;/span&gt;, &lt;span class="re0"&gt;Chunks&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="br0"&gt;{&lt;/span&gt;http,&lt;span class="br0"&gt;{&lt;/span&gt;_&lt;span class="re0"&gt;Ref&lt;/span&gt;,&lt;span class="br0"&gt;{&lt;/span&gt;error,&lt;span class="re0"&gt;Why&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="me1"&gt;io&lt;/span&gt;:&lt;span class="kw3"&gt;format&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="st0"&gt;"Closed: ~w&lt;span class="es0"&gt;\n&lt;/span&gt;"&lt;/span&gt;,&lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="re0"&gt;Why&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            recv&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;&lt;span class="re0"&gt;Active&lt;/span&gt;&lt;span class="nu0"&gt;-1&lt;/span&gt;, &lt;span class="re0"&gt;Closed&lt;/span&gt;&lt;span class="nu0"&gt;+1&lt;/span&gt;, &lt;span class="re0"&gt;Chunks&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="br0"&gt;{&lt;/span&gt;loadurl, &lt;span class="re0"&gt;Url&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;            &lt;span class="me1"&gt;http&lt;/span&gt;:&lt;span class="me2"&gt;request&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;get, &lt;span class="br0"&gt;{&lt;/span&gt;&lt;span class="re0"&gt;Url&lt;/span&gt;, &lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;, &lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;, &lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;sync,  false&lt;span class="br0"&gt;}&lt;/span&gt;, &lt;span class="br0"&gt;{&lt;/span&gt;stream, self&lt;span class="br0"&gt;}&lt;/span&gt;, &lt;span class="br0"&gt;{&lt;/span&gt;version, &lt;span class="nu0"&gt;1.1&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt;, &lt;span class="br0"&gt;{&lt;/span&gt;body_format, binary&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                recv&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Stats&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="kw1"&gt;end&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;timer&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;T&lt;/span&gt;, &lt;span class="re0"&gt;Who&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;    &lt;span class="kw1"&gt;receive&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="kw1"&gt;after&lt;/span&gt; &lt;span class="re0"&gt;T&lt;/span&gt;  -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="re0"&gt;Who&lt;/span&gt; ! &lt;span class="br0"&gt;{&lt;/span&gt;stats&lt;span class="br0"&gt;}&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="kw1"&gt;end&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    timer&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;T&lt;/span&gt;, &lt;span class="re0"&gt;Who&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;&lt;span class="co1"&gt;% Read lines from a file with a specified delay  between lines:&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;for_each_line_in_file&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Name&lt;/span&gt;, &lt;span class="re0"&gt;Proc&lt;/span&gt;, &lt;span class="re0"&gt;Mode&lt;/span&gt;,  &lt;span class="re0"&gt;Accum0&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="br0"&gt;{&lt;/span&gt;ok, &lt;span class="re0"&gt;Device&lt;/span&gt;&lt;span class="br0"&gt;}&lt;/span&gt; = file:&lt;span class="me2"&gt;open&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Name&lt;/span&gt;, &lt;span class="re0"&gt;Mode&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    for_each_line&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Device&lt;/span&gt;, &lt;span class="re0"&gt;Proc&lt;/span&gt;, &lt;span class="re0"&gt;Accum0&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;for_each_line&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Device&lt;/span&gt;, &lt;span class="re0"&gt;Proc&lt;/span&gt;, &lt;span class="re0"&gt;Accum&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="kw1"&gt;case&lt;/span&gt; io:&lt;span class="me2"&gt;get_line&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Device&lt;/span&gt;,  &lt;span class="st0"&gt;""&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; &lt;span class="kw1"&gt;of&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        eof  -&gt; &lt;span class="me1"&gt;file&lt;/span&gt;:&lt;span class="kw3"&gt;close&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Device&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;, &lt;span class="re0"&gt;Accum&lt;/span&gt;;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="re0"&gt;Line&lt;/span&gt; -&gt; &lt;span class="re0"&gt;NewAccum&lt;/span&gt; = &lt;span class="re0"&gt;Proc&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Line&lt;/span&gt;, &lt;span class="re0"&gt;Accum&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;                    for_each_line&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Device&lt;/span&gt;, &lt;span class="re0"&gt;Proc&lt;/span&gt;, &lt;span class="re0"&gt;NewAccum&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="kw1"&gt;end&lt;/span&gt;.&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt; &lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;loadurls&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Filename&lt;/span&gt;,  &lt;span class="re0"&gt;Callback&lt;/span&gt;, &lt;span class="re0"&gt;Wait&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;    &lt;span class="me1"&gt;for_each_line_in_file&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Filename&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;        fun&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Line&lt;/span&gt;,  &lt;span class="re0"&gt;List&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="re0"&gt;Callback&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;string:&lt;span class="me2"&gt;strip&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="re0"&gt;Line&lt;/span&gt;, right, $\n&lt;span class="br0"&gt;)&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="kw1"&gt;receive&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="kw1"&gt;after&lt;/span&gt; &lt;span class="re0"&gt;Wait&lt;/span&gt; -&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;                &lt;span class="me1"&gt;noop&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li2"&gt; &lt;div class="de2"&gt;            &lt;span class="kw1"&gt;end&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;            &lt;span class="re0"&gt;List&lt;/span&gt;&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="kw1"&gt;end&lt;/span&gt;,&lt;/div&gt; &lt;/li&gt;&lt;li class="li1"&gt; &lt;div class="de1"&gt;        &lt;span class="br0"&gt;[&lt;/span&gt;read&lt;span class="br0"&gt;]&lt;/span&gt;,  &lt;span class="br0"&gt;[&lt;/span&gt;&lt;span class="br0"&gt;]&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;.&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;我 们建立的每个连接都需要一个端口，即文件描述符(file descriptor)。默认情况下，文件描述符的上限为1024。为了避免『too many open files』问题，你需要修改ulimit，可以在/etc/security/limits.conf中&lt;br /&gt;修改，但是需要重启。现在你可以sudo，修改当前的shell：&lt;br /&gt;&lt;br /&gt;$ sudo bash&lt;br /&gt;# ulimit -n 999999&lt;br /&gt;# erl&lt;br /&gt;&lt;br /&gt;你也需要增加端口范围：&lt;br /&gt;&lt;code&gt;# echo "1024 65535" &gt; /proc/sys/net/ipv4/ip_local_port_range&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;为floodtest程序批量生成URL：&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;( for i in `seq 1 10000`; do echo "http://localhost:8000/$i" ; done ) &gt;&lt;br /&gt;/tmp/mochi-urls.txt&lt;br /&gt;&lt;br /&gt;现在你可以编译、运行floodtest.erl：&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt;erl&gt; c(floodtest).&lt;br /&gt;erl&gt; floodtest:start("/tmp/mochi-urls.txt", 100).&lt;br /&gt;&lt;br /&gt;它将每秒建立10条新的连接（例如，每100毫秒一条连接）。&lt;br /&gt;&lt;br /&gt;它将以{Active, Closed, Chunks}格式输出状态信息，其中Active是并发连接的数目，Closed是由于某种&lt;br /&gt;原因断开的连接，Chunks是mochiweb以块方式传输的块数目。Closed应该为0，Chunks应该大于Active，因&lt;br /&gt;为每个活跃的连接将接收多个块（每10秒1个）。&lt;br /&gt;&lt;br /&gt;1万个活跃连接占用450MB的内存，也就是说每个连接45KB。CPU占用率几乎没有。&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size:130%;"&gt;现阶段总结&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;每个连接占用45KB内存，似乎有点高。用C + libevent库，我想我可以做到每连接占用4.5KB(只是个猜想，&lt;br /&gt;谁有这方面的经历，请讲讲)。如果从代码量和实现时间比较Erlang和C，我想多一点内存消耗是可以理解的。&lt;br /&gt;&lt;br /&gt;在之后的文章中，我将实现一个消息路由（取消mochiconntest_web.erl的25行和41-43行的注释），讨论一些降低内存使用量的方法。&lt;br /&gt;&lt;br /&gt;我也会和大家一起分享10万和100万连接的结果。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14949417-1528683366598794799?l=ro4tub.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ro4tub.blogspot.com/feeds/1528683366598794799/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14949417&amp;postID=1528683366598794799' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14949417/posts/default/1528683366598794799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14949417/posts/default/1528683366598794799'/><link rel='alternate' type='text/html' href='http://ro4tub.blogspot.com/2008/10/mochiwebcomet.html' title='[译]使用Mochiweb构建百万级Comet程序,第一篇'/><author><name>ro4tub</name><uri>http://www.blogger.com/profile/05900229797645474112</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14949417.post-112270173539689790</id><published>2005-07-29T22:32:00.000-07:00</published><updated>2005-07-29T22:35:35.400-07:00</updated><title type='text'>终于可以上网了</title><content type='html'>3月1号到上海的,也已经工作了5个月了,公司不能上外网,所以一直盼望着能够自己办理adsl业务,总算&lt;br /&gt;现在被我办成了!庆祝,庆祝!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14949417-112270173539689790?l=ro4tub.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ro4tub.blogspot.com/feeds/112270173539689790/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14949417&amp;postID=112270173539689790' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14949417/posts/default/112270173539689790'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14949417/posts/default/112270173539689790'/><link rel='alternate' type='text/html' href='http://ro4tub.blogspot.com/2005/07/blog-post.html' title='终于可以上网了'/><author><name>ro4tub</name><uri>http://www.blogger.com/profile/05900229797645474112</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
