分类 生活 下的文章

还是信号量占满了(平均2天一次),我没时间查代码。
跟据在线服务稳定第一的原则, 我还是写了一个脚本,2小时清理一次。

一个在线服务要上线,常会出现,测试机正常放到线上就出错的情况。
我们团队在上周就经历过这种情况。
解决的办法一般有log重放和旁路测试。相对来说,旁路测试更有效。
所谓旁路测试是制将 对线上服务器LS访问的流量,拷贝一份给测试服务程序TS。而响应返回则是有LS完成,TS的返回被丢弃或者记录
我写了一个通用的程序(基于tiwstd,理解思路不基于也很容易,基于twisted 能够很快完成一个可用的系统,当然也可以自己封装网络通信框架实现灵活和快捷,这是题外话),能够支持旁路测试的无缝切换,且能够支持一组旁路测试服务器。(也即旁路测试服务器可以有TS1 TS2...) 。
程序如下(我现在就在旁路测试情况下发文的,nklog系统目前就在旁路测试中:)),今天太晚了就不解释了。
from twisted.internet.protocol import Protocol, ClientFactory, ServerFactoryfrom twisted.internet import reactor  import time   import sys#ABTestServer A is Online Server ;B is Testing Server#The IPtable rules to support follows:#/sbin/iptables -t nat -A PREROUTING -p tcp -i eth0 -s ! 60.28.222.137 -d 60.28.222.137   --dport 8301  -j DNAT --to 60.28.222.137:80#echo 1 >/proc/sys/net/ipv4/ip_forward class ServerHost:    host=""    port=0class ServerConnector:        passclass ForwardServer(Protocol):    def __init__(self, hostA, portA,hostsB):        self.hostA = hostA        self.portA = portA        self.hostsB = hostsB        self.data = ""        self._connected = False    def dataReceived(self, data): #From Client To FWServer         self.data += data        if (len(self.data) > 0):            self.connectorA.connector.transport.write(self.data)        for aBConnector in self.connectorsB:            aBConnector.connector.transport.write(self.data)            self.data = ""    def connectionMade(self):        self.beginTime=time.time()        print "INFO:: client connection made"        aClientFC = ForwardClientFactory(self,1)        aServConnector=ServerConnector()        aServConnector.connector = reactor.connectTCP(self.hostA, self.portA, aClientFC)        self.connectorA=aServConnector        self.connectorsB=[]        for aBHost in self.hostsB:                bClientFC = ForwardClientFactory(self,0)                bServConnector=ServerConnector()                bServConnector.connector = reactor.connectTCP(aBHost.host, aBHost.port, bClientFC)                self.connectorsB.append( bServConnector )    def setConnected(self, flag):        if flag:            self.onConnected()        else:            self.transport.loseConnection()                                                                self._connected = flag      def onConnected(self):        if len(self.data) > 0:            self.connectorA.connector.transport.write(self.data)            for aBConnector in self.connectorsB:                aBConnector.connector.transport.write(self.data)            self.data = ""    def connectionLost(self, reason):        self.connectorA.connector.transport.loseConnection()        for aBConnector in self.connectorsB:            aBConnector.connector.transport.loseConnection()        self._connected = False        print "Lost Connection "+ str( (time.time()-self.beginTime) )+" secs"class ForwardClient(Protocol):    def __init__(self, forward,ctype):        self.forward = forward        self.type=ctype
self.bConnected=False    def dataReceived(self, data):  #From FWServer to Client#       print self.type        if self.type !=0 : #Send To A only                 self.forward.transport.write(data)    def connectionMade(self):        self.bConnected=True    def connectionLost(self, reason):        self.bConnected=False        if self.type!=0:            self.forward.transport.loseConnection()            self.forward.connectionLost("client lost"        else:            pass            #self.transport.loseConnection()class ForwardServerFactory(ServerFactory):    def __init__(self, host, port,hostsB):        self.host = host        self.port = port        self.hostsB=hostsB    def buildProtocol(self, addr):        return ForwardServer(self.host, self.port,hostsB)class ForwardClientFactory(ClientFactory):    def __init__(self, forward,ctype):        self.forward = forward        self.type=ctype    def buildProtocol(self, addr):        return ForwardClient(self.forward,self.type)    def clientConnectionFailed(self, connector, reason):        self.forward.transport.loseConnection()        self.forward.connectionLost("client connect failed"if __name__ == "__main__":    if len(sys.argv) != 5:        print "USAGE: %s " % sys.argv[0]        sys.exit(1)    host, port, listen_port = sys.argv[1], int(sys.argv[2]), int(sys.argv[3])                                                                                         strFHostsB=sys.argv[4]    fHostsB=open(strFHostsB)    lines = fHostsB.readlines()    hostsB=[]    for aLine in lines:        aLine=aLine.replace("
",""        aLine=aLine.replace("
",""        segs = aLine.split(" "        if len(segs) != 2:                continue        servHost = ServerHost()        servHost.host=segs[0]        servHost.port=int(segs[1])        hostsB.append(servHost)    print "INFO:: Load B Host "+str(len(hostsB))    server_factory = ForwardServerFactory(host, port,hostsB)    reactor.listenTCP(listen_port, server_factory)    reactor.run()
举例说明如下
http服务旁路测试数据转发
80--iptables->8300(python abtest.py ...)
8300--abtester-->80(apache )
8300--abtester-->8310(tcpeserver 0.0.0.0 8310./a.out)

