Python項目自動化多服務器部署的工具:essay

jopen 11年前發布 | 37K 次閱讀 essay Python開發

介紹:


essay是我們團隊在過去兩年Python項目持續部署上經驗的總結,核心功能是打包和多Server部署。這個工具的主要功能是簡化從開發到部署的流程,方便服務器的擴展。除了打包和部署功能之外,essay還提供了其他的工具,在后面的接口描述中有詳細介紹。

essay是基于Fabric開發,在使用上依賴于pypi Server和github/Gitlab。

快速開始


這里使用自己搭建的pypiserver作為pypi server,github作為代碼倉庫。

  1. 安裝essay: pip install essay
  2. github上創建項目:essay_demo_webpy
  3. 創建項目。終端上執行: es create essay_demo_webpy ,根據提示輸入你新創建的git倉庫地址,回車完畢你會發現你的github上已經有了初始化好的一個項目結構

    .
    └── essay_demo_webpy
        ├── MANIFEST.in
        ├── README.md
        ├── conf
        │   └── supervisord.conf
        ├── essay_demo
        │   ├── __init__.py
        │   ├── log.py
        │   ├── main.py
        │   └── settings.py
        ├── fabfile
        │   └── __init__.py
        └── setup.py
    
    4 directories, 9 files
  4. 打包項目。此時你可以在本地的essay_demo_webpy目錄下執行: fab -l 命令查看哪些命令可用。然后執行 fab build.build 命令,會幫你打包成tar的源碼包,并添加版本后綴,如:essay_demo_webpy-3.11.20.1.tar.gz,之后會被上傳到上面說到得pypiserver上。

    關于build.build有四個可選參數,fab build.build:name=fixbug,version=0.1,commit=451a9a2784f,branch=master,也可以使用位置參數: fab build.build:fixbug,0.1,451a9a2784f,master 。其中commit和branch不能同時設置,commit優先于branch起作用。

    各參數詳解:

    name, 版本的后綴,如上例的結果是: essay_demo_webpy-0.1-fixbug.tar.gz
    varsion, 版本號,如果為空則會產生:essay_demo_webpy-3.11.20.1-fixbug.tar.gz。規則是:年.月.日.次
    commit, 是要打包的commit節點
    branch, 要打包的分支,默認為fabfile下__init__.py中的配置
  5. 部署項目。這時在pypiserver上已經有了打好的包,假設為: essay_demo_webpy-3.11.20.1.tar.gz 。然后開始安裝,執行: fab -R dev deploy:3.11.20.1,a,test 把項目安裝到fabfile里設置的dev這個role的服務器上,可以是一個或者多個server。

    deploy參數解釋:

    deploy后面有三個參數,分別表示:版本號,虛擬環境目錄名,profile(會傳遞到supervisord.conf中)
    版本號在上面已經提到,不贅述。
    虛擬環境目錄名:依賴于fabfile中設置的 env.VIRTUALENV_PREFIX='~/essay_demo_webpy' ,這里參數為a,
    
    表示將在服務器家目錄下得essay_demo_webpy目錄下創建一個目錄為 a 的virtualenv環境。
    profile:用來控制程序處于什么狀態,比如可以傳遞debug進去,需要程序自己處理。參數會被傳遞到supervisord.conf中。

deploy的內部的過程是:登錄-R指定的服務器,在配置的VIRTUALENV_PREFIX目錄下創建a虛擬環境,之后在此環境中通過pip安裝已打包好的項目,最后通過supervisord來啟動程序進程。

可以參考Demo:https://github.com/SohuTech/essay_demo_webpy 中的一些配置

配置文件詳解


介紹主要的兩個配置文件fabfile和supervisord

fabfile配置

** myproject/fabfile/init.py **

