本周將python web服務管理更換成nginx unit以后發現接口性能有了明顯的提升,訪問速度快了不少。不過有個很大的問題就是使用svn自動化發布以后,服務並沒有刷新使用新的代碼運行,而又不懂得如何將它弄成服務自動重啟,只能用迂回救國的方式來想辦法處理。
試過用kill命令將unit進程殺死,然后啟動服務方式,操作后發現會引發很多問題,最后放棄了。而unit有的特點就是配置文件更新以后會自動重啟對應的服務,從而達到更新代碼服務的效果,針對於這個特點所以想出了一個辦法,那就是寫個腳本,當代碼發布成功以后,通過svn的勾子執行該腳本,從而改變unit配置從而達到想要重啟服務的效果。
要實現這個功能,腳本必須具體以下功能:
1.讀取原始配置文件內容(也可以直接放在腳本代碼中)
2.接收要重啟服務的application名稱
3.使用字符串替換操作,將配置中的application名稱替換成添加了隨機數的新名稱
4.將新配置寫入到文件中
5.執行配置刷新命令,重啟unit服務
下面是完成的腳本代碼update_unit_json.py
#!/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))
執行命令看看效果
[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
將******替換成你的服務器密碼,如果有多台服務器時,這里可以直接添加web2、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/