人生苦短我用python[0x02] nginx与python结合
背景
nginx是一款高性能的http服务器,python是一门无论做系统开发还是业务逻辑开发都是非常不错的动态语言,现在流行微服务,微服务往往又以http协议居多,LAMP是一直以来比较受欢迎的技术组合,Apache+PHP,PHP确实也是一门用来做web开发不错的语言,如果涉及到一些系统方面的调用可能用上来就没有python那么顺手,apahce相对于nginx讲,在功能方面会比较全面,性能就有所落后,nginx显得更灵活和高效。今天我们要讲的是用nginx作为http服务的框架,用python来开发后端的逻辑实现,这样的组合很适合把一些系统接口包装成http接口对外提供服务。nginx与python结合的姿势
通常http服务与后端对接往往用的是CGI(Common Gateway Interface)的方式对接,比如apache服务器可以对接一个用c语言编写的可执行文件,只要这个c语言编写的执行文件符合CGI的规范就可以处理并返回来自apache服务器的http请求。nginx与python对接,目前使用最为广泛的方式是WSGI(Web Server Gateway Interface),跟CGI类似,WSGI只是一个标准,他不是一种实现方式,目前开源项目uWSGI是大家用得比较多的实现,本文将会用uWSGI给大家讲解nginx与python的结合,并给出一些简单的例子说明python如何处理来自前端nginx的http请求,如何把处理结果返回给http调用者。下载安装nginx
http://nginx.org/en/download.html
#到nginx官网下载最新版本的源码包到/opt目录
#解压后进入代码目录进行编译和安装
#如果configure过程提示没有pcre,则需要先安装pcre-devel库
./configure --prefix=/opt/nginx
make
make install
#一切顺利的话,nginx已经安装好在/opt/nginx目录下,我们先去安装uWSGI然后再回头设置nginx的配置文件
下载安装uWSGI
https://uwsgi-docs.readthedocs.io/en/latest/Download.html
#到uWSGI官网下载最新版本的源码包到/opt目录
#解压后进入代码目录进行编译
make
#编译顺利完成后,会在当前目录下看到uwsgi的可执行文件
#比如我们的目录是 /opt/uwsgi-2.0.8/uwsgi
准备python uWSGI脚本
#我们把所有uWSGI的python脚本都放在/opt/uwsgi目录下
mkdir /opt/uwsgi
cd /opt/uwsgi
#先建立一个uwsgi的软连接
ln -s /opt/uwsgi-2.0.8/uwsgi uwsgi
#写一个启动uWSGI进程的脚本
cat run_uwsgi.sh
#!/bin/sh
./uwsgi -s 127.0.0.1:3031 -M -p 16 \ #监听本机3031端口,16个子进程
--harakiri=120 \ #处理超时时间是120秒
--pythonpath /opt/uwsgi \ #python目录
--chdir /opt/uwsgi
--wsgi-file main.py \ #uWSGI的入口文件是main.py,下面会有main.py内容
--daemonize /var/log/uwsgi.log \ #日志输出文件
--touch-logreopen=/var/log/touch-uwsgi-logreopen #设置可以通知uWSGI重新打开日志文件
uWSGI入口文件 main.py
import web
import os
import json
from urllib import unquote
urls = ("/.*", "main")
class main:
def GET(self):
try:
#获取GET参数
query = unquote(web.ctx.env['QUERY_STRING'])
#返回内容就是nginx返回给http调用者的内容,这里只返回GET请求内容
return query
except Exception as e:
return e
def POST(self):
try:
#获取POST数据
post_data = json.loads(web.data())
#同GET一样,返回POST数据
return post_data
except Exception as e:
return e
app = web.application(urls, globals())
application = app.wsgifunc()
配置nginx.conf
#在nginx server,比如在80端口server块里面增加后端uWSGI信息
#增加一个/uwsgi/的子目录,专门用于处理uWSGI服务
location ~ /uwsgi/(.*) {
include uwsgi_params;
uwsgi_send_timeout 120s; #设置超时时间
uwsgi_read_timeout 120s;
uwsgi_pass 127.0.0.1:3031; #跟uWSGI服务端口一致
}
运行uWSGI和nginx
#启动uWSGI服务
sh /opt/uwsgi/run_uwsgi.sh
#检查uwsgi是否启动成功监听服务端口
netstat -lnp|grep uwsgi
#启动nginx
/opt/nginx/sbin/nginx
#测试uWSGI GET
curl "http://127.0.0.1/uwsgi/?arg1=123&arg2=abc"
#测试uWSGI POST
curl -d "hello" "http://127.0.0.1/uwsgi/"