所有env配置項,可根據自身業務刪除/添加

    1. git服務器

        env.GIT_SERVER = 'https://github.com/' # ssh地址只需要填:github.com

    2. 項目名(與git上項目名保持一致) 

        env.PROJECT = 'project_name'

    3. 項目在打包服務器上的路徑,會在此目錄下執行打包操作

        env.BUILD_PATH = '/opt/deploy/'

    4. 項目所有者(與git保持一致)

        env.PROJECT_OWNER = 'EssayTech'

    5. git默認分支

        env.DEFAULT_BRANCH = 'master'

    6. pypi-server地址

        env.PYPI_INDEX = 'http://pypi.python.org/simple/'

    部署相關:

    7. 部署啟動進程數目

        env.PROCESS_COUNT = 2 #部署時啟動的進程數目, 會傳遞到supervisord.conf中

    8. 服務器角色, 打包或部署時通過 ``-R`` 參數指定服務器角色, 每個角色可以定義多組服務器

        env.roledefs = {
        'build': ['username@buildserverip:port'], # 打包服務器配置
        'dev': ['eassay@127.0.0.1:2202'],   #部署服務器配置
        }

    9. 虛擬環境目錄, 部署時會在服務器上此目錄下創建虛擬環境

        env.VIRTUALENV_PREFIX = '/home/SohuTech/project_name'

    12. supervisor配置文件地址, PROJECT_ROOT為項目根目錄

        env.SUPERVISOR_CONF_TEMPLATE = os.path.join(PROJECT_ROOT, 'conf', 'supervisord.conf')

    13. 根據工程確定項目編號, 不同虛擬環境監聽不同的端口,用來配置一個同一機器多個虛擬環境。

        通過port參數傳到supervisord.conf中。

        PROJECT_NUM = 88
        env.VENV_PORT_PREFIX_MAP = {
        'a': '%d0' % PROJECT_NUM,
        'b': '%d1' % PROJECT_NUM,
        'c': '%d2' % PROJECT_NUM,
        'd': '%d3' % PROJECT_NUM,
        'e': '%d4' % PROJECT_NUM,
        'f': '%d5' % PROJECT_NUM,
        'g': '%d6' % PROJECT_NUM,
        'h': '%d7' % PROJECT_NUM,
        'i': '%d8' % PROJECT_NUM,
        }


    nginx配置用于啟動、停止、重啟、修改配置文件:

    14. nginx執行文件地址

        env.NGINX_BIN = '/usr/local/nginx/bin/nginx'

    15. nginx配置文件地址

        env.NGINX_CONF = '/usr/local/nginx/conf/nginx.conf'

    16. 切換nginx環境(關于此項,請看下方essay高級功能用法)

        env.NGINX_SWITCH_CONF = '/etc/nginx/nginx.conf'

supervisord配置

** myproject/conf/supervisor.conf **

幾個被替換的字段

    以下參數在fab deploy的時候會替換為fabfile里配置的字段

    1. {{ run_root }}  虛擬環境地址,對應于fabfile/__init__.py里的env.VIRTUALENV_PREFIX

    2. {{ username }}   essay.task.util自動生成用戶名

    3. {{ password }}   essay.task.util自動生成密碼

    4. {{ project }}    項目名,對應于fabfile/__init__.py里的env.PROJECT

    5. {{ port }}  取env.VENV_PORT_PREFIX_MAP對應虛擬環境的端口號

    6. {{ process_count }}  對應于fabfile配置中的PROCESS_COUNT

具體配置

    #項目名(被自動替換)
    [program:{{ project }}]     

    #運行命令
    command={{ venv_dir}}/bin/{{ project }} --profile={{ profile }}     

    #進程名,示例:test_2
    process_name=%(program_name)s_%(process_num)d   

    #設置進程umask,即權限為755
    umask=022   

    #啟動后10秒內沒有異常則認為啟動成功
    startsecs=10        

    #等待0秒退出
    stopwaitsecs=0  

    #重定向日志輸出地址
    redirect_stderr=true    


    #日志輸出地址
    stdout_logfile={{ run_root }}/logs/process_%(process_num)02d.log


    #啟動進程數
    numprocs={{ process_count }}    

    #如果開啟進程數大于1,則指定從序號為0的進程開始
    numprocs_start=0    

可用命令清單及詳解


1. 創建本地工程,然后同步到git服務器(需要git倉庫地址)

    用默認模板創建

    1. 先在gitlab/github上創建庫:myprojecti,拿到git地址

    2. es create myproject (后邊不加-t參數會使用默認模板創建項目)

    3. 輸入項目git地址

    用django模板創建

    es create myproject -t django

2. 創建本地工程,創建時不需要連接git服務器,后期需要自己git init

#####用法一:

    生成全新項目

    1. es init myproject

    2. cd myproject

    3. git init

    4. git remote add origin [git庫地址]

    5. 然后就可以commit和push了  

#####用法二:

    在已存在項目下

    1. cd myproject

    2. es init

    會為項目生成fabfile, conf, setup.py, MANIFEST.in, README.md

3. 打包

    1. fab build.build

4. 獲取項目最新版本號

    1. cd myproject

    2. fab build.get_latest_version

5. 計算項目下一版本號

    1. cd myproject

    2. fab build.get_next_version

6. 部署(參數: 項目版本號, 虛擬環境名, profile)

    1. cd myproject

    2. fab deploy:3.11.18.2,virtualenv_name,test 

7. 重啟指定虛擬環境的supervisor(參數: 虛擬環境名)

    1.cd myproject

    2.fab supervisor.reload:virtualenv_name

8. 重啟虛擬環境的項目的特定進程(參數: 進程名, 虛擬環境名)

    1. cd myproject

    2. fab supervisor.restart_process:process_name,virtualenv_name

