ECS生产环境搭建
介绍了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
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
注意
:
- supervisor的配置要仔细
- 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向服务器一键部署代码