因为一个奇怪的需求,使用 Python 和 Tornado 框架实现了一个 Web 站点的反向代理。实现的功能是这样:
- 假设这个反向代理网站的地址是 http://www.example.com
- 访问 http://www.example.com/.site.backend_site0/ 访问的是 backend_site0,这个网站可以是部署在内网的某个站点(外网当然也是可以)。
- 访问 http://www.example.com/.site.backend_site1/ 访问另外一个站点 backend_site1
怎么通过一个公共的站点反向代理访问后端的多个站点,当时的讨论帖在这里,我采用的是:
- 在url中添加前缀
.site.
,第一次访问的时候使用 http://www.example.com/.site.backend_site/ - 服务端识别出请求的后端站点
backend_site
后,会设置 Cookie,.site = backend_site
,后续的访问会根据Cookie来识别出来。 - 当访问另外一个网站 http://www.example.com/.site.backend_site1/ 这时候,服务端会清除旧的 Cookie,并设置新的 Cookie,
.site = backend_site1
,这样就切换到新的站点backend_site1
- 启用页面内容替换,保证页面内的内网IP地址转换成反向代理的地址。例如后端站点 backend_site0 的地址是 http://10.1.2.3/ 页面内有链接 http://10.1.2.3/img/a.png 将其替换成 /.site.backend_site0/img/a.png
项目的代码开源在 Github 上,有需要的可以自取。
https://github.com/restran/web_proxy
环境需求
Python 2.7
Tornado 4.0
所代理的后端网站注意事项
url 的前缀不应出现 /.site.
由于反向代理采用url前缀来区分后端网站,如 /.site.example/,表示后端站点example。
例如以下为禁用的url:
/.site./
/.site.example/
/.site.example/user/login/cookies 中不应出现以 .site 命名的 cookie 值,这个 cookie 是用来标识当前访问的后端站点
CentOS 7.0 部署
Tornado 的部署可以参照这里的教程。通过启动多个 Tornado 实例,来避免调用到同步函数块,导致阻塞住,无法响应其他用户的请求。使用 supervisor 来启动 Tornado Server,并使用 Nginx 作为 Web 服务器,反向代理后端的这些 Tornado 实例。
修改配置文件 settings.py
1 | # 转发到后端需要代理的网站的地址列表 |
使用 supervisor 启动 Tornado Server
设置配置文件
vim /etc/supervisord.conf
输入如下信息
1 | [program:tornado_server_9001] |
重新加载配置文件
supervisorctl reload
重新启动所有程序
sudo supervisorctl restart all
配置 nginx
添加 nginx 配置文件
vim /etc/nginx/conf.d/web_proxy.conf
输入如下配置信息
1 | upstream tornadoes { |
重启 nginx
service nginx restart
todo
URL 访问控制,访问列表