<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
 
 <title>Work Note</title>
 
 <updated>2011-12-27T18:58:02-08:00</updated>
 <id>http://jessinio.github.com</id>
 <author>
   <name>jessinio</name>
   <email>jessinio@gmail.com</email>
 </author>

 
 <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/jessinio/sPJd" /><feedburner:info uri="jessinio/spjd" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:browserFriendly></feedburner:browserFriendly><entry>
   <title>network hangup</title>
   <link href="http://jessinio.github.com/linux/2011/12/27/read-hangup.html" />
   <updated>2011-12-27T00:00:00-08:00</updated>
   <id>http://jessinio.github.com/linux/2011/12/27/read-hangup</id>
   <content type="html">&lt;p&gt;前几天因工作需要，使用python的httplib库写了一个简单的测试服务脚本。但是出现个好玩的问题。&lt;br /&gt;
这里描述一下：&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;client端 即运行脚本的服务器&lt;/li&gt;
	&lt;li&gt;server端 即被脚本访问的服务器&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果server突然crash后, client端的脚本会出现一直hangup的情况(不是100%出现)&lt;/p&gt;
&lt;p&gt;下面就是在现场找到的信息:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@lvs1_s ~&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="c"&gt;# strace -p 18235 (脚本的PID号)&lt;/span&gt;
Process 18235 attached - interrupt to quit
&lt;span class="nb"&gt;read&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;8, ^C &amp;lt;unfinished ...&amp;gt;
Process 18235 detached
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;一直hangup在read系统调用中, file descriptor 8是什么? 查看一下:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@lvs1_s ~&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="c"&gt;# lsof -p 18235|grep 8u&lt;/span&gt;
python  18235 root    8u  IPv4 23796661      0t0      TCP 58.xxx.xx.116:36217-&amp;gt;58.xxx.xx.85:https &lt;span class="o"&gt;(&lt;/span&gt;ESTABLISHED&lt;span class="o"&gt;)&lt;/span&gt;
python  18235 root   88u  IPv4 23795354      0t0      TCP self:49292-&amp;gt;10.176.22.42:https &lt;span class="o"&gt;(&lt;/span&gt;ESTABLISHED&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;可以看出， 是socket。抓包也不见有任何数据:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@lvs1_s ~&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="c"&gt;# tcpdump -i eth1 -n &amp;#39;ip host 58.xxx.xx.85 and port 443&amp;#39;&lt;/span&gt;
tcpdump: verbose output suppressed, use -v or -vv &lt;span class="k"&gt;for &lt;/span&gt;full protocol decode
listening on eth1, link-type EN10MB &lt;span class="o"&gt;(&lt;/span&gt;Ethernet&lt;span class="o"&gt;)&lt;/span&gt;, capture size 65535 bytes
^C
0 packets captured
0 packets received by filter
0 packets dropped by kernel
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;解决这个问题,可以有几种方法,比如:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;使用thread&lt;/li&gt;
	&lt;li&gt;使用child process&lt;/li&gt;
	&lt;li&gt;不使用httplib, 直接使用socket,这样可以使用更多的IO特性&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;选1的话,把thread给hangup了也是个问题.&lt;br /&gt;
选2的话,看上去不够优雅&lt;br /&gt;
选3的话,又懒得去分析HTTP协议, 特别是https!.&lt;/p&gt;
&lt;p&gt;经过测试,发现只有https才会有这种问题. 测试方法如下:&lt;/p&gt;
&lt;p&gt;client端:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="text"&gt;    import os
    import traceback
    import sys
    import threading
    import httplib
    import ssl

    connection = httplib.HTTPSConnection(host=&amp;quot;10.241.31.44&amp;quot;, port=8082, timeout=7)
    connection.request(&amp;quot;GET&amp;quot;, &amp;quot;/&amp;quot;, headers={})
    response = connection.getresponse()
    print response.status, response.read()
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;server端:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="text"&gt;    import os
    import sys
    import traceback
    import socket
    import select
    import time


    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind((&amp;#39;0.0.0.0&amp;#39;, 8082))
    sock.listen(10)

    while True:
        try:
            s = sock.accept()[0]
            fd = s.fileno()
            fd_list = [fd]

            write_list = select.select([], fd_list, [])[1]
            d = 0
            for fd in write_list:
                time.sleep(50) # 为了方便重现问题这里sleep, 在这50秒里把网线拨了就出现hangup
                os.close(fd)
                fd_list.remove(fd)
        except:
            traceback.print_exc()
            print &amp;#39;error!&amp;#39;

        time.sleep(5)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;为了找个这个问题的原因, 查看httplib库的HTTPSConnection类,发现它的作用和下面的代码一致(当然也引发了这个hangup的问题):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="text"&gt;    import socket
    import ssl

    timeout = 10
    socket.setdefaulttimeout(timeout)

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    sock.connect((&amp;quot;10.241.31.44&amp;quot;, 8082))
    ssl_sock= ssl.wrap_socket(sock, None, None)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;很显示,问题出在ssl库的上. 再跟进ssl库,可以看到如下的代码:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="text"&gt;            # yes, create the SSL object
            self._sslobj = _ssl.sslwrap(self._sock, server_side,
                                        keyfile, certfile,
                                        cert_reqs, ssl_version, ca_certs)
            if do_handshake_on_connect:
                timeout = self.gettimeout()
                try:
                    self.settimeout(None)
                    self.do_handshake()
                finally:
                    self.settimeout(timeout)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;我靠! 因为do_handshake_on_connect参数, 让HTTPSConnection类实例化时timeout参数在do_handshake()之前被清了. fuck~~~~~~&lt;/p&gt;
&lt;p&gt;看到只能把HTTPSConnection类的connect方法override一下了.&lt;/p&gt;
&lt;p&gt;HTTPSConnection原代码是这样的:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="text"&gt;    class HTTPSConnection(HTTPConnection):
        &amp;quot;This class allows communication via SSL.&amp;quot;

        default_port = HTTPS_PORT

        def __init__(self, host, port=None, key_file=None, cert_file=None,
                     strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
            HTTPConnection.__init__(self, host, port, strict, timeout)
            self.key_file = key_file
            self.cert_file = cert_file

        def connect(self):
            &amp;quot;Connect to a host on a given (SSL) port.&amp;quot;

            sock = socket.create_connection((self.host, self.port), self.timeout)
            if self._tunnel_host:
                self.sock = sock
                self._tunnel()
            self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;把connect方法override:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="text"&gt;    import socket
    import os
    import traceback
    import sys
    import threading
    import httplib
    import ssl

    from _ssl import CERT_NONE, PROTOCOL_SSLv23

    class MyHTTPSConnection(httplib.HTTPSConnection):

        def connect(self):
            &amp;quot;Connect to a host on a given (SSL) port.&amp;quot;

            sock = socket.create_connection((self.host, self.port), self.timeout)
            if self._tunnel_host:
                self.sock = sock
                self._tunnel()
            #self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file)
            self.sock = ssl.wrap_socket(sock, keyfile=None, certfile=None,
                            server_side=False, cert_reqs=CERT_NONE,
                            ssl_version=PROTOCOL_SSLv23, ca_certs=None,
                            do_handshake_on_connect=False,
                            suppress_ragged_eofs=True)
            # 在允许超时的情况下调用do_handshake()
            self.sock.do_handshake()

    connection = MyHTTPSConnection(host=&amp;quot;10.241.31.44&amp;quot;, port=8082, timeout=7)
    connection.request(&amp;quot;GET&amp;quot;, &amp;quot;/&amp;quot;, headers={})
    response = connection.getresponse()
    print response.status, response.read()
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;哈, override后的MyHTTPSConnection一切正常&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>windows文本编辑器</title>
   <link href="http://jessinio.github.com/linux/2011/10/15/notepad-plus-plus.html" />
   <updated>2011-10-15T00:00:00-07:00</updated>
   <id>http://jessinio.github.com/linux/2011/10/15/notepad-plus-plus</id>
   <content type="html">&lt;p&gt;为了使用公司的VPN和公司内部服务，只能使用windows。&lt;br /&gt;
有时需要在windows下编辑文件，还是需要熟悉一下此环境。&lt;br /&gt;
首先是回车问题：&lt;br /&gt;
&lt;img src="http://blog.jessinio.info/images/notepad++_newline_format.jpg" alt="" /&gt;&lt;br /&gt;
最好是显示new line符：&lt;br /&gt;
&lt;img src="http://blog.jessinio.info/images/notepad++_display_newline.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;还有万恶的BOM头！！&lt;br /&gt;
&lt;img src="http://blog.jessinio.info/images/notepad++_without_bom.png" alt="" /&gt;&lt;br /&gt;
最讨厌的就是加入BOM了，常常会为这种屁字节调试N久。下面对比有BOM与没有BOM的文件：&lt;br /&gt;
&lt;img src="http://blog.jessinio.info/images/notepad++_bom.png" alt="" /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>arp annoucement</title>
   <link href="http://jessinio.github.com/linux/2011/10/15/arp-announcement.html" />
   <updated>2011-10-15T00:00:00-07:00</updated>
   <id>http://jessinio.github.com/linux/2011/10/15/arp-announcement</id>
   <content type="html">&lt;p&gt;又忘记了arp announcement就是gratuitous ARP了（旧blog: http://jessinio.blogspot.com/2010/12/ethernet.html）&lt;/p&gt;
&lt;p&gt;回顾一下：arp announcement的作用：&lt;/p&gt;
&lt;p&gt;&lt;/notextile&gt;&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;http://en.wikipedia.org/wiki/Address_Resolution_Protocol#ARP_announcements&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;linux kernel 2.6.x使用一个特殊的flag来处理这个问题：&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;http://www.austintek.com/&lt;span class="caps"&gt;LVS&lt;/span&gt;/&lt;span class="caps"&gt;LVS&lt;/span&gt;-&lt;span class="caps"&gt;HOWTO&lt;/span&gt;/&lt;span class="caps"&gt;HOWTO&lt;/span&gt;/&lt;span class="caps"&gt;LVS&lt;/span&gt;-&lt;span class="caps"&gt;HOWTO&lt;/span&gt;.arp_problem.html#2_6_arp_announce&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;随便提一下， ipvs文档（http://www.linuxvirtualserver.org/docs/arp.html）里使用hidden这个flag，这在2.6.x kernel时代被去掉了。&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>static route rule</title>
   <link href="http://jessinio.github.com/linux/2011/09/26/linux-static-route-rule.html" />
   <updated>2011-09-26T00:00:00-07:00</updated>
   <id>http://jessinio.github.com/linux/2011/09/26/linux-static-route-rule</id>
   <content type="html">&lt;h2&gt;centOS&lt;/h2&gt;
&lt;/notextile&gt;

此脚本的内容：
&lt;notextile&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;FILES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/etc/sysconfig/network-scripts/route-$1&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; -n &lt;span class="s2"&gt;&amp;quot;$2&amp;quot;&lt;/span&gt; -a &lt;span class="s2"&gt;&amp;quot;$2&amp;quot;&lt;/span&gt; !&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;$1&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="k"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;FILES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;$FILES /etc/sysconfig/network-scripts/route-$2&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;file in &lt;span class="nv"&gt;$FILES&lt;/span&gt;; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="k"&gt;   if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; -f &lt;span class="s2"&gt;&amp;quot;$file&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="k"&gt;       if &lt;/span&gt;egrep -q &lt;span class="s1"&gt;&amp;#39;^[[:space:]]*ADDRESS[0-9]+=&amp;#39;&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt; ; &lt;span class="k"&gt;then&lt;/span&gt;
           &lt;span class="c"&gt;# new format&lt;/span&gt;
           handle_file &lt;span class="nv"&gt;$file&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="p"&gt;%:*&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
       &lt;span class="k"&gt;else&lt;/span&gt;
           &lt;span class="c"&gt;# older format&lt;/span&gt;
           &lt;span class="o"&gt;{&lt;/span&gt; cat &lt;span class="s2"&gt;&amp;quot;$file&amp;quot;&lt;/span&gt; ; &lt;span class="nb"&gt;echo&lt;/span&gt; ; &lt;span class="o"&gt;}&lt;/span&gt; | &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read &lt;/span&gt;line; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="k"&gt;               if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; ! &lt;span class="s2"&gt;&amp;quot;$line&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;~ &lt;span class="s1"&gt;&amp;#39;^[[:space:]]*(\#.*)?$&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;; &lt;span class="k"&gt;then&lt;/span&gt;
                   /sbin/ip route add &lt;span class="nv"&gt;$line&lt;/span&gt;
               &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="k"&gt;           done&lt;/span&gt;
&lt;span class="k"&gt;       fi&lt;/span&gt;
&lt;span class="k"&gt;   fi&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2&gt;ubuntu&lt;/h2&gt;</content>
 </entry>
 
 <entry>
   <title>git笔记</title>
   <link href="http://jessinio.github.com/tools/2011/09/17/git-note.html" />
   <updated>2011-09-17T00:00:00-07:00</updated>
   <id>http://jessinio.github.com/tools/2011/09/17/git-note</id>
   <content type="html">&lt;h2&gt;git与svn的区别：&lt;/h2&gt;
&lt;ol&gt;
	&lt;li&gt;本地working tree是一个完整的仓库。&lt;/li&gt;
	&lt;li&gt;clone来的本地仓库与源仓库没有从属关系。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;使用git时容易受svn用法的影响的地方：&lt;/h2&gt;
&lt;ol&gt;
	&lt;li&gt;commit不是本地与源的数据交流方法，而是利用pull和push进行两个仓库之前的数据交流。&lt;/li&gt;
	&lt;li&gt;使用分支是良好的习惯。&lt;/li&gt;
	&lt;li&gt;diff不仅仅是同一分支的版本比较，还可以比较不同分支的版本。&lt;/li&gt;
	&lt;li&gt;checkout是在本地仓库上进行分支切换&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;本地仓库与git的分支管理&lt;/h2&gt;
&lt;h2&gt;使用diff&lt;/h2&gt;</content>
 </entry>
 
 <entry>
   <title>上海沈家海鲜面</title>
   <link href="http://jessinio.github.com/life/2011/09/17/first-post.html" />
   <updated>2011-09-17T00:00:00-07:00</updated>
   <id>http://jessinio.github.com/life/2011/09/17/first-post</id>
   <content type="html">&lt;p&gt;测试发布博文&lt;/p&gt;
&lt;p&gt;再测试代码的highlight&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="python"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
	&lt;span class="s"&gt;&amp;#39;test function&amp;#39;&lt;/span&gt;
	&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Hello World&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img src="http://blog.jessinio.info/images/shenjia_noodles_shanghai.jpg" alt="" /&gt;&lt;/p&gt;</content>
 </entry>
 
 
</feed>

