supervisor用法

2015年7月09日 18:12

以什么方式运行进程?将它做成服务,再以"service xxx start/stop"方式运行。
或者以"nohup xxx &"方式运行,需要停止时,先ps获得进程id,然后kill掉.
有什么好点的办法?supervisor正好解决这个问题。
  • 安装
sudo pip install supervisor
  • 创建配置文件
echo_supervisord_conf > /etc/supervisord.conf
  • 取消注释
打开/etc/supervisord.conf,取消下面两行注释,并修改files内容.
[include]
files = /etc/supervisor/*.ini
  • 新建配置目录
新建supervisor目录及test.ini文件
➜  /etc  tree supervisor
supervisor
└── test.ini
  • 配置内容
test.init内容
[program:test]
command=python -m SimpleHTTPServer 8000
directory=/home/wyq/
  • 运行
运行后,在浏览器访问8000端口
supervisord 
 
调试运行,此时需要先将test.ini中directory注释掉.
supervisord -d
supervisor也可指定配置文件
 
supervisord -c xxxx
  • 查看日志
tail -f supervisord.conf
  • 查看运行状态
➜  ~  supervisorctl status
test                             RUNNING   pid 4922, uptime 0:00:07
  • 停止任务
启动与重启参数为start/restart
 
➜  ~  supervisorctl stop test
test: stopped
➜  ~  supervisorctl status   
test                             STOPPED   Jul 09 04:32 PM
  • 停止
supervisorctl shutdown
 

评论(2) 阅读(2507)

利用setuptools的entry_point参数实现模块动态导入

2015年7月06日 14:34

setuptools提供了entry_points参数,允许在安装时,动态导入模块. 下面是简单示例.
  • 目录结构  
建立如下文件
➜  book  tree
.
├── book
│   ├── add.py
│   ├── __init__.py
│   ├── remove.py
│   └── update.py
└── setup.py
  • add.py内容  
remove.py、update.py与add.py相同
def make():
    print "add"
  • setup.py内容
from setuptools import setup, find_packages

setup(
    name = "book",
    version = "0.1",
    packages = find_packages(),
    entry_points={
        "book":[
            "add=book.add:make",  #add=模块:函数/类
            "update=book.update:make",
            "remove=book.remove:make",
        ]
    }
)
  • 编译成egg包
python setup.py bdist_egg
  • 安装到系统路径  
上面编译命令可以不用,直接用install安装
python setup.py install
  • 用法
from pkg_resources import iter_entry_points

for r in iter_entry_points("book"):
    m = r.load()
    m()
 

Tags: 模块化
评论(282) 阅读(23897)

apscheduler如何传递参数给job

2015年7月03日 10:17

import tornado
from apscheduler.schedulers.tornado import TornadoScheduler
sched = TornadoScheduler()


def job1(a, b, c):
    print "job1:", a,b,c


def job2(a, b, c):
    print "job2:", a,b,c

sched.add_job(job1, 'interval', seconds=1, args=["a", "b", "c"])
sched.add_job(job2, 'interval', seconds=1, kwargs={"a": "a", "b": "b", "c": "c"})
sched.start()

tornado.ioloop.IOLoop.instance().start()

Tags: apscheduler
评论(3) 阅读(8578)

apscheduler定时任务

2015年6月30日 16:50

使用apscheduler定时任务,可以使用interval任务+cron任务,interval定时更新cron配置信息,cron则实现作业计划。

通常用法

from apscheduler.schedulers.blocking import BlockingScheduler
sched = BlockingScheduler()

def my_job():
    print 'hello world'

# 使用修饰器
@sched.scheduled_job('cron', id='my_job_id', second=10)
def hello():
    print "hello decorate"

# 轮循
sched.add_job(my_job, 'interval', seconds=5)
# 定时计划
sched.add_job(my_job, 'cron', second=5, minute=1, hour=12, day_of_week=2)
sched.start()

在tarnado中用法

import tornado
from apscheduler.schedulers.tornado import TornadoScheduler
sched = TornadoScheduler()

def my_job():
    print sched.get_jobs()

sched.add_job(my_job, 'interval', seconds=5, id="1")
sched.start()

tornado.ioloop.IOLoop.instance().start()

任务触发器比较

很多情况下,任务是根据数据库调整触发时间,时间改变了,如何判断触发器是否变化?
生成新trigger然后,专程字符串比较比较
# 触发器比较
str(job.trigger) != str(trigger)
# 修改触发器
sched.reschedule_job(job.id, trigger=trigger)
 

Tags: apscheduler
评论(3) 阅读(8534)

python动态加载是否影响性能

2015年6月06日 16:39

  • 说明
看见这个标题觉得有些好笑。受先入为主观念影响,心里隐约觉得动态加载有点慢,最近受一些启发,开始思考java反射、python动态加载的性能问题. 下面是测试python不同加载方式的性能
  • 示例
有m1.py m2.py m3.py三个文件,内容如下
class Test:
    def func(self):
        pass
测试主体
#encoding=utf-8
import time
import importlib
import m1
from m3 import Test as m3_Test

class Test:
    def func(self):
        pass

def main():
    #A import
    nums = range(1, pow(10, 7))
    start = time.time()
    for i in nums:
        m1.Test()
    end =  time.time()
    print "%sms" % (( end - start ) * 1000)

    #B import_module
    im = importlib.import_module("m2")
    start = time.time()
    for i in nums:
        im.Test()
    end = time.time()
    print "%sms" % ((end - start) * 1000)
    #C from import
    start = time.time()
    for i in nums:
        m3_Test()
    end = time.time()
    print "%sms" % ((end - start) * 1000)

    #D 当前类
    start = time.time()
    for i in nums:
        Test()
    end = time.time()
    print "%sms" % ((end - start) * 1000)

if __name__ == "__main__":
    main()
    '''
    结果
        1619.62890625ms
        1586.80582047ms
        1359.44890976ms
        1369.25506592ms
    '''
  • 结论
可以得到几点结论:
  1. A与B比较: 动态加载并不会慢
  2. A与C比较: 通过from减少导入内容,可以加快载入速度
python本身就是动态语言,动态加载不会对性能产生影响,所以,尽管用,这是非常好的一个特性.
 

Tags: 反射
评论(44) 阅读(3397)

与python内建函数重名

2015年6月06日 15:43

自定义函数与内建函数重名,又不想改为,怎么办?加前缀.
 
例如:list可以使用__builtin__.list区分
import __builtin__

def list(f):
    '''
    将返回结果转为list
    '''
    def __call(*args, **kwargs):
        return __builtin__.list(f(*args, **kwargs))
    return __call
 

评论(7) 阅读(2828)

python2.6.6控制台输出小数问题

2015年5月12日 17:32

示例
[root@wyq-vserver-vm-master ~]# python
Python 2.6.6 (r266:84292, Jun  3 2012, 00:16:45) 
[GCC 4.4.6 20110731 (Red Hat 4.4.6-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a=3.4
>>> a
3.3999999999999999   #输出不正常
>>> b=2
>>> b
2
>>> a*b
6.7999999999999998   #输出不正常
>>> print a*b
6.8                  #输出正常并且数值正确
>>> 
 
从上面内容,可以看出,a与b的数值本身正常,只是控制台在进行格式化输出时不正常
 

评论(0) 阅读(1931)

pillow模块生成缩略图

2015年3月26日 15:32

python使用pillow模块生成缩略图

  • 安装
pip install Pillow
  • 示例
from PIL import Image

im = Image.open("logo.png")
im.thumbnail((32, 32))
im.save("thumbnail.png", "png")
pillow文档地址

 

 

评论(1) 阅读(4690)

mkstemp、mktemp、TemporaryFile区别

2014年7月30日 13:07

mkstemp

fd, name = tempfile.mkstemp 创建临时文件,并且将文件打开
>>> import tempfile
>>> tempfile.mkstemp()
(3, '/tmp/tmpkgWSR1')
查看/tmp目录,看到已经生成真实的文件
 
lsof查询打开的临时文件
[wyq@localhost tmp]$ lsof|grep tmp|grep python
python    8095           wyq    3u      REG               0,33         0     254593 /tmp/tmpkgWSR1
 
发现mkstemp不仅创建文件,而且将文件打开. 使用mkstemp很容易忘了这点,最终造成OSError: [Errno 24] Too many open files错误.
mkstemp返回的是文件描述和文件路径,并不常用,常用的是下面两个.

mktemp

name = tempfile.mktemp 返回一个临时文件的路径,但不创建该临时文件
>>> import tempfile
>>> tempfile.mktemp()
'/tmp/tmpPVidBM'
仅仅生成临时文件名

TemporaryFile

tempfile.TemporaryFile 返回文件对象(file-like)用于临时数据保存。当文件对象被close或者被del的时候,临时文件将从磁盘上删除
import time
with tempfile.TemporaryFile(mode='w+r') as f:
    f.write("=============")
    f.seek(0)
    print f.read()
    time.sleep(10)
TemporaryFile并未在/tmp目录中创建临时文件,应该只存在与内存中.
 

评论(34) 阅读(5411)

python终端模拟工具pexpect

2014年7月14日 22:28

Pexpect是一个纯Python模块。 可以用来和ssh、ftp、passwd、telnet 等命令行程序进行自动交互。实现与命令行交互的自动化.
 
它提供了两个主要接口 run()函数和spawn类.
 
run()函数
run功能相对简单,只能实现简单交互
run(command,timeout=-1,withexitstatus=False,events=None,extra_args=None, logfile=None, cwd=None, env=None)
run运行命令,然后返回结果,与os.system类似.
示例
pexpect.run('ls -la')

# 返回值(输出,退出状态)
(command_output, exitstatus) = pexpect.run('ls -l /bin', withexitstatus=1)
 
spawn类
spawn功能比run强大,可以实现更复杂交互
class spawn 
    __init__(self, command, args=[], timeout=30, maxread=2000, searchwindowsize=None, logfile=None, cwd=None, env=None)
timeout指定交互是等待的超时值
maxread设置read buffer大小. 每次pexpect尝试从TTY(Teletype终端)从读取的最大字节数.
searchwindowsize 指定了从输入缓冲区中进行模式匹配的位置,默认从开始匹配.
logfile 参数指定日志的记录位置
 
工作过程
# 第一步与终端建立连接
child = pexpect.spawn('scp foo user@example.com:.')
# 第二步等待终端返回匹配内容
child.expect('Password:')
# 第三步根据返回内容发送命令进行交互
child.sendline(mypassword)
 
pxssh类
pxssh是pexpect的派生类,用于建立ssh连接,比pexpect好用.
 
login()  建立到目标机器的ssh连接
logout() 释放该连接
prompt() 等待提示符,通常用于等待命令执行结束
 
工作过程与pexpect相同
# 初始化pxssh示例
s = pxssh.pxssh() 

hostname = raw_input('hostname: ') 
username = raw_input('username: ') 
password = getpass.getpass('password: ') 
# 建立ssh连接
s.login (hostname, username, password) 
# 发送命令到远程终端
s.sendline ('uptime') # run a command 
# 等待远程终端返回
s.prompt() # match the prompt 
# 打印匹配到的内容
print s.before  # print everything before the propt. 

# 发送命令到远程终端
s.sendline ('ls -l') 
# 等待远程终端返回
s.prompt() 
# 打印匹配到的内容
print s.before 

s.sendline ('df') 
s.prompt() 
print s.before 

# 释放ssh连接
s.logout() 
 
 
 

评论(1) 阅读(4506)