我就会一点php,最近才又开始学习。。
--------------------------------
发现php中没有类似asp jsp的application对象。连页面内的长存对象都没有。
写一个计数器都需要文件读写或者用数据库,或者数据库加memcached.到网上看到用人用文件来模拟application。
改进了一下,使用共享内存shompapi,使用序列化,使用构造和析构函数 。但是仍然不适合大规模使用,因为由于php中没有指针,所以不可避免需要内存拷贝。
不过其实用shm_ attach序列aip能够更高效率实现。
我的封装的使用方法如下
require_once("shmop_app.php"
调用示范,计数器代码如下
1   5   6

  7   8 You are visitor number  9  10 to this web site. 11  12

 13
smop_app.php代码 如下
1 application_start(); 32    } 33  34    function __destruct() { 35        $this->application_end(); 36    } 37 } 38  39 $gOApp = new CAppObj; 40 ?>

招聘的公司非常多,有的电话都打到我这来了。
不过产品经理这个东西很微妙,在很多公司产品经理成为被一些研发背地里埋怨头脑有问题的人。而产品经理在每个公司角色各不相同, 在同一公司产品经理的工作职责都不固定。
据说百度的产品经理很成功,其实我觉得贴吧真的挺烂的。
我的意见:产品经理对个人要求很高,也应该能够集中智慧和发挥团队潜力的。并不是任命一些产品经理,产品就专业化了。 无胜于差。
产品助理好招,产品经理不好招。

---
住房的郁闷
作者: onebird
发布时间: 2007-07-29 12:54
分类: 生活

本来北京房价高就很郁闷但是郁闷的不只是房价。年初为了让父母偶尔能过来玩可以方便居住,自己自学工作有一个好的书房。将之前租的一居室换成地坛公园了两居室。果然环境很好,心情很好,和安静。但是。。自从租了两居室后,我和ww的同学的朋友纷至沓来,放东西的放东西,找工作的找工作,出差的出差,上课的上课。时间从几天的到几个月的。倒不是小气,白租了两居室,是觉得自己一直希望有一个安静的环境,但是反而没有。上班劳累之后,回家还要招待客人。我只希望一个自己的空间。但是没办法,北京租房宾馆价格都不菲,人家从外地而来总是应该能节省些。我想即使另外再租一间房子专供外地朋友来京也未必就能解决问题呢,
即使自己买房子还是不解决问题呢

2年多前,看了一个下午的电子书,写了一个晚上,狂丑(不过现在python程序也写的很丑)。
---------------------------------------------------------------------

