<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_wsky's blog,Record my technical life</title><subtitle type="text">just coding</subtitle><id>http://feed.cnblogs.com/blog/u/27680/rss</id><updated>2011-09-18T05:25:52Z</updated><author><name>wsky</name><uri>http://www.cnblogs.com/wsky/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/wsky/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/27680/rss"/><entry><id>http://www.cnblogs.com/wsky/archive/2011/09/18/2180358.html</id><title type="text">生产环境使用Nuget</title><summary type="text">关于Nuget http://nuget.org/官方提供的使用文档比较丰富 http://docs.nuget.org/要在实际生产环境使用它来做打包和包管理，比之更为成熟的Maven来说，从目前版本来看稍有不足，提供一些实际使用的做法参考</summary><published>2011-09-18T05:15:00Z</published><updated>2011-09-18T05:15:00Z</updated><author><name>wsky</name><uri>http://www.cnblogs.com/wsky/</uri></author><link rel="alternate" href="http://www.cnblogs.com/wsky/archive/2011/09/18/2180358.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/wsky/archive/2011/09/18/2180358.html"/><content type="html">&lt;p&gt;关于Nuget &lt;a href="http://nuget.org/"&gt;http://nuget.org/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;官方提供的使用文档比较丰富 &lt;a href="http://docs.nuget.org/"&gt;http://docs.nuget.org/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;要在实际生产环境使用它来做打包和包管理，比之更为成熟的Maven来说，从目前版本来看稍有不足，主要是以下几点：&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;packages.config的继承和解决方案中的识别&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;比如：&lt;/p&gt;  &lt;div &gt;   &lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;nuget &lt;span &gt;update&lt;/span&gt; xx.sln&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   2:  &lt;/span&gt;nuget &lt;span &gt;update&lt;/span&gt; packages.config&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&#xD;
&#xD;
&lt;p&gt;它做的事只是对比包得版本是否有更新并更新之，只要版本没有变化，即使本地仓库没有这个包也不会去下载它，而&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;nuget install packages.config&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;只能指定具体的config文件，不能通过一个sln件自动去扫描解决方案里的所有packages.config&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;和build的集成度：&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;类似上面一点，build的时候不会对本地仓库不存在的必备依赖去自动获取&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;nuget虽然提供 -build参数，但是仅是使用了MSBuild，本身的构建描述能力缺乏（所以下文在生产环境使用会搭配NANT来完成构建过程），而maven中则比较完整的集成了这个过程&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;repository的安装位置不可配置：&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;默认情况下package的安装目录是在.sln所在的目录下建立一个packages目录，也就是说是solutionfile级别的，这个对于项目数量多的时候是比较难接受的，本地开发还好，在build服务器构建的时候就比较麻烦了，不能再同一个位置管理包&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;这个问题在它的官方已经有人在问了，估计下几个版本会有动作&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;以下提供一些解决上述问题或实际应用时的一些方法&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;下述范例所在目录结构：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wsky/201109/201109181315001607.png"&gt;&lt;img style="border: 0px currentColor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline;background-image: none;" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wsky/201109/201109181315033719.png" width="326" height="500" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://ops-base/feeds/"&gt;http://ops-base/feeds/&lt;/a&gt; 是自己hosting的一个nuget feed（&lt;a title="http://docs.nuget.org/docs/creating-packages/hosting-your-own-nuget-feeds" href="http://docs.nuget.org/docs/creating-packages/hosting-your-own-nuget-feeds"&gt;http://docs.nuget.org/docs/creating-packages/hosting-your-own-nuget-feeds&lt;/a&gt;）&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;创建包描述文件：&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;&lt;span &gt;&amp;lt;?&lt;/span&gt;&lt;span &gt;xml&lt;/span&gt; &lt;span &gt;version&lt;/span&gt;&lt;span &gt;="1.0"&lt;/span&gt;?&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   2:  &lt;/span&gt;&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;package&lt;/span&gt; &lt;span &gt;xmlns&lt;/span&gt;&lt;span &gt;="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   3:  &lt;/span&gt;  &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;metadata&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   4:  &lt;/span&gt;    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;id&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;Package.Castle&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;id&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   5:  &lt;/span&gt;    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;version&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;2.1&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;version&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   6:  &lt;/span&gt;    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;title&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;Castle&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;title&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   7:  &lt;/span&gt;    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;authors&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;Castle&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;authors&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   8:  &lt;/span&gt;    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;owners&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   9:  &lt;/span&gt;    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;requireLicenseAcceptance&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;false&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;requireLicenseAcceptance&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  10:  &lt;/span&gt;    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;description&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  11:  &lt;/span&gt;      IOC容器&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  12:  &lt;/span&gt;    &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;description&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  13:  &lt;/span&gt;    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;copyright&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;2011&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;copyright&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  14:  &lt;/span&gt;    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;language&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;zh-CN&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;language&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  15:  &lt;/span&gt;  &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;metadata&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  16:  &lt;/span&gt;  &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;files&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  17:  &lt;/span&gt;    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;file&lt;/span&gt; &lt;span &gt;src&lt;/span&gt;&lt;span &gt;="Castle\Castle.Core.dll"&lt;/span&gt; &lt;span &gt;target&lt;/span&gt;&lt;span &gt;="lib\net40\Castle.Core.dll"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  18:  &lt;/span&gt;    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;file&lt;/span&gt; &lt;span &gt;src&lt;/span&gt;&lt;span &gt;="Castle\Castle.Core.xml"&lt;/span&gt; &lt;span &gt;target&lt;/span&gt;&lt;span &gt;="lib\net40\Castle.Core.xml"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  19:  &lt;/span&gt;    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;file&lt;/span&gt; &lt;span &gt;src&lt;/span&gt;&lt;span &gt;="Castle\Castle.DynamicProxy2.dll"&lt;/span&gt; &lt;span &gt;target&lt;/span&gt;&lt;span &gt;="lib\net40\Castle.DynamicProxy2.dll"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  20:  &lt;/span&gt;    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;file&lt;/span&gt; &lt;span &gt;src&lt;/span&gt;&lt;span &gt;="Castle\Castle.DynamicProxy2.xml"&lt;/span&gt; &lt;span &gt;target&lt;/span&gt;&lt;span &gt;="lib\net40\Castle.DynamicProxy2.xml"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  21:  &lt;/span&gt;    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;file&lt;/span&gt; &lt;span &gt;src&lt;/span&gt;&lt;span &gt;="Castle\Castle.MicroKernel.dll"&lt;/span&gt; &lt;span &gt;target&lt;/span&gt;&lt;span &gt;="lib\net40\Castle.MicroKernel.dll"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  22:  &lt;/span&gt;    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;file&lt;/span&gt; &lt;span &gt;src&lt;/span&gt;&lt;span &gt;="Castle\Castle.MicroKernel.xml"&lt;/span&gt; &lt;span &gt;target&lt;/span&gt;&lt;span &gt;="lib\net40\Castle.MicroKernel.xml"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  23:  &lt;/span&gt;    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;file&lt;/span&gt; &lt;span &gt;src&lt;/span&gt;&lt;span &gt;="Castle\Castle.Windsor.dll"&lt;/span&gt; &lt;span &gt;target&lt;/span&gt;&lt;span &gt;="lib\net40\Castle.Windsor.dll"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  24:  &lt;/span&gt;    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;file&lt;/span&gt; &lt;span &gt;src&lt;/span&gt;&lt;span &gt;="Castle\Castle.Windsor.xml"&lt;/span&gt; &lt;span &gt;target&lt;/span&gt;&lt;span &gt;="lib\net40\Castle.Windsor.xml"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  25:  &lt;/span&gt;  &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;files&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  26:  &lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;package&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&#xD;
&lt;p&gt;批量打包和发布到feeds，pack.bat脚本如下：&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;echo &lt;span &gt;off&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   2:  &lt;/span&gt;mkdir assembly\packages&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   3:  &lt;/span&gt;echo pack&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   4:  &lt;/span&gt;forfiles /p assembly /m *.nuspec /c "cmd /c ..\tools\nuget pack @&lt;span &gt;file&lt;/span&gt; -outputdirectory packages"&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   5:  &lt;/span&gt;echo push&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   6:  &lt;/span&gt;forfiles /p assembly\packages /m *.nupkg /c "cmd /c ..\..\tools\nuget push @&lt;span &gt;file&lt;/span&gt; -s &lt;a href="http://ops-base/feeds/"&gt;http://ops-base/feeds/&lt;/a&gt; hello1234"&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   7:  &lt;/span&gt;echo on&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;批量安装和更新本地package，nuget.install.bat脚本如下：&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;echo off&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   2:  &lt;/span&gt;echo install&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   3:  &lt;/span&gt;forfiles /s /m packages.config /c &lt;span &gt;"cmd /c %1\nuget install @file -o %2"&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   4:  &lt;/span&gt;echo update&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   5:  &lt;/span&gt;forfiles /s /m packages.config /c &lt;span &gt;"cmd /c %1\nuget update @file -source &lt;a href="http://ops-base/feeds/nuget"&gt;http://ops-base/feeds/nuget&lt;/a&gt;"&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   6:  &lt;/span&gt;echo on&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;然后使用NANT然完成构建过程，nant.build部分内容如下：&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;&lt;span &gt;&amp;lt;?&lt;/span&gt;&lt;span &gt;xml&lt;/span&gt; &lt;span &gt;version&lt;/span&gt;&lt;span &gt;="1.0"&lt;/span&gt;?&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   2:  &lt;/span&gt;&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;project&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="infrastructure"&lt;/span&gt; &lt;span &gt;default&lt;/span&gt;&lt;span &gt;="build"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   3:  &lt;/span&gt;  &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;property&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="project.config"&lt;/span&gt; &lt;span &gt;value&lt;/span&gt;&lt;span &gt;="release"&lt;/span&gt; &lt;span &gt;dynamic&lt;/span&gt;&lt;span &gt;="true"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   4:  &lt;/span&gt;  &lt;span &gt;&amp;lt;!--path--&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   5:  &lt;/span&gt;  &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;property&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="dir"&lt;/span&gt; &lt;span &gt;value&lt;/span&gt;&lt;span &gt;="."&lt;/span&gt;&lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   6:  &lt;/span&gt;  &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;property&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="dir.tools"&lt;/span&gt; &lt;span &gt;value&lt;/span&gt;&lt;span &gt;=".\tools"&lt;/span&gt;&lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   7:  &lt;/span&gt;  &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;property&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="build.base"&lt;/span&gt; &lt;span &gt;value&lt;/span&gt;&lt;span &gt;="build\${project.config}"&lt;/span&gt;&lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   8:  &lt;/span&gt;  &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;property&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="build.absolutepath"&lt;/span&gt; &lt;span &gt;value&lt;/span&gt;&lt;span &gt;="${path::get-full-path(build.base)}"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   9:  &lt;/span&gt;  &lt;span &gt;&amp;lt;!--msbuild--&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  10:  &lt;/span&gt;  &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;property&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="msbuild"&lt;/span&gt; &lt;span &gt;value&lt;/span&gt;&lt;span &gt;="C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  11:  &lt;/span&gt;  &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;property&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="msbuild.config"&lt;/span&gt; &lt;span &gt;value&lt;/span&gt;&lt;span &gt;="Debug"&lt;/span&gt; &lt;span &gt;dynamic&lt;/span&gt;&lt;span &gt;="true"&lt;/span&gt;&lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  12:  &lt;/span&gt;  &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;if&lt;/span&gt; &lt;span &gt;test&lt;/span&gt;&lt;span &gt;="${project.config=='Release'}"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  13:  &lt;/span&gt;    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;property&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="msbuild.config"&lt;/span&gt; &lt;span &gt;value&lt;/span&gt;&lt;span &gt;="Release"&lt;/span&gt;&lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  14:  &lt;/span&gt;  &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;if&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  15:  &lt;/span&gt;  &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;property&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="msbuild.params"&lt;/span&gt; &lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  16:  &lt;/span&gt;            &lt;span &gt;value&lt;/span&gt;&lt;span &gt;="/t:rebuild &lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  17:  &lt;/span&gt;            /p:Configuration=${msbuild.config}&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  18:  &lt;/span&gt;            /p:AllowUnsafeBlocks=true&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  19:  &lt;/span&gt;            /t:ResolveReferences" &lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  20:  &lt;/span&gt;  &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;property&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="msbuild.params.weboutput"&lt;/span&gt; &lt;span &gt;value&lt;/span&gt;&lt;span &gt;="/t:_CopyWebApplication /p:WebProjectOutputDir=${build.absolutepath}"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  21:  &lt;/span&gt;  &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;property&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="msbuild.params.output"&lt;/span&gt; &lt;span &gt;value&lt;/span&gt;&lt;span &gt;="/p:OutputPath=${build.absolutepath}"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  22:  &lt;/span&gt;  &lt;span &gt;&amp;lt;!--nuget--&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  23:  &lt;/span&gt;  &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;property&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="nuget"&lt;/span&gt; &lt;span &gt;value&lt;/span&gt;&lt;span &gt;="${path::get-full-path(dir.tools)}"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  24:  &lt;/span&gt;  &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;property&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="nuget.packages"&lt;/span&gt; &lt;span &gt;value&lt;/span&gt;&lt;span &gt;="${dir}\packages"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  25:  &lt;/span&gt;  &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;property&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="nuget.install"&lt;/span&gt; &lt;span &gt;value&lt;/span&gt;&lt;span &gt;="${dir}\nuget.install.bat"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  26:  &lt;/span&gt;  &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;property&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="nuget.params.install"&lt;/span&gt; &lt;span &gt;value&lt;/span&gt;&lt;span &gt;="${nuget} ${path::get-full-path(nuget.packages)}"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  27:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  28:  &lt;/span&gt;   &lt;span &gt;&amp;lt;!--build infrastructure--&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  29:  &lt;/span&gt;  &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;target&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="base"&lt;/span&gt; &lt;span &gt;description&lt;/span&gt;&lt;span &gt;="Infrastructure"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  30:  &lt;/span&gt;    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;exec&lt;/span&gt; &lt;span &gt;program&lt;/span&gt;&lt;span &gt;="${nuget.install}"&lt;/span&gt; &lt;span &gt;commandline&lt;/span&gt;&lt;span &gt;="${nuget.params.install}"&lt;/span&gt; &lt;span &gt;workingdir&lt;/span&gt;&lt;span &gt;="${dir}"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;     &lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  31:  &lt;/span&gt;    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;exec&lt;/span&gt; &lt;span &gt;program&lt;/span&gt;&lt;span &gt;="${msbuild}"&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  32:  &lt;/span&gt;          &lt;span &gt;commandline&lt;/span&gt;&lt;span &gt;="${msbuild.params} ${msbuild.params.output}"&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  33:  &lt;/span&gt;          &lt;span &gt;workingdir&lt;/span&gt;&lt;span &gt;="${dir}\Infrastructure\"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  34:  &lt;/span&gt;  &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;target&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  35:  &lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;project&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;上述nant脚本中，target=base的构建目标就是要构建的项目了，首先执行nuget.install.bat脚本更新本地packages，然后执行msbuild&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;然后运行下述脚本执行构建：&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;.\tools\nant\bin\nant base&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;到这里就完成了将nuget投入项目环境使用的相关准备工作：）&lt;/p&gt; &#xD;
 &lt;img src="http://www.cnblogs.com/wsky/aggbug/2180358.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/wsky/archive/2011/09/18/2180358.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/wsky/archive/2011/05/10/2042378.html</id><title type="text">为WebClient增加Cookie支持</title><summary type="text">System.Net.WebClient是.net提供的高级api，使用上很便捷，但是默认的实现缺乏对cookie的支持，比如您希望使用它来进行模拟登录时，无法直接获取响应的cookie（它没有直接提供操作方法），做一些简易的改进即可支持</summary><published>2011-05-10T10:31:00Z</published><updated>2011-05-10T10:31:00Z</updated><author><name>wsky</name><uri>http://www.cnblogs.com/wsky/</uri></author><link rel="alternate" href="http://www.cnblogs.com/wsky/archive/2011/05/10/2042378.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/wsky/archive/2011/05/10/2042378.html"/><content type="html">&lt;p&gt;System.Net.WebClient是.net提供的高级api，使用上很便捷，但是默认的实现缺乏对cookie的支持，比如您希望使用它来进行模拟登录时，无法直接获取响应的cookie（它没有直接提供操作方法），google了一下，也发现了很简易的改进，如：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://couldbedone.blogspot.com/2007/08/webclient-handling-cookies.html"&gt;http://couldbedone.blogspot.com/2007/08/webclient-handling-cookies.html&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://codehelp.smartdev.eu/2009/05/08/improve-webclient-by-adding-useragent-and-cookies-to-your-requests/"&gt;http://codehelp.smartdev.eu/2009/05/08/improve-webclient-by-adding-useragent-and-cookies-to-your-requests/&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;就是重写GetWebRequest(Uri address)即可，不过实际场景这样可不够用，比如你要模拟登录的地址并非是要访问的目标地址时，比如登录过程有302重定向之类的，上述文章中的实现都会使得您携带的cookie并不是目标站点需要的，&lt;/p&gt;&#xD;