9. 啟動虛擬環境的項目的特定進程(參數: 進程名, 虛擬環境名)

    1. cd myproject

    2. fab supervisor.start_process:process_name,virtualenv_name

10. 關閉虛擬環境的項目的特定進程(參數: 進程名, 虛擬環境名)

    1. cd myproject

    2. fab supervisor.stop_process:process_name,virtualenv_name

11. 啟動nginx(參數: nginx執行命令地址, nginx配置文件地址)

    注意: nginx_bin, nginx_conf 可在myproject/fabfile/__init__.py中配置
    例如: env.NGINX_BIN = '/usr/local/nginx/sbin/nginx'
          env.NGINX_CONF = '/usr/local/nginx/conf/nginx.conf'

    1. cd myproject

    2. fab nginx.start

    如果不配置__init__.py

    fab nginx.start:nginx_bin,nginx_conf

12. 重啟nginx(參數: nginx執行命令地址, nginx配置文件地址)

    1. cd myproject

    2. fab nginx.reload:nginx_bin,nginx_conf

13. 關閉nginx(參數: nginx執行命令地址, nginx配置文件地址)

    1. cd myproject

    2. fab nginx.stop:nginx_bin,nginx_conf

14. 修改nginx配置文件并重啟(參數: 源文本, 目標文本, nginx執行命令令, nginx配置文件地址)

    1. cd myproject

    2. fab nginx.switch:src_pattern,dst_pattern,nginx_bin,nginx_conf

15. 獲取幫助

    es -h

16. 從內部pypi安裝包,pypi服務器地址在project/init.py中可設置

    es pinstall xxx

17. 從官方pypi安裝包(支持pip其他命令)

    es install xxx

高級功能介紹


介紹nginx服務器配置以及a,b環境切換的處理

功能:

1. 保證新代碼上線時,重啟某一虛擬環境中的web服務,不會對用戶訪問造成中斷。
2. 新上線代碼出現bug時,及時回滾到上一次的版本。

場景介紹

假設目前有server1和server2兩臺服務器,ip分別為ip1、ip2。兩臺服務器均部署了兩個虛擬環境a和b。

a環境運行的項目監聽在端口8801,b環境運行的項目監聽在端口8811。

下面是簡單的nginx示例:

nginx.conf

    user nginx;
    worker_processes 1;

    #error_log /var/log/nginx/error.log warn;
    pid /var/run/nginx.pid;

    events {
        worker_connections 1024;
    }

    http {
        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        log_format main '$remote_addr - $remote_user [$time_local] "$request" '
        '$status $body_bytes_sent "$http_referer" '
        '"$http_user_agent" "$http_x_forwarded_for"';

        #access_log /var/log/nginx/access.log main;

        sendfile on;
        #tcp_nopush on;

        keepalive_timeout 65;

        #gzip on;


        include extra/essay_demo.conf;
        include extra/upstreamA.conf;
    }

extra/essay_demo.conf

    server {
        listen 80;
        server_name localhost;
        access_log /var/log/nginx/essay.access.log main;
        location / {
            proxy_pass http://essay_demo;
            proxy_intercept_errors on;
            proxy_redirect off;
            proxy_connect_timeout 60;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            set $cookiesize '0';
            if ($http_cookie ~ "_"){
                set $cookiesize 1;
            }
        }
    }

extra/upstreamA.conf

    upstream essay_demo {
        server ip1:8801;
        server ip2:8801;
    }

extra/upstreamB.conf

    upstream essay_demo {
        server ip1:8811;
        server ip2:8811;
    }

目前nginx中配置的是upstreamA.conf,此時用戶的訪問會被反向代理到ip1和ip2的8801端口上。現在發布新版本上線,使用命令: fab -R dev deploy:<版本號>,b,test ,發布到b環境。

之后通過命令: fab -R nginx nginx.switch:upstreamA,upstreamB 把nginx中的upstreamA替換為upstreamB,并reload nginx,這樣用戶的訪問就會被反向代理到ip1和ip2的8811端口上,也就是剛才發布到b環境中的新部署的項目。

switch完整命令 fab -R nginx nginx.switch:src_pattern,dst_pattern,root,nginx_bin,nginx_conf

switch參數解釋:

    src_pattern: 原文本 (必填)

    dst_pattern: 目標文本 (必填)

    root: 是否使用root用戶,  是:root 否:None (可選項,默認為None)

    nginx_bin: nginx執行命令路徑,可以在fabfile/__init__.py下設定 (可選項)

    nginx_conf: nginx配置文件路徑,可以在fabfile/__init__.py下設定 (可選項)

圖示

Python項目自動化多服務器部署的工具:essay

fab -R dev nginx.switch: upstreamA.conf, upstreamB.conf

Python項目自動化多服務器部署的工具:essay

項目主頁:http://www.baiduhome.net/lib/view/home/1386232708908

 

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!