本週將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/