Python网络框架——Web服务器

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: Web服务器是连接用户浏览器与Python服务器端程序的中间节点,在网站建立的过程中起着重要的作用。目前最主流的Web服务器包括Nginx、Apache、lighthttpd、IIS等。Python服务器端程序在Linux平台下使用最广泛的是Nginx。

引言:Web服务器是连接用户浏览器与Python服务器端程序的中间节点,在网站建立的过程中起着重要的作用。目前最主流的Web服务器包括Nginx、Apache、lighthttpd、IIS等。Python服务器端程序在Linux平台下使用最广泛的是Nginx。
本文将带您学习Python程序与Web服务器连接的WSGI接口、Nginx的安装和配置方法,以及搭建SSL网站的技术。本文选自《Python高效开发实战——Django、Tornado、Flask、Twisted》一书。

实战演练1:WSGI接口

WSGI是将Python服务器端程序连接到Web服务器的通用协议。由于WSGI的通用性,出现了独立的WSGI程序,例如uWSGI和Apache的mod_wsgi。
WSGI的全称为Web Server Gateway Interface,也可称作Python Web Server Gateway Interface,开始于2003年,为Python语言定义Web服务器和服务器端程序的通用接口规范。因为WSGI在Python中的成功,所以其他语言诸如Perl和Ruby也定义了类似WSGI作用的接口规范。WSGI的作用如图。
图片描述
从上图中可见WSGI的接口分为两个:一个是与Web服务器的接口,另一个是与服务器端程序的接口。WSGI Server与Web服务器的接口包括uwsgi、fast cgi等,服务器端程序的开发者无须学习这部分的详细内容。服务器端的开发者需要关注的是WSGI与服务器程序的接口。
WSGI的服务器程序的接口非常简单,以下是一个服务器端程序的例子,将该文件保存为webapp.py:

