使用 supervisor 管理进程

Supervisor (http://supervisord.org) 是一个用 Python 写的进程管理工具,可以很方便的用来启动、重启、关闭进程(不仅仅是 Python 进程)。除了对单个进程的控制,还可以同时启动、关闭多个进程,比如很不幸的服务器出问题导致所有应用程序都被杀死,此时可以用 supervisor 同时启动所有应用程序而不是一个一个地敲命令启动。
supervisord 配置
Supervisor 相当强大,提供了很丰富的功能,不过我们可能只需要用到其中一小部分。安装完成之后,可以编写配置文件,来满足自己的需求。为了方便,我们把配置分成两部分:supervisord(supervisor 是一个 C/S 模型的程序,这是 server 端,对应的有 client 端:supervisorctl)和应用程序(即我们要管理的程序)。
首先来看 supervisord 的配置文件。安装完 supervisor 之后,可以运行echo_supervisord_conf 命令输出默认的配置项,也可以重定向到一个配置文件里:

echo_supervisord_conf > /etc/supervisord.conf

去除里面大部分注释和“不相关”的部分,我们可以先看这些配置:

[unix_http_server]
file=/tmp/supervisor.sock   ; UNIX socket 文件,supervisorctl 会使用
;chmod=0700                 ; socket 文件的 mode,默认是 0700
;chown=nobody:nogroup       ; socket 文件的 owner,格式: uid:gid

;[inet_http_server]         ; HTTP 服务器,提供 web 管理界面
;port=127.0.0.1:9001        ; Web 管理后台运行的 IP 和端口,如果开放到公网,需要注意安全性
;username=user              ; 登录管理后台的用户名
;password=123               ; 登录管理后台的密码

[supervisord]
logfile=/tmp/supervisord.log ; 日志文件,默认是 $CWD/supervisord.log
logfile_maxbytes=50MB        ; 日志文件大小,超出会 rotate,默认 50MB
logfile_backups=10           ; 日志文件保留备份数量默认 10
loglevel=info                ; 日志级别,默认 info,其它: debug,warn,trace
pidfile=/tmp/supervisord.pid ; pid 文件
nodaemon=false               ; 是否在前台启动,默认是 false,即以 daemon 的方式启动
minfds=1024                  ; 可以打开的文件描述符的最小值,默认 1024
minprocs=200                 ; 可以打开的进程数的最小值,默认 200

; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; 通过 UNIX socket 连接 supervisord,路径与 unix_http_server 部分的 file 一致
;serverurl=http://127.0.0.1:9001 ; 通过 HTTP 的方式连接 supervisord

; 包含其他的配置文件
[include]
files = relative/directory/*.ini    ; 可以是 *.conf 或 *.ini

我们把上面这部分配置保存到 /etc/supervisord.conf(或其他任意有权限访问的文件),然后启动 supervisord(通过 -c 选项指定配置文件路径,如果不指定会按照这个顺序查找配置文件:$CWD/supervisord.conf, $CWD/etc/supervisord.conf, /etc/supervisord.conf):

supervisord -c /etc/supervisord.conf

查看 supervisord 是否在运行:

ps aux | grep supervisord

program 配置
上面我们已经把 supervisrod 运行起来了,现在可以添加我们要管理的进程的配置文件。可以把所有配置项都写到 supervisord.conf 文件里,但并不推荐这样做,而是通过 include 的方式把不同的程序(组)写到不同的配置文件里。
为了举例,我们新建一个目录 /etc/supervisor/ 用于存放这些配置文件,相应的,把 /etc/supervisord.conf 里 include 部分的的配置修改一下:

[include]
files = /etc/supervisor/*.conf

假设有个用 Python 和 Flask 框架编写的用户中心系统,取名 usercenter,用 gunicorn (http://gunicorn.org/) 做 web 服务器。项目代码位于 /home/leon/projects/usercenter,gunicorn 配置文件为 gunicorn.py,WSGI callable 是 wsgi.py 里的 app 属性。所以直接在命令行启动的方式可能是这样的:

cd /home/leon/projects/usercenter
gunicorn -c gunicorn.py wsgi:app

现在编写一份配置文件来管理这个进程(需要注意:用 supervisord 管理时,gunicorn 的 daemon 选项需要设置为 False):

[program:usercenter]
directory = /home/leon/projects/usercenter ; 程序的启动目录
command = gunicorn -c gunicorn.py wsgi:app  ; 启动命令,可以看出与手动在命令行启动的命令是一样的
autostart = true     ; 在 supervisord 启动的时候也自动启动
startsecs = 5        ; 启动 5 秒后没有异常退出,就当作已经正常启动了
autorestart = true   ; 程序异常退出后自动重启
startretries = 3     ; 启动失败自动重试次数,默认是 3
user = leon          ; 用哪个用户启动
redirect_stderr = true  ; 把 stderr 重定向到 stdout,默认 false
stdout_logfile_maxbytes = 20MB  ; stdout 日志文件大小,默认 50MB
stdout_logfile_backups = 20     ; stdout 日志文件备份数
; stdout 日志文件,需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord 会自动创建日志文件)
stdout_logfile = /data/logs/usercenter_stdout.log

; 可以通过 environment 来添加需要的环境变量,一种常见的用法是修改 PYTHONPATH
; environment=PYTHONPATH=$PYTHONPATH:/path/to/somewhere

一份配置文件至少需要一个 [program:x] 部分的配置,来告诉 supervisord 需要管理那个进程。[program:x] 语法中的 x 表示 program name,会在客户端(supervisorctl 或 web 界面)显示,在 supervisorctl 中通过这个值来对程序进行 start、restart、stop 等操作。

使用 supervisorctl
Supervisorctl 是 supervisord 的一个命令行客户端工具,启动时需要指定与 supervisord 使用同一份配置文件,否则与 supervisord 一样按照顺序查找配置文件。

supervisorctl -c /etc/supervisord.conf

上面这个命令会进入 supervisorctl 的 shell 界面,然后可以执行不同的命令了:

> status    # 查看程序状态
> stop usercenter   # 关闭 usercenter 程序
> start usercenter  # 启动 usercenter 程序
> restart usercenter    # 重启 usercenter 程序
> reread    # 读取有更新(增加)的配置文件,不会启动新添加的程序
> update    # 重启配置文件修改过的程序

上面这些命令都有相应的输出,除了进入 supervisorctl 的 shell 界面,也可以直接在 bash 终端运行:

$ supervisorctl status
$ supervisorctl stop usercenter
$ supervisorctl start usercenter
$ supervisorctl restart usercenter
$ supervisorctl reread
$ supervisorctl update

其它
除了 supervisorctl 之外,还可以配置 supervisrod 启动 web 管理界面,这个 web 后台使用 Basic Auth 的方式进行身份认证。
除了单个进程的控制,还可以配置 group,进行分组管理。
经常查看日志文件,包括 supervisord 的日志和各个 pragram 的日志文件,程序 crash 或抛出异常的信息一半会输出到 stderr,可以查看相应的日志文件来查找问题。
Supervisor 有很丰富的功能,还有其他很多项配置,可以在官方文档获取更多信息:http://supervisord.org/index.html

Sublime text 3 3103 注册码

Sublime text 3 (Build 3103) license key,these all tested available on 2016/02/10 .Feel free to enjoy them.

—– BEGIN LICENSE —–
Michael Barnes
Single User License
EA7E-821385
8A353C41 872A0D5C DF9B2950 AFF6F667
C458EA6D 8EA3C286 98D1D650 131A97AB
AA919AEC EF20E143 B361B1E7 4C8B7F04
B085E65E 2F5F5360 8489D422 FB8FC1AA
93F6323C FD7F7544 3F39C318 D95E6480
FCCC7561 8A4A1741 68FA4223 ADCEDE07
200C25BE DBBC4855 C4CFB774 C5EC138C
0FEC1CEF D9DCECEC D3A5DAD1 01316C36
—— END LICENSE ——

—– BEGIN LICENSE —–
Nicolas Hennion
Single User License
EA7E-866075
8A01AA83 1D668D24 4484AEBC 3B04512C
827B0DE5 69E9B07A A39ACCC0 F95F5410
729D5639 4C37CECB B2522FB3 8D37FDC1
72899363 BBA441AC A5F47F08 6CD3B3FE
CEFB3783 B2E1BA96 71AAF7B4 AFB61B1D
0CC513E7 52FF2333 9F726D2C CDE53B4A
810C0D4F E1F419A3 CDA0832B 8440565A
35BF00F6 4CA9F869 ED10E245 469C233E
—— END LICENSE ——

—– BEGIN LICENSE —–
Anthony Sansone
Single User License
EA7E-878563
28B9A648 42B99D8A F2E3E9E0 16DE076E
E218B3DC F3606379 C33C1526 E8B58964
B2CB3F63 BDF901BE D31424D2 082891B5
F7058694 55FA46D8 EFC11878 0868F093
B17CAFE7 63A78881 86B78E38 0F146238
BAE22DBB D4EC71A1 0EC2E701 C7F9C648
5CF29CA3 1CB14285 19A46991 E9A98676
14FD4777 2D8A0AB6 A444EE0D CA009B54
—— END LICENSE ——

—– BEGIN LICENSE —–
Alexey Plutalov
Single User License
EA7E-860776
3DC19CC1 134CDF23 504DC871 2DE5CE55
585DC8A6 253BB0D9 637C87A2 D8D0BA85
AAE574AD BA7D6DA9 2B9773F2 324C5DEF
17830A4E FBCF9D1D 182406E9 F883EA87
E585BBA1 2538C270 E2E857C2 194283CA
7234FF9E D0392F93 1D16E021 F1914917
63909E12 203C0169 3F08FFC8 86D06EA8
73DDAEF0 AC559F30 A6A67947 B60104C6
—— END LICENSE ——

 

php秒数转换成多少天/多少小时/多少分

function get_stay_time($timestamp, $is_hour = 1, $is_minutes = 1)
{
    if(empty($timestamp) || $timestamp <= 60) {
        return false;
    }

    $time = time();
    $remain_time = $time - $timestamp;

    $day = floor($remain_time / (3600*24));
    $day = $day > 0 ? $day.'天' : '';
    $hour = floor(($remain_time % (3600*24)) / 3600);
    $hour = $hour > 0 ? $hour.'小时' : '';
    if($is_hour && $is_minutes) {
        $minutes = floor((($remain_time % (3600*24)) % 3600) / 60);
        $minutes = $minutes > 0 ? $minutes.'分' : '';
        return $day.$hour.$minutes;
    }

    if($hour) {
        return $day.$hour;
    }
    return $day;
}

git 常用命令

Git常用操作命令收集:
1) 远程仓库相关命令

检出仓库:$ git clone git://github.com/jquery/jquery.git
查看远程仓库:$ git remote -v
添加远程仓库:$ git remote add [name] [url]
删除远程仓库:$ git remote rm [name]
修改远程仓库:$ git remote set-url –push[name][newUrl]
拉取远程仓库:$ git pull [remoteName] [localBranchName]
推送远程仓库:$ git push [remoteName] [localBranchName]

2)分支(branch)操作相关命令
查看本地分支:$ git branch
查看远程分支:$ git branch -r
创建本地分支:$ git branch [name] —-注意新分支创建后不会自动切换为当前分支
切换分支:$ git checkout [name]
创建新分支并立即切换到新分支:$ git checkout -b [name]
删除分支:$ git branch -d [name] —- -d选项只能删除已经参与了合并的分支,对于未有合并的分支是无法删除的。如果想强制删除一个分支,可以使用-D选项
合并分支:$ git merge [name] —-将名称为[name]的分支与当前分支合并
创建远程分支(本地分支push到远程):$ git push origin [name]
删除远程分支:$ git push origin :heads/[name]

我从master分支创建了一个issue5560分支,做了一些修改后,使用git push origin master提交,但是显示的结果却是’Everything up-to-date’,发生问题的原因是git push origin master 在没有track远程分支的本地分支中默认提交的master分支,因为master分支默认指向了origin master 分支,这里要使用git push origin issue5560:master 就可以把issue5560推送到远程的master分支了。
如果想把本地的某个分支test提交到远程仓库,并作为远程仓库的master分支,或者作为另外一个名叫test的分支,那么可以这么做。

$ git push origin test:master // 提交本地test分支作为远程的master分支
$ git push origin test:test // 提交本地test分支作为远程的test分支

如果想删除远程的分支呢?类似于上面,如果:左边的分支为空,那么将删除:右边的远程的分支。

$ git push origin :test // 刚提交到远程的test将被删除,但是本地还会保存的,不用担心
3)版本(tag)操作相关命令
查看版本:$ git tag
创建版本:$ git tag [name]
删除版本:$ git tag -d [name]
查看远程版本:$ git tag -r
创建远程版本(本地版本push到远程):$ git push origin [name]
删除远程版本:$ git push origin :refs/tags/[name]

4) 子模块(submodule)相关操作命令
添加子模块:$ git submodule add [url] [path]
如:$ git submodule add git://github.com/soberh/ui-libs.git src/main/webapp/ui-libs
初始化子模块:$ git submodule init —-只在首次检出仓库时运行一次就行
更新子模块:$ git submodule update —-每次更新或切换分支后都需要运行一下
删除子模块:(分4步走哦)
1)$ git rm –cached [path]
2) 编辑“.gitmodules”文件,将子模块的相关配置节点删除掉
3) 编辑“.git/config”文件,将子模块的相关配置节点删除掉
4) 手动删除子模块残留的目录

5)忽略一些文件、文件夹不提交
在仓库根目录下创建名称为“.gitignore”的文件,写入不需要的文件夹名或文件,每个元素占一行即可,如
target
bin
*.db

Windows 8的最大缺陷:两种UI关系错乱

微软想在一台机器上同时提供PC和平板的体验,这是个不错想法,平板电脑迟早要和PC融合。但台式PC和平板电脑毕竟是相差甚远的东西,中间还有笔记本、 TablePC、一体机等各种不同设备,其体验各不相同,作为一款通用系统,必须同时照顾到各种设备下的体验。

如果开始屏幕和桌面模式这两种UI以适当的 形式结合起来,让用户能清楚地意识到在什么时候需要什么UI,从而在不同的场合各取所需,它们的共存其实不会带来多少困扰,但微软恰恰没处理好这一点。

两种UI有一些共通的地方:都用同一个开始屏幕打开软件,都可以用Alt+Tab切换任务组合键,在这里你能看到两种UI下打开的全部应用和软件,但在这一点相通之后,两种UI的逻辑就是完全不一样的,也是不能互通的,这会让用户感到费解,不知道两种UI到底是什么关系。你会发现所有使用平板UI的应用都无法在桌面上使用,当你把它们打开以后,也别想从桌面模式找到它和关闭它。同样,在平板模式你也找不到桌面模式下打开的软件(但诡异的是,桌面模式自己像一个软件似的呆在开始屏幕上),你没办法关闭它们,只能关闭桌面模式——而且那根本不是真正的关闭,再次打开桌面模式的时候会发现它们还在那里,你只能切到桌面模式一个个的关窗口。

如果平板用户认为它关闭桌面模式就能关掉桌面上的软件,那他就上当了,所有软件都在后台继续占用着内存和CPU,很快把电量吃光。而对于PC用户,平板模式的应用又会让他们不适应:应用只要离开就会处于挂起状态,只有少数应用被允许后台运行,用户没必要一一退出它们。

除此之外,这种设计是在浪费硬盘空间和用户的时间——很多软件你被迫装两个,一个桌面版一个平板版,例如你要装两个Evernote,而且它们的数据还不同步,你在其中一个上面写的东西如果没上传,在另一个上面绝对看不见。还有一个问题是,有些应用还没有桌面版,当你坐下来,打开键盘用桌面模式上网、编辑文档的时候,你想要约炮怎么办?你只能进开始屏幕打开陌陌(只是举个例子,暂时还没登陆Win8),每当有消息来了,你就得全屏切换到陌陌,聊一句再切回来。应该承认的是,这种切换和以前的多窗口切换其实差不多,因为用户本来就没法同时操作两个窗口,总是要点一下鼠标或按一次Alt+Tab,但多窗口的意义在于,人们常常需要不切换任务就同时看到几个窗口的运行状态。

移动操作系统设计为不可切换窗口和限制多任务,是因为移动设备体积限制了其屏幕和电量的大小,而如今台式PC的屏幕普遍都是20多寸,电量自然更不是问题,多窗口和多后台对其并无任何压力,硬塞给台式PC用户这样一个系统,只能添麻烦。实际上,连手机都已经支持多窗口了,Palm手机在十几年以前就有一种叫DA的小程序能实现小窗口的效果,要知道Palm手机屏幕连3寸都不到。如今随着手机屏幕越做越大,三星又为Note 2和Note 10.1带来了Multi-view多窗口功能,微软却来个反其道而行之。

我认为比较理想的情况是Windows 8的两种UI在体验上能够相对独立,让用户不必在同一时间段内来回切换,单独设计一个按钮用于平板模式和桌面模式的切换。开始屏幕中不必出现桌面软件的快捷方式,让一大堆“帮助”、“卸载”、“访问我们的网站”在那里浪费空间。而桌面模式下则继续保留开始菜单,其中只有桌面软件。与此同时,两种UI应该在技术上能够互相联系,在平板模式左侧的应用切换界面提示用户桌面模式打开了哪些软件,在桌面模式也提示用户平板模式打开了哪些应用。此外,还可以将平板应用切换到桌面打开,使其能够多窗口运行,已经具有两种UI版本的软件,应该合并其安装包并在安装后使用同一数据库,做到在切换UI时软件UI也自动切换。

Windows 8提出了不错的理念,通过用户对Windows的习惯借势推行其平板系统,也是正确的策略,但其推行过于生硬,两种UI结合得不合理。用户对Windows系统的使用习惯是其他厂商无法获得的巨大财富,放弃它无异于自废武功,要更好地让两种UI和谐并存,照顾多种设备的体验,微软还有很多改进要做。

转自:http://cnbeta.com/articles/211370.htm