twisted的一些代码

之前用swoole写的一段程序在数据量大的时候存在内存泄漏,改为twisted实现,自测无误,记录如下(压力测试cpu占用从80%降到20%,吞吐rps从120提升到280)。

#!/usr/bin/env python

from twisted.internet import task, reactor
from twisted.python import log
from twisted.web import static, server, resource
import MySQLdb
import json

class RotateMap(object):
    def __init__(self):
        self.using = 0
        self.unuse = 1
        self.map = [{},{}]

    def find(self, key):
        if self.map[self.using].has_key(key):
            return self.map[self.using][key]
        return False

    def set(self, nmap):
        self.map[self.unuse] = nmap
        self._swap()

    def get(self):
        return self.map[self.using]

    def _swap(self):
        self.using,self.unuse = self.unuse,self.using

check = RotateMap()
allow = RotateMap()
start = RotateMap()

log.startLogging(open("/tmp/tserver.log",‘w‘))

class TServer(resource.Resource):
    isLeaf = True
    def getChild(self, name, request):
        if name == ‘‘:
            return self
        return Resource.getChild(self, name, request)

    def render_GET(self, request):
        if request.requestHeaders.hasHeader("x-forwarded-for"):
            log.msg("%s %s %s" % (request.requestHeaders.getRawHeaders("x-forwarded-for"), request.path, json.dumps(request.args)))
        else:
            log.msg("%s %s %s" % ("127.0.0.1", request.path, json.dumps(request.args)))

        if "/api1" == request.path:
            if request.args.has_key("version"):
                version = request.args["version"][0]
            if version != "":
                global start
                info = start.get()
                result = {}
                if info["version"] != version:
                    result["needUp"] = True
                    result["version"] = info
                else:
                    result["needUp"] = False

                return json.dumps(result)

        elif "/api2" == request.path:
            host = ""
            if request.args.has_key("host"):
                host = request.args["host"][0]
            global check
            if host != "":
                v1 = check.find(host)
                if v1 == False:
                    v1 = "0"
            return "%s" % (v1)

        elif "/api3" == request.path:
            host = ""
            if request.args.has_key("host"):
                host = request.args["host"][0]
            v1 = v2 = 1
            global allow
            if host != "" and allow.find(host) != False:
                v1 = 0
            return "%d|%d" % (v1,v2)

        elif "/reload" == request.path:
            cmd = "file"
            if request.args.has_key("cmd"):
                cmd = request.args["cmd"][0]
            helper = ReloadHelper()
            helper.reload(cmd)
            return "done"
        else:
            request.setResponseCode(404)
            return "404 not found"

        request.setResponseCode(400)
        return "400 bad request"

class ReloadHelper(object):
    def reload(self, cmd):
        log.msg("reload %s start" % (cmd))
        if cmd == "db":
            self._reloadDB()
        elif cmd == "file":
            self._reloadFile()
        log.msg("reload %s end" % (cmd))

    def _reloadFile(self):
        data = {}
        f = open("check.data")
        line = f.readline()
        while line:
            domain, levelid = line.strip().split("|")
            data[domain] = levelid
            line = f.readline()
        f.close()
        global check
        check.set(data)

        data = {}
        f = open("allow.data")
        line = f.readline()
        while line:
            domain = line.strip()
            data[domain] = "0"
            line = f.readline()
        f.close()
        global allow
        allow.set(data)

    def _reloadDB(self):
        try:
            conn=MySQLdb.connect(host=‘hostname‘,user=‘username‘,passwd=‘passwd‘,port=3306)
            conn.select_db("dbname")
            cur = conn.cursor()
            cur.execute("set names utf8")
            cur.execute("SELECT id, version, name FROM table ORDER BY id DESC LIMIT 1")
            row = cur.fetchone()
            if len(row) == 3:
                data = {}
                data["id"] = row[0]
                data["version"] = row[1]
                data["name"] = row[2]
                global start
                start.set(data)
            cur.close()
            conn.close()
        except MySQLdb.Error, e:
            log.err("mysql error %d, %s" %(e.args[0], e.args[1]))

helper = ReloadHelper()
l = task.LoopingCall(helper.reload, "db")
l.start(600)

l = task.LoopingCall(helper.reload, "file")
l.start(3600000)

def main():
    tserver = static.File("/usr/local/nginx/html")
    tserver.putChild("service", TServer())
    tserver.putChild("html", static.File("/usr/nginx/html"))

    reactor.listenTCP(8080, server.Site(tserver), 50, "127.0.0.1")
    reactor.run()

if __name__ == ‘__main__‘:
    main()
时间: 2024-08-03 20:01:59

twisted的一些代码的相关文章

twisted之python代码解释

