<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[张宴的博客]]></title> 
<link>http://blog.s135.com/index.php</link> 
<description><![CDATA[Web系统架构与底层研发]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[张宴的博客]]></copyright>
<item>
<link>http://blog.s135.com/file_get_contents/</link>
<title><![CDATA[PHP-CGI 进程 CPU 100% 与 file_get_contents 函数的关系]]></title> 
<author>张宴 &lt;net@s135.com&gt;</author>
<category><![CDATA[Web服务器]]></category>
<pubDate>Fri, 05 Aug 2011 07:33:05 +0000</pubDate> 
<guid>http://blog.s135.com/file_get_contents/</guid> 
<description>
<![CDATA[ 
	　　[文章作者：张宴 本文版本：v1.0 最后修改：2011.08.05 转载请注明原文链接：<a href="http://blog.s135.com/file_get_contents/" target="_blank">http://blog.s135.com/file_get_contents/</a>]<br/><br/>　　有时候，运行 Nginx、PHP-CGI(php-fpm) Web服务的 Linux 服务器，突然系统负载上升，使用 top 命令查看，很多 php-cgi 进程 CPU 使用率接近100%。后来，我通过跟踪发现，这类情况的出现，跟 PHP 的 file_get_contents() 函数有着密切的关系。<br/><br/>　　大、中型网站中，基于 HTTP 协议的 API 接口调用，是家常便饭。PHP 程序员们喜欢使用简单便捷的 file_get_contents("http://example.com/") 函数，来获取一个 URL 的返回内容，但是，如果 <a href="http://example.com/" target="_blank">http://example.com/</a> 这个网站响应缓慢，file_get_contents() 就会一直卡在那儿，不会超时。<br/><br/>　　我们知道，在 php.ini 中，有一个参数 max_execution_time 可以设置 PHP 脚本的最大执行时间，但是，在 php-cgi(php-fpm) 中，该参数不会起效。真正能够控制 PHP 脚本最大执行时间的是 php-fpm.conf 配置文件中的以下参数：<br/><textarea name="code" class="xml" rows="15" cols="100">The timeout (in seconds) for serving a single request after which the worker process will be terminated
Should be used when 'max_execution_time' ini option does not stop script execution for some reason
'0s' means 'off'
<value name="request_terminate_timeout">0s</value></textarea>　　默认值为 0 秒，也就是说，PHP 脚本会一直执行下去。这样，当所有的 php-cgi 进程都卡在 file_get_contents() 函数时，这台 Nginx+PHP 的 WebServer 已经无法再处理新的 PHP 请求了，Nginx 将给用户返回“502 Bad Gateway”。修改该参数，设置一个 PHP 脚本最大执行时间是必要的，但是，治标不治本。例如改成 &lt;value name=&quot;request_terminate_timeout&quot;&gt;30s&lt;/value&gt;，如果发生 file_get_contents() 获取网页内容较慢的情况，这就意味着 150 个 php-cgi 进程，每秒钟只能处理 5 个请求，WebServer 同样很难避免“502 Bad Gateway”。<br/><br/>　　要做到彻底解决，只能让 PHP 程序员们改掉直接使用 file_get_contents("http://example.com/") 的习惯，而是稍微修改一下，加个超时时间，用以下方式来实现 HTTP GET 请求。要是觉得麻烦，可以自行将以下代码封装成一个函数。<br/><textarea name="code" class="php" rows="15" cols="100"><?php
$ctx = stream_context_create(array(
&nbsp;&nbsp; 'http' => array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'timeout' => 1 //设置一个超时时间，单位为秒
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )
&nbsp;&nbsp; )
);
file_get_contents("http://example.com/", 0, $ctx);
?></textarea>　　当然，导致 php-cgi 进程 CPU 100% 的原因不只有这一种，那么，怎么确定是 file_get_contents() 函数导致的呢？<br/><br/>　　首先，使用 top 命令查看 CPU 使用率较高的 php-cgi 进程。<br/><br/><div class="code">top - 10:34:18 up 724 days, 21:01,&nbsp;&nbsp;3 users,&nbsp;&nbsp;load average: 17.86, 11.16, 7.69<br/>Tasks: 561 total,&nbsp;&nbsp;15 running, 546 sleeping,&nbsp;&nbsp; 0 stopped,&nbsp;&nbsp; 0 zombie<br/>Cpu(s):&nbsp;&nbsp;5.9%us,&nbsp;&nbsp;4.2%sy,&nbsp;&nbsp;0.0%ni, 89.4%id,&nbsp;&nbsp;0.2%wa,&nbsp;&nbsp;0.0%hi,&nbsp;&nbsp;0.2%si,&nbsp;&nbsp;0.0%st<br/>Mem:&nbsp;&nbsp; 8100996k total,&nbsp;&nbsp;4320108k used,&nbsp;&nbsp;3780888k free,&nbsp;&nbsp; 772572k buffers<br/>Swap:&nbsp;&nbsp;8193108k total,&nbsp;&nbsp;&nbsp;&nbsp;50776k used,&nbsp;&nbsp;8142332k free,&nbsp;&nbsp; 412088k cached<br/><br/>&nbsp;&nbsp;PID USER&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PR&nbsp;&nbsp;NI&nbsp;&nbsp;VIRT&nbsp;&nbsp;RES&nbsp;&nbsp;SHR S %CPU %MEM&nbsp;&nbsp;&nbsp;&nbsp;TIME+&nbsp;&nbsp;COMMAND&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>10747 www&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 18&nbsp;&nbsp; 0&nbsp;&nbsp;360m&nbsp;&nbsp;22m&nbsp;&nbsp;12m R 100.6 0.3&nbsp;&nbsp;&nbsp;&nbsp;0:02.60 php-cgi&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>10709 www&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 16&nbsp;&nbsp; 0&nbsp;&nbsp;359m&nbsp;&nbsp;28m&nbsp;&nbsp;17m R 96.8&nbsp;&nbsp;0.4&nbsp;&nbsp;&nbsp;&nbsp;0:11.34 php-cgi&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>10745 www&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 18&nbsp;&nbsp; 0&nbsp;&nbsp;360m&nbsp;&nbsp;24m&nbsp;&nbsp;14m R 94.8&nbsp;&nbsp;0.3&nbsp;&nbsp;&nbsp;&nbsp;0:39.51 php-cgi&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>10707 www&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 18&nbsp;&nbsp; 0&nbsp;&nbsp;360m&nbsp;&nbsp;25m&nbsp;&nbsp;14m S 77.4&nbsp;&nbsp;0.3&nbsp;&nbsp;&nbsp;&nbsp;0:33.48 php-cgi&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>10782 www&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 20&nbsp;&nbsp; 0&nbsp;&nbsp;360m&nbsp;&nbsp;26m&nbsp;&nbsp;15m R 75.5&nbsp;&nbsp;0.3&nbsp;&nbsp;&nbsp;&nbsp;0:10.93 php-cgi&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>10708 www&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 25&nbsp;&nbsp; 0&nbsp;&nbsp;360m&nbsp;&nbsp;22m&nbsp;&nbsp;12m R 69.7&nbsp;&nbsp;0.3&nbsp;&nbsp;&nbsp;&nbsp;0:45.16 php-cgi&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>10683 www&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 25&nbsp;&nbsp; 0&nbsp;&nbsp;362m&nbsp;&nbsp;28m&nbsp;&nbsp;15m R 54.2&nbsp;&nbsp;0.4&nbsp;&nbsp;&nbsp;&nbsp;0:32.65 php-cgi&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>10711 www&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 25&nbsp;&nbsp; 0&nbsp;&nbsp;360m&nbsp;&nbsp;25m&nbsp;&nbsp;15m R 52.2&nbsp;&nbsp;0.3&nbsp;&nbsp;&nbsp;&nbsp;0:44.25 php-cgi&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>10688 www&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 25&nbsp;&nbsp; 0&nbsp;&nbsp;359m&nbsp;&nbsp;25m&nbsp;&nbsp;15m R 38.7&nbsp;&nbsp;0.3&nbsp;&nbsp;&nbsp;&nbsp;0:10.44 php-cgi&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>10719 www&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 25&nbsp;&nbsp; 0&nbsp;&nbsp;360m&nbsp;&nbsp;26m&nbsp;&nbsp;16m R&nbsp;&nbsp;7.7&nbsp;&nbsp;0.3&nbsp;&nbsp;&nbsp;&nbsp;0:40.59 php-cgi</div><br/>　　找其中一个 CPU 100% 的 php-cgi 进程的 PID，用以下命令跟踪一下：<br/><div style="border-left: 0px dashed #D6C094; margin: 5px; padding: 3px; margin-bottom:0px; border: 1px dashed #00a0c6; background-color: #ffffff;">strace -p 10747</div><br/>　　如果屏幕显示：<br/><div class="code">select(7, &#91;6&#93;, &#91;6&#93;, &#91;&#93;, &#123;15, 0&#125;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 1 (out &#91;6&#93;, left &#123;15, 0&#125;)<br/>poll(&#91;&#123;fd=6, events=POLLIN&#125;&#93;, 1, 0)&nbsp;&nbsp;&nbsp;&nbsp; = 0 (Timeout)<br/>select(7, &#91;6&#93;, &#91;6&#93;, &#91;&#93;, &#123;15, 0&#125;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 1 (out &#91;6&#93;, left &#123;15, 0&#125;)<br/>poll(&#91;&#123;fd=6, events=POLLIN&#125;&#93;, 1, 0)&nbsp;&nbsp;&nbsp;&nbsp; = 0 (Timeout)<br/>select(7, &#91;6&#93;, &#91;6&#93;, &#91;&#93;, &#123;15, 0&#125;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 1 (out &#91;6&#93;, left &#123;15, 0&#125;)<br/>poll(&#91;&#123;fd=6, events=POLLIN&#125;&#93;, 1, 0)&nbsp;&nbsp;&nbsp;&nbsp; = 0 (Timeout)<br/>select(7, &#91;6&#93;, &#91;6&#93;, &#91;&#93;, &#123;15, 0&#125;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 1 (out &#91;6&#93;, left &#123;15, 0&#125;)<br/>poll(&#91;&#123;fd=6, events=POLLIN&#125;&#93;, 1, 0)&nbsp;&nbsp;&nbsp;&nbsp; = 0 (Timeout)<br/>select(7, &#91;6&#93;, &#91;6&#93;, &#91;&#93;, &#123;15, 0&#125;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 1 (out &#91;6&#93;, left &#123;15, 0&#125;)<br/>poll(&#91;&#123;fd=6, events=POLLIN&#125;&#93;, 1, 0)&nbsp;&nbsp;&nbsp;&nbsp; = 0 (Timeout)<br/>select(7, &#91;6&#93;, &#91;6&#93;, &#91;&#93;, &#123;15, 0&#125;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 1 (out &#91;6&#93;, left &#123;15, 0&#125;)<br/>poll(&#91;&#123;fd=6, events=POLLIN&#125;&#93;, 1, 0)&nbsp;&nbsp;&nbsp;&nbsp; = 0 (Timeout)<br/>select(7, &#91;6&#93;, &#91;6&#93;, &#91;&#93;, &#123;15, 0&#125;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 1 (out &#91;6&#93;, left &#123;15, 0&#125;)<br/>poll(&#91;&#123;fd=6, events=POLLIN&#125;&#93;, 1, 0)&nbsp;&nbsp;&nbsp;&nbsp; = 0 (Timeout)<br/>select(7, &#91;6&#93;, &#91;6&#93;, &#91;&#93;, &#123;15, 0&#125;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 1 (out &#91;6&#93;, left &#123;15, 0&#125;)<br/>poll(&#91;&#123;fd=6, events=POLLIN&#125;&#93;, 1, 0)&nbsp;&nbsp;&nbsp;&nbsp; = 0 (Timeout)<br/>select(7, &#91;6&#93;, &#91;6&#93;, &#91;&#93;, &#123;15, 0&#125;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 1 (out &#91;6&#93;, left &#123;15, 0&#125;)<br/>poll(&#91;&#123;fd=6, events=POLLIN&#125;&#93;, 1, 0)&nbsp;&nbsp;&nbsp;&nbsp; = 0 (Timeout)<br/>select(7, &#91;6&#93;, &#91;6&#93;, &#91;&#93;, &#123;15, 0&#125;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 1 (out &#91;6&#93;, left &#123;15, 0&#125;)<br/>poll(&#91;&#123;fd=6, events=POLLIN&#125;&#93;, 1, 0)&nbsp;&nbsp;&nbsp;&nbsp; = 0 (Timeout)</div><br/>　　那么，就可以确定是 file_get_contents() 导致的问题了。<br/>Tags - <a href="http://blog.s135.com/tags/nginx/" rel="tag">nginx</a> , <a href="http://blog.s135.com/tags/php/" rel="tag">php</a> , <a href="http://blog.s135.com/tags/file_get_contents/" rel="tag">file get contents</a> , <a href="http://blog.s135.com/tags/max_execution_time/" rel="tag">max execution time</a> , <a href="http://blog.s135.com/tags/request_terminate_timeout/" rel="tag">request terminate timeout</a>
]]>
</description>
</item><item>
<link>http://blog.s135.com/httpsqs_1_7/</link>
<title><![CDATA[HTTPSQS 1.7 发布：Libevent 2.0.x 的 evhttp_parse_query BUG 与动态编译时指定动态链接库 .so 寻找路径]]></title> 
<author>张宴 &lt;net@s135.com&gt;</author>
<category><![CDATA[Cache与存储]]></category>
<pubDate>Tue, 26 Jul 2011 09:07:57 +0000</pubDate> 
<guid>http://blog.s135.com/httpsqs_1_7/</guid> 
<description>
<![CDATA[ 
	　　[文章作者：张宴 本文版本：v1.0 最后修改：2011.07.26 转载请注明原文链接：<a href="http://blog.s135.com/httpsqs_1_7/" target="_blank">http://blog.s135.com/httpsqs_1_7/</a>]<br/><br/>　　HTTPSQS（HTTP Simple Queue Service）是一款基于 HTTP GET/POST 协议的轻量级开源简单消息队列服务，使用 Tokyo Cabinet 的 B+Tree Key/Value 数据库来做数据的持久化存储。<br/><br/>　　<span style="font-size: 14px;"><span style="color: #FF0000;">项目网址</span>：<a href="http://code.google.com/p/httpsqs/" target="_blank">http://code.google.com/p/httpsqs/</a></span><br/>　　<span style="font-size: 14px;"><span style="color: #FF0000;">使用文档</span>：<a href="http://blog.s135.com/httpsqs/" target="_blank">http://blog.s135.com/httpsqs/</a></span><br/>　　<span style="font-size: 14px;">使用环境：</span>Linux（同时支持32位、64位操作系统，推荐使用64位操作系统）<br/>　　<span style="font-size: 14px;">软件作者：</span>张宴<br/><br/><hr/><br/>　　<strong>HTTPSQS 1.7 版本更新内容：</strong><br/><br/>　　下面的内容不只是介绍 HTTPSQS 1.7 更新了哪些东西，更多的介绍在于：如何绕开 Libevent 2.0.x evhttp 使用过程中，无法正常处理包含“&#124;”字符的 URI 参数的问题；提供了一份比 Libevent 官方网站更新的在线文档；Linux 下如何动态编译程序，运行时不用在 /etc/ld.so.conf 文件中添加动态链接库路径。<br/><br/>　　<strong>1、针对 Libevent 2.0.x 版本 evhttp_parse_query 函数的 BUG。</strong><br/><br/>　　网友发邮件，反应了一个 HTTPSQS 的 BUG，见下图，data 的值为NULL。我查找发现，这不是 HTTPSQS 的 BUG，而是 Libevent 2.0.x 版本的 BUG。在 Libevent 1.4.14b 版本中，evhttp_parse_query 函数是能够正常处理包含“&#124;”字符的 URI 的，而在 Libevent 2.0.12 版本中，同样使用 evhttp_parse_query 函数，包含“&#124;”字符的 URI&nbsp;&nbsp;处理后的结果是 NULL。<br/><br/>　　<a href="http://blog.s135.com/attachment/201107/evbug0.gif" target="_blank"><img src="http://blog.s135.com/attachment/201107/evbug0.gif" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>　　对比 Libevent 2.0.12 和 1.4.14b 版本的 evhttp_parse_query 函数代码，发现在 2.0.12 版本中，evhttp_parse_query(const char *uri, struct evkeyvalq *headers) 实际变成了调用 evhttp_parse_query_impl(uri, headers, 1) 函数，该函数内再调用的一个 2.0.x 版本新增的函数 evhttp_uri_parse(const char *source_uri)，逻辑处理代码在 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags) 函数中。evhttp_uri_parse(const char *source_uri) 无法正确解析含有“&#124;”的URL，遇到类似“<a href="http://127.0.0.1:1218/?opt=get&name=aaa&#124;bbb" target="_blank">http://127.0.0.1:1218/?opt=get&name=aaa&#124;bbb</a>”的URL，直接返回NULL，也就是 BUG 所在。<br/><br/>　　libevent-2.0.12-stable/http.c<br/>　　<a href="http://blog.s135.com/attachment/201107/evbug1.gif" target="_blank"><img src="http://blog.s135.com/attachment/201107/evbug1.gif" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>　　<a href="http://blog.s135.com/attachment/201107/evbug2.gif" target="_blank"><img src="http://blog.s135.com/attachment/201107/evbug2.gif" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>　　<a href="http://blog.s135.com/attachment/201107/evbug3.gif" target="_blank"><img src="http://blog.s135.com/attachment/201107/evbug3.gif" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>　　不建议修改第三方库，这个 BUG 还是留给 Libevent 自己去解决吧。使用 Libevent 2.0.x evhttp 作开发的同学，遇到URI参数中包含“&#124;”的问题，注意一下吧。<br/><br/>　　我修改了 HTTPSQS 代码，在 HTTPSQS 1.7 版本，采用以下方式来绕开evhttp_uri_parse(const char *source_uri)函数，解决这个问题。其中用到了 Libevent 2.0.x&nbsp;&nbsp;evhttp_request 结构体中新增的 struct evhttp_uri *uri_elems，以及新增的函数 evhttp_parse_query_str (const char *uri, struct evkeyvalq *headers)。<br/><textarea name="code" class="c" rows="15" cols="100">
/* 处理模块 */
void httpsqs_handler(struct evhttp_request *req, void *arg)
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct evbuffer *buf;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf = evbuffer_new();
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* 分析URL参数 */&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const char *httpsqs_query_part;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct evkeyvalq httpsqs_http_query;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;httpsqs_query_part = evhttp_uri_get_query(req->uri_elems);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;evhttp_parse_query_str(httpsqs_query_part, &httpsqs_http_query);
</textarea><br/>　　Libevent 的官方文档只有 <a href="http://monkey.org/~provos/libevent/doxygen-1.4.10" target="_blank">1.4.10-stable</a> 和 <a href="http://monkey.org/~provos/libevent/doxygen-2.0.1" target="_blank">2.0.1-alpha</a> 版本的，2.0.1x 很多新增的函数、结构体都没有。<br/><br/>　　<span style="font-size: 14px;"><span style="color: #FF0000;">我这里提供一份最新的 Libevent 在线文档：</span> <a href="http://blog.s135.com/book/libevent/" target="_blank">http://blog.s135.com/book/libevent/</a> </span><br/><br/><hr/><br/>　　<strong>2、静态编译改为动态编译，并指定程序运行时查找的动态链接库路径 </strong><br/><br/>　　一些网友反映，CentOS 6.0、Fedora 等系统没有默认安装lz、lbz2、lrt、...等静态链接库，出现无法编译HTTPSQS的情况：<br/><div class="code">gcc -o httpsqs httpsqs.c prename.c -L/usr/local/libevent-2.0.10-stable/lib/ -levent -L/usr/local/tokyocabinet-1.4.47/lib/ -ltokyocabinet -I/usr/local/libevent-2.0.10-stable/include/ -I/usr/local/tokyocabinet-1.4.47/include/ -lz -lbz2 -lrt -lpthread -lm -lc -O2 -g --static&nbsp;&nbsp;<br/>/usr/bin/ld: cannot find -lz&nbsp;&nbsp;<br/>/usr/bin/ld: cannot find -lbz2&nbsp;&nbsp;<br/>/usr/bin/ld: cannot find -lrt&nbsp;&nbsp;<br/>/usr/bin/ld: cannot find -lpthread&nbsp;&nbsp;<br/>/usr/bin/ld: cannot find -lm&nbsp;&nbsp;<br/>/usr/bin/ld: cannot find -lc&nbsp;&nbsp;<br/>/usr/bin/ld: cannot find -lc&nbsp;&nbsp;<br/>collect2: ld 返回 1&nbsp;&nbsp;<br/>make: *** &#91;httpsqs&#93; 错误 1</div><br/><br/>　　HTTPSQS 1.7 版本改为动态编译，编译时使用“<span style="color: red;">-Wl,-rpath</span>”参数指定了程序运行时的动态库搜索路径。这样就不需要在 /etc/ld.so.conf 中 添加 HTTPSQS 程序运行时需要的 libevent、tokyocabinet 动态链接库路径了，可以避免与其他软件（例如：Memcached、TT）使用的 libevent、tokyocabinet 动态链接库版本相冲突。详情请见 Makefile 文件：<br/><div class="code"># Makefile for httpsqs<br/>CC=gcc<br/>CFLAGS=-Wl,-rpath,/usr/local/libevent-2.0.12-stable/lib/:/usr/local/tokyocabinet-1.4.47/lib/ -L/usr/local/libevent-2.0.12-stable/lib/ -levent -L/usr/local/tokyocabinet-1.4.47/lib/ -ltokyocabinet -I/usr/local/libevent-2.0.12-stable/include/ -I/usr/local/tokyocabinet-1.4.47/include/ -lz -lbz2 -lrt -lpthread -lm -lc -O2 -g<br/><br/>httpsqs: httpsqs.c<br/>&nbsp;&nbsp;$(CC) -o httpsqs httpsqs.c prename.c $(CFLAGS)<br/>&nbsp;&nbsp;@echo &quot;&quot;<br/>&nbsp;&nbsp;@echo &quot;httpsqs build complete.&quot;<br/>&nbsp;&nbsp;@echo &quot;&quot;&nbsp;&nbsp;<br/><br/>clean: httpsqs<br/>&nbsp;&nbsp;rm -f httpsqs<br/><br/>install: httpsqs<br/>&nbsp;&nbsp;install $(INSTALL_FLAGS) -m 4755 -o root httpsqs $(DESTDIR)/usr/bin<br/></div><br/><br/>............<br/><br/>Tags - <a href="http://blog.s135.com/tags/httpsqs/" rel="tag">httpsqs</a> , <a href="http://blog.s135.com/tags/libevent/" rel="tag">libevent</a> , <a href="http://blog.s135.com/tags/evhttp/" rel="tag">evhttp</a> , <a href="http://blog.s135.com/tags/evhttp_parse_query/" rel="tag">evhttp parse query</a> , <a href="http://blog.s135.com/tags/evhttp_uri_parse/" rel="tag">evhttp uri parse</a>
]]>
</description>
</item><item>
<link>http://blog.s135.com/mu_lan_wei_chang/</link>
<title><![CDATA[2011年夏，木兰围场与乌兰布统大草原三日游]]></title> 
<author>张宴 &lt;net@s135.com&gt;</author>
<category><![CDATA[心情随笔]]></category>
<pubDate>Tue, 12 Jul 2011 09:17:41 +0000</pubDate> 
<guid>http://blog.s135.com/mu_lan_wei_chang/</guid> 
<description>
<![CDATA[ 
	　　2011年7月8日早上7:00，作为领队，带领金山游戏运营技术中心部分同事、家属组成的45人旅行团，乘大巴车从北京金山软件大厦出发，开始承德木兰围场、内蒙古乌兰布统大草原三日游。<br/><br/>　　没有去过的朋友，可以将本文当成一篇攻略；无论是否去过的朋友，都可以将本文当成一篇美景欣赏相册。木兰围场、乌兰布统大草原，真是太漂亮了。<br/><br/>　　<strong>【第一天：2011年7月8日】</strong><br/><br/>　　“北京→木兰围场”行车路线：<br/>　　<br/>此处包含一个多媒体文件，请用网页方式查看。<br/><br/><hr/><br/>　　<strong>【万顷林海】</strong><br/><br/>　　经过3个小时的京承高速、3个小时的国道，到达“塞罕坝国家森林公园”山门。<br/><br/>　　车过山门，还需1小时的山路，观千里松林、万顷林海。53座的大巴车，挑战360度的下坡大转弯，还是有些难度的。<br/><br/>　　<a href="http://blog.s135.com/attachment/201107/mlwc/immense_forest/P7080043.JPG" target="_blank"><img src="http://blog.s135.com/attachment/201107/mlwc/immense_forest/P7080043.JPG" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>............<br/><br/>Tags - <a href="http://blog.s135.com/tags/%25E6%259C%25A8%25E5%2585%25B0%25E5%259B%25B4%25E5%259C%25BA/" rel="tag">木兰围场</a> , <a href="http://blog.s135.com/tags/%25E4%25B9%258C%25E5%2585%25B0%25E5%25B8%2583%25E7%25BB%259F/" rel="tag">乌兰布统</a> , <a href="http://blog.s135.com/tags/%25E8%258D%2589%25E5%258E%259F/" rel="tag">草原</a> , <a href="http://blog.s135.com/tags/%25E9%25AA%2591%25E9%25A9%25AC/" rel="tag">骑马</a> , <a href="http://blog.s135.com/tags/%25E4%25B8%2583%25E6%2598%259F%25E6%25B9%2596/" rel="tag">七星湖</a> , <a href="http://blog.s135.com/tags/%25E6%25B3%25B0%25E4%25B8%25B0%25E6%25B9%2596/" rel="tag">泰丰湖</a> , <a href="http://blog.s135.com/tags/%25E6%259C%2588%25E4%25BA%25AE%25E6%25B9%2596/" rel="tag">月亮湖</a> , <a href="http://blog.s135.com/tags/%25E7%2599%25BE%25E8%258A%25B1%25E5%259D%25A1/" rel="tag">百花坡</a> , <a href="http://blog.s135.com/tags/%25E6%25BB%25A6%25E6%25B2%25B3%25E6%25BA%2590%25E5%25A4%25B4/" rel="tag">滦河源头</a> , <a href="http://blog.s135.com/tags/%25E7%2595%258C%25E6%25B2%25B3%25E6%25BC%2582%25E6%25B5%2581/" rel="tag">界河漂流</a> , <a href="http://blog.s135.com/tags/%25E5%2586%259B%25E9%25A9%25AC%25E5%259C%25BA/" rel="tag">军马场</a> , <a href="http://blog.s135.com/tags/%25E5%25B0%2586%25E5%2586%259B%25E6%25B3%25A1%25E5%25AD%2590/" rel="tag">将军泡子</a>
]]>
</description>
</item><item>
<link>http://blog.s135.com/windows_mstsc/</link>
<title><![CDATA[Windows 服务程序、窗口界面与远程桌面的那点事]]></title> 
<author>张宴 &lt;net@s135.com&gt;</author>
<category><![CDATA[Windows相关]]></category>
<pubDate>Tue, 28 Jun 2011 09:17:51 +0000</pubDate> 
<guid>http://blog.s135.com/windows_mstsc/</guid> 
<description>
<![CDATA[ 
	　　[文章作者：张宴 本文版本：v1.0 最后修改：2011.06.28 转载请注明原文链接：<a href="http://blog.s135.com/windows_mstsc/" target="_blank">http://blog.s135.com/windows_mstsc/</a>]<br/><br/>　　个人不喜欢服务端程序，以 Windows 操作系统作为运行平台，但是，很多时候，迫于环境现状，需要让自己的程序实现跨平台。<br/><br/>　　在开发全新的金山游戏运营平台时，发现：虽然大部分游戏，服务端程序运行在 Linux 服务器，但是，仍有例外。几款最近代理的游戏，服务端运行在 Windows 服务器上。西山居开发的游戏，服务端集群架构，既有 Windows 服务器，又有 Linux 服务器。<br/><br/>　　<a href="http://blog.s135.com/attachment/201106/knose01.png" target="_blank"><img src="http://blog.s135.com/attachment/201106/knose01.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><hr/><br/>　　游戏运行系统的 Knose 程序，我最初是在 Linux 下开发的，后来才实现了兼容 Windows 的跨平台版本。<br/><br/>　　<a href="http://blog.s135.com/attachment/201106/knose02.png" target="_blank"><img src="http://blog.s135.com/attachment/201106/knose02.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><hr/><br/>　　在 Linux 下，Knose 为“父子进程+指令处理线程池+独立功能多线程”结构；在 Windows 上，将 Knose 父子进程结构，拆分成了 knose_daemon.exe（Service 服务程序）和 knose.exe（主程序），由 knose_daemon.exe 启动 knose.exe。<br/><br/>　　<a href="http://blog.s135.com/attachment/201106/knose03.png" target="_blank"><img src="http://blog.s135.com/attachment/201106/knose03.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><hr/><br/>　　遇到了问题：按照运营维护需求，knose.exe 以及通过它启动的游戏服务端进程，需要有“窗口界面”，显示在桌面中。而 knose_daemon.exe 是以服务方式运行的，无窗口界面，knose_daemon.exe 启动的 knose.exe，窗口界面没有弹出来。<br/><br/>　　为了解决这个问题，我在 install.bat 中，用了 Windows 的 sc 命令，将 knose_daemon.exe 启动为系统服务，“type= interact type= own”设置了“允许桌面与服务交互”。在本机（Windows XP SP3）测试，knose.exe 的窗口界面以及通过它启动的游戏进程窗口界面，都弹出来了。<br/><br/><div style="border-left: 0px dashed #D6C094; margin: 5px; padding: 3px; margin-bottom:0px; border: 1px dashed #00a0c6; background-color: #ffffff;">@echo off<br/>sc create "KingeyesKnose" binPath= "%CD%&#92;knose_daemon.exe" DisplayName= "Kingeyes Knose Daemon" start= auto type= interact type= own<br/>sc description KingeyesKnose "金山游戏运营系统 KingEyes Knose 守护进程。"<br/>sc start KingeyesKnose</div><br/><br/>　　<a href="http://blog.s135.com/attachment/201106/knose04.png" target="_blank"><img src="http://blog.s135.com/attachment/201106/knose04.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><hr/><br/>　　于是将程序发布到 Windows Server 2003 服务器上，远程桌面连接上去，发现 knose.exe 的窗口界面始终弹不出来。<br/><br/>　　后来，同事发现，原来是“远程桌面”惹的祸：<br/><br/>　　远程桌面客户端 mstsc 有一个 /console 参数，模式等同于本地终端显示器登录，/console 不会去占用非 /console 远程桌面，远程桌面允许两个正常连接和一个控制台/console方式连接，并且正常连接和 /console 连接的桌面操作不能相互看见，只有通过 /console 参数远程桌面连接到 Windows 2003 服务器，才能够看到弹出的 knose.exe 窗口界面。<br/><br/>　　在 Windows XP SP3 以上版本，/console 参数改名为 /admin，需要用 mstsc /admin 启动远程桌面：<br/><br/>　　<a href="http://blog.s135.com/attachment/201106/knose05.png" target="_blank"><img src="http://blog.s135.com/attachment/201106/knose05.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>　　连上后，终于能够看到由 knose_daemon.exe 启动的 knose.exe 程序窗口，以及由 knose.exe 启动的游戏服务端进程窗口了。<br/><br/>Tags - <a href="http://blog.s135.com/tags/windows/" rel="tag">windows</a> , <a href="http://blog.s135.com/tags/mstsc/" rel="tag">mstsc</a> , <a href="http://blog.s135.com/tags/console/" rel="tag">console</a> , <a href="http://blog.s135.com/tags/admin/" rel="tag">admin</a> , <a href="http://blog.s135.com/tags/%25E8%25BF%259C%25E7%25A8%258B%25E6%25A1%258C%25E9%259D%25A2/" rel="tag">远程桌面</a>
]]>
</description>
</item><item>
<link>http://blog.s135.com/2011phptc/</link>
<title><![CDATA[2011中国PHP技术高峰论坛：PHP在金山游戏运营中的应用]]></title> 
<author>张宴 &lt;net@s135.com&gt;</author>
<category><![CDATA[PHP/JS/Shell]]></category>
<pubDate>Sun, 08 May 2011 11:40:41 +0000</pubDate> 
<guid>http://blog.s135.com/2011phptc/</guid> 
<description>
<![CDATA[ 
	　　5月7日，我在北京长城饭店“<a href="http://www.phpchina.com/2011phptc/" target="_blank">2011中国PHP技术高峰论坛</a>”上的演讲PPT：<br/><br/>　　下载地址1（国外服务器）：<a href="http://blog.s135.com/attachment/201105/2011phptc_zy.zip" target="_blank">http://blog.s135.com/attachment/201105/2011phptc_zy.zip</a><br/><br/>　　下载地址2（国内服务器）：<a href="http://ishare.iask.sina.com.cn/f/15231659.html" target="_blank">http://ishare.iask.sina.com.cn/f/15231659.html</a><br/><br/><hr/><br/>　　<a href="http://blog.s135.com/attachment/201105/2011phptc_zy.jpg" target="_blank"><img src="http://blog.s135.com/attachment/201105/2011phptc_zy.jpg" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>　　以下是我在会议主办方对演讲文字速录的基础上，修正错漏内容，整理之后，对应到每页PPT的文字内容：<br/><br/>　　[PPT No.1]<br/>　　大家下午好，现在我来跟大家分享的是PHP在金山游戏运营中的应用，包括团队协助开发实现方式、网站Web架构设计、游戏运营平台设计这些信息。<br/><br/>　　[PPT No.2]<br/>　　我议题主要有两个，一个是<a href="http://www.xoyo.com" target="_blank">金山游戏官方网站</a>的一些应用，另一个是金山游戏运营系统Keyes中的架构设计。<br/><br/>　　[PPT No.3]<br/>　　金山游戏官方网站包括<a href="http://my.xoyo.com" target="_blank">用户中心</a>、<a href="http://kefu.xoyo.com" target="_blank">客服系统</a>、<a href="http://bbs.xoyo.com" target="_blank">论坛</a>、<a href="http://v.xoyo.com" target="_blank">视频</a>、各游戏<a href="http://jx3.xoyo.com" target="_blank">官网</a>，以及其他跟游戏相关的一些产品，主要采用64位CentOS Linux系统、Nginx、PHP 5.2版本、MySQL 5.5。<br/><br/>　　[PPT No.4]<br/>　　首先来看团队协作开发。我们肯定遇到过这样一种情况，在很多项目中，都是多个人同时开发，涉及到开发环境和测试环境不一样。我们很多PHP工程师，都是在Windows上开发代码，虽然Windows上也可以配置Nginx+PHP+MySQL环境，但是，由于测试环境、生产环境都是Linux系统，而且一些功能只能在Linux下运行，还有一些PHP扩展（例如：分布式图片处理、金山通行证加密扩展），也只能运行在Linux环境中。当我们在Windows上修改完几行PHP代码，想马上看一下执行结果，如果利用FTP之类的工具传到Linux测试服务器上再测试，就太慢了。如果同一台Linux测试服务器上，有多少人同时开发，你上传上去PHP文件，可能会覆盖别人上传的同名文件，就没有办法做到版本控制。<br/><br/>　　[PPT No.5]<br/>　　我们从图中可以看到，假如是程序员A和B都在Windows上开发代码，由于Nginx与PHP之间采用的是TCP FastCGI协议通讯，因此，两者可以分离到不同的服务器上。我们可以把Nginx安装在程序员各自的Windows PC机上，用本机的Nginx处理HTTP请求，用Linux测试服务器上的php-cgi程序，处理PHP请求。程序员在Windows上开发程序，保存之后，不用做任何上传操作，即可用Linux上的php-cgi调试程序。从图中这个流程可以看到，首先，两个程序员分别从SVN版本库，获取到一个项目的最新版本，各自进行一些修改。两人修改程序时，采用的是同一台Linux测试服务器的php-cgi，对各自PC机上的PHP程序进行调试。在PC机上本地测试没有问题，可以提交到SVN版本库。我们做了一个自动同步程序，利用SVN钩子，在每次发生svn commit提交时，在对应的测试服务器的对应项目路径内，执行svn update，将最新修改到文件同步到测试服务器。后来发现有一些问题，如果我们一个项目的目录、程序文件特别多的话，svn update需要遍历扫描目录列表，非常慢。因为我们的SVN是和Apache结合起来使用的，Apache可以记录日志，于是，我们进行了改进，将SVN提交日志记录到Linux下的命名管道内，再用一个程序从命名管道内读取日志，只svn update每次修改的几个文件，这样，速度就非常快了。设置hosts为Linux测试服务器的IP，就可以测试多位程序员代码合并后的效果了。<br/><br/>............<br/><br/>Tags - <a href="http://blog.s135.com/tags/php/" rel="tag">php</a>
]]>
</description>
</item><item>
<link>http://blog.s135.com/httpsqs_1_6/</link>
<title><![CDATA[轻量级开源简单队列服务 HTTPSQS 1.6 版本发布]]></title> 
<author>张宴 &lt;net@s135.com&gt;</author>
<category><![CDATA[Cache与存储]]></category>
<pubDate>Thu, 21 Apr 2011 10:12:37 +0000</pubDate> 
<guid>http://blog.s135.com/httpsqs_1_6/</guid> 
<description>
<![CDATA[ 
	　　[文章作者：张宴 本文版本：v1.0 最后修改：2011.04.21 转载请注明原文链接：<a href="http://blog.s135.com/httpsqs_1_6/" target="_blank">http://blog.s135.com/httpsqs_1_6/</a>]<br/><br/>　　HTTPSQS（HTTP Simple Queue Service）是一款基于 HTTP GET/POST 协议的轻量级开源简单消息队列服务，使用 Tokyo Cabinet 的 B+Tree Key/Value 数据库来做数据的持久化存储。<br/><br/>　　<span style="font-size: 14px;"><span style="color: #FF0000;">项目网址</span>：<a href="http://code.google.com/p/httpsqs/" target="_blank">http://code.google.com/p/httpsqs/</a></span><br/>　　<span style="font-size: 14px;"><span style="color: #FF0000;">使用文档</span>：<a href="http://blog.s135.com/httpsqs/" target="_blank">http://blog.s135.com/httpsqs/</a></span><br/>　　<span style="font-size: 14px;">使用环境：</span>Linux（同时支持32位、64位操作系统，推荐使用64位操作系统）<br/>　　<span style="font-size: 14px;">软件作者：</span>张宴<br/><br/>　　队列（Queue）又称先进先出表（First In First Out），即先进入队列的元素，先从队列中取出。加入元素的一头叫“队头”，取出元素的一头叫“队尾”。利用消息队列可以很好地异步处理数据传送和存储，当你频繁地向数据库中插入数据、频繁地向搜索引擎提交数据，就可采取消息队列来异步插入。另外，还可以将较慢的处理逻辑、有并发数量限制的处理逻辑，通过消息队列放在后台处理，例如FLV视频转换、发送手机短信、发送电子邮件等。<br/><br/>　　<strong>HTTPSQS 具有以下特征：</strong><br/><br/>　　● 非常简单，基于 HTTP GET/POST 协议。PHP、Java、Perl、Shell、Python、Ruby等支持HTTP协议的编程语言均可调用。<br/>　　● 非常快速，入队列、出队列速度超过10000次/秒。<br/>　　● 高并发，支持上万的并发连接，<a href="http://www.kegel.com/c10k.html" target="_blank">C10K</a>不成问题。<br/>　　● 支持多队列。<br/>　　● 单个队列支持的最大队列数量高达10亿条。<br/>　　● 低内存消耗，海量数据存储，存储几十GB的数据只需不到100MB的物理内存缓冲区。<br/>　　● 可以在不停止服务的情况下便捷地修改单个队列的最大队列数量。<br/>　　● 可以实时查看队列状态（入队列位置、出队列位置、未读队列数量、最大队列数量）。<br/>　　● 可以查看指定队列ID（队列点）的内容，包括未出、已出的队列内容。<br/>　　● 查看队列内容时，支持多字符集编码。<br/>　　● 源代码不超过800行，适合二次开发。<br/><br/><hr/><br/>　　<strong>HTTPSQS 1.6 版本更新内容：</strong><br/><br/>　　<strong>一、服务器端：</strong><br/><br/>　　<strong>1、修正了定时将内存缓冲区内容同步到磁盘，有时候出现段错误，导致进程崩溃的BUG。</strong>感谢以下网友的反馈：<br/><br/>　　<a href="http://blog.s135.com/attachment/201104/httpsqs_bug1_1.png" target="_blank"><img src="http://blog.s135.com/attachment/201104/httpsqs_bug1_1.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>　　<a href="http://blog.s135.com/attachment/201104/httpsqs_bug1_2.png" target="_blank"><img src="http://blog.s135.com/attachment/201104/httpsqs_bug1_2.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>　　<a href="http://blog.s135.com/attachment/201104/httpsqs_bug1_3.png" target="_blank"><img src="http://blog.s135.com/attachment/201104/httpsqs_bug1_3.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/><hr/><br/>　　<strong>2、修正了判断队列已满，遗漏的一种情况。</strong>感谢以下网友的反馈：<br/><br/>　　<a href="http://blog.s135.com/attachment/201104/httpsqs_bug2_1.png" target="_blank"><img src="http://blog.s135.com/attachment/201104/httpsqs_bug2_1.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>　　<a href="http://blog.s135.com/attachment/201104/httpsqs_bug2_2.png" target="_blank"><img src="http://blog.s135.com/attachment/201104/httpsqs_bug2_2.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/><hr/><br/>　　<strong>3、改为父子进程模式，生产环境稳定性更高。</strong><br/><br/>　　<strong>4、改进了 ps 命令查看 httpsqs 的用户体验：</strong><br/><br/>　　<a href="http://blog.s135.com/attachment/201104/httpsqs_m_w.gif" target="_blank"><img src="http://blog.s135.com/attachment/201104/httpsqs_m_w.gif" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/><hr/><br/>　　<strong>5、增加了密码校验功能（通过以下启动参数设置密码，通过URL参数“/?auth=密码”访问）：</strong><br/><br/>　　<a href="http://blog.s135.com/attachment/201104/httpsqs_auth.gif" target="_blank"><img src="http://blog.s135.com/attachment/201104/httpsqs_auth.gif" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/><hr/><br/>　　<strong>6、改为静态编译，编译完成后的 HTTPSQS 二进制文件，运行不再依赖 Libevent、Tokyocabinet 动态链接库。</strong><br/><br/><hr/><br/>　　<strong>7、HTTPSQS 旧版本如何升级到 HTTPSQS 1.6 版本：</strong><br/><br/>　　HTTPSQS 1.6 版本完全兼容以前版本：编译安装 HTTPSQS 1.6，替换旧的 HTTPSQS，然后“kill httpsqs的进程ID”，按原来的启动参数启动 HTTPSQS 即可，数据完全兼容。<br/><br/><hr/><br/>　　<strong>二、客户端：</strong><br/><br/>　　<strong>1、客户端代码不再集成在 HTTPSQS 源码包中，可通过链接自行查看。</strong> <br/><br/><hr/><br/>　　<span style="font-size: 14px;"><span style="color: #FF0000;">HTTPSQS 1.6 版本的详细使用说明，请访问：</span> <a href="http://blog.s135.com/httpsqs/" target="_blank">http://blog.s135.com/httpsqs/</a></span><br/><br/><br/>Tags - <a href="http://blog.s135.com/tags/httpsqs/" rel="tag">httpsqs</a> , <a href="http://blog.s135.com/tags/http/" rel="tag">http</a> , <a href="http://blog.s135.com/tags/queue/" rel="tag">queue</a> , <a href="http://blog.s135.com/tags/queues/" rel="tag">queues</a> , <a href="http://blog.s135.com/tags/sqs/" rel="tag">sqs</a> , <a href="http://blog.s135.com/tags/memcacheq/" rel="tag">memcacheq</a> , <a href="http://blog.s135.com/tags/memcachedb/" rel="tag">memcachedb</a> , <a href="http://blog.s135.com/tags/activemq/" rel="tag">activemq</a> , <a href="http://blog.s135.com/tags/starling/" rel="tag">starling</a> , <a href="http://blog.s135.com/tags/amazonsqs/" rel="tag">amazonsqs</a> , <a href="http://blog.s135.com/tags/tokyocabinet/" rel="tag">tokyocabinet</a> , <a href="http://blog.s135.com/tags/simple/" rel="tag">simple</a> , <a href="http://blog.s135.com/tags/service/" rel="tag">service</a> , <a href="http://blog.s135.com/tags/%25E9%2598%259F%25E5%2588%2597/" rel="tag">队列</a> , <a href="http://blog.s135.com/tags/%25E7%25AE%2580%25E5%258D%2595%25E9%2598%259F%25E5%2588%2597/" rel="tag">简单队列</a> , <a href="http://blog.s135.com/tags/%25E6%25B6%2588%25E6%2581%25AF%25E9%2598%259F%25E5%2588%2597/" rel="tag">消息队列</a>
]]>
</description>
</item><item>
<link>http://blog.s135.com/samba_linux_windows/</link>
<title><![CDATA[快速配置 Samba 将 Linux 目录映射为 Windows 驱动器，用于跨平台编程]]></title> 
<author>张宴 &lt;net@s135.com&gt;</author>
<category><![CDATA[其他Unix技术]]></category>
<pubDate>Fri, 08 Apr 2011 00:53:45 +0000</pubDate> 
<guid>http://blog.s135.com/samba_linux_windows/</guid> 
<description>
<![CDATA[ 
	　　[文章作者：张宴 本文版本：v1.0 最后修改：2011.04.08 转载请注明原文链接：<a href="http://blog.s135.com/samba_linux_windows/" target="_blank">http://blog.s135.com/samba_linux_windows/</a>]<br/><br/>　　<strong>一、局域网内的 Linux 服务器上操作步骤：</strong><br/><br/>　　1、安装samba（CentOS Linux）：<br/><div style="border-left: 0px dashed #D6C094; margin: 5px; padding: 3px; margin-bottom:0px; border: 1px dashed #00a0c6; background-color: #ffffff;">yum install samba system-config-samba samba-client samba-common</div><br/><br/>　　2、创建www账号<br/><div style="border-left: 0px dashed #D6C094; margin: 5px; padding: 3px; margin-bottom:0px; border: 1px dashed #00a0c6; background-color: #ffffff;">/usr/sbin/groupadd www<br/>/usr/sbin/useradd -g www www<br/><br/>mkdir -p /data0/knose/<br/>chmod 777 /data0/knose/<br/><br/>mkdir -p /data0/htdocs/<br/>chown -R www:www /data0/htdocs/<br/>chmod 777 /data0/htdocs/<br/><br/>cat /etc/passwd &#124; mksmbpasswd.sh> /etc/samba/smbpasswd</div><br/><br/>　　3、创建samba配置文件<br/><div style="border-left: 0px dashed #D6C094; margin: 5px; padding: 3px; margin-bottom:0px; border: 1px dashed #00a0c6; background-color: #ffffff;">mv -f /etc/samba/smb.conf /etc/samba/smb.conf.bak<br/>vi /etc/samba/smb.conf</div><br/>　　输入以下内容：<br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content">[global]<br/>server string = Samba Server<br/>security = user<br/>encrypt passwords = yes <br/>smb passwd file = /etc/samba/smbpasswd<br/><br/>[knose]<br/>workgroup = root<br/>netbios name = root<br/>path = /data0/knose<br/>browseable = yes<br/>writeable = yes<br/><br/>[web]<br/>workgroup = www<br/>netbios name = www<br/>path = /data0/htdocs<br/>browseable = yes<br/>writeable = yes</div></div><br/><br/>　　4、为samba用户www、root设立一个密码：<br/><div style="border-left: 0px dashed #D6C094; margin: 5px; padding: 3px; margin-bottom:0px; border: 1px dashed #00a0c6; background-color: #ffffff;">smbpasswd -a www<br/>smbpasswd -a root</div><br/><br/>　　5、启动samba：<br/><div style="border-left: 0px dashed #D6C094; margin: 5px; padding: 3px; margin-bottom:0px; border: 1px dashed #00a0c6; background-color: #ffffff;">/sbin/service smb start</div><br/><br/><hr/><br/>　　<strong>二、局域网内的 Windows 服务器上操作步骤：</strong><br/><br/>............<br/><br/>Tags - <a href="http://blog.s135.com/tags/samba/" rel="tag">samba</a> , <a href="http://blog.s135.com/tags/linux/" rel="tag">linux</a> , <a href="http://blog.s135.com/tags/windows/" rel="tag">windows</a>
]]>
</description>
</item><item>
<link>http://blog.s135.com/libevent_windows/</link>
<title><![CDATA[Windows 上静态编译 Libevent 2.0.10 并实现一个简单 HTTP 服务器]]></title> 
<author>张宴 &lt;net@s135.com&gt;</author>
<category><![CDATA[Windows相关]]></category>
<pubDate>Wed, 30 Mar 2011 00:40:22 +0000</pubDate> 
<guid>http://blog.s135.com/libevent_windows/</guid> 
<description>
<![CDATA[ 
	　　[文章作者：张宴 本文版本：v1.0 最后修改：2011.03.30 转载请注明原文链接：<a href="http://blog.s135.com/libevent_windows/" target="_blank">http://blog.s135.com/libevent_windows/</a>]<br/><br/>　　本文介绍了如何在 Windows 操作系统中，利用微软 Visual Studio 2005 编译生成 <a href="http://monkey.org/~provos/libevent/" target="_blank">Libevent</a> 2.0.10 静态链接库，并利用 <a href="http://monkey.org/~provos/libevent/" target="_blank">Libevent</a> 静态链接库，实现一个简单的 HTTP Web服务器程序：httpd.exe。<br/><br/>　　假设 Visual Studio 2005 的安装路径为“D:&#92;Program Files&#92;Microsoft Visual Studio 8&#92;”，<a href="http://monkey.org/~provos/libevent/" target="_blank">Libevent</a> 2.0.10 解压后的路径为“D:&#92;libevent-2.0.10-stable”。<br/><br/><hr/><br/>　　<strong>一、编译生成 Libevent 2.0.10 静态链接库。</strong><br/>　　<br/>　　1、修改“D:&#92;libevent-2.0.10-stable&#92;event_iocp.c”、“D:&#92;libevent-2.0.10-stable&#92;evthread_win32.c”、“D:&#92;libevent-2.0.10-stable&#92;listener.c”三个文件，在文件开头分别加上一行：<br/><div style="border-left: 0px dashed #D6C094; margin: 5px; padding: 3px; margin-bottom:0px; border: 1px dashed #00a0c6; background-color: #ffffff;">#define _WIN32_WINNT 0x0500</div><br/><br/>　　2、鼠标点击Windows左下角的【开始】-【所有程序】，找到【Microsoft Visual Studio 2005】，执行下图中的脚本：<br/><br/>　　<a href="http://blog.s135.com/attachment/201103/libevent/libevent1.png" target="_blank"><img src="http://blog.s135.com/attachment/201103/libevent/libevent1.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/><br/>　　3、按照下图中的方法编译Libevent 2.0.10：<br/><br/>　　<a href="http://blog.s135.com/attachment/201103/libevent/libevent2.png" target="_blank"><img src="http://blog.s135.com/attachment/201103/libevent/libevent2.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/><br/>　　4、生成的“libevent.lib”、“libevent_core.lib”、“libevent_extras.lib”三个文件就是我们需要的 Libevent 静态链接库。<br/><br/>　　<a href="http://blog.s135.com/attachment/201103/libevent/libevent3.png" target="_blank"><img src="http://blog.s135.com/attachment/201103/libevent/libevent3.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/><hr/><br/>　　<strong>二、利用 Libevent 静态链接库，实现一个简单的 HTTP Web服务器程序</strong><br/><br/>　　1、打开 Visual Studio 2005，新建一个项目<br/><br/>　　<a href="http://blog.s135.com/attachment/201103/libevent/libevent4.png" target="_blank"><img src="http://blog.s135.com/attachment/201103/libevent/libevent4.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>............<br/><br/>Tags - <a href="http://blog.s135.com/tags/libevent/" rel="tag">libevent</a> , <a href="http://blog.s135.com/tags/windows/" rel="tag">windows</a> , <a href="http://blog.s135.com/tags/vs2005/" rel="tag">vs2005</a> , <a href="http://blog.s135.com/tags/visual/" rel="tag">visual</a> , <a href="http://blog.s135.com/tags/studio/" rel="tag">studio</a> , <a href="http://blog.s135.com/tags/lib/" rel="tag">lib</a> , <a href="http://blog.s135.com/tags/%25E9%259D%2599%25E6%2580%2581%25E9%2593%25BE%25E6%258E%25A5%25E5%25BA%2593/" rel="tag">静态链接库</a>
]]>
</description>
</item><item>
<link>http://blog.s135.com/post/459/</link>
<title><![CDATA[Windows 和 Linux 下生成以当前时间命名的文件]]></title> 
<author>张宴 &lt;net@s135.com&gt;</author>
<category><![CDATA[PHP/JS/Shell]]></category>
<pubDate>Mon, 28 Feb 2011 07:33:09 +0000</pubDate> 
<guid>http://blog.s135.com/post/459/</guid> 
<description>
<![CDATA[ 
	　　在 Windows、Linux 操作系统，分别利用BAT批处理文件和Shell脚本，生成类似“20110228_082905.txt”以“年月日_时分秒”命名的文件。<br/><br/>　　Windows BAT批处理文件：<br/><div class="code">@echo off<br/>set time_hh=%time:~0,2%<br/>if /i %time_hh% LSS 10 (set time_hh=0%time:~1,1%)<br/>set filename=%date:~,4%%date:~5,2%%date:~8,2%_%time_hh%%time:~3,2%%time:~6,2%<br/>echo test &gt;&gt; %filename%.txt<br/></div><br/><br/>　　Linux Shell 脚本：<br/><div class="code">#!/bin/sh<br/>echo test &gt;&gt; $(date -d &quot;today&quot; +&quot;%Y%m%d_%H%M%S&quot;).txt<br/></div><br/>
]]>
</description>
</item><item>
<link>http://blog.s135.com/go_home/</link>
<title><![CDATA[回家]]></title> 
<author>张宴 &lt;net@s135.com&gt;</author>
<category><![CDATA[生活琐事]]></category>
<pubDate>Sun, 30 Jan 2011 10:29:05 +0000</pubDate> 
<guid>http://blog.s135.com/go_home/</guid> 
<description>
<![CDATA[ 
	　　下班了，从此刻开始，公司统一放13天的春节假期，2月13日（正月十一）上班。<br/><br/>　　明天下午，离开北京。结婚之后，每逢春节，只能在 My Home Town 和 My Wife's Home Town 之间轮询了，今年带着老婆回我家。阔别了两年的美丽故乡，终于可以回到你的怀抱了。<br/><br/>　　1500公里的航程<br/><br/>　　<a href="http://blog.s135.com/attachment/201101/gohome1.gif" target="_blank"><img src="http://blog.s135.com/attachment/201101/gohome1.gif" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>　　还需100公里的车程<br/><br/>　　<a href="http://blog.s135.com/attachment/201101/gohome2.jpg" target="_blank"><img src="http://blog.s135.com/attachment/201101/gohome2.jpg" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>　　故乡的小城，不是浮云<br/><br/>　　<a href="http://blog.s135.com/attachment/201101/gohome3.jpg" target="_blank"><img src="http://blog.s135.com/attachment/201101/gohome3.jpg" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>............<br/>
]]>
</description>
</item><item>
<link>http://blog.s135.com/truecrypt/</link>
<title><![CDATA[让U盘变成安全的加密便携式绿色软件盘]]></title> 
<author>张宴 &lt;net@s135.com&gt;</author>
<category><![CDATA[Windows相关]]></category>
<pubDate>Sat, 29 Jan 2011 10:07:22 +0000</pubDate> 
<guid>http://blog.s135.com/truecrypt/</guid> 
<description>
<![CDATA[ 
	　　[文章作者：张宴 本文版本：v1.0 最后修改：2010.01.29 转载请注明原文链接：<a href="http://blog.s135.com/truecrypt" target="_blank">http://blog.s135.com/truecrypt</a>]<br/><br/>　　QQ、MSN、RTX的聊天历史记录，有时候在处理问题时，想查看一下，但换台电脑，就查看不到了，怎么办？Foxmail在公司收取的邮件，在家就看不到了，怎么解决？SecureCRT存放大量服务器SSH密码信息，换台电脑，如何不在新电脑上保存信息，同时又使用起来又方便、安全？存放在U盘上的机密文件，如何避免U盘丢失、被盗后，文件泄漏？<br/><br/>　　市面上有很多加密软件，但由于未开源，可能存在后门，或者漏洞，导致加密的文件可破解。因此，对于加密软件来说，还是开源的比较靠谱。源码都公开，留有后门的可能性不存在了。在源码都可以查看的情况下，如果能够破解，早就可以破解了。<br/><br/>　　TrueCrypt（<a href="http://www.truecrypt.org/" target="_blank">http://www.truecrypt.org/</a>）是一款开源的绿色加密软件。它可以在硬盘或闪存上创建一个或多个虚拟磁盘，所有虚拟磁盘上的文件都被自动加密，加密后需要通过密码来进行访问，由于加入了AES-256加密算法，使得加密数据几乎不可能被，对于没有商务安全功能的普通电脑，或者不舍得购买加密闪存的商务用户，TrueCrypt可以让他们的数据存储安全可靠。<br/><br/>　　前几天公司发了两个2GB的金山毒霸版U盘，我将我的QQ、MSN、公司内部通讯工具RTX、SSH客户端SecureCRT、OpenSSL VPN、Foxmail、一些文档都装在了其中一个U盘上。<br/><br/>　　<a href="http://blog.s135.com/attachment/201001/v1.gif" target="_blank"><img src="http://blog.s135.com/attachment/201001/v1.gif" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>　　关于TrueCrypt的安全性，有一则外电新闻：<a href="http://www.security.nl/artikel/33724" target="_blank">http://www.security.nl/artikel/33724</a><br/>&nbsp;&nbsp;<br/>　　FBI在经过一年的尝试后，还是未能破译被巴西执法机构指控金融犯罪的巴西银行家的加密文件。巴西一家葡萄牙语报纸报道（葡萄牙语），巴西联邦警察在2008年7月展开的Satyagraha行动中，在银行家Daniel Dantas位于里约热内卢的公寓内收缴了5个硬盘。文章提到硬盘使用了两种加密程序，一种是TrueCrypt，另一种是不知名的256位AES加密软件。在专家未能破解密码后，巴西政府在2009年初请求美国提供帮助，然而美国联邦警察在一年不成功的尝试后，退还了硬盘。巴西现有的法律中不存在强制要求Dantas交出密码的规定。<br/><br/><hr/><br/>　　使用步骤：将TrueCrypt拷贝到U盘上，然后运行TrueCrypt.exe。<br/><br/>　　1、创建文件加密卷<br/><br/>............<br/><br/>Tags - <a href="http://blog.s135.com/tags/truecrypt/" rel="tag">truecrypt</a> , <a href="http://blog.s135.com/tags/u%25E7%259B%2598/" rel="tag">u盘</a> , <a href="http://blog.s135.com/tags/%25E5%258A%25A0%25E5%25AF%2586/" rel="tag">加密</a> , <a href="http://blog.s135.com/tags/aes/" rel="tag">aes</a>
]]>
</description>
</item><item>
<link>http://blog.s135.com/android_apk_zip/</link>
<title><![CDATA[APK 变成 ZIP：Android 手机应用程序文件下载服务器需要注意的问题]]></title> 
<author>张宴 &lt;net@s135.com&gt;</author>
<category><![CDATA[Web服务器]]></category>
<pubDate>Thu, 20 Jan 2011 01:00:53 +0000</pubDate> 
<guid>http://blog.s135.com/android_apk_zip/</guid> 
<description>
<![CDATA[ 
	　　[文章作者：张宴 本文版本：v1.0 最后修改：2010.01.20 转载请注明原文链接：<a href="http://blog.s135.com/android_apk_zip" target="_blank">http://blog.s135.com/android_apk_zip</a>]<br/><br/>　　前天，金山网络的一位同事向我咨询了一个问题：很多用户反映，网站上提供的Android手机应用程序文件“xxx.apk”，用IE浏览器下载，扩展名就被自动被重命名成了“xxx.zip”，拷贝到手机上无法安装。我发现，由于APK文件本身就是压缩包，如果用户的电脑上装了WinRAR（85%的装机量），用IE下载APK文件，扩展名就会被自动改为“.zip”。<br/><br/>　　如果你的下载服务器为Nginx服务器，那么，在Nginx安装目录下的conf/mime.types文件的对应位置，加上以下一行语句，指定APK文件的MIME类型为 application/vnd.android.package-archive 即可：<br/><br/><div style="border-left: 0px dashed #D6C094; margin: 5px; padding: 3px; margin-bottom:0px; border: 1px dashed #00a0c6; background-color: #ffffff;">application/vnd.android.package-archive&nbsp;&nbsp;&nbsp;&nbsp; apk;</div><br/><br/>　　截至本文发布时，存在“xxx.apk”下载时被自动重命名为“xxx.zip”问题的网站很多，其中不乏一些提供 Android 程序下载的知名网站，例如：新浪微博、街旁网。<br/><br/>　　新浪微博官方 Android 手机客户端下载页：<a href="http://t.sina.com.cn/mobile/android.php" target="_blank">http://t.sina.com.cn/mobile/android.php</a><br/><br/>　　<a href="http://blog.s135.com/attachment/201101/apk_sina_1.jpg" target="_blank"><img src="http://blog.s135.com/attachment/201101/apk_sina_1.jpg" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>　　<a href="http://blog.s135.com/attachment/201101/apk_sina_2.jpg" target="_blank"><img src="http://blog.s135.com/attachment/201101/apk_sina_2.jpg" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>　　街旁 Android 版客户端下载页：<a href="http://we.jiepang.com/client-android/" target="_blank">http://we.jiepang.com/client-android/</a><br/><br/>............<br/><br/>Tags - <a href="http://blog.s135.com/tags/android/" rel="tag">android</a> , <a href="http://blog.s135.com/tags/apk/" rel="tag">apk</a> , <a href="http://blog.s135.com/tags/zip/" rel="tag">zip</a> , <a href="http://blog.s135.com/tags/winrar/" rel="tag">winrar</a> , <a href="http://blog.s135.com/tags/ie/" rel="tag">ie</a>
]]>
</description>
</item><item>
<link>http://blog.s135.com/architect_solitaire/</link>
<title><![CDATA[架构师接龙：盛大许式伟 VS 金山张宴]]></title> 
<author>张宴 &lt;net@s135.com&gt;</author>
<category><![CDATA[系统架构与硬件]]></category>
<pubDate>Thu, 06 Jan 2011 05:12:52 +0000</pubDate> 
<guid>http://blog.s135.com/architect_solitaire/</guid> 
<description>
<![CDATA[ 
	　　（本文来自《程序员》杂志2011年01期，《程序员》官网地址：<a href="http://www.programmer.com.cn/4544/" target="_blank">http://www.programmer.com.cn/4544/</a>）<br/><br/>　　主持人：冯大辉，现任丁香园 （<a href="http://www.dxy.cn" target="_blank">http://www.dxy.cn</a>）网站CTO。曾历任支付宝架构师、数据库团队负责人等职。<br/><br/><a href="http://blog.s135.com/attachment/201101/architect_solitaire.png" target="_blank"><img src="http://blog.s135.com/attachment/201101/architect_solitaire.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0" align="right"/></a>　　<strong>许式伟：作为系统架构师，您一般会从哪些方面来保证网站的高可用性（降低故障时间）？</strong><br/><br/>　　<strong>张宴：</strong>很多因素都会导致网站发生故障，从而影响网站的高可用性，比如服务器硬件故障、软件系统故障、IDC机房故障、程序上线前测试未发现的Bug、遭受分布式攻击、突发访问人数剧增等。<br/><br/>　　一套良好的网站系统架构，应该尽可能地避免只有一台服务器、一个数据库、一套软件节点等单点故障的存在。单点故障一旦发生，将直接导致网站服务不可用，恢复正常服务所需的时间也比较长，甚至还可能无法恢复。负载均衡集群、双节点热备、分布式处理等都可以用来解决单点故障，比如提供相同业务的Web服务器、MySQL数据库从库，都可以构建负载均衡集群。一旦集群中的一台服务器、一个服务出现故障，自动实时摘除，对用户来说是不可感知的，不会影响到整个网站的访问，可以为运维工程师留下足够的时间去排查和解决故障。<br/><br/>　　对于重要的MySQL数据库主库，我们习惯于从硬件层和软件层来实现热备，避免单点。越是复杂的设备，发生故障的概率越大。在磁盘没有损坏的情况下，应用程序导致服务器宕机的概率，远高于简单的磁盘阵列宕机的概率。所以，从硬件层解决的话，可以在两台服务器上安装相同的数据库版本、进行相同的配置，用SAS或SCSI线连接一台磁盘阵列，将数据库数据文件存放到盘阵上。正常情况下用服务器A挂载盘阵分区，启动MySQL，绑定虚拟IP；如果服务器A宕机，则用服务器B挂载盘阵分区，启动MySQL，接管虚拟IP。从软件层解决的话，则可以借助DRBD等软件做镜像。<br/><br/>　　IDC机房发生故障的概率较小，但如果发生的话，影响面也是最大的。如果所有服务器都托管在一个IDC机房，一旦该机房遭遇长时间流量攻击、断电、断网、地方政策性封网等，通常只能联系IDC去处理，除此之外束手无策，解决时间也比较长。如果成本允许，将网站服务器分布在两个以上的IDC机房，当某个IDC发生故障时，可以临时切换DNS域名解析来优先恢复服务。<br/><br/>　　虽然程序代码上线前，经过了测试人员的严格测试，但测试环境和生产环境毕竟有差异，所以一些会急剧影响性能、正常服务的Bug往往在程序上线之后，才会被发现，这就要求我们在发现Bug后，能够迅速回滚到上一正常版本。我们在SVN的基础上，开发了Web代码发布系统，会将每个发布版本之间的文件变更记录下来，一键实现程序代码在多台Web服务器上的发布和回滚。<br/><br/>　　遭遇DDOS分布式拒绝服务攻击，使用防火墙来对付半连接、假IP，还算比较容易。而那种专挑复杂动态应用程序URL进行的分布式CC攻击，来源为真实IP、真实HTTP请求，具有模拟正规浏览器User-Agent、单个IP的每秒请求数不高、有成千上万个攻击源等特征，很难与正常访问区分开，比较难对付。但是，正常通过浏览器访问一个URL，会加载该URL中引入的JavaScript脚本、CSS样式、图片等文件。遇到CC攻击，需要及时分析日志，找出访问量异常上涨的URL，然后用事先写好的shell脚本找出哪些IP的请求只访问了该URL，而不加载该URL引入的文件，对这些IP进行自动封锁。<br/><br/>　　系统架构设计时，需要事先考虑到高于目前访问量多少倍的突发访问。对于网游站点来说，访问量受广告集中时间段投放、线上活动的影响较大，带宽峰值时间不固定，对于静态内容，可以使用商业CDN，按实际使用量计费。对于动态内容，如果遇到突发访问人数剧增，超过现有服务器处理能力，最简单的临时处理办法就是增加服务器。上架新服务器需要时间，但是，同一个IDC机房内，可以借助其他业务的服务器，在不同端口开启一组新进程，加入到原有负载均衡池中。另外，可以临时关闭一些Web中的次要功能，来减少服务器消耗。<br/><br/><hr/><br/>　　<strong>许式伟：您在任务切分上，有什么经验分享？您通过哪些手段保证任务的独立性？</strong><br/><br/>　　<strong>张宴：</strong>相信很多人都遇到过这种情况：在一个老项目上修改、增加一些新功能所花费的时间，不比重新来做一个包含所有功能的新项目时间用得少。一个需要长期维护的项目，不可避免地会面临老员工的离职、新员工的接手，很多时候，项目代码的可维护性将决定一个项目的生存周期。让一个新员工在规定开发时间的压力下，去面对一个文档不够详细、陌生的、功能复杂的庞大项目，短时间弄明白所有功能逻辑不是一件容易的事。所以，任务需要切分，将一个大的任务切分成一个个小模块之后，各模块之间可以做到代码独立，互不影响，可维护性也大大增强。<br/><br/>　　关于任务切分，我以本人今年负责的两个重要项目架构设计为例来介绍一下。在第一个项目：金山游戏官网的《用户行为分析系统》中，由于数据挖掘计算需要消耗较高的内存、CPU资源，一台服务器的处理能力不够，而商业的分布式数据仓库价格又太贵，所以，只有从程序应用中下手，进行任务切分。我们先按需要挖掘的数据指标，将整个数据挖掘任务切分成多个数据挖掘插件，每个插件可以在不同的服务器上运行，多个插件可以同时在多台服务器上。多个数据挖掘插件之间，如果用到相同的某项数据，那么，就将该项数据以冗余方式，复制几份提供给需要的插件，从而实现插件之间无交互、无关联，保证了超大数据量下插件的运算速度。<br/><br/>　　在第二个项目：金山游戏新版运营管理系统中，则将整个任务切分成了PHP Web管理界面、PHP Web API功能接口、C/C++中间件引擎三部分。这是一种分层结构切分，最上层的“PHP Web管理界面”调用“PHP Web API功能接口”，“PHP Web API功能接口”调用运行在游戏服务器端的“C/C++中间件引擎”，“C/C++中间件引擎”与“游戏服务器端进程”通过TCP、UDP二进制协议、信号、命令行等多种方式通信。四者之间相对独立，代码无关联，通过一层层API接口实现交互。“PHP Web管理界面”负责通用界面实现。“PHP Web API功能接口”内部，又按接入的游戏模块、子功能模块进行了更细的切分，各功能模块之间通过内部API交互。“C/C++中间件引擎”大而全，不处理具体指令，但兼容TCP、UDP、HTTP、HTTPS/SSL、信号、命令行等大多数通信方式，负责和各种类型的游戏服务端交互。这是一套完全由API接口驱动的系统架构，一款新游戏接入运营管理系统时，只需在“PHP Web API功能接口”中增加一个模块；一个游戏新管理功能的增加，只需要在“PHP Web API功能接口”中增加一个子模块。通过任务切分，将复杂功能简单化，也将原来接入一款新游戏所需要的几个月时间，缩短为1~2周。<br/><br/><hr/><br/>　　<strong>许式伟：您通过哪些手段，来保障产品的质量？您倾向于多久更新一次您的网站？</strong><br/><br/>............<br/><br/>Tags - <a href="http://blog.s135.com/tags/%25E7%25A8%258B%25E5%25BA%258F%25E5%2591%2598/" rel="tag">程序员</a> , <a href="http://blog.s135.com/tags/%25E6%259E%25B6%25E6%259E%2584%25E5%25B8%2588%25E6%258E%25A5%25E9%25BE%2599/" rel="tag">架构师接龙</a>
]]>
</description>
</item><item>
<link>http://blog.s135.com/buy_house/</link>
<title><![CDATA[龙山华府：一个非常艰难的决定]]></title> 
<author>张宴 &lt;net@s135.com&gt;</author>
<category><![CDATA[心情随笔]]></category>
<pubDate>Sat, 20 Nov 2010 15:26:05 +0000</pubDate> 
<guid>http://blog.s135.com/buy_house/</guid> 
<description>
<![CDATA[ 
	　　当您看到这篇博客的时候，我们刚刚作出了一个非常艰难的决定。在“房价不降反增，<a href="http://news.cz.soufun.com/2010-11-18/4064496.htm" target="_blank">左一个国十条，右一个国五条压不下房价</a>”之前，在“<a href="http://finance.sina.com.cn/roll/20101112/07238942184.shtml" target="_blank">CPI持续增加、通货膨胀、物价飞涨、现金贬值</a>”无法缓解之前，在“贷过两次款，即使卖掉也算第三套房，银行不予放贷的<a href="http://baike.baidu.com/view/3730198.htm" target="_blank">认房又认贷</a>政策”结束之前，我和老婆经过商量，决定拿出手中拥有的全部现金，卖掉在香港股市的全部股票，变现在宇通客车公司的全部债券投资，刷光信用卡的4万元限额，再通过多方筹借现金40万元，以打完97折后的总价145万元，全款买下位于昌平区的“<a href="http://house.focus.cn/votehouse/2801.html" target="_blank">龙山华府</a>”4号楼的一套3室2厅1卫，101.89平米，南、北、西三面通透，2011年底交房。<br/><br/>　　今年年底，地铁昌平线开通，可乘地铁昌平线到达西二旗站，与13号线换乘。如果入住后买辆车，可以直接走八达岭高速到金山软件大厦。<br/><br/>　　今天，交了10万元订金，和开发商签订了《北京市商品房认购书》。下周交付剩余的135万元。此役之后，手无分文，所有投资只保留美股市场的部分资金和青岛的一处房产，打算借此在两年内归还40多万元借款。<br/><br/>　　也许，只有那么一天，当通货膨胀、货币贬值的速度超过了房价的涨速，房价才会相对地降下来。有史可鉴，人民日报1989年2月20日第2版：“北京最近提供2万多平方米住房，每平方米1600元至1900元。若买两居室，少说也要6万多元。一名大学生从参加工作起就日日节衣缩食，每月存储50元，已是极限，100年才能买上两居室。”如今，20年过去了，按照当时那样的攒钱法到现在，6万元能买个几平米？<br/><br/>　　小区效果图：<br/>　　<a href="http://blog.s135.com/attachment/201011/wg.jpg" target="_blank"><img src="http://blog.s135.com/attachment/201011/wg.jpg" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>　　户型图（点击图片看大图）：<br/>　　<a href="attachment/201011/hx.jpg" title="点击看大图"><img src="attachment/201011/hx_min.jpg" border="0"></a><br/><br/><br/>Tags - <a href="http://blog.s135.com/tags/%25E9%25BE%2599%25E5%25B1%25B1%25E5%258D%258E%25E5%25BA%259C/" rel="tag">龙山华府</a> , <a href="http://blog.s135.com/tags/%25E4%25B9%25B0%25E6%2588%25BF/" rel="tag">买房</a> , <a href="http://blog.s135.com/tags/%25E6%2588%25BF%25E4%25BB%25B7/" rel="tag">房价</a>
]]>
</description>
</item><item>
<link>http://blog.s135.com/nasdaq_stock/</link>
<title><![CDATA[纳斯达克之旅：我的美股投资实录]]></title> 
<author>张宴 &lt;net@s135.com&gt;</author>
<category><![CDATA[在商言商]]></category>
<pubDate>Sun, 07 Nov 2010 16:01:31 +0000</pubDate> 
<guid>http://blog.s135.com/nasdaq_stock/</guid> 
<description>
<![CDATA[ 
	　　5月开始炒美股，投入资金不多，2500美元（按当时汇率为17000元人民币）。几个月来，一直在摸索，其间有赚有赔，到9月下旬，只实现盈亏平衡。但也就是在9月下旬，我摸索出了一条“超短线美股投资”道路。<br/><br/>　　于是，在10月一个月，实现了净利润1708美元（11366元人民币）。11月，继续保持这种势头，11月1日至4日的短短四天，净利润466.57美元（3105元人民币）。相对于2500美元的成本，现在的投资回报率已经达到87%，相信在下周末之前即可超过100%。<br/><br/>　　<strong>一、关于美股</strong><br/><br/>　　很多网站介绍美股时，都不详细，很多细节没有介绍到，我这里就做一个详细的介绍吧：<br/><br/>　　<strong>1、开户</strong><br/>　　⑴、开户年龄需满20岁；<br/>　　⑵、开户免费，没有最低开户金额限制（但一些美国证券公司要求至少500美元）；<br/>　　⑶、非美国人（国际账户）买卖股票不征税；<br/>　　⑷、只需要证券账户即可，不需要额外开立美国银行账户；<br/>　　⑸、开通一个证券账户，可以交易美国纽约交易所、纳斯达克、美国证券交易所的股票；<br/>　　⑹、开户需填写《开户申请表》、《W-8BEN 表格》：W-8BEN 表格是用作向美国国税局 Internal Revenue Service) 申报非美国人士身份的文件。此表格是需要每 3 年更新一次。否则，于 W-8BEN 表格过期后后所进行之美股交易将不会再按非美国人士之标准征税。<br/>　　⑺、记得填写融资账户申请单，开通融资账户。默认的现金账户只能做T+3交易。<br/>　　⑻、更多关于开户的信息可以参考：<a href="http://www.firstrade.com/content/zh-cn/international" target="_blank">http://www.firstrade.com/content/zh-cn/international</a><br/><br/>　　<strong>2、账户类型</strong><br/>　　<strong>⑴、现金账户：</strong><br/>　　①、只能做T+3交易，也就是当天买的股票只能第3天才能卖掉，否者，你的账户将被限制90天内禁止买卖股票。<br/>　　②、现金账户只能做“买进、卖出”交易，不能做“卖空、卖空补回”交易。<br/>　　③、现金账户没有融资购买力，现金是多少，就只能买多少钱的股票。<br/><br/>　　<strong>⑵、融资账户：</strong><br/>　　①、最低开户金额为2000美元（汇款时会扣几美元的国际银行中转费，所有尽量比2000美元多一点），可以做T+0当日冲销。当日冲销，也就是说可以当天“买进、卖出”同一支股票。<br/>　　②、对于非美国公民，融资账户具有2倍的融资购买力（美国公民为4倍），也就是说，假如你投入2500美元，就可以买价值5000美元的股票。假设你卖出股票后赚了1000美元，现在账户总值为3500美元，就可以买价值7000美元的股票。融资买进股票每股必须高于4美元，有些股票无法融资交易系统将自动驳回订单。看板市场或店头小型股不可用融资买卖。<br/>　　③、融资账户可以做“卖空、卖空补回”交易。“卖空”就相当于买跌，对应“卖空补回”是一对交易。假设现在新浪的股价为59.14美元，你觉得新浪股价会下跌，而此时你手中又没有新浪股票，你就可以“卖空”，从证券公司借来新浪的股票卖掉，在新浪股价下跌后，再“卖空补回”，买进新浪股票还给证券公司，赚钱差价。卖空的股价必须高过4美元，同时您帐户资产总值必须到达卖空总价值的50%［纳斯达克为100%］。<br/>　　④、融资的那部分钱，是需要付利息的。只有动用融资账户的钱买了股票，才计算利息，买了股票第二天卖掉，就按买股票时的价值，计算一天的利息。如果做当日冲销，当天买、当天卖，就不扣利息。其实，融资的利息没多少，这是我9月、10月的融资利息，10月当日冲销比较多，利息不到4美元。<br/><br/>　　<a href="http://blog.s135.com/attachment/201011/meigu-lx.png" target="_blank"><img src="http://blog.s135.com/attachment/201011/meigu-lx.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/><br/>　　<strong>3、美股交易</strong><br/>　　⑴、美股的最小交易单位为1股。<br/>　　⑵、美股为单一手续费，无论你买卖多少股，买进一次佣金为6.95美元，卖出一次佣金也为6.95美元（以Firstrade.com证券公司的佣金为例），无其他费用。“卖空、卖空补回”的佣金也是一样。<br/>　　⑶、美国股市的交易时间是在中国北京时间的夜里（非工作时间），换算成北京时间，美股夏令是晚上9:30开盘，清晨4:00收市；冬令则晚上10:30开盘，清晨5:00结束。美国股市的一天交易时间是不间断的，也就是说“中午不休息”。<br/>　　⑷、盘前盘后交易就是在非正常开盘时段（开盘前1个半小时及收盘后1个半小时）也可以进行交易。盘前和盘后交易的交易量不高，流动性不强，买卖价差（Bid Ask Spread）也较高。如果遇到发布财报等重要经济交易事件，则可以在盘前或盘后预先交易。<br/><br/>............<br/><br/>Tags - <a href="http://blog.s135.com/tags/nasdaq/" rel="tag">nasdaq</a> , <a href="http://blog.s135.com/tags/stock/" rel="tag">stock</a> , <a href="http://blog.s135.com/tags/%25E7%25BE%258E%25E8%2582%25A1/" rel="tag">美股</a> , <a href="http://blog.s135.com/tags/%25E8%2582%25A1%25E7%25A5%25A8/" rel="tag">股票</a> , <a href="http://blog.s135.com/tags/%25E4%25B8%25AD%25E5%259B%25BD%25E6%25A6%2582%25E5%25BF%25B5%25E8%2582%25A1/" rel="tag">中国概念股</a> , <a href="http://blog.s135.com/tags/%25E7%2599%25BE%25E5%25BA%25A6/" rel="tag">百度</a> , <a href="http://blog.s135.com/tags/%25E6%2596%25B0%25E6%25B5%25AA/" rel="tag">新浪</a> , <a href="http://blog.s135.com/tags/%25E7%25BA%25B3%25E6%2596%25AF%25E8%25BE%25BE%25E5%2585%258B/" rel="tag">纳斯达克</a> , <a href="http://blog.s135.com/tags/%25E7%25BA%25BD%25E7%25BA%25A6%25E8%25AF%2581%25E5%2588%25B8%25E4%25BA%25A4%25E6%2598%2593%25E6%2589%2580/" rel="tag">纽约证券交易所</a> , <a href="http://blog.s135.com/tags/%25E7%25BE%258E%25E5%259B%25BD%25E8%25AF%2581%25E5%2588%25B8%25E4%25BA%25A4%25E6%2598%2593%25E6%2589%2580/" rel="tag">美国证券交易所</a>
]]>
</description>
</item>
</channel>
</rss>
