Nginx
概念
nginx(engine x)是一个HTTP和反向代理服务器,一个邮件代理服务器,一个通用TCP/UDP代理服务器。nginx一开始由Igor Sysoev所编写,在世界各处都有广泛应用。
实践
安装
第一步,增加Centos7 EPEL仓库:
yum install epel-release
第二步,安装Nginx:
yum install nginx
第三步,启动Nginx:
systemctl start nginx
第四步,测试nginx正常启动:
wget localhost:80
配置ssl
上面步骤,我们仅能访问http://host:80
,但是现在大部分浏览器都会将其标记为不安全。
我们需要先生成自己的私钥以及对应的证书crt文件。之后编辑/etc/nginx/nginx.conf
文件,增加下面内容:
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name _;
root /usr/share/nginx/html;
ssl_certificate "/root/.ssh/server.crt";
ssl_certificate_key "/root/.ssh/server.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
现在你就可以访问https://host:443
了。(注意证书和私钥要设置为只读)
路径匹配
nginx路径匹配的一般语法为
location [ = | ~ | ~* | ^~ ] uri {...}
location表示这是一段映射关系,后面可以跟可选的修饰符,之后是uri,括号内撰写对应的操作。
nginx支持四种修饰符
=
表示只有请求地址完全匹配uri时才会被接受~
表示uri为区分大小写的正则表达式,仅匹配正则表达式的地址才会被接受~*
表示uri为不区分大小写的正则表达式,仅匹配正则表达式的地址才会被接受^~
表示只有uri为请求地址的前缀时,才会接受请求
由于可能一个请求会同时匹配多个location,而nginx会选取优先级最高的location来处理请求,下面列出的优先级从高到低:
- 匹配修饰符
=
修饰的location - 从上到下匹配正则表达式(用
~
和~*
修饰的location)。 - 匹配uri长度最长的用
^~
修饰的location。
nginx还有一种路径的写法。
location / {
try_files $uri $uri/ @custom
}
location @custom {...}
我们为下面的location赋予了一个别名custom,并允许在nginx.conf内部引用这个别名用作转发。
静态资源
nginx可以用于处理静态资源的下载。
location /a/ {
root /data/;
}
所有形如/a/file
的请求都会直接下载/data/a/file
。
还有一种写法是使用alias。
location /b/ {
alias /data/;
}
此时所有形如/b/file
的请求会直接下载/data/file
。
root和alias的区别在于root是本地路径拼接完整的请求路径,而alias是本地路径拼接多余的请求路径。
反向代理
反向代理主要用于负载均衡,nginx可以从多个站点无缝获得数据。
代理配置
在nginx配置文件中增加如下内容:
location /some/path/ {
proxy_pass http://www.example.com/lnik/;
}
这样假如你访问host/some/path/index.html时,实际上nginx会把你的请求转发到http://www.example.com/lnik/index.html。这里的请求是可以跨协议的,比如nginx接受的是https协议,但是转发的时候却是以http协议进行转发。还有需要注意的是尾部的斜杆是有必要的。
nginx支持以其他协议进行转发:
协议 | 描述 |
---|---|
proxy_pass | 转发给http或https |
fastcgi_pass | 转发给FastCGI服务器 |
uwsgi_pass | 转发给uwsgi服务器 |
scgi_pass | 转发给SCGI服务器 |
memcached_pass | 转发给memcached服务器 |
携带Headers
默认情况下,Nginx会设置host和connection两个头部,并且会剔除值为空的头部。Host头部会被赋值为$proxy_host
,Connection会被赋值为close
。
你可以利用proxy_set_header
来要求nginx在转发的时候携带指定头部,其用法类似于之前提到的proxy_pass。
location /some/path/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://localhost:8000;
}
如果你想删除头部,则只要将其设置为空字符串即可,比如:
proxy_set_header Host ""
设置Buffers
默认情况下,nginx会保存被代理服务器的响应内容在缓冲区中,直到从被代理服务器上获得了完整的响应内容,才会发送给客户端。缓冲区有助于在客户端较慢的时候优化性能表现,因为发送给客户端和从被代理服务器获取响应是同步的。
并且保存在缓冲区中的内容将会在客户端需要下载时重复使用。
用于开启和禁用缓冲的指令为proxy_buffering
。默认它的值是on
。
而proxy_buffers
指令用于控制为每一个请求分配的缓冲区的大小和数量。响应的第一部分被保存在一个分离的缓冲区中,可以通过proxy_buffer_size
指令设置其大小。这部分往往包含一些相对较小的响应头,因此可以设置得比其他响应内容得缓冲区小些。
location /some/path/ {
proxy_buffers 16 4k;
proxy_buffer_size 2k;
proxy_pass http://localhost:8000;
}
一旦关闭了缓冲功能,来自被代理服务器得响应内容会同步地发送给客户端。这对于对交互式客户端是有必要得,提早返回数据有助于客户端可以尽快处理响应。
location /some/path/ {
proxy_buffering off;
proxy_pass http://localhost:8000;
}
负载均衡
多应用实例之间的负载均衡是一种提高资源使用率的常用技术,可以最大化吞吐,减少延迟,并且确保能容错。
Nginx可以作为一个非常有效的负载均衡服务,将流量分布到数个应用服务器,以提高性能,可伸缩性,以及服务的可靠性。
Nginx支持三种负载的均衡策略:
- round-robin:以取余数的方式分配服务,比如你有3台服务器,那么第i个请求分配给服务i%3。(默认)
- least-connected:将请求分配给活跃连接数最少的服务。
- ip-hash:对ip进行哈希,之后取余,这样就可以确保来自同一个ip的请求会分配给同一台服务器来处理。
upstream myapp1 {
least
}
上面的配置将要求nginx将所有http请求按最少连接数策略转发给三台服务器。
在反向代理的情况下HTTP,HTTPS,FastCGI,uwsgi,SCGI,memcached,gRPC都支持负载均衡。
如果你的三台服务器的性能并不平衡,比如一台特别强劲,而另外两台相对羸弱。我们可以通过为服务配置weight
属性来表示其权值。weight=k
表示该服务相当于k台服务,默认weight=1
。
upstream myapp1 {
server srv1.example.com weight=3;
server srv2.example.com;
server srv3.example.com;
}
上面的内容等价于:
upstream myapp1 {
server srv1.example.com;
server srv1.example.com
server srv1.example.com
server srv2.example.com;
server srv3.example.com;
}