ECS生产环境搭建

1

介绍了ECS生产环境的搭建,用到的工具包括Virtualenv,Gunicorn,Supervisor,Nginx,git。Virtualenv用来构建Python的虚拟工作环境;Supervisor用来管理进程;Nginx用作负载均衡;git用来实现代码的push-to-deploy功能。下面详细介绍了这些工具的安装、配置、使用。

1. python-dev, pip安装

$ sudo apt-get install build-essential python-dev
$ wget https://raw.github.com/pypa/pip/master/contrib/get-pip.py
$ sudo python get-pip.py

2. VirtualEnv构建Python的虚拟工作环境

安装

$ sudo pip install virtualenv
$ sudo pip install virtualenvwrapper
# 把下面这句加到~/.bash_profile里面,如不嫌麻烦,也可以每次都手动执行。
$ source /usr/local/bin/virtualenvwrapper.sh

使用

$ mkvirtualenv virtualenv_name

3. Gunicorn^

Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX. It's a pre-fork worker model ported from Ruby's Unicorn project. The Gunicorn server is broadly compatible with various web frameworks, simply implemented, light on server resources, and fairly speedy.

在tornado下用处不大,先放一放...

安装

$ pip install gunicorn

4. Supervisor^

Supervisor is a client/server system that allows its users to control a number of processes on UNIX-like operating systems ()

安装 3.0a8

$ sudo apt-get install supervisor

配置 /etc/supervisor/conf.d/pein.conf

在conf.d中可以给不同的进程创建各自的conf

[program:pein]
; 相当与virtualenv的workon, 运行在8000端口
command=/home/june/.virtualenvs/ws/bin/python /home/june/droprest.com/pein/app.py ---port=800%(process_num)01d
process_name=pein-%(process_num)01d
numprocs=1
numprocs_start=0
directory=/home/june/droprest.com/pein
autostart=true     ; supervisor守护进程启动时自动启动
autorestart=true   ; supervisor重启时自动重启
redirect_stderr=true  ; 将stderr重定向到stdout
user=june
stdout_logfile=/home/june/logs/supervisor.log

配置 /etc/supervisor/supervisor.conf

为了在脚本中可以操作supervisorctl而进行的配置,一般都是Permission denied问题

$ groupadd supervisor
$ usermod -a -G supervisor <myusername>

修改supervisor.conf

[unix_http_server]
file=/var/run//supervisor.sock   ; (the path to the socket file)
- chmod=0700              ; sockef file mode (default 0700)
+ chmod=0770              ; sockef file mode (default 0700)
+ chown=root:supervisor

ref: Supervisord, or How I Learned to Stop Worrying and… um… Use Supervisord

使用

#启动|终止|重启服务
$ sudo service supervisor start|stop|restart


#重新读取配置
$ sudo supervisorctl reload

#查看监控的所有进程
$ sudo supervisorctl status 

#启动|停止|重启 进程pein-1或重启进程组pein,如pein:pein-0, pein:pein-1,...,pein:pein-n
$ sudo supervisorctl start|stop|restart pein-1|pein:

#也可以进入交互式界面进行上述操作
$ sudo supervisorctl

5. nginx^

nginx [engine x] is an HTTP and reverse proxy server, as well as a mail proxy server, written by Igor Sysoev.

安装 1.7.4

nginx: Linux packages

curl -O http://nginx.org/keys/nginx_signing.key
sudo apt-key add nginx_signing.key
vim /etc/apt/source.list
  deb http://nginx.org/packages/mainline/debian/ precise nginx
  deb-src http://nginx.org/packages/mainline/debian/ precise nginx
sudo apt-get update
sudo apt-get install nginx

配置/etc/nginx/conf.d

/etc/nginx/nginx.conf

events {
+   use epoll;
}

在conf.d中可以给不同的站点配置各自的conf

# 配置负载均衡
upstream frontends {
    server 127.0.0.1:8000;
}