&lt;p&gt;那么我们来对它再做一下改进，既然重写了GetWebRequest，不如把GetWebResponse也重写一下吧：&lt;/p&gt;&#xD;
&lt;div &gt;&lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;    &lt;span &gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   2:  &lt;/span&gt;    &lt;span &gt;/// 支持cookie的webclient&lt;/span&gt;&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;   3:  &lt;/span&gt;    &lt;span &gt;/// &amp;lt;remarks&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   4:  &lt;/span&gt;    &lt;span &gt;/// 请求完成后会自动将响应cookie填充至CookieContainer&lt;/span&gt;&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;   5:  &lt;/span&gt;    &lt;span &gt;/// &amp;lt;/remarks&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   6:  &lt;/span&gt;    &lt;span &gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;   7:  &lt;/span&gt;    &lt;span &gt;internal&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; CookieAwareWebClient : WebClient&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   8:  &lt;/span&gt;    {&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;   9:  &lt;/span&gt;        &lt;span &gt;internal&lt;/span&gt; CookieContainer _cookieContainer = &lt;span &gt;new&lt;/span&gt; CookieContainer();&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  10:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;  11:  &lt;/span&gt;        &lt;span &gt;protected&lt;/span&gt; &lt;span &gt;override&lt;/span&gt; WebRequest GetWebRequest(Uri address)&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  12:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;  13:  &lt;/span&gt;            var request = &lt;span &gt;base&lt;/span&gt;.GetWebRequest(address);&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  14:  &lt;/span&gt;            &lt;span &gt;if&lt;/span&gt; (request &lt;span &gt;is&lt;/span&gt; HttpWebRequest)&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;  15:  &lt;/span&gt;                (request &lt;span &gt;as&lt;/span&gt; HttpWebRequest).CookieContainer = &lt;span &gt;this&lt;/span&gt;._cookieContainer;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  16:  &lt;/span&gt;            &lt;span &gt;return&lt;/span&gt; request;&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;  17:  &lt;/span&gt;        }&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  18:  &lt;/span&gt;        &lt;span &gt;protected&lt;/span&gt; &lt;span &gt;override&lt;/span&gt; WebResponse GetWebResponse(WebRequest request)&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;  19:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  20:  &lt;/span&gt;            var r = &lt;span &gt;base&lt;/span&gt;.GetWebResponse(request);&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;  21:  &lt;/span&gt;            &lt;span &gt;if&lt;/span&gt; (r &lt;span &gt;is&lt;/span&gt; HttpWebResponse)&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  22:  &lt;/span&gt;                &lt;span &gt;this&lt;/span&gt;._cookieContainer.Add((r &lt;span &gt;as&lt;/span&gt; HttpWebResponse).Cookies);&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;  23:  &lt;/span&gt;            &lt;span &gt;return&lt;/span&gt; r;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  24:  &lt;/span&gt;        }&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;  25:  &lt;/span&gt;    }&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;上述便是完整代码：）&lt;/p&gt;&lt;img src="http://www.cnblogs.com/wsky/aggbug/2042378.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/wsky/archive/2011/05/10/2042378.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/wsky/archive/2011/04/12/2013903.html</id><title type="text">keepalived安装和使用</title><summary type="text">keepalived：http://www.keepalived.org/index.html 它是一个基于VRRP协议来实现的WEB服务高可用方案，可以利用其来避免单点故障。一个WEB服务至少会有2台服务器运行Keepalived，一台为主服务器（MASTER），一台为备份服务器（BACKUP），但是对外表现为一个虚拟IP，主服务器会发送特定的消息给备份服务器，当备份服务器收不到这个消息的时候，...</summary><published>2011-04-12T09:27:00Z</published><updated>2011-04-12T09:27:00Z</updated><author><name>wsky</name><uri>http://www.cnblogs.com/wsky/</uri></author><link rel="alternate" href="http://www.cnblogs.com/wsky/archive/2011/04/12/2013903.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/wsky/archive/2011/04/12/2013903.html"/><content type="html">&lt;p&gt;keepalived：&lt;a href="http://www.keepalived.org/index.html"&gt;http://www.keepalived.org/index.html&lt;/a&gt;&lt;/p&gt;  &lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;   &lt;p&gt;&lt;em&gt;它是一个基于VRRP协议来实现的WEB服务高可用方案，可以利用其来避免单点故障。一个WEB服务至少会有2台服务器运行Keepalived，一台为主服务器（MASTER），一台为备份服务器（BACKUP），但是对外表现为一个虚拟IP，主服务器会发送特定的消息给备份服务器，当备份服务器收不到这个消息的时候，即主服务器宕机的时候，备份服务器就会接管虚拟IP，继续提供服务，从而保证了高可用性。（摘）&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wsky/201104/201104121727268950.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wsky/201104/201104121727267870.png" width="365" height="88" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;可以使用lvs或haproxy+keepalived做高可用的负载均衡方案&lt;/p&gt;  &lt;p&gt;记录一下安装过程和问题处理过程&lt;/p&gt;  &lt;p&gt;首先需要安装ipvsadm：&lt;/p&gt;  &lt;div &gt;   &lt;pre &gt;yum -y install ipvsadm&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;或者：&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;&lt;span &gt;#在这里查找适合的版本http://www.linuxvirtualserver.org/software/ipvs.html&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   2:  &lt;/span&gt;wget http://www.linuxvirtualserver.org/software/kernel-2.6/ipvsadm-1.24-6.src.rpm&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   3:  &lt;/span&gt;tar –zxvf ipvsadm-1.24.tar.gz&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   4:  &lt;/span&gt;cd ipvsadm-1.24&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   5:  &lt;/span&gt;make&amp;amp;&amp;amp;make install&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;然后安装keepalived&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;wget http:&lt;span &gt;//www.keepalived.org/software/keepalived-1.2.2.tar.gz&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   2:  &lt;/span&gt;tar –zxvf keepalived-1.2.2.tar.gz&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   3:  &lt;/span&gt;cd keepalived-1.2.2&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   4:  &lt;/span&gt;./configure&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   5:  &lt;/span&gt;make &amp;amp;&amp;amp; make install&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;configure时若出现以下结果：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wsky/201104/20110412172726379.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wsky/201104/201104121727266475.png" width="492" height="167" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;只有一项为yes，因为keepalived没有找到内核目录导致的，解决的方法是在编译的时候：&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;./configure --with-kernel-dir=/usr/src/kernels/2.6.18-194.el5-i686/&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;若/usr/src/kernel目录下没有内核目录，则需要安装内核开发包：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;用命令uname -a查看内核版本，然后可以在这里查找对应的&lt;a href="http://zid-luxinst.uibk.ac.at/linux/rpm2html/centos/5/os/i386/CentOS/kernel-devel-2.6.18-194.el5.i686.html"&gt;http://zid-luxinst.uibk.ac.at/linux/rpm2html/centos/5/os/i386/CentOS/kernel-devel-2.6.18-194.el5.i686.html&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;不推荐使用yum install -y kernel-devel安装&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;安装完成后建立一下链接：&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;ln -s /usr/src/kernels/2.6.18-194.el5-i686/ /usr/src/linux/&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;上述过程完毕后，在进行configure：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wsky/201104/201104121727268983.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wsky/201104/201104121727265080.png" width="517" height="186" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;若还是出现no或者make的时候出现：“ error: linux/ip_masq.h: No such file or directory”之类的错误时，在/usr/src/kernels/2.6.18-194.el5-i686/include/linux/version.h中增加声明：&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;&lt;span &gt;#define&lt;/span&gt; UTS_RELEASE &lt;span &gt;&amp;quot;2.6.18&amp;quot;&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;再进行configure就会都是yes了：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wsky/201104/201104121727265952.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wsky/201104/201104121727274556.png" width="431" height="183" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;接着执行make是若出现“types.h:62: error: conflicting types for ‘dev_t’”错误，需要修改源码目录下的keepalived/libipvs-2.6/ip_vs.h&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;把#include linux/types.h移到#include sys/types.h 这行的下面&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wsky/201104/201104121727277064.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wsky/201104/201104121727277936.png" width="582" height="121" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;上述错误都解决后make&amp;amp;&amp;amp;make install就可以通过了，然后运行：&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;&lt;span &gt;#查看帮助&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;keepalived -h&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;#运行 由于keepalived配置文件不是在启动时一次性加载并读取完成的，所以必须是完整路径，可以根据log判断是否加载了正确的配置文件&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;keepalived –f /usr/&lt;span &gt;local&lt;/span&gt;/etc/keepalived/keepalived.conf &lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;运行过程可以查看log：&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;tail -f /var/log/message&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;img src="http://www.cnblogs.com/wsky/aggbug/2013903.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/wsky/archive/2011/04/12/2013903.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/wsky/archive/2011/04/07/2007908.html</id><title type="text">NHibernate分享 PPT</title><summary type="text">最近在部门内做的NHibernate的分享，这份主要讲的一些nh几个主要设计原理上的，这几个概念弄清楚了剩下的就是使用经验问题了。</summary><published>2011-04-07T06:47:00Z</published><updated>2011-04-07T06:47:00Z</updated><author><name>wsky</name><uri>http://www.cnblogs.com/wsky/</uri></author><link rel="alternate" href="http://www.cnblogs.com/wsky/archive/2011/04/07/2007908.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/wsky/archive/2011/04/07/2007908.html"/><content type="html">&lt;div style="width: 425px" id="__ss_7544020"&gt;&lt;strong style="margin: 12px 0px 4px; display: block"&gt;&lt;a title="NHibernate分享(1) share" href="http://www.slideshare.net/wsky/nhibernate1-share"&gt;NHibernate分享(1) share&lt;/a&gt;&lt;/strong&gt;     &lt;div style="padding-bottom: 12px; padding-left: 0px; padding-right: 0px; padding-top: 5px"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/wsky"&gt;wsky&lt;/a&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;最近在部门内做的NHibernate的分享，这份主要讲的一些nh几个主要设计原理上的，这几个概念弄清楚了剩下的就是使用经验问题了。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/wsky/aggbug/2007908.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/wsky/archive/2011/04/07/2007908.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/wsky/archive/2011/04/07/2007543.html</id><title type="text">开源选型关注点</title><summary type="text">开源框架、产品非常多，部分框架的相似度也比较高，下面列了一些我在选型时会关注的点，随着使用经验积累再继续补充</summary><published>2011-04-07T02:16:00Z</published><updated>2011-04-07T02:16:00Z</updated><author><name>wsky</name><uri>http://www.cnblogs.com/wsky/</uri></author><link rel="alternate" href="http://www.cnblogs.com/wsky/archive/2011/04/07/2007543.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/wsky/archive/2011/04/07/2007543.html"/><content type="html">&lt;p&gt;开源框架、产品非常多，部分框架的相似度也比较高，下面列了一些我在选型时会关注的点，随着使用经验积累再继续补充&lt;/p&gt;&#xD;
&lt;ul&gt;&lt;li&gt;是否主流&lt;/li&gt;&lt;li&gt;是否有实际案例&lt;/li&gt;&lt;li&gt;是否有理论支持&lt;/li&gt;&lt;li&gt;是否有社区支持&lt;/li&gt;&lt;li&gt;若是服务器技术，是否有运维能力&lt;/li&gt;&lt;li&gt;若是组件技术，是否有源码阅读能力&lt;/li&gt;&lt;li&gt;技术是否容易被大部分团队成员学习和理解&lt;/li&gt;&lt;/ul&gt;&#xD;
&lt;p&gt;&lt;strong&gt;ORM：&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;ul&gt;&lt;li&gt;POCO支持&lt;/li&gt;&lt;li&gt;对象状态管理&lt;/li&gt;&lt;li&gt;关系映射&lt;/li&gt;&lt;li&gt;设计侵入性&lt;/li&gt;&lt;li&gt;自动事务控制，管理&lt;/li&gt;&lt;li&gt;SQL支持&lt;/li&gt;&lt;li&gt;文档，源码质量&lt;/li&gt;&lt;li&gt;数据库无关性支持&lt;/li&gt;&lt;li&gt;存储过程支持&lt;/li&gt;&lt;li&gt;SQL跟踪，调优&lt;/li&gt;&lt;li&gt;批处理&lt;/li&gt;&lt;li&gt;多级缓存&lt;/li&gt;&lt;li&gt;开源&lt;/li&gt;&lt;li&gt;contrib丰富&lt;/li&gt;&lt;li&gt;lazyload&lt;/li&gt;&lt;li&gt;api粒度，设计优雅&lt;/li&gt;&lt;/ul&gt;&#xD;
&lt;p&gt;&lt;strong&gt;容器：&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;ul&gt;&lt;li&gt;注册方式灵活&lt;/li&gt;&lt;li&gt;支持主流模式&lt;/li&gt;&lt;li&gt;api优雅&lt;/li&gt;&lt;li&gt;多级容器,父子容器对象管理是否有内存溢出问题&lt;/li&gt;&lt;li&gt;加载卸载方便&lt;/li&gt;&lt;li&gt;拦截器支持&lt;/li&gt;&lt;li&gt;动态静态依赖&lt;/li&gt;&lt;li&gt;属性注入&lt;/li&gt;&lt;li&gt;完全代码初始化&lt;/li&gt;&lt;li&gt;配置文件易于理解可维护&lt;/li&gt;&lt;li&gt;文档，范例齐全&lt;/li&gt;&lt;li&gt;高性能反射&lt;/li&gt;&lt;li&gt;轻量&lt;/li&gt;&lt;li&gt;多种生命周期管理&lt;/li&gt;&lt;li&gt;源码质量&lt;/li&gt;&lt;li&gt;contrib丰富 &lt;/li&gt;&lt;/ul&gt;&lt;img src="http://www.cnblogs.com/wsky/aggbug/2007543.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/wsky/archive/2011/04/07/2007543.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/wsky/archive/2011/04/06/2007201.html</id><title type="text">SocketAsyncEventArgs</title><summary type="text">SocketAsyncEventArgs是.net提供的关于异步socket类，封装了IOCP的使用，可以用它方便的实现NIO（non-blocking IO）NIO对于提升某些场景下Server性能和吞吐量有很大益处，准备在服务框架中使用它来编写简易rpc的部分</summary><published>2011-04-06T13:08:00Z</published><updated>2011-04-06T13:08:00Z</updated><author><name>wsky</name><uri>http://www.cnblogs.com/wsky/</uri></author><link rel="alternate" href="http://www.cnblogs.com/wsky/archive/2011/04/06/2007201.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/wsky/archive/2011/04/06/2007201.html"/><content type="html">&lt;p&gt;SocketAsyncEventArgs是.net提供的关于异步socket类，封装了IOCP的使用，可以用它方便的实现NIO（non-blocking IO）&lt;/p&gt;  &lt;p&gt;NIO对于提升某些场景下Server性能和吞吐量有很大益处，准备在服务框架中使用它来编写简易rpc的部分&lt;/p&gt;  &lt;p&gt;微软官方的demo代理有所缺少：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.net.sockets.socketasynceventargs.aspx"&gt;http://msdn.microsoft.com/en-us/library/system.net.sockets.socketasynceventargs.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;还有篇老外写的补充了缺少的代码：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.codeproject.com/KB/IP/socketasynceventargssampl.aspx"&gt;http://www.codeproject.com/KB/IP/socketasynceventargssampl.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;不过例子还是感觉复杂了点，我只是需要知道SocketAsyncEventArgs本身如何使用而已，于是自行简化了一下：&lt;/p&gt;  &lt;div &gt;   &lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;&lt;span &gt;using&lt;/span&gt; System;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   2:  &lt;/span&gt;&lt;span &gt;using&lt;/span&gt; System.Net;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   3:  &lt;/span&gt;&lt;span &gt;using&lt;/span&gt; System.Net.Sockets;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   4:  &lt;/span&gt;&lt;span &gt;using&lt;/span&gt; System.Text;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   5:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   6:  &lt;/span&gt;&lt;span &gt;namespace&lt;/span&gt; SocketAsyncServer&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   7:  &lt;/span&gt;{&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   8:  &lt;/span&gt;    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; Program&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   9:  &lt;/span&gt;    {&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  10:  &lt;/span&gt;        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; Main(String[] args)&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  11:  &lt;/span&gt;        {&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  12:  &lt;/span&gt;            IPAddress[] addressList = Dns.GetHostEntry(Environment.MachineName).AddressList;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  13:  &lt;/span&gt;            &lt;span &gt;new&lt;/span&gt; TcpListener().Listen(&lt;span &gt;new&lt;/span&gt; IPEndPoint(addressList[addressList.Length - 1], 9900));&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  14:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  15:  &lt;/span&gt;            Console.ReadKey();&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  16:  &lt;/span&gt;        }&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  17:  &lt;/span&gt;    }&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  18:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  19:  &lt;/span&gt;    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; TcpListener&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  20:  &lt;/span&gt;    {&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  21:  &lt;/span&gt;        &lt;span &gt;private&lt;/span&gt; SocketAsyncEventArgs Args;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  22:  &lt;/span&gt;        &lt;span &gt;private&lt;/span&gt; Socket ListenerSocket;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  23:  &lt;/span&gt;        &lt;span &gt;private&lt;/span&gt; StringBuilder buffers;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  24:  &lt;/span&gt;        &lt;span &gt;public&lt;/span&gt; TcpListener() { }&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  25:  &lt;/span&gt;        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; Listen(EndPoint e)&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  26:  &lt;/span&gt;        {&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  27:  &lt;/span&gt;            &lt;span &gt;//buffer&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  28:  &lt;/span&gt;            buffers = &lt;span &gt;new&lt;/span&gt; StringBuilder();&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  29:  &lt;/span&gt;            &lt;span &gt;//socket&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  30:  &lt;/span&gt;            ListenerSocket = &lt;span &gt;new&lt;/span&gt; Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  31:  &lt;/span&gt;            ListenerSocket.Bind(e);&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  32:  &lt;/span&gt;            ListenerSocket.Listen(10);&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  33:  &lt;/span&gt;            &lt;span &gt;//异步socket事件&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  34:  &lt;/span&gt;            Args = &lt;span &gt;new&lt;/span&gt; SocketAsyncEventArgs();&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  35:  &lt;/span&gt;            Args.Completed += &lt;span &gt;new&lt;/span&gt; EventHandler&amp;lt;SocketAsyncEventArgs&amp;gt;(ProcessAccept);&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  36:  &lt;/span&gt;            BeginAccept(Args);&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  37:  &lt;/span&gt;            Console.WriteLine(&lt;span &gt;"server run at {0}"&lt;/span&gt;, e.ToString());&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  38:  &lt;/span&gt;        }&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  39:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  40:  &lt;/span&gt;        &lt;span &gt;//开始接受&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  41:  &lt;/span&gt;        &lt;span &gt;void&lt;/span&gt; BeginAccept(SocketAsyncEventArgs e)&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  42:  &lt;/span&gt;        {&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  43:  &lt;/span&gt;            e.AcceptSocket = &lt;span &gt;null&lt;/span&gt;;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  44:  &lt;/span&gt;            &lt;span &gt;if&lt;/span&gt; (!ListenerSocket.AcceptAsync(e))&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  45:  &lt;/span&gt;                ProcessAccept(ListenerSocket, e);&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  46:  &lt;/span&gt;        }&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  47:  &lt;/span&gt;        &lt;span &gt;//接受完毕 开始接收和发送&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  48:  &lt;/span&gt;        &lt;span &gt;void&lt;/span&gt; ProcessAccept(&lt;span &gt;object&lt;/span&gt; sender, SocketAsyncEventArgs e)&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  49:  &lt;/span&gt;        {&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  50:  &lt;/span&gt;            Socket s = e.AcceptSocket;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  51:  &lt;/span&gt;            e.AcceptSocket = &lt;span &gt;null&lt;/span&gt;;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  52:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  53:  &lt;/span&gt;            &lt;span &gt;int&lt;/span&gt; bufferSize = 10;&lt;span &gt;//1000 * 1024;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  54:  &lt;/span&gt;            var args = &lt;span &gt;new&lt;/span&gt; SocketAsyncEventArgs();&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  55:  &lt;/span&gt;            args.Completed += &lt;span &gt;new&lt;/span&gt; EventHandler&amp;lt;SocketAsyncEventArgs&amp;gt;(OnIOCompleted);&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  56:  &lt;/span&gt;            args.SetBuffer(&lt;span &gt;new&lt;/span&gt; &lt;span &gt;byte&lt;/span&gt;[bufferSize], 0, bufferSize);&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  57:  &lt;/span&gt;            args.AcceptSocket = s;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  58:  &lt;/span&gt;            &lt;span &gt;if&lt;/span&gt; (!s.ReceiveAsync(args))&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  59:  &lt;/span&gt;                &lt;span &gt;this&lt;/span&gt;.ProcessReceive(args);&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  60:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  61:  &lt;/span&gt;            BeginAccept(e);&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  62:  &lt;/span&gt;        }&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  63:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  64:  &lt;/span&gt;        &lt;span &gt;//IOCP回调&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  65:  &lt;/span&gt;        &lt;span &gt;void&lt;/span&gt; OnIOCompleted(&lt;span &gt;object&lt;/span&gt; sender, SocketAsyncEventArgs e)&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  66:  &lt;/span&gt;        {&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  67:  &lt;/span&gt;            &lt;span &gt;switch&lt;/span&gt; (e.LastOperation)&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  68:  &lt;/span&gt;            {&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  69:  &lt;/span&gt;                &lt;span &gt;case&lt;/span&gt; SocketAsyncOperation.Receive:&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  70:  &lt;/span&gt;                    &lt;span &gt;this&lt;/span&gt;.ProcessReceive(e);&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  71:  &lt;/span&gt;                    &lt;span &gt;break&lt;/span&gt;;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  72:  &lt;/span&gt;                &lt;span &gt;case&lt;/span&gt; SocketAsyncOperation.Send:&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  73:  &lt;/span&gt;                    &lt;span &gt;this&lt;/span&gt;.ProcessSend(e);&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  74:  &lt;/span&gt;                    &lt;span &gt;break&lt;/span&gt;;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  75:  &lt;/span&gt;                &lt;span &gt;default&lt;/span&gt;:&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  76:  &lt;/span&gt;                    &lt;span &gt;throw&lt;/span&gt; &lt;span &gt;new&lt;/span&gt; ArgumentException(&lt;span &gt;"The last operation completed on the socket was not a receive or send"&lt;/span&gt;);&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  77:  &lt;/span&gt;            }&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  78:  &lt;/span&gt;        }&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  79:  &lt;/span&gt;        &lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  80:  &lt;/span&gt;        &lt;span &gt;//接收完毕&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  81:  &lt;/span&gt;        &lt;span &gt;void&lt;/span&gt; ProcessReceive(SocketAsyncEventArgs e)&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  82:  &lt;/span&gt;        {&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  83:  &lt;/span&gt;            &lt;span &gt;if&lt;/span&gt; (e.BytesTransferred &amp;gt; 0)&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  84:  &lt;/span&gt;            {&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  85:  &lt;/span&gt;                &lt;span &gt;if&lt;/span&gt; (e.SocketError == SocketError.Success)&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  86:  &lt;/span&gt;                {&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  87:  &lt;/span&gt;                    &lt;span &gt;//读取&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  88:  &lt;/span&gt;                    var data=Encoding.ASCII.GetString(e.Buffer, e.Offset, e.BytesTransferred);&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  89:  &lt;/span&gt;                    buffers.Append(data);&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  90:  &lt;/span&gt;                    Console.WriteLine(&lt;span &gt;"Received:{0}"&lt;/span&gt;, data);&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  91:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  92:  &lt;/span&gt;                    &lt;span &gt;if&lt;/span&gt; (e.AcceptSocket.Available == 0)&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  93:  &lt;/span&gt;                    {&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  94:  &lt;/span&gt;                        &lt;span &gt;//读取完毕&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  95:  &lt;/span&gt;                        Console.WriteLine(&lt;span &gt;"Receive Complete.Data:{0}"&lt;/span&gt;, buffers.ToString());&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  96:  &lt;/span&gt;                        &lt;span &gt;//重置&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  97:  &lt;/span&gt;                        buffers = &lt;span &gt;new&lt;/span&gt; StringBuilder();&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  98:  &lt;/span&gt;                        &lt;span &gt;//发送反馈&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  99:  &lt;/span&gt;                        Byte[] sendBuffer = Encoding.ASCII.GetBytes(&lt;span &gt;"result from server"&lt;/span&gt;);&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt; 100:  &lt;/span&gt;                        e.SetBuffer(sendBuffer, 0, sendBuffer.Length);&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt; 101:  &lt;/span&gt;                        &lt;span &gt;if&lt;/span&gt; (!e.AcceptSocket.SendAsync(e))&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt; 102:  &lt;/span&gt;                        {&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt; 103:  &lt;/span&gt;                   &lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt; 104:  &lt;/span&gt;                            &lt;span &gt;this&lt;/span&gt;.ProcessSend(e);&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt; 105:  &lt;/span&gt;                        }&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt; 106:  &lt;/span&gt;                    }&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt; 107:  &lt;/span&gt;                    &lt;span &gt;else&lt;/span&gt; &lt;span &gt;if&lt;/span&gt; (!e.AcceptSocket.ReceiveAsync(e))&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt; 108:  &lt;/span&gt;                    {&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt; 109:  &lt;/span&gt;                        &lt;span &gt;this&lt;/span&gt;.ProcessReceive(e);&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt; 110:  &lt;/span&gt;                    }&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt; 111:  &lt;/span&gt;                }&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt; 112:  &lt;/span&gt;                &lt;span &gt;else&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt; 113:  &lt;/span&gt;                {&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt; 114:  &lt;/span&gt;                    &lt;span &gt;//this.ProcessError(e);&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt; 115:  &lt;/span&gt;                }&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt; 116:  &lt;/span&gt;            }&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt; 117:  &lt;/span&gt;            &lt;span &gt;else&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt; 118:  &lt;/span&gt;            {&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt; 119:  &lt;/span&gt;                &lt;span &gt;//this.CloseClientSocket(e);&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt; 120:  &lt;/span&gt;            }&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt; 121:  &lt;/span&gt;        }&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt; 122:  &lt;/span&gt;        &lt;span &gt;//发送完毕&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt; 123:  &lt;/span&gt;        &lt;span &gt;void&lt;/span&gt; ProcessSend(SocketAsyncEventArgs e)&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt; 124:  &lt;/span&gt;        {&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt; 125:  &lt;/span&gt;            &lt;span &gt;if&lt;/span&gt; (e.SocketError == SocketError.Success)&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt; 126:  &lt;/span&gt;            {&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt; 127:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt; 128:  &lt;/span&gt;                &lt;span &gt;if&lt;/span&gt; (!e.AcceptSocket.ReceiveAsync(e))&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt; 129:  &lt;/span&gt;                {&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt; 130:  &lt;/span&gt;                    &lt;span &gt;this&lt;/span&gt;.ProcessReceive(e);&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt; 131:  &lt;/span&gt;                }&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt; 132:  &lt;/span&gt;            }&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt; 133:  &lt;/span&gt;            &lt;span &gt;else&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt; 134:  &lt;/span&gt;            {&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt; 135:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt; 136:  &lt;/span&gt;            }&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt; 137:  &lt;/span&gt;        }&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt; 138:  &lt;/span&gt;    }&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt; 139:  &lt;/span&gt;     &lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt; 140:  &lt;/span&gt;}&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;上述代码run起来之后，打开cmd用telnet测试下即可&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;telnet 127.0.0.1 9900&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&#xD;
&lt;p&gt;顺便推荐一下园子兄弟写的一个框架实现了nio的rpc&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://shuttler.codeplex.com/"&gt;http://shuttler.codeplex.com/&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/overred/archive/2009/12/20/Shuttler_Net_2.html"&gt;http://www.cnblogs.com/overred/archive/2009/12/20/Shuttler_Net_2.html&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/wsky/aggbug/2007201.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/wsky/archive/2011/04/06/2007201.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/wsky/archive/2011/04/06/2007095.html</id><title type="text">stunnel+haproxy SSL以及问题记录</title><summary type="text">最近在用stunnel做透明代理，配合haproxy做ssl方案，在用户和原有的反向代理之间加入stunnel，这样可以让用户和stunnel之间走ssl，stunnel之后的真实web就不用负担https的开销。</summary><published>2011-04-06T10:03:00Z</published><updated>2011-04-06T10:03:00Z</updated><author><name>wsky</name><uri>http://www.cnblogs.com/wsky/</uri></author><link rel="alternate" href="http://www.cnblogs.com/wsky/archive/2011/04/06/2007095.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/wsky/archive/2011/04/06/2007095.html"/><content type="html">&lt;p&gt;最近在用stunnel做透明代理，配合haproxy做ssl方案，在用户和原有的反向代理之间加入stunnel，这样可以让用户和stunnel之间走ssl，stunnel之后的真实web就不用负担https的开销。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wsky/201104/201104061802319137.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wsky/201104/201104061802314469.png" width="411" height="136" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wsky/201104/201104061802315026.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wsky/201104/201104061802315582.png" width="312" height="282" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;记录一下配置过程和问题，以下安装方式在centos和ubuntu上都配置通过：&lt;/p&gt;  &lt;p&gt;首先先去stunnel官网上获取安装包，因为要给stunnel打haproxy的补丁，而haproxy官方提供的补丁目前版本是4.32的，所以stunnel选择4.32版本，官方提供的ftp上可以找到&lt;a href="http://www.cnblogs.com/wsky/admin/ftp://ftp.stunnel.org/stunnel/obsolete/4.x/"&gt;ftp://ftp.stunnel.org/stunnel/obsolete/4.x/&lt;/a&gt;，这里使用rsync同步对应的版本：&lt;/p&gt;  &lt;div &gt;   &lt;pre &gt;&lt;span &gt;   1:  rsync &lt;/span&gt;rsync.stunnel.org::stunnel/obsolete/4.x/stunnel-4.32.tar.gz stunnel-4.32.tar.gz&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   2:  &lt;/span&gt;wget http:&lt;span &gt;//haproxy.1wt.eu/download/patches/stunnel-4.32-xforwarded-for.diff&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   3:  &lt;/span&gt;tar -zxvf stunnel-4.32.tar.gz&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   4:  &lt;/span&gt;cd stunnel-4.32&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   5:  &lt;/span&gt;patch -p1 &amp;lt; ../stunnel-4.32-xforwarded-&lt;span &gt;for&lt;/span&gt;.diff&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   6:  &lt;/span&gt;./configure&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   7:  &lt;/span&gt;make &amp;amp;&amp;amp; make install&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
&#xD;
&#xD;
&#xD;
&#xD;
&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;在上述过程中如果出现&amp;quot;Couldn't find your SSL library installation dir&amp;quot;，是缺少openssl，安装后在进行上述过程即可：&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;apt-get install libcurl3-openssl-dev&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&#xD;
&lt;p&gt;或：&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;yum install openssl-devel&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
&#xD;
&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;配置stunnel.conf:&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;sslVersion=all&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   2:  &lt;/span&gt;fips=no&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   3:  &lt;/span&gt;cert=/usr/local/etc/stunnel/stunnel.pem&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   4:  &lt;/span&gt;CAfile=/usr/local/etc/stunnel/cacert.pem&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   5:  &lt;/span&gt;pid =/var/run/stunnel.pid&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   6:  &lt;/span&gt;setuid=root&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   7:  &lt;/span&gt;setgid=root&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   8:  &lt;/span&gt; &lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   9:  &lt;/span&gt;socket=l:TCP_NODELAY=1&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  10:  &lt;/span&gt;socket=r:TCP_NODELAY=1&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  11:  &lt;/span&gt;output=/var/log/stunnel.log&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  12:  &lt;/span&gt; &lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  13:  &lt;/span&gt;[https]&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  14:  &lt;/span&gt;accept=443&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  15:  &lt;/span&gt;connect=127.0.0.1:8080&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;  16:  &lt;/span&gt;TIMEOUTclose=0&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;  17:  &lt;/span&gt;xforwardedfor=yes&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&#xD;
&lt;div &gt;&amp;#160;&lt;/div&gt;&#xD;
&#xD;
&lt;p&gt;-----------------------------------------------------------------------------&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;搞定上面的步骤就可以运行了：&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;stunnel&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
&#xD;
&#xD;
&#xD;
&#xD;
&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;在运行stunel的时候若出现routines:FIPS_mode_set:fingerprint does not match错误，可以通过设置上述参数fips=no解决。若出现nobody权限，可设置：&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;chmod 755 /var/run/stunnel/&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
&#xD;
&#xD;
&#xD;
&#xD;
&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;-------------------------------------------------------------------------------&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;关于ssl证书&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;使用自己签发的证书：&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;openssl req -&lt;span &gt;new&lt;/span&gt; -x509 -days 365 -nodes -&lt;span &gt;out&lt;/span&gt; stunnel.pem -keyout stunnel.pem&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
&#xD;
&#xD;
&#xD;
&#xD;
&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;若是现有的证书导入pfx和CA(配置文件中设置对应的CAfile参数)：&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;openssl&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   2:  &lt;/span&gt;&lt;span &gt;//cer转pem&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   3:  &lt;/span&gt;openssl&amp;gt;x509 -&lt;span &gt;in&lt;/span&gt; cacert.cer -&lt;span &gt;out&lt;/span&gt; cacert.pem&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   4:  &lt;/span&gt;&lt;span &gt;//pfx转pem&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   5:  &lt;/span&gt;openssl&amp;gt;pkcs12 -&lt;span &gt;in&lt;/span&gt; stunnel.pfx -&lt;span &gt;out&lt;/span&gt; stunnel.pem -nodes&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
&#xD;
&#xD;
&#xD;
&#xD;
&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;通常为了简化证书的使用，我们会签发或购买如 *.xxx.org的证书，这样二级域名下的站点都可共用，要注意的是*.*.xxx.org是无效的&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;-------------------------------------------------------------------------------&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;其他&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;stunnel只能对linux机器进行代理&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;可以区分ip，ip+端口来代理 &lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;简单高效，系统利器：）&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&amp;#160;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;顺便附带haproxy安装：&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;在这里找你要安装的版本&lt;a href="http://haproxy.1wt.eu/download/1.4/src/"&gt;http://haproxy.1wt.eu/download/1.4/src/&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;以centos5安装为例：&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;wget http:&lt;span &gt;//haproxy.1wt.eu/download/1.4/src/haproxy-1.4.9.tar.gz  &lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   2:  &lt;/span&gt;tar -zxvf haproxy-1.4.9.tar.gz&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   3:  &lt;/span&gt;cd haproxy-1.4.9&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   4:  &lt;/span&gt;make TARGET=linux26 PREFIX=/usr/local/&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   5:  &lt;/span&gt;make install PREFIX=/usr/local/&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
&#xD;
&#xD;
&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;一些实际应用中的问题和解决方法&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;IE6下使用SSL通道时出现&amp;#8220;Page can not load&amp;#8221;问题，是由于openssl支持的问题，官方有一段FAQ：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wsky/201104/201104251210428813.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wsky/201104/201104251210423796.png" width="644" height="96" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a title="http://www.stunnel.org/?page=faq" href="http://www.stunnel.org/?page=faq"&gt;http://www.stunnel.org/?page=faq&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a title="http://www.daniweb.com/hardware-and-software/microsoft-windows/web-browsers/threads/50765" href="http://www.daniweb.com/hardware-and-software/microsoft-windows/web-browsers/threads/50765"&gt;http://www.daniweb.com/hardware-and-software/microsoft-windows/web-browsers/threads/50765&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;stunnel做了兼容，不过没有附上具体的解决方法，下面是解决方法，修改一下stunnel.conf配置文件即可：&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;ciphers=RC4-SHA&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   2:  &lt;/span&gt;options=DONT_INSERT_EMPTY_FRAGMENTS&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&#xD;
&lt;p&gt;顺便列一下IE6支持的加密方式以供选择（完整的可到openssl官网上查找）：&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;SSL_RSA_WITH_RC4_128_MD5&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;SSL_RSA_WITH_RC4_128_SHA &lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;SSL_RSA_WITH_3DES_EDE_CBC_SHA &lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;SSL2_CK_RC4 SSL2_CK_3DES &lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;SSL2_CK_RC2 SSL_RSA_WITH_DES_CBC_SHA &lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;SSL2_CK_DES SSL_RSA_EXPORT1024_WITH_RC4_56_SHA &lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA &lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;SSL_RSA_EXPORT_WITH_RC4_40_MD5 &lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 &lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;SSL2_CK_RC4_EXPORT40 &lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;SSL2_CK_RC2_EXPORT40 &lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA &lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;SSL_DHE_DSS_WITH_DES_CBC_SHA &lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;SSL_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;选取合适的加密算法即可，可以通过log来查看算法加载是否成功：&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;tail -f /var/log/stunnel.log&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wsky/201104/201104251210427700.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wsky/201104/201104251210426828.png" width="654" height="75" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;上图说明ciphers设置不正确，还要注意的是配置文件中的sslVersion会影响相关算法的匹配&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;-------------------------------------------------------------------------------------------------------&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;由于客户端到stuunel是ssl，haproxy到web走的是http，也就是说实际请求的url是http的，为了让web端能知晓客户端请求的url是http还是https，可通过如下配置：&lt;/p&gt;&#xD;
&#xD;
&lt;div &gt;&#xD;
  &lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;option forwardfor&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre&gt;&lt;span &gt;   2:  &lt;/span&gt;option httpclose&lt;/pre&gt;&#xD;