什么是twisted? twisted是一个用python语言写的事件驱动的网络框架,他支持很多种协议,包括UDP,TCP,TLS和其他应用层协议,比如HTTP,SMTP,NNTM,IRC,XMPP/Jabber. 非常好的一点是twisted实现和很多应用层的协议,开发人员可以直接只用这些协议的实现.其实要修改Twisted的SSH服务器端实现非常简单.很多时候,开发人员需要实现protocol类. 一个Twisted程序由reactor发起的主循环和一些回调函数组成.当事件发生了,比如一个c

Python Twisted 学习系列10(转载stulife最棒的Twisted入门教程)

第十部分:增强defer功能的客户端 作者:[email protected]http://krondo.com/?p=1956译者:杨晓伟(采用意译) 第十部分:增强defer功能的客户端 可以从这里从头开始阅读这个系列. 版本5.0 现在我们将要向诗歌下载客户端添加一些新的处理逻辑,包括在第九部分提到要添加的功能.不过,首先我要说明一点:我并不知道如何实现Byronification引擎.那超出了我的编程能力范围.取而代之的,我想实现一个简单的功能,即Cummingsifier.其只是将诗歌

Python Twisted 学习系列9(转载stulife最棒的Twisted入门教程)

第九部分:第二个小插曲,Deferred 作者:[email protected]http://krondo.com/?p=1825译者:杨晓伟(采用意译) 第九部分:第二个小插曲,Deferred 可以从这里从头来阅读这个系列 更多关于回调的知识 稍微停下来再思考一下回调的机制.尽管对于以Twisted方式使用Deferred写一个简单的异步程序已经非常了解了,但Deferred提供更多的是只有在比较复杂环境下才会用到的功能.因此,下面我们自己想出一些复杂的环境,以此来观察当使用回调编程时会遇

Tornado模块分类和各模块之间的关系

1. Core web framework tornado.web — 包含web框架的大部分主要功能,包含RequestHandler和Application两个重要的类 tornado.httpserver — 一个无阻塞HTTP服务器的实现 tornado.template — 模版系统 tornado.escape — HTML,JSON,URLs等的编码解码和一些字符串操作 tornado.locale — 国际化支持 2. Asynchronous networking 底层模块 t

Python 开源异步并发框架的未来(转)

Python 开源异步并发框架的未来 fantix 1.1k 2014年04月16日 发布 推荐 4 推荐 收藏 31 收藏,8.9k 浏览 呵呵,这个标题有点大,其实只是想从零开始介绍一下异步的基础,以及 Python 开源异步并发框架的发展和互操作性. 另外,这是我在 OSTC 2014 做的一个 20140330-OSTC-分论坛1王川 http://v.youku.com/v_show/id_XNjk2ODI0ODQ4.html ,幻灯片在这里,欢迎拍砖. 开源 Python 是开源的,

“Tornado源码解析篇”导读索引

最近花了2周时间断断续续地阅读了 Tornado 的源码,写了“Tornado源码解析”这个系列专题.由于写得比较散,这里简单做一个索引与导读. 为什么要选择 Tornado 这个框架?先给大家讲一个小故事:赌王娱乐城 "[web.py inspired the] web framework we use at FriendFeed [and] the webapp framework that ships with App Engine..." — Brett Taylor, co-

Python 开源异步并发框架的未来

http://segmentfault.com/a/1190000000471602 开源 Python 是开源的,介绍的这几个框架 Twisted.Tornado.Gevent 和 tulip 也都是开源的,最后这个演讲是在开源大会弄的,所以标题里肯定少不了开源.另外,我的 gevent3 项目也是开源的——貌似不少同学被我起的极品名字给搞混了,特别说明一下,gevent3 虽然有跟 Gevent 一样的接口外貌,但底层却是 tulip 驱动的(考虑把名字改回 gulip 之类的):请区别于将

第十部分:增强defer功能的客户端

作者:[email protected]http://krondo.com/?p=1956  译者:杨晓伟(采用意译) 可以从这里从头开始阅读这个系列. 版本5.0 现在我们将要向诗歌下载客户端添加一些新的处理逻辑,包括在第九部分提到要添加的功能.不过,首先我要说明一点:我并不知道如何实现Byronification引擎.那超出了我的编程能力范围.取而代之的,我想实现一个简单的功能,即Cummingsifier.其只是将诗歌内容转换成小写字母: def cummingsify(poem) ret

第九部分:第二个小插曲,Deferred

作者:[email protected]http://krondo.com/?p=1825  译者:杨晓伟(采用意译) 可以从这里从头来阅读这个系列 更多关于回调的知识 稍微停下来再思考一下回调的机制.尽管对于以Twisted方式使用Deferred写一个简单的异步程序已经非常了解了,但Deferred提供更多的是只有在比较复杂环境下才会用到的功能.因此,下面我们自己想出一些复杂的环境,以此来观察当使用回调编程时会遇到哪些问题.然后,再来看看deferred是如何解决这些问题的. 因此,我们为诗