svn + nginx unit + python3自動化發佈web服務方法

  本週將python web服務管理更換成nginx unit之後發現接口性能有了明顯的提高,訪問速度快了很多。不過有個很大的問題就是使用svn自動化發佈之後,服務並無刷新使用新的代碼運行,而又不懂得如何將它弄成服務自動重啓,只能用迂迴救國的方式來想辦法處理。python

  試過用kill命令將unit進程殺死,而後啓動服務方式,操做後發現會引起不少問題,最後放棄了。而unit有的特色就是配置文件更新之後會自動重啓對應的服務,從而達到更新代碼服務的效果,針對於這個特色因此想出了一個辦法,那就是寫個腳本,當代碼發佈成功之後,經過svn的勾子執行該腳本,從而改變unit配置從而達到想要重啓服務的效果。nginx

  要實現這個功能,腳本必須具體如下功能:web

  1.讀取原始配置文件內容(也能夠直接放在腳本代碼中)json

  2.接收要重啓服務的application名稱vim

  3.使用字符串替換操做,將配置中的application名稱替換成添加了隨機數的新名稱服務器

  4.將新配置寫入到文件中app

  5.執行配置刷新命令,重啓unit服務dom

  下面是完成的腳本代碼update_unit_json.pyssh

#!/usr/bin/env python
# coding=utf-8
"""
更新unit配置,重啓Python web服務
"""

import logging
import os
import sys
import random

# 獲取本腳本所在的路徑
pro_path = os.path.split(os.path.realpath(__file__))[0]
sys.path.append(pro_path)

# 定義日誌輸出格式
logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                    filename="/data/logs/service/update_unit_json.log",
                    filemode='a')

# unit配置信息
unit_json = """{
    "listeners": {
        "*:51000": {
            "application": "test_app_application"
        }
    },
    "applications": {
        "test_app_application": {
            "type": "python",
            "processes": {
                "max":20,
                "spare": 2
            },
            "path": "/data/www/test_app",
            "module": "main"
        }
    },
    "access_log": "/data/logs/www/access.log"
}
"""

def save_file(file_path, content, mode='a', encoding='utf-8'):
    """保存內容到文件裏"""
    try:
        file_object = open(file_path, mode, encoding=encoding)
        file_object.write(content)
        file_object.close()
        return True
    except Exception as e:
        print(str(e.args))
        return False

def get_random():
    """
    獲取指定長度的隨機字符
    """
    return str(random.randint(1000, 9999))


if __name__ == "__main__":
    if len(sys.argv) == 1:
        print('缺乏必要參數')
        sys.exit()

    # 獲取服務名稱
    application = sys.argv[1]
    print(application)

    try:
        # 設置配置文件存儲地址
        file_path = '/data/unit/unit.json'
        # 替換json中的application串
        unit_json = unit_json.replace(application, application + get_random())
        print(unit_json)
        # 寫入配置文件
        save_file(file_path, unit_json, 'w')
        # 設置unit配置重載命令(unit.json存儲位置能夠放到本身喜歡的任何地方;
        # control.unit.sock會根據在不一樣路徑輸入unitd啓動命令,而直接在該路徑下建立該文件,若是想要正常啓動必須在build目錄下運行unitd啓動,另外不一樣服務器安裝方式build位置可能不同)
        command = 'curl -X PUT -d @/data/unit/unit.json --unix-socket /usr/local/unit/build/control.unit.sock http://localhost/config/'
        print(command)
        os.system(command)
        print('成功')
    except Exception as e:
        print('服務出現異常,異常信息:' + str(e.args))

  執行命令看看效果curl

[root@izwz94jx1zymn4ogxqstsxz pre_release]# python3 update_unit_json.py test_app_application
test_app
{
    "listeners": {
        "*:51000": {
            "application": "test_app_application261542"
        }
    },
    "applications": {
        "test_app_application261542": {
            "type": "python",
            "processes": {
                "max":20,
                "spare": 2
            },
            "path": "/data/www/test_app",
            "module": "main"
        }
    },
        "access_log": "/data/logs/www/access.log"
}

curl -X PUT -d @/data/unit/unit.json --unix-socket /usr/local/unit/build/control.unit.sock http://localhost/config/
{
        "success": "Reconfiguration done."
}
成功

 

  寫完腳本之後,直接在svn勾子post-commit裏添加對應的命令

#!/bin/sh

export LANG=en_US.UTF-8
/usr/bin/svn up /data/www/test_app
chown -R nobody:nobody /data/www/test_app
python3 /data/service/test/update_unit_json.py test_app_application

  因爲unit使用的是nobody用戶運行的,因此在勾子中須要添加chown -R nobody:nobody /data/www/test_app命令,將新增或修改的文件的用戶和組修改成nobody,否則可能運行會出錯

 

  若是是多服務器須要同步發佈和更新重啓時,以上命令也達不到想要的自動化發佈效果,因此可使用ansible來進行管理,它能夠幫咱們跨服務器執行咱們須要執行的命令,固然代碼的跨服務器發佈也可使用rsync來管理

  安裝epel源
  yum -y install epel-release

  安裝ansible
  yum –y install ansible

  輸入命令修改配置vim /etc/ansible/hosts,並添加下面內容:

[all]

[web1]
127.0.0.1:22 ansible_ssh_user=root ansible_ssh_pass=****** ansible_sudo_pass=****** ansible_ssh_private_key_file=~/.ssh/id_rsa

  將******替換成你的服務器密碼,若是有多臺服務器時,這裏能夠直接添加web二、web3等

  修改/etc/ansible/ansible.cfg配置,將下面內容前面的#去掉,改成對應的內容

inventory = /etc/ansible/hosts
forks = 5
poll_interval = 15
sudo_user = root
transport = smart
remote_port = 22
module_lang = C
gathering = implicit
gather_timeout = 10
host_key_checking = False
sudo_exe = sudo
private_key_file = ~/.ssh/id_rsa
deprecation_warnings = False

 

  主控端生成ssh密鑰文件:
  ssh-keygen -t rsa -P ''
  添加信任到客戶端:
  ssh-copy-id -i ~/.ssh/id_rsa.pub root@127.0.0.1
  顯示要求輸入密碼時,輸入目標客戶端主機的登陸密碼
  對全部分組機器執行ping測試
  ansible all -m ping
  就能夠看到各臺主機返回執行命令成功的信息了。

  重啓客戶端全部主機的服務,須要將svn服務器的勾子命令修改成下面內容

#!/bin/sh

export LANG=en_US.UTF-8
/usr/bin/svn up /data/www/test_app
/usr/bin/ansible all -s -a "chown -R nobody:nobody /data/www/test_app"
/usr/bin/ansible all -s -a "python3 /data/service/pre_release/update_unit_json.py test_app_application"

  添加其餘須要執行的命令時,只須要按上面的格式,將命令放在/usr/bin/ansible all -s -a ""裏就能夠了

  當svn提交成功後,就會自動重啓目標主機的對應服務了

 

版權聲明:本文原創發表於 博客園,做者爲 AllEmpty 本文歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然視爲侵權。

python開發QQ羣:669058475(本羣已滿)、733466321(能夠加2羣)    做者博客:http://www.cnblogs.com/EmptyFS/

相關文章
相關標籤/搜索