server {
    listen 80;
    server_name pein.url2io.com;
    root /home/june/droprest.com/pein/;
    index app.py

    # Allow file uploads
    client_max_body_size 50M;

    location ^~ /static/ {
        root /home/june/droprest.com/pein;
        if ($query_string) {
            expires max;
        }
    }
    location = /favicon.ico {
        rewrite (.*) /static/favicon.ico;
    }
    location = /robots.txt {
        rewrite (.*) /static/robots.txt;
    }
    # 支持websocket
    location /w {
        proxy_pass http://frontends;
        proxy_http_version 1.1;
        proxy_pass_header Server;
        proxy_redirect off;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $http_host;
    }
    location / {
        proxy_pass_header Server;
        proxy_redirect off;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_pass http://frontends;
    }
}

使用

#重启
$ sudo service nginx restart

:将nginx进程也交由supervisor管理

tips:

我们曾经犯过一个错误,在服务器上部署了两个node.js应用,然后每个应用都开了N-1个进程。 结果,它们互相之间抢夺CPU,导致系统的负荷急升。 虽然我们的服务器都是8核的机器,但仍然可以明显地感觉到由上下文切换引起的性能开销。 上下文切换是指CPU为了执行其它任务而挂起当前任务的现象。 在切换时,内核必须挂起当前进程的所有状态,然后装载和执行另一个进程。 为了解决这个问题,我们减少了每个应用开启的进程数,让它们公平地分享CPU,结果系统负荷就降了下来。 出处: http://www.oschina.net/translate/optimising-nginx-node-js-and-networking-for-heavy-workloads 进程数不是越多越好的,过多的进程或者线程的上下文切换会耗近CPU,性能反而变差。 Tornado没用过,这里拿常见的Nginx来分析下,如果运行在一台4核服务器上,假设这台服务器专门用来做Web服务器,主要运行 Nginx 服务,这时建议 开3个Nginx worker进程,把这3个worker进程绑定到后面3个CPU核心(其他系统任务会优先使用第一个核心0001): worker_processes 3; worker_cpu_affinity 0010 0100 1000; 注:Nginx的worker进程是一个单线程的进程。Nginx除了worker进程,还有master进程和一些管理cache的进程(如果使用了nginx的cache功能)。

git部署代码push-to-deploy

目标是执行以下代码后,更新代码到服务器,重启代码相关的服务进程。完全在本地操作,利用的是git的post-receive hook

$ git push origin master post-receive 挂钩在整个过程完结以后运行,可以用来更新其他系统服务或者通知用户。它接受与 pre-receive 相同的标准输入数据。应用实例包括给某邮件列表发信,通知实时整合数据的服务器,或者更新软件项目的问题追踪系统 —— 甚至可以通过分析提交信息来决定某个问题是否应该被开启,修改或者关闭。该脚本无法组织推送进程,不过客户端在它完成运行之前将保持连接状态;所以在用它作一些消耗时间的操作之前请三思。

remote

#1/ ssh到远程服务器,建一个裸代码库(只有历史记录和索引)
$ ssh user@server
$ git init --bare repo.git

#2/ 建一个部署代码的仓库,它的origin为repo.git
$ git clone repo.git repo

local

#3/ 添加remote源为远程的裸仓库
$ git remote add origin ssh://user@server/home/.../repo.git
#4/ 在项目中添加hook脚本(任意名字,此处是post-receive.sh),并使之可执行(重要)
$ touch ./hooks/post-receive.sh
$ chmod 775 ./hooks/post-receive.sh
#5/ 定义post-receive的操作,在post-receive.sh中添加如下代码

#!/bin/sh
set -xe
echo "Running Post Receive Hook"
export GIT_WORK_TREE=$HOME/droprest.com/pein
export GIT_DIR=${GIT_WORK_TREE}/.git
cd ${GIT_WORK_TREE}
git pull origin
git reset --hard origin/master
# restart apps
echo "restart apps"
supervisorctl -c /etc/supervisor/supervisord.conf restart pein:

#6/ 将更新push到远程服务器
$ git commit -a -m 'push-to-deploy test1'
$ git push origin master

注意

  1. supervisor的配置要仔细
  2. supervisorctl请明确指定其配置文件,因为supervisorctl会先在当前目录寻找配置文件。

remote

#7/ 此时repo仓库并不会自动更新,手动更新一下
$ git pull origin
#8/ 将post-receive hook放到repo.git中,绝对路径。名字必须是post-receive
$ ln -s .../repo/hooks/post-receive.sh .../repo.git/hooks/post-receive
#9/ 设置完成

ref: 利用git push向服务器一键部署代码

aliyun first time 移动机器人视觉系统
>