import urllibimport threadimport urlparseimport pullparser, sysimport re
def getPhoto(surl,burl,sfname,bfname):        wps = open(sfname, "wb"           fps = urllib.urlopen(surl)        n=0        while 1:            s = fps.read(8192)            if not s:                break            wps.write(s)            n = n + len(s)        fps.close()        wps.close()
wpb = open(bfname ,"wb"        fpb = urllib.urlopen(burl)        k=0        while 1:            b = fpb.read(8192)            if not b:                break            wpb.write(b)            k = k + len(b)        fpb.close()        wpb.close()        print "copied "+str(n)+" " +str(k)+" from "+"  "+surl+"  "+burl

#以下是 网易相册中 某一目录的链接地址
DirURL ="http://photo.163.com/openalbum.php?username=帐号&_dir=%目录号&page="
pat = r'(S*)/__scale__1_(S*.jpg$)' # My patternr = re.compile(pat) # Compile it
for i in [1, 2, 3, 4, 5 ,6 ,7]:    baseURL=DirURL+str(i)    print "baseURL ="+baseURL    usock = urllib.urlopen(baseURL)   # print usock.read()    p = pullparser.PullParser(usock)    for token in p.tags("img":        if token.type == "endtag": continue        print "hello
"        imgurl = dict(token.attrs).get("src", "-"        print imgurl+"
"        m = r.match(imgurl) # See if string s matches        if not m:            continue ;        surl=imgurl;        burl=m.group(1)+"/"+m.group(2)        sfname = "s"+m.group(2)        bfname ="b"+m.group(2)                print "surl "+surl+" "+sfname+"
"        print "burl "+burl+" "+bfname+"
"        try:            thread.start_new_thread(getPhoto,(surl,burl,sfname,bfname))        except IOError:            print "!!!IOException
"

1 # -*- coding: gbk -*-  2 #!/usr/bin/env python  3 from sets import Set  4 import os  5 import md5  6 class CAvoidSame:  7         def __init__(self,md5fname):  8                 self.md5fname = md5fname;  9                 self.md5set = Set() 10                 if os.path.exists( self.md5fname ) == False: 11                         fMD5=open(self.md5fname,"w+" 12                         fMD5.close() 13                         return  14                 else: 15                         fMD5=open(self.md5fname,"r+" 16                         while True: 17                                 md5data = fMD5.read(16) 18                                 md5datalen = len(md5data) 19                                 if md5datalen == 16: 20                                         self.md5set.add(md5data) 21                                         continue 22                                 if md5datalen == 0: 23                                         fMD5.close() 24                                         break 25                                 nToFill = 16 - md5datalen 26                                 while nToFill > 0: 27                                         md5data+="0" 28                                         fMD5.write("0" 29                                         nToFill-=1 30                                 self.md5set.add(md5data) 31                                 fMD5.close() 32                                 break 33         def IsInAddIfNot(self,aStr): 34                 m = md5.new(aStr) 35                 bIsIn = m.digest() in self.md5set 36                 if bIsIn == False: 37                         fMD5 = open(self.md5fname,"a" 38                         fMD5.write(m.digest()) 39                         fMD5.close() 40                         self.md5set.add(m.digest()) 41                 return bIsIn 42                          43          44 if __name__ == "__main__":
45         avoidSame = CAvoidSame("test.md5" 46         print avoidSame.IsInAddIfNot("aaa" 47         print avoidSame.IsInAddIfNot("bbb" 48         print avoidSame.IsInAddIfNot("ccc" 49         print avoidSame.IsInAddIfNot("aaa" 50         print avoidSame.IsInAddIfNot("bbb" 51         print avoidSame.IsInAddIfNot("ddd"

下午去了 公园门票十元  红五月歌会二十元 下午了有何洁 安又琪 rebon等 音效不算好,不过还挺有意思的。(在草地上听音乐会)。 连续7天(除了红五月歌会还有一些其他活动) 大家有兴趣地还可以去。

演 出日程
Btw 能带一个公司的宣传画去做广告更好了。(人多效果好啊)

用了两个周末的时间。

实现了几个特点
1 网络和链接管理部分模块化。(目前用线程池实现 但是可以替换epoll)
CWebServer
2 http协议解析部分模块化.(这个是应该的。。)
CHttpProcessor
3 采用注册Handler的方式
CHttpHandler
不过写完之后(真的是写完之后看的)我看了看apache的源码,发现加Handler的思路和apache的类似。
不过由于我的是标准C++写的,发现可以做一个有趣的用途。
给公司代码做基于web的单元测试。。。
因为接口非常简单,试验了一下非常方便输入测试用力和产看结果。(下周介绍给同事玩玩)
不过由于模块化还是非常好的。我试了一下很容易的改成httpproxy 和 http cache Server
同时也给一个师弟做毕业设计用了。

Kooxoo 酷讯公司招聘
作者: onebird
发布时间: 2007-04-30 15:30
分类: 工作