&#xD;
  &lt;pre &gt;&lt;span &gt;   3:  &lt;/span&gt;reqadd X-Forwarded-Proto:\ https&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&#xD;
&#xD;
&lt;p&gt;在web端可通过获取request header[&amp;#8220;X-Forwarded-Proto&amp;#8221;]来分辨&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;需要注意的是关于httpclose配置：若没有此项，只有第一次请求才会传递X-Forwarded，开启此项则无法keepalive,如无法windows验证&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;-------------------------------------------------------------------------------------------------------&lt;/p&gt;&#xD;
&#xD;
&lt;pre&gt;&lt;font face="微软雅黑"&gt;xp系统ie打补丁后，导致https无法打开的问题：&lt;/font&gt;&lt;/pre&gt;&#xD;
&#xD;
&lt;pre&gt;&lt;a href="http://www.microsoft.com/downloads/zh-cn/details.aspx?FamilyID=6429fd02-8138-4919-9942-80d62ecef22e&amp;amp;DisplayLang=zh-cn"&gt;&lt;font face="微软雅黑"&gt;http://www.microsoft.com/downloads/zh-cn/details.aspx?FamilyID=6429fd02-8138-4919-9942-80d62ecef22e&amp;amp;DisplayLang=zh-cn&lt;/font&gt;&lt;/a&gt;&lt;/pre&gt; &lt;img src="http://www.cnblogs.com/wsky/aggbug/2007095.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/wsky/archive/2011/04/06/2007095.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/wsky/archive/2010/12/17/1909146.html</id><title type="text">快速实现一个简单的bigpipe模型</title><summary type="text">其实重点在于模块化以及模块化之后随之带来的好处，功能开发分工，页面级别的功能隔离、功能降级等都可以以模块为单位进行，从而简化web项目的模型，在这个基础上再构建一系列的开发框架来支撑这种开发模式即可</summary><published>2010-12-17T04:48:00Z</published><updated>2010-12-17T04:48:00Z</updated><author><name>wsky</name><uri>http://www.cnblogs.com/wsky/</uri></author><link rel="alternate" href="http://www.cnblogs.com/wsky/archive/2010/12/17/1909146.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/wsky/archive/2010/12/17/1909146.html"/><content type="html">&lt;p&gt;在这篇&lt;a href="http://www.cnblogs.com/wsky/archive/2010/12/11/1902969.html"&gt;http://www.cnblogs.com/wsky/archive/2010/12/11/1902969.html&lt;/a&gt;文章中对facebook的bigpipe作了较长篇幅的描述，现在我们来快速实现一个简单的bigpipe模型&lt;/p&gt;&#xD;
&lt;p&gt;先描述几个概念：&lt;/p&gt;&#xD;
&lt;p&gt;Pagelet：页面功能模块化的单位&lt;/p&gt;&#xD;
&lt;p&gt;BigPipeClient：解释并呈现Pagelet的客户端，可以是javascript或服务器端语言编写（如c#）&lt;/p&gt;&#xD;
&lt;p&gt;其实重点在于模块化以及模块化之后随之带来的好处，功能开发分工，页面级别的功能隔离、功能降级等都可以以模块为单位进行，从而简化web项目的模型，在这个基础上再构建一系列的开发框架来支撑这种开发模式即可&lt;/p&gt;&#xD;
&lt;p&gt;先看一下Pagelet的定义：&lt;/p&gt;&#xD;
&lt;div &gt;&lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;    &lt;span &gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   2:  &lt;/span&gt;    &lt;span &gt;/// 模块&lt;/span&gt;&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;   3:  &lt;/span&gt;    &lt;span &gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   4:  &lt;/span&gt;    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; Pagelet&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;   5:  &lt;/span&gt;    {&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   6:  &lt;/span&gt;        &lt;span &gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;   7:  &lt;/span&gt;        &lt;span &gt;/// 模块标识&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   8:  &lt;/span&gt;        &lt;span &gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;   9:  &lt;/span&gt;        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;string&lt;/span&gt; Name { get; set; }&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  10:  &lt;/span&gt;        &lt;span &gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;  11:  &lt;/span&gt;        &lt;span &gt;/// 获取数据Url&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  12:  &lt;/span&gt;        &lt;span &gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;  13:  &lt;/span&gt;        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;string&lt;/span&gt; Url { get; set; }&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  14:  &lt;/span&gt;        &lt;span &gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;  15:  &lt;/span&gt;        &lt;span &gt;/// 目标容器&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  16:  &lt;/span&gt;        &lt;span &gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;  17:  &lt;/span&gt;        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;string&lt;/span&gt; Target { get; set; }&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  18:  &lt;/span&gt;        &lt;span &gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;  19:  &lt;/span&gt;        &lt;span &gt;/// HTML内容模板&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  20:  &lt;/span&gt;        &lt;span &gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;  21:  &lt;/span&gt;        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;string&lt;/span&gt; Template { get; set; }&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  22:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;  23:  &lt;/span&gt;        &lt;span &gt;//and so on&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  24:  &lt;/span&gt;    }&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;p&gt;它包含了模块的Html模板内容，呈现的位置，获取数据的地址等，&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wsky/201012/201012171248225264.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wsky/201012/201012171248227739.png" width="309" height="199" /&gt;&lt;/a&gt;这是一个pagelet实例，&lt;/p&gt;&#xD;
&lt;p&gt;然后编写一个页面，把这个页面需要的模块都输出到页面中：&lt;/p&gt;&#xD;
&lt;div &gt;&lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;   &lt;span &gt;&amp;lt;%&lt;/span&gt;&lt;span &gt;foreach&lt;/span&gt; (var let &lt;span &gt;in&lt;/span&gt; ViewData[&lt;span &gt;"pagelets"&lt;/span&gt;] &lt;span &gt;as&lt;/span&gt; IEnumerable&amp;lt;BigPipe.Controllers.Pagelet&amp;gt;)&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   2:  &lt;/span&gt;      { &lt;span &gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;   3:  &lt;/span&gt;      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;script&lt;/span&gt; &lt;span &gt;type&lt;/span&gt;&lt;span &gt;="text/javascript"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   4:  &lt;/span&gt;          $(&lt;span &gt;function&lt;/span&gt; () {&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;   5:  &lt;/span&gt;            &amp;lt;%=&lt;span &gt;"client.add("&lt;/span&gt; + &lt;span &gt;new&lt;/span&gt; JavaScriptSerializer().Serialize(let) + &lt;span &gt;");"&lt;/span&gt; %&amp;gt;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   6:  &lt;/span&gt;          });&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;   7:  &lt;/span&gt;      &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;script&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   8:  &lt;/span&gt;    &lt;span &gt;&amp;lt;%&lt;/span&gt;}&lt;span &gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;BigPipe.js客户端的简易实现：&lt;/p&gt;&#xD;
&lt;div &gt;&lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;(&lt;span &gt;function&lt;/span&gt; ($) {&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   2:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;   3:  &lt;/span&gt;    &lt;span &gt;//pagelets holder&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   4:  &lt;/span&gt;    &lt;span &gt;var&lt;/span&gt; pagelets = {};&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;   5:  &lt;/span&gt;    &lt;span &gt;//bipipe&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   6:  &lt;/span&gt;    &lt;span &gt;var&lt;/span&gt; bigpipe = &lt;span &gt;function&lt;/span&gt; () { &lt;span &gt;this&lt;/span&gt;._init.apply(&lt;span &gt;this&lt;/span&gt;, arguments); };&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;   7:  &lt;/span&gt;    bigpipe.prototype = {&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   8:  &lt;/span&gt;        _init: &lt;span &gt;function&lt;/span&gt; () { },&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;   9:  &lt;/span&gt;        add: &lt;span &gt;function&lt;/span&gt; (let) {&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  10:  &lt;/span&gt;            pagelets[let[&lt;span &gt;'Name'&lt;/span&gt;]] = let;&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;  11:  &lt;/span&gt;            $.getJSON(let[&lt;span &gt;'Url'&lt;/span&gt;], &lt;span &gt;function&lt;/span&gt; (data) {&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  12:  &lt;/span&gt;                $(&lt;span &gt;'#'&lt;/span&gt; + let[&lt;span &gt;'Target'&lt;/span&gt;]).append(let[&lt;span &gt;'Template'&lt;/span&gt;]&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;  13:  &lt;/span&gt;                    .replace(&lt;span &gt;'${name}'&lt;/span&gt;, data[&lt;span &gt;'name'&lt;/span&gt;])&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  14:  &lt;/span&gt;                    .replace(&lt;span &gt;'${description}'&lt;/span&gt;, data[&lt;span &gt;'description'&lt;/span&gt;]));&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;  15:  &lt;/span&gt;            });&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  16:  &lt;/span&gt;        }&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;  17:  &lt;/span&gt;    }&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  18:  &lt;/span&gt;    window.client = &lt;span &gt;new&lt;/span&gt; bigpipe();&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;  19:  &lt;/span&gt;})(jQuery);&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;p&gt;调用add的时候将pagelet加入客户端缓存，同时执行ajax请求数据并和html模板装配后呈现到指定位置&#xD;
&lt;style type="text/css"&gt;&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;本文实现了两种呈现方式的pagelet：服务器端并行push和客户端pull方式&lt;/p&gt;&#xD;
&lt;p&gt;下图为使用bigpipe.js客户端进行ajax pull方式拉取数据并呈现pagelet&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wsky/201012/201012171248222723.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wsky/201012/201012171248227150.png" width="469" height="212" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;生成的pagelet内容如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wsky/201012/201012171248223213.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wsky/201012/201012171248231544.png" width="644" height="132" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;下图为使用服务器端并行push多个pagelet内容并呈现，可以看到模块并不会按顺序加载，而是根据各自加载情况决定顺序，这样可以使得更快被处理完的模块立刻被呈现给用户：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wsky/201012/201012171248234019.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wsky/201012/201012171248238131.png" width="465" height="234" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;原理就是对respone并行写入内容并立刻flush到客户端：&lt;/p&gt;&#xD;
&lt;div &gt;&lt;pre &gt;&lt;span &gt;   1:  &lt;/span&gt;context.Response.Write(&lt;span &gt;string&lt;/span&gt;.Format(&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   2:  &lt;/span&gt;                &lt;span &gt;"&amp;lt;script type=\"text/javascript\"&amp;gt;client.add({0});&amp;lt;/script&amp;gt;"&lt;/span&gt;&lt;/pre&gt;&lt;pre &gt;&lt;span &gt;   3:  &lt;/span&gt;                , &lt;span &gt;new&lt;/span&gt; JavaScriptSerializer().Serialize(let)));&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   4:  &lt;/span&gt;            context.Response.Flush();&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;本文只简易实现了pagelet的处理模型，描述一下思路，相信有思路之后针对各自的应用或项目情况编写一套合适模块化框架会有些益处的&lt;/p&gt;&#xD;
&lt;p&gt;在完成bigpipe加载后，pageCache以及记录回放等在浏览器中的优化技巧也是很有意思的，之后会尝试做一些实现&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;DEMO源码可以在这里下载：&lt;a href="https://github.com/wsky/wsky.github.com/tree/master/bigpipe"&gt;https://github.com/wsky/wsky.github.com/tree/master/bigpipe&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;DEMO中用到简单并行实现：&lt;a href="http://www.cnblogs.com/wsky/archive/2009/12/23/1630548.html"&gt;http://www.cnblogs.com/wsky/archive/2009/12/23/1630548.html&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/wsky/aggbug/1909146.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/wsky/archive/2010/12/17/1909146.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/wsky/archive/2010/12/11/1902969.html</id><title type="text">Velocity2010大会回顾</title><summary type="text">velocity 2010 北京之行收获良多，选择的几个session都很有料，当然也有个别还是比较虚这次大会主题是web性能和运维，主题也基本分为两大块：web前端性能，分布式接下来就把我参加的session逐个回顾一下：简述一下facebook的bigpipe技术等</summary><published>2010-12-11T06:30:00Z</published><updated>2010-12-11T06:30:00Z</updated><author><name>wsky</name><uri>http://www.cnblogs.com/wsky/</uri></author><link rel="alternate" href="http://www.cnblogs.com/wsky/archive/2010/12/11/1902969.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/wsky/archive/2010/12/11/1902969.html"/><content type="html">&lt;p&gt;velocity 2010 北京之行收获良多，选择的几个session都很有料，当然也有个别还是比较虚&lt;/p&gt;  &lt;p&gt;这次大会主题是web性能和运维，主题也基本分为两大块：web前端性能，分布式&lt;/p&gt;  &lt;p&gt;接下来就把我参加的session逐个回顾一下：&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="https://docs.google.com/viewer?url=http://velocity.oreilly.com.cn/ppts/ChanghaoJiang.pdf"&gt;《Facebook网站的Ajax化、缓存和流水线 》Changhao Jiang(Facebook)&lt;/a&gt;&lt;/p&gt;  &lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;   &lt;p&gt;&lt;em&gt;在这个报告中，我将介绍在Facebook网站前端性能优化中采用的最主要的一些技术。这些技术不光降低了服务器的开销，而且同时极大地提高了Facebook网站的用户体验性能。&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;我将首先介绍Quickling技术。通过Quickling，Facebook将所有的用户点击访问自动地转变成AJAX调用，避免了大量的服务器端重复计算和客户端的重复渲染。       &lt;br /&gt;然后我将介绍基于Quickling的PageCache技术，通过JavaScript自动缓存用户访问过的页面，极大的加速Facebook主页的性能并降低服务器开销。        &lt;br /&gt;最后，我将介绍BigPipe技术，通过采用微处理器内的流水线技术，将Facebook网站用户感知性能加速一倍以上。&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;a href="https://docs.google.com/viewer?url=http://velocity.oreilly.com.cn/ppts/VelocityChina2010Dec7StaticResource.pdf"&gt;《静态网页资源的管理和优化》David Wei(Facebook)&lt;/a&gt;&lt;/p&gt;  &lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;   &lt;p&gt;&lt;em&gt;静态网页资源包括Javascript、CSS和图标图片，它们是现代网站不可缺少的部分。而这部分的性能又直接影响了网页的速度。在这个讲座里，我将与大家分享我们在静态网页资源的管理和优化上的经验。Facebook的五亿活跃用户来自五湖四海：不同文化、不同的语言、不同的网络链接质量。巨大的用户差异性给我们的静态网页资源管理提出了很多新的挑战。这个讲座将围绕这些挑战讨论：&lt;/em&gt;&lt;/p&gt;    &lt;ol&gt;     &lt;li&gt;&lt;em&gt;系统架构：为全公司开发团队的提供简易透明的固态网页资源编程接口； &lt;/em&gt;&lt;/li&gt;      &lt;li&gt;&lt;em&gt;系统扩展性：研发一个可扩展的固态资源管理，以满足不断增长的网站功能、不断增加的用户语言和不断变化的个性化策略 &lt;/em&gt;&lt;/li&gt;      &lt;li&gt;&lt;em&gt;自适应性：为固态资源管理研发自适应的优化模块，让系统随功能的增减和用户使用方式的变化自动调节，几乎不需要人力干预。&lt;/em&gt;&lt;/li&gt;   &lt;/ol&gt; &lt;/blockquote&gt;  &lt;p&gt;facebook本次的几个分享都相当给力，绝对让听的人不虚此行，想必对fb的bigpipe技术早有耳闻，这次算是大揭秘了，把技术细节和思路都详细介绍并用实例进行了说明&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wsky/201012/201012111429384437.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wsky/201012/201012111429394927.png" width="328" height="94" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;上图就是fb的前端优化使用到的三个主要技术，Quickling是他们的异步（ajax）框架，用于整个fb网站的ajax化，&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wsky/201012/201012111429393815.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wsky/201012/201012111429395418.png" width="375" height="199" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;使用过fb的话可以发现，网站在页面切换过程中并不像传统页面加载一样，进入一个新页面浏览器就整个页面重新渲染，特别是当你点击后退的时候，上一个页面几乎是立刻出现的，这里便是quickling+pagecache的优化，quickling负责在切换页面的时候清空主体内容区域，发送ajax加载新的内容，下载需要的JavaScript、CSS等资源，然后呈现新的页面，被清空的页面被保存在pagecache中，当用户点击后退的时候立刻从中恢复上一个页面，他们在这个过程中还模拟了浏览器加载效果，地址变换等。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wsky/201012/201012111429404305.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wsky/201012/201012111429406780.png" width="244" height="222" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;上面描述了要实现这样一个页面前端处理模型所使用到的具体技术细节，要模拟游览器前进后退行为，因而需要记录用户的操作历史，在同一个窗口频繁加载卸载页面，页面中积累了大量的css资源，也需要能够在不需要的时候被卸载掉，一些settimeout定时器也需要被管理，在切换页面的时候被重置或移除。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wsky/201012/201012111429409256.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wsky/201012/201012111429409222.png" width="437" height="184" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;在使用quickling+pagecache提升性能的同时，也存在一些挑战：&lt;/p&gt;  &lt;p&gt;被缓存的页面和用户当前操作的页面存在数据关联时如何同步pagecahce？缓存一致性如何保障？&lt;/p&gt;  &lt;p&gt;fb的用户主页（home）有用户的动态（新鲜事），会随着用户在其他页面的操作而产生更新，当home被从缓存中重建后如何知晓这个变化并作出更新的呢？&lt;/p&gt;  &lt;p&gt;这里使用到了一个&amp;#8220;replayable&amp;#8221;记录重播技术来解决这个问题：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wsky/201012/201012111429413650.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wsky/201012/201012111429412711.png" width="472" height="207" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;所有的ajax post调用均会被记录，在缓存页面被重新呈现的时候，进行&amp;#8220;重播&amp;#8221;，来达到更新的效果，pagecache本身也提供了callback机制，在重建页面的时候允许指定执行一些额外的动作&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wsky/201012/201012111429429647.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wsky/201012/201012111429426582.png" width="244" height="50" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;最后一个bigpipe，前面2个技术加上这个，算是把web前端性能做到极致了，bigpipe更带来了工程上的意义，在达到优化页面并行加载的同时，模块化的开发也让fb的优雅降级，分工，超短周期迭代成为可能。&lt;/p&gt;  &lt;p&gt;讲bigpipe之前，先需要介绍pagelet，&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wsky/201012/201012111429426549.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wsky/201012/201012111429437530.png" width="405" height="225" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;pagelet就是作为模块的单位，定义了一个模块需要的js,css,html等信息，bigpipe.js便作为一个客户端按照pagelet的信息来解释并呈现一个个模块，&lt;/p&gt;  &lt;p&gt;值得一提的是，pagelet在模块化的同时，还提供了高级特性，比如：嵌套，优先级，关联性等，来满足应用层面的需求，使用上，对php而言，只是继承一个pagelet基类，提供该有信息，然后再在bigpipe客户端注册这个pagelet。&lt;/p&gt;  &lt;p&gt;这次大会的几个主题还有一个共同点就是：都在努力设计和实现一个适合于自己业务的框架或平台，使得这种性能优化等最佳实践可以被传播应用在任何一个具体业务应用中，而无须让产品开发者过多关注，可以简易的被使用而达到好的效果，并通过架构约束来实现大型团队的开发模式管理，fb的另外一个静态资源优化方面的主题就是一个很好例子&lt;/p&gt;  &lt;p&gt;静态资源管理，看似简单，而fb算是做到极致了，之前也曾思考并尝试一些方式来做自动化的资源管理，但离fb的深入度还是差一个量级~&lt;/p&gt;  &lt;p&gt;自动化的伸缩性，自适应性，用节点模型来描述资源，通过绘制节点关系图，和引用计数等方式生成一张成本/收益图来自动进行决策，从而自动的进行打包并输出给客户端，同时还会根据用户的区域，语言等信息，选取合适的资源进行打包&lt;/p&gt;  &lt;p&gt;在开发使用上，通过开发人员的注释约定识别这种引用关系，监控各种资源文件的使用情况&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;《腾讯相册存储系统》 谢明 (腾讯)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;低调的tx的分享，全场爆满，听后不得不说是一个让人敬畏的对手&lt;/p&gt;  &lt;p&gt;tx的TFS分为LogFileSystem和ImageFileSystem，相册会生成多种规格的图片，他们也有自己的KV叫TDB，值得一提的是TFS是直接读写裸设备，他们也同样大量定制自己规格的server，存储等&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;《构建高性能的MySQL系统》 杨海朝(新浪)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;海量数据已经是近年来很火的话题了，使得存储，数据库的话题备受关注，特别是云存储概念出来后，各种热议，国内的各大互联网公司也都开始有大规模的实践案例&lt;/p&gt;  &lt;p&gt;不过这位sina的首席DBA没有往大的讲，而是选择讲了一些MySql优化原则方面的东西，介绍了MYSQL的两个表存储引擎MyISAM和InnoDB的差异和使用场景，&lt;/p&gt;  &lt;p&gt;前者关系型，不适合做HA，因为一旦down了之后repaire时间太长，锁级别是tablelock&lt;/p&gt;  &lt;p&gt;后者适合大字段R/W高的，具有高可用性高并发，锁级别是rowlock&lt;/p&gt;  &lt;p&gt;索引个数在3-5个以内合适，在需要的时候覆盖索引可以获得很好的性能，如sort,count，组合索引要注意索引和列的次序&lt;/p&gt;  &lt;p&gt;MySql特别适合分布式场景，读写分离架构下甚至可以让M、S使用不同的存储引起来根据场景优化&lt;/p&gt;  &lt;p&gt;对于应用，有一个重要观点就是：对于应用层面应该弱化DB，只需要认为DB是一个存储即可，这样的设计才能做到scacle-out,说到这点，再加上盛大创新院许式伟的《分布式存储与Web服务伸缩性》，基本上可以说，存储还是让有资源的巨头去捣腾吧，关注应用才是更能快速获取价值的：）&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;《构建Yahoo下一代Mail》 Daniel Hunt(Yahoo!)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;从几场老外的主题里，基本得出一个结论，他们对性能和体验的重视程度远高于国内企业&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;《卷土重来：服务器端JavaScript》 Douglas Crockford(Yahoo!)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;老道的主题自然吸引无数人，服务器端js也是近期火起来的话题了，只是实在不懂为什么是在chrome的v8引擎起来了才火了，相信js的语言魅力已经让大多数web开发者爱上它了，而今让它不仅跑在浏览器里，还能run在server上，让server编程也获得事件模型的好处，是不是很让人兴奋？&lt;/p&gt;  &lt;p&gt;node.js是一个尝试，之后准备关注一下，其实乍一看这个标题，你可能或想到另外一种解释：浏览器不支持js的时候让它跑在服务器端，这样是不是更有吸引力？恰巧这个想法在yahoo的《构建Yahoo下一代Mail》中有提高，用户多样性使得他们必须满足这种情况，他们因此提供了这样一种模型来支撑这种编程模型，让你只需要知晓一个中间语言，从而能编写出client or server script，很诱人吧，所以这个也准备去关注了。&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;《Facebook: 一个可持续发展的高性能网站》 David Wei(Facebook)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;这个主题就是上文提到的一个观点的完整版，用架构去支撑你的网站持续的发展，保持简单，而又能获得性能的收益。Fase By Default（与生俱来的快）&lt;/p&gt;  &lt;p&gt;我归纳的几点：&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;数据驱动，获取足够的数据来支撑你的优化决策，要让性能工作可以被测量&lt;/li&gt;    &lt;li&gt;让开发人员遵循简单的约定就可以编写出高性能的应用&lt;/li&gt;    &lt;li&gt;不符合约定的代码应越早被发现，开发过程中就要暴露出来，这要求你的框架有这样严谨的支持&lt;/li&gt;    &lt;li&gt;减少人工的，临时的优化工作，通过建立各种模型来提供支持&lt;/li&gt;    &lt;li&gt;组件化，模块化，丰富的开发参考文档，便于使用和理解的代码片段参考&lt;/li&gt;    &lt;li&gt;隐藏细节，让性能小组、架构者获得主动权&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;还有几个技巧点：&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;把脚本作为文本加载避免阻塞&lt;/li&gt;    &lt;li&gt;利用iframe的沙箱环境来实现一些缓存，预加载之类的效果&lt;/li&gt;    &lt;li&gt;用new Image()来预加载js&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;《分布式存储与Web服务伸缩性》 许式伟(盛大创新院)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;最深的印象是：存储不是谁都需要去做的，太消耗脑细胞，对创业者的规劝&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;《移动互联网内容平台的架构与性能优化》 孙立(凤凰网)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;很务实的一位speaker，把ifeng的IMCP平台架构描述的清清楚楚，他们的场景使得CodeOnline尤为合适，人员成本，开发管理等思想也是我比较倾向的。&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;《CWF：C++用于web开发的实践》 邵军辉(人人网)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;很有意思的哥们，号称愿望是让C++在web开发有一席之地，对于Mashup比较感兴趣，所以特地来听了这场，确实有不少的亮点，CTemplate号称没有XSS问题，&lt;/p&gt;  &lt;p&gt;这场让我看到了主流web技术之外的实践，算是偏好+性能追求极致的实践吧&lt;/p&gt;  &lt;p&gt;不过自行构建这样一个web框架，一系列的工具都需要自行开发，同时还要考虑开发成本，难度等，不容易啊&lt;/p&gt;  &lt;p&gt;这也让我想到：各种各样的团队，主导者往往有这样的幸运能够有机会能主导自己的架构，并组建一个团队共同发展，不过这个发展一旦主导者离开而没有能够完成足够的沉淀，恐怕之后很难维持吧&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;IE9&amp;amp;Mozilla Firefox4&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;两个知名浏览器在同一个屋檐下宣传，相敬如宾啊，哈&lt;/p&gt;  &lt;p&gt;IE9演示了GPU加速的性能，和chrome对比，让现场如此多的google迷情何以堪啊&amp;#8230;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;PPT下载：&lt;a href="http://velocity.oreilly.com.cn/index.php?func=slidesvideos"&gt;http://velocity.oreilly.com.cn/index.php?func=slidesvideos&lt;/a&gt;&lt;/p&gt;&lt;p&gt;视频：&lt;a href="http://www.youku.com/playlist_show/id_5333814.html"&gt;http://www.youku.com/playlist_show/id_5333814.html&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/wsky/aggbug/1902969.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/wsky/archive/2010/12/11/1902969.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/wsky/archive/2010/10/11/1848289.html</id><title type="text">小结一下关于bpm实施方面的交流</title><summary type="text">下午部门和几位资深专家交流了一个下午，了解了一下对方在国内几家大型企业做BPM实施和工作流产品构建的心得，小结一下，他人的见解结合自身的分析： 需求调研，业务分析设计在项目中的占比和重要最高，业务是最有价值和最需要被关注的，同时它复杂也难以整理，获取最高层的支持很重要 几个视图来帮助分析和全面的反应你的项目状况和期望成效：流程视图，数据视图，逻辑视图 技术框架很重要，严谨和健壮的设计来支撑系统，同...</summary><published>2010-10-11T14:20:00Z</published><updated>2010-10-11T14:20:00Z</updated><author><name>wsky</name><uri>http://www.cnblogs.com/wsky/</uri></author><link rel="alternate" href="http://www.cnblogs.com/wsky/archive/2010/10/11/1848289.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/wsky/archive/2010/10/11/1848289.html"/><content type="html">&lt;p&gt;下午部门和几位资深专家交流了一个下午，了解了一下对方在国内几家大型企业做BPM实施和工作流产品构建的心得，小结一下，他人的见解结合自身的分析：&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;需求调研，业务分析设计在项目中的占比和重要最高，业务是最有价值和最需要被关注的，同时它复杂也难以整理，获取最高层的支持很重要&lt;/li&gt;    &lt;li&gt;几个视图来帮助分析和全面的反应你的项目状况和期望成效：流程视图，数据视图，逻辑视图&lt;/li&gt;    &lt;li&gt;技术框架很重要，严谨和健壮的设计来支撑系统，同时这也是成本控制和团队建设方向的重要一环&lt;/li&gt;    &lt;li&gt;流程开发工作也重要，但这一块工作是可以通过需求（上层）和架构（下层设施）来简化和弱化的，它不应该是IT部门的重点，外包可能是更合理的方案&lt;/li&gt;    &lt;li&gt;流程的深度广度应该在项目启动前就被明确，不同层次投入不同的成本，过度承诺毫无意义，长期只停留于浅的层次，追求数量也毫无意义，这种项目只有上升到管理层面，真正的提供管理，控制，决策支持才能放大项目和你的价值，否则你只是工人&lt;/li&gt;    &lt;li&gt;电子化--&amp;gt;BPR--&amp;gt;Controller--&amp;gt;KPI&lt;/li&gt;    &lt;li&gt;流程链，流程组：我们不是在接需求，而是给业务方提供咨询和建议，优化业务流程，应该提出有管理价值的建议，如果这个东西不是你该有职责，你或许可以交给其他部门去完成，关注你该关注的&lt;/li&gt;    &lt;li&gt;不要吝啬在流程分析上投入的时间，因为不只是分析需求方告诉你的东西，而是要挖掘更大的流程价值，沿着链条往上，得到最完整的业务模型，并把它列入你的计划里&lt;/li&gt;    &lt;li&gt;做流程，是要创造价值，更是为你的老板服务：）&lt;/li&gt;    &lt;li&gt;做流程，你要耐得住~也要有魄力~&lt;/li&gt; &lt;/ol&gt;&lt;img src="http://www.cnblogs.com/wsky/aggbug/1848289.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/wsky/archive/2010/10/11/1848289.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