def application(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
return '<b>Hello, world!</b>'

该代码只定义了一个函数app,所有来自Web服务器的HTTP请求都会由WSGI服务转换为对该函数的调用。该示例的app函数中没有复杂的处理,只是通过start_response返回了状态码,并通过return返回了一个固定的HTTP消息体。与该服务器端程序相对应的是下面的WSGI Server程序:

#引入Python的WSGI包
fromwsgiref.simple_server import make_server
#引入服务器端程序的代码
fromwebapp import application

#实例化一个监听8080端口的服务器
server = make_server('', 8080, application)
# 开始监听HTTP请求:
server.serve_forever()

将该WSGI Server的程序保存为wsgi_server.py,通过下面的命令即可启动一个Web服务器,该服务器对所有的请求都返回Hello World页面:

#python wsgi_server.py

注意:虽然WSGI的设计目标是连接标准的Web服务器(Nginx、Apache等)与服务器端程序,但WSGI Server本身也可以作为Web服务器运行。由于性能方面的原因,该服务器一般只做测试使用,不能用于正式运行。

实战演练2:Linux+Nginx+uWSGI配置

Nginx 是由俄罗斯工程师开发的一个高性能HTT和反向代理服务器,其第1个公开版本0.1.0于2004年以开源形式发布。自发布后,它以运行稳定、配置简单、资源消耗低而闻名。许多知名网站(百度、新浪、腾讯等)均采用Nginx作为Web服务器。
因为Nginx是Python在Linux环境下的首选Web服务器之一,所以本节以Ubuntu Linux为例演示Nginx的安装及配置方法。

1.安装Nginx

在Ubuntu Linux中可以通过如下命令安装Nginx:

#sudo apt-get install nginx

安装结果如下。
图片描述

安装程序把Nginx以服务的形式安装在系统中,相关的程序及文件路径如下。

  • 程序文件:放在/usr/sbin/nginx目录中。
  • 全局配置文件:/etc/nginx/nginx.conf。
  • 访问日志文件:/var/log/nginx/access.log。
  • 错误日志文件:/var/log/nginx/error.log。
  • 站点配置文件:/etc/nginx/sites-enabled/default。

安装好后,可以通过如下命令启动Nginx服务器:

.#sudo service nginx start

停止Nginx服务器:

#sudo service nginx stop

查看Nginx服务的状态:

#sudo service nginx status

重启Nginx服务器:

#sudo service nginx restart

2.Nginx配置文件

Nginx安装后以默认方式启动,在开发调试的过程中可能需要调整Nginx的运行参数,这些运行参数通过全局配置文件(nginx.conf)和站点配置文件(sites-enabled/*)进行设置。对全局配置文件(/etc/nginx/nginx.conf)中的关键可设置参数解析如下:

user www-data;                         ##定义运行Nginx的用户

worker_processes 4;                     ##Nginx进程数,应设置与系统CPU数量相等的数值

worker_rlimit_nofile 65535;             ##每个Nginx进程可以打开的最大文件数

events {                        
    worker_connections 768;             ##每个Nginx进程允许的最大客户端连接数

    #在Nginx接到一个新连接通知后调用accept()来接受尽量多的连接
    multi_accept off;
}

http {

    ##
    # Basic Settings
    ##

sendfile on;                        ##是否允许文件上传
client_header_buffer_size 32k;        ##上传文件大小限制
tcp_nopush on;                            ##防止网络阻塞
tcp_nodelay on;                        ##防止网络阻塞
keepalive_timeout 65;                ##允许的客户端长连接最大秒数

    ##Nginx散列表大小。本值越大,占用的内存空间越大,但路由速度越快
types_hash_max_size 2048;        

access_log /var/log/nginx/access.log;         ##访问日志文件路径名
error_log /var/log/nginx/error.log;             ##错误日志文件路径名

    ## 如下两条用include命令加载站点配置文件
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
在每个Nginx服务器中可以运行多个Web站点,每个站点的配置通过站点配置文件设置。每个站点应该以一个单独的配置文件存放在/etc/nginx/sites-enabled目录中,默认站点的配置文件名为/etc/nginx/sites-enabled/default,对其中关键内容的解析如下:
server {

    ##配置站点监听的端口
    listen 80;            

    root /usr/share/nginx/html;                 ##配置HTTP根页面目录
    index index.html index.htm;                 ##配置HTTP根目录中的默认页面

    #站点监听的IP地址,默认的localhost只可用于本机访问,一般需要将其更改为真实IP
    server_name localhost;

    ##location用于配置URL的转发接口
    location /user/ {
        ##此处配置http://server_name/user/的转发地址
        proxy_pass http://127.0.0.1:8080;
    }

    ##错误页面配置,如下配置定义HTTP 404错误的显示页面为/404.html
    error_page 404 /404.html;
}

3.安装uWSGI及配置

uWSGI是WSGI在Linux中的一种实现,这样开发者就无须自己编写WSGI Server了。
使用pip命令可以直接安装uWSGI:

#pip install uwsgi

安装完成后即可运行uwsgi命令启动WSGI服务器,uwsgi命令通过启动参数的方式配置可选的运行方式。比如,如下命令可以运行uWSGI,用于加载之前编写的服务器端程序webapp.py:

#uwsgi--http:9090--wsgi-file webapp.py
*** Starting uWSGI 2.0.12 (64bit) on [Wed Feb 17 15:27:21 2016] ***
compiled with version: 4.8.2 on 17 February 2016 15:21:40
os: Linux-3.13.0-32-generic #57-Ubuntu SMP Tue Jul 15 03:51:08 UTC 2014
nodename: iZ28e3m2w7rZ
machine: x86_64
clock source: unix
pcrejit disabled
detected number of CPU cores: 1
current working directory: /home/lynn/project/my_project
detected binary path: /home/lynn/project/my_project/venv/bin/uwsgi
*** WARNING: you are running uWSGI without its master process manager ***
your processes number limit is 3746
your memory page size is 4096 bytes
detected max file descriptor number: 65535
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uWSGI http bound on 9090 fd 4
spawneduWSGI http 1 (pid: 18669)
uwsgi socket 0 bound to TCP address 127.0.0.1:34755 (port auto-assigned) fd 3
Python version: 2.7.6 (default, Jun 22 2015, 18:01:27)  [GCC 4.8.2]
*** Python threads support is disabled. You can enable it with --enable-threads ***
Python main interpreter initialized at 0x1ff3b20
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 72768 bytes (71 KB) for 1 cores
*** Operational MODE: single process ***
WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x1ff3b20 pid: 18668 (default app)
*** uWSGI is running in multiple interpreter mode ***
spawneduWSGI worker 1 (and the only) (pid: 18668, cores: 1)

启动时用--http参数指定了监听端口,用--wsgi-file指定了服务器端的程序名。如上所示,uWSGI在启动的过程中会输出系统的一些环境信息:服务器名、进程数限制、服务器硬件配置、最大文件句柄数等。
除了在uWSGI启动命令行中提供配置参数,uWSGI还允许通过一个配置文件设置这些配置参数,比如可以编写如下配置文件,保存在文件名uwsgi.ini中:

[uwsgi]
http = 9090
wsgi-file = webapp.py

启动uWSGI时直接指定配置文件即可:

#uwsgi uwsgi.ini

此时用浏览器访问服务器的9090端口,效果如下。

除了http和wsgi-file参数,uWSGI还有很多其他参数,常用的如下。
图片描述

  • socket:以WSGI的Socket方式运行,并指定连接地址和端口。该Socket接口是uWSGI与其他Web服务器(Nginx/Apache)等进行对接的方式。
  • chdir:指定uWSGI启动后的当前目录。
  • processes:指定启动服务器端程序的进程数。
  • threads:指定每个服务器端程序的线程数。即服务器端的总线程数为precessesthreads。
  • uid:指定运行uWSGI的Linux用户id。

比如,如下配置文件用于用Socket方式启动一个uWSGI服务器,并配置了进程和线程数:、

uwsgi]
socket = 127.0.0.1: 3011
wsgi-file = webapp.py
processes = 4
threads = 3

4.集成Nginx与uWSGI

直接通过在站点配置文件中为location配置uwsgi_pass,即可将Nginx与uWSGI集成,建立一个基于Nginx+Python的正式站点。针对如下uWSGI接口有:

uwsgi]
socket = 127.0.0.1: 3011
wsgi-file = webapp.py
Nginx的站点配置文件为:
server {
    listen 80;            

##此处改为服务器的真实IP
    server_name121.12.134.11;

    location /{
        ##此处IP与Port配置必须与uwsgi接口中参数相同
        uwsgi_pass http://127.0.0.1:3011;
    }
}

技巧:可以为一个uWSGI配置多个Nginx Server和location,这样就轻松实现了以多域名访问同一个Python程序。

实战演练3:建立安全的HTTPS网站

普通HTTP站点的协议与数据以明文方式在网络上传输,而HTTPS(Hypertext Transfer Protocol over Secure Socket Layer)是以安全为目标的HTTP通道,即在HTTP下加入SSL层,通过SSL达到数据加密及身份认证的功能。目前几乎所有的银行、证券、公共交通的网站均以HTTPS方式搭建。
OpenSSL是一个强大的免费Socket层密码库,蕴含了主要的密码算法、常用的密钥和证书封装管理功能及SSL协议。目前大多数网站通过OpenSSL工具包搭建HTTPS站点,其步骤如下。

  • 在服务器中安装OpenSSL工具包。
  • 生成SSL密钥和证书。
  • 将证书配置到Web服务器。
  • 在客户端安装CA证书。

本节演示在Linux Ubuntu下OpenSSL的使用方法,以及Nginx在Linux下的证书配置方式。Windows中OpenSSL的使用方式与Linux中的完全一致,读者可以自行尝试。

1.在服务器中安装OpenSSL工具包

通过如下两条命令安装OpenSSL:

#sudo apt-get install openssl
#sudo apt-get install libssl-dev

命令运行成功后,OpenSSL命令和配置文件将被安装到Linux系统目录中。

  • OpenSSL命令:/usr/bin/openssl。
  • 配置文件:/usr/lib/ssl/*。

2.生成SSL密钥和证书

通过如下步骤生成CA证书ca.crt、服务器密钥文件server.key和服务器证书server.crt:

#生成CA 密钥
opensslgenrsa -out ca.key 2048

#生成CA证书,days参数以天为单位设置证书的有效期。在本过程中会要求输入证书的所在地、公司名、站点名等
opensslreq -x509 -new -nodes -key ca.key -days 365 -out ca.crt

#生成服务器证书RSA的密钥对
opensslgenrsa -out server.key 2048

#生成服务器端证书CSR,本过程中会要求输入证书所在地、公司名、站点名等。
opensslreq -new -key server.key -out server.csr

#生成服务器端证书 ca.crt
openssl x509 -req -in server.csr -CA ca.crt -CAkeyca.key -CAcreateserial -out server.crt -days 365

上述命令生成服务器端证书时,必须在Common Nanme (CN) 字段中如实输入站点的访问地址。即如果站点通过www.mysite.com访问,则必须定义CN=www.mysite.com;如果通过IP地址访问,则需设置CN为具体的IP地址。

3.配置Nginx HTTPS服务器

在站点配置文件/etc/nginx/sites-enabled/default中添加如下server段,可以定义一个基于HTTPS的接口,该接口的服务器端程序仍旧为uWSGI接口127.0.0.1:3011。

server {
listen       443;                            #HTTPS服务端口
server_name0.0.0.0;                        #本机上的所有IP地址
ssl                  on;
ssl_certificate    /etc/nginx/ssl/server.crt;
ssl_certificate_key    /etc/nginx/ssl/server.key;

location \ {
    uwsgi_passhttp://127.0.0.1:3011;
}

}

其中需要注意的是参数ssl_certificate和ssl_certificate_key需要分别指定生成的服务器证书和服务器密钥的全路径文件名。
至此,我们已经可以使用浏览器访问服务器的443端口进行HTTPS加密通信了。
想及时获得更多精彩文章,可在微信中搜索“博文视点”或者扫描下方二维码并关注。
图片描述

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
1天前
|
数据采集 网络协议 API
HTTP协议大揭秘!Python requests库实战,让网络请求变得简单高效
【9月更文挑战第13天】在数字化时代,互联网成为信息传输的核心平台,HTTP协议作为基石,定义了客户端与服务器间的数据传输规则。直接处理HTTP请求复杂繁琐,但Python的`requests`库提供了一个简洁强大的接口,简化了这一过程。HTTP协议采用请求与响应模式,无状态且结构化设计,使其能灵活处理各种数据交换。
25 8
|
1天前
|
Python
使用Python和Flask构建简单的Web应用
使用Python和Flask构建简单的Web应用
13 6
|
1天前
|
SQL 安全 数据库
从入门到精通:Python Web安全守护指南,SQL注入、XSS、CSRF全防御!
【9月更文挑战第13天】在开发Python Web应用时,安全性至关重要。本文通过问答形式,详细介绍如何防范SQL注入、XSS及CSRF等常见威胁。通过使用参数化查询、HTML转义和CSRF令牌等技术,确保应用安全。附带示例代码,帮助读者从入门到精通Python Web安全。
14 6
|
2天前
|
网络协议 安全 网络安全
震惊!Python Socket竟能如此玩转网络通信,基础到进阶全攻略!
【9月更文挑战第12天】在网络通信中,Socket编程是连接不同应用与服务的基石。本文通过问答形式,从基础到进阶全面解析Python Socket编程。涵盖Socket的重要性、创建TCP服务器与客户端、处理并发连接及进阶话题如非阻塞Socket、IO多路复用等,帮助读者深入了解并掌握网络通信的核心技术。
16 6
|
2天前
|
SQL 安全 JavaScript
告别Web安全小白!Python实战指南:抵御SQL注入、XSS、CSRF的秘密武器!
【9月更文挑战第12天】在Web开发中,安全漏洞如同暗礁,尤其对初学者而言,SQL注入、跨站脚本(XSS)和跨站请求伪造(CSRF)是常见挑战。本文通过实战案例,展示如何利用Python应对这些威胁。首先,通过参数化查询防止SQL注入;其次,借助Jinja2模板引擎自动转义机制抵御XSS攻击;最后,使用Flask-WTF库生成和验证CSRF令牌,确保转账功能安全。掌握这些技巧,助你构建更安全的Web应用。
10 5
|
4天前
|
安全 Python
使用Python实现简单的Web服务器
使用Python实现简单的Web服务器
15 6
|
1天前
|
消息中间件 网络协议 网络安全
解锁Python Socket新姿势,进阶篇带你玩转高级网络通信技巧!
【9月更文挑战第13天】在掌握了Python Socket编程基础后,你是否想进一步提升技能?本指南将深入探讨Socket编程精髓,包括从阻塞到非阻塞I/O以提高并发性能,使用`select`进行非阻塞操作示例;通过SSL/TLS加密通信保障数据安全,附带创建SSL服务器的代码实例;以及介绍高级网络协议与框架,如HTTP、WebSocket和ZeroMQ,帮助你简化复杂应用开发。通过学习这些高级技巧,你将在网络编程领域更进一步。
11 2
|
3天前
|
机器学习/深度学习 人工智能 TensorFlow
深入骨髓的解析:Python中神经网络如何学会‘思考’,解锁AI新纪元
【9月更文挑战第11天】随着科技的发展,人工智能(AI)成为推动社会进步的关键力量,而神经网络作为AI的核心,正以其强大的学习和模式识别能力开启AI新纪元。本文将探讨Python中神经网络的工作原理,并通过示例代码展示其“思考”过程。神经网络模仿生物神经系统,通过加权连接传递信息并优化输出。Python凭借其丰富的科学计算库如TensorFlow和PyTorch,成为神经网络研究的首选语言。
10 1
|
4天前
|
API 开发者 Python
揭秘Python网络请求的幕后英雄:requests与urllib的恩怨情仇
【9月更文挑战第10天】在Python的网络请求领域,urllib与requests犹如武林中的两大高手,各自展现了独特的魅力。urllib作为标准库成员,自Python诞生以来便承担着网络请求的任务,以其稳定性和全面性著称。然而,其复杂的API让不少开发者望而却步。
11 2
|
5天前
|
数据采集 JavaScript 前端开发
构建你的首个Python网络爬虫
【9月更文挑战第8天】本文将引导你从零开始,一步步构建属于自己的Python网络爬虫。我们将通过实际的代码示例和详细的步骤解释,让你理解网络爬虫的工作原理,并学会如何使用Python编写简单的网络爬虫。无论你是编程新手还是有一定基础的开发者,这篇文章都将为你打开网络数据获取的新世界。