为什么要将https转发为http
当前的互联网应用基本都要支持https协议,而当浏览器头通过https协议将请求发到到负责负载的nginx后,会由当前nginx再以http协议向后端upstream进行请求,之所以这么做是因为https协议的安全性也带来的额外的性能消耗。而源端基本都是在一个内网里面的,对于通讯协议的安全性要求没那么高,采用http协议通讯性能会更优,也能降低证书的部署成本。
因此在实际应用中的部署架构如下方所示
浏览器 ---- https (http2) —> nginx (负载均衡) ---- http1.1—> nginx/tomcat/node (upstream 源端)
如何配置
假设我当前的域名为 aaa.com
并且已经有了aaa.com的ssl证书(自签或购买),本文重点不在于如何生成证书,具体就不写了。
证书会包含2个文件:
aaa_com.key , aaa_com.crt
建议将这2个文件cpoy到 nginx的安装目录(默认为:/usr/local/nginx)的ssl目录中(需要自行创建)
然后创建aaa.com的虚拟主机配置文件aaa.conf,示例如下
server {
listen 80;
server_name www.aaa.com aaa.com;
access_log /data/log/nginx/aaa_access.log main;
error_log /data/log/nginx/aaa_error.log;
#核心代码
rewrite ^(.*)$ https://${server_name}$1 permanent;
}
#配置源端
upstream aaa-upstream {
#源端的ip与端口
server x.x.x.x:port weight=5 max_fails=3 fail_timeout=30s;
}
server {
server_name www.aaa.com aaa.com;
#https相关配置,开启http2.0
#启用https需要安装openssl,同时在安装nginx的时候添加 --with-http_ssl_module --with-http_v2_module
listen 443 ssl http2;
#指定证书位置
ssl_certificate /usr/local/nginx/ssl/aaa_com.crt;
ssl_certificate_key /usr/local/nginx/ssl/aaa_com.key;
ssl_session_cache shared:SSL:10m;
#1m大约可以存储4000个TLS握手,当某个https连接在规定时间重连时,可以通过session_cahce重用TLS秘钥,也就是client只要发起一次http请求就可以再次进行连接。
#根据TLS通讯过程,如果你的https开启了session_cache,在第二步,server获取到client请求就会去读取session_cache文件,如果存在client的key就直接复用,进行数据传输。
#设置存储会话参数的高速缓存的类型和大小。缓存可以是以下任何一种类型:
# off 严禁使用会话缓存:nginx明确告诉客户端会话可能不会被重用。
# none 会话缓存的使用被轻轻地禁止:nginx告诉客户端会话可能被重用,但实际上不会将会话参数存储在缓存中。
# builtin 建立在OpenSSL中的缓存; 仅由一个工作进程使用。缓存大小在会话中指定。如果没有给出大小,则等于20480个会话。内置缓存的使用可能导致内存碎片。
# shared 所有工作进程之间共享的缓存。缓存大小以字节为单位指定; 一兆字节可以存储大约4000个会话。每个共享缓存都应该有一个任意的名字。具有相同名称的缓存可以在多个虚拟服务器中使用。
# 两种缓存类型都可以同时使用,例如:ssl_session_cache builtin:1000 shared:SSL:10m;
#注意:但只使用没有内置缓存的共享缓存应该更有效率。
#ssi on; #服务器嵌套,主要是实现网站的内容更新,时间和日期的动态显示,以及执行shell和CGI脚本程序等复杂的功能。
ssl_session_timeout 10m;
access_log /data/log/nginx/aaa_access.log main;
error_log /data/log/nginx/aaa_error.log;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1; #这行很关键,没有的话可能导致https访问报bad request 400
proxy_set_header Upgrade $http_upgrade; # 做websocket应用,需要实时感知客户端头信息变化的场景需要加
proxy_set_header Connection "upgrade"; # 做websocket应用,需要实时感知客户端头信息变化的场景需要加
#设定回源通过http协议
proxy_pass http://aaa-upstream;
}
}
重点说明
-
要启用nginx https支持,需要在安装openssl,并安装–with-http_ssl_module --with-http_v2_module 模块,有需要可以参考tengine安装(包含常用模块)
-
建议开启 ssl会话缓存,降低握手时间 ssl_session_cache shared:SSL:10m;
-
proxy_http_version 1.1; 需要重点关注,在实际使用中发现,不配置的话,可能会导致转发到源端的http请求变成http1.0协议,从而导致源端报bad request 400的异常(如果源端也是一个nginx负载的情况下),而且http1.0协议的性能最差,最好还是加上。
-
websocket 应用场景(比如IM实时通讯),开启以下配置文章来源:https://www.toymoban.com/news/detail-818704.html
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade"
这2行都是为了实时让服务端能感知到客户端的状态变化文章来源地址https://www.toymoban.com/news/detail-818704.html
- 创建好的aaa.conf,可以放到nginx安装目录下的conf/site/下,同时在conf/nginx.conf中的http对象配置中添加 include site/*.conf; 以便于各站点配置的分别维护
- 遇到问题先定位一下是那一层出了问题,是负载层,还是源端层,再判断问题根源
到了这里,关于tengine/nginx https请求 转发 http upstream的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!