本周将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/

svn + nginx unit + python3自动化发布web服务方法的更多相关文章

  1. nginx下配置多个web服务

    参考 nginx配置详解  nginx反向代理与负载均衡详解 一.nginx简介: Nginx("engine x")是一款是由俄罗斯的程序设计师Igor Sysoev所开发高性能 ...

  2. nginx 与 tomcat 组合搭建web服务

    部分内容转自 http://www.cnblogs.com/naaoveGIS/ 1. Web服务 nginx是常用的web服务器,用于获取静态资源,类似的服务器还有apache. tomcat是基于 ...

  3. (七)CXF之与spring整合发布web服务

    一.需求分析 用spring发布服务 二.案例 2.1 引入maven依赖 <dependencies> <!-- 添加Spring支持 --> <dependency& ...

  4. 使用Ant自动化发布web工程

    通常在web应用程序需要上线或测试时通常需要部署到类似于tomcat.jboss.weblogic或webspare这些web服务器中,为避免手动部署带来的操作繁琐.易出错等问题,这里使用ant进行标 ...

  5. Linux(8)- nginx+uWSGI+virtualenv+supervisor 发布web服务器

    一.理论梳理 WSGI是web服务器的网关接口,它是一个规范,描述了web服务器(下图中的WEB server)如何与web应用程序(下图中的Application)通信,以及web应用程序如何链接在 ...

  6. dubbo发布web服务实例

    dubbo角色与调用执行过程 dubbo节点角色说明:provider: 暴露服务的服务提供方consumer: 调用远程服务的服务消费方registry: 服务注册于发现的注册中心monitor: ...

  7. IIS7.0发布Web服务-0001

    配置错误 不能在此路径中使用此配置节.如果在父级别上锁定了该节,便会出现这种情况.锁定是默认设置的 (overrideModeDefault="Deny"),或者是通过包含 ove ...

  8. Jetty 发布web服务

    Jetty provides a Web server and javax.servlet container, plus support for HTTP/2, WebSocket, OSGi, J ...

  9. 在Eclipse中,用XFire发布web服务

    配置及相关说明见http://www.cnblogs.com/xshy3412/archive/2007/09/29/910848.html 仅确定发布xfire需要的最基本的jar activati ...

随机推荐

  1. windows根据端口号杀进程

    有时候eclipse会被卡死, 结束进程后重新启动项目会出现端口已经被占用 这时候需要杀掉进程 1, cmd打开dos窗口 2, netstat -ano | findstr "端口号&qu ...

  2. Web前端 前端工程师首选的几款编辑器/IDE以及Markdown的编辑器、语法

    前端工程师常使用的编辑器/IDE 本地在线工具 webstrom 推荐指数 ***** vs code 推荐指数 **** atom 推荐指数 **** subline-text 推荐指数 **** ...

  3. Certbot为域名申请免费SSL证书

    Certbot(Let's Encrypt)是一个非盈利性认证机构通过运行互联网安全研究小组(ISRG)提供X.509 证书的传输层安全性不收取任何费用(TLS)加密.证书有效期为90天,在此期间可以 ...

  4. gulp+ThinkPHP配置

    gulp+ThinkPHP配置 gulp+ThinkPHP配置 目录结构: html |-src 开发目录 |-Home 静态页面 |-Public 静态资源目录 |-dist 生产目录 |-Home ...

  5. Linux新手随手笔记1.8

    配置网卡服务 将网卡的配置文件,保存成模板,叫做会话. nmcli命令查看网卡信息.nmcli是一款基于命令行的网络配置工具 只有一个网卡信息,下面我们再添加一个. 公司:静态IP地址 家庭:DHCP ...

  6. MIP开发教程(二) 使用MIP-CLI工具调试MIP网页

    初始化 MIP 配置 新建一个 MIP 网页 编写 MIP 网页代码 校验 MIP 网页 调试 MIP 网页 1. 初始化 MIP 配置 首先在html目录下进行初始化 MIP 配置: $ mip i ...

  7. 多线程工具类:CountDownLatch、CyclicBarrier、Semaphore、LockSupport

    ◆CountDownLatch◆ 假如有一个任务想要往下执行,但必须要等到其他的任务执行完毕后才可以.比如你想要买套房子,但是呢你现在手上没有钱.你得等这个月工资发了.然后年终奖发了.然后朋友借你得钱 ...

  8. Java并发-建立线程

    一.建立新的线程 Runnable r = () ->{ //线程所执行的逻辑代码 }; Thread thread = new Thread(r); thread.start(); 方法介绍 ...

  9. 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之九 || 依赖注入IoC学习 + AOP界面编程初探

    更新 1.如果看不懂本文,或者比较困难,先别着急问问题,我单写了一个关于依赖注入的小Demo,可以下载看看,多思考思考注入的原理: https://github.com/anjoy8/BlogArti ...

  10. scala获取某个时间间隔的时间

    原始 dataFrame : //获取前7天的时间long类型 def getDaytimeTime(day:Int): Long = { val cal = Calendar.getInstance ...