nginx简单使用与配置
Nginx
是一个高性能的HTTP
和反向代理web
服务器、一个邮件代理服务器,一个通用的 TCP/UDP
代理服务器。支持FastCGI
、SSL
、Virtual Host
、URL Rewrite
、Gzip
等功能。并且支持很多第三方的模块扩展。
前端可以通过nginx
实现以下功能:
- 搭建静态资源服务器
- 反向代理分发后端服务(可以和
nodejs
搭配实现前后端分离)和跨域问题 - 多域名配置
- 根据
User Agent
选择站点 url
重写,使用rewrie
规则本地映射- 获取
cookie
做分流 - 资源合并
gzip
压缩- 压缩图片
sourceMap
调试
下面便介绍一下一些功能的具体实现方式:
本地部署nginx
在官网上下载nginx
官网上提供了多个版本的nginx
压缩包,选择最新稳定版(其他也可以)下载,解压到任意位置。在演示中安装在D
盘,通过命令提示符进入nginx
根目录,执行start nginx
命令启动服务(访问localhost80
如果失败这种情况是80端口被其他应用占用了,此时可以更改conf/nginx.conf
文件中的监听端口)。
将端口改成8080
保存后再次执行start nginx
。
注意最好不要直接点击根目录下的nginx.exe
启动,这样会导致当再次点击时启动多个nginx
服务,最好使用命令行运行,这样在关闭的时候执行nginx -s stop
即可
搭建静态资源服务器
在nginx.conf
文件上指定路径对应目录,比如
location /images/ {
root usr/local/static/;
autoindex on;
}
autoindex
用来开启浏览目录权限,默认为off
。
在nginx
的根目录下创建一个usr/local/static/images
目录,将图片资源放在该目录下,然后启动nginx
服务,通过localhost:8080/images/xxx
访问图片。
将root
的值替换成具体盘里的资源目录也可以实现映射。
location /images/ {
root D:/pictures/;
autoindex on;
}
反向代理分发后端服务解决跨域问题
与反向代理相关的配置说明:
proxy_pass
: 设置要代理的uri
,注意最后的/
。可以是Unix
域套接字路径或者正则表达式。proxy_redirect off
:设置后端服务器Location
响应头和Refresh
响应头的替换文本proxy_set_header X-Real-IP $remote_addr;
: 获取用户的真实IP
地址proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
后端的Web
服务器可以通过X-Forwarded-For
获取用户真实IP,多个nginx
反代的情况下,例如 CDN。proxy_set_header Host $host;
:允许重新定义或者添加发往后端服务器的请求头。client_max_body_size 10m;
:允许客户端请求的最大单文件字节数client_body_buffer_size 128k;
:缓冲区代理缓冲用户端请求的最大字节数,proxy_connect_timeout 90;
:nginx
跟后端服务器连接超时时间(代理连接超时)proxy_send_timeout 90;
:后端服务器数据回传时间(代理发送超时)proxy_read_timeout 90;
: 连接成功后,后端服务器响应时间(代理接收超时)proxy_buffer_size 4k;
:设置代理服务器(nginx
)保存用户头信息的缓冲区大小proxy_buffers 4 32k;
:proxy_buffers
缓冲区,网页平均在32k以下的设置proxy_busy_buffers_size 64k;
:高负荷下缓冲大小(proxy_buffers*2
)proxy_temp_file_write_size 64k;
: 设定缓存文件夹大小,大于这个值,将从upstream
服务器获取
不过对于简单的代理只需要配置proxy_pass
即可。
比如:
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://test.com:8080
}
}
上面的配置启动后,访问域名为localhost
,会跳转到 http://test.com:8080
路径上。
除此之外还可以根据访问路径跳转到不同服务中:
server {
listen 80;
server_name localhost;
location ~ /server1 {
proxy_pass http://test.com:8080
}
location ~ /server2 {
proxy_pass http://example.com:8081
}
}
上面配置会根据路径进行跳转,比如localhost/server1
会跳转到http://test.com:8080
,localhost/server2
会跳转到http://example.com:8081
由于浏览器存在跨域问题,当需要访问其他服务上的资源,会报错,因此可以通过反向代理来解决该问题。
多域名配置
由于在域名管理的控制面板设置域名对应ip
只能设置到ip
,不能详细设置到端口。如果一台服务器部署了多个web
应用,使用的不同端口启动的,那么就可以nginx
做映射。
比如有两个域名test.com
和example.com
都想指向同一个服务器,这时test.com
和example.com
的域名映射都默认对应到端口80
的服务。如果访问其他端口就需要在域名后面带上端口号(如test.com:8080
)
通过nginx
配置可以把其他端口都映射到80
端口。
server
{
listen 80;
server_name test.com;
location / {
proxy_pass http://localhost:8880;
}
}
server
{
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:8881;
}
}
这样,当访问test.com
的时候就会代理到http://localhost:8880
的服务,example.com
会代理到http://localhost:8881
根据User Agent选择站点
nginx
可实现根据访问源的设备类型进行判断并跳转到不同的服务或其它项目中。
upstream mobileserver {
server localhost:8080;
}
upstream computerserver {
server localhost:8081;
}
server {
listen 80;
server_name localhost;
rewrite_log on;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
access_log /data/logs/nginx/mobile.access.log main;
error_log /data/logs/nginx/mobile.error.log;
# 设置一个变量来控制代理
set $client "";
#如果是IPhone设备、iPad设备、iPod设备、苹果其它非PC设备、苹果PC设备
if ( $http_user_agent ~* "(iPhone|iPad|iPod|iOS|Android|Mobile|nokia|samsung|htc|blackberry)") {
set $client "1";
}
if ($client = '1') {
proxy_pass http://mobileserver;
break;
}
proxy_pass http://computerserver;
}
同时,通过判断user agent
,在nginx
中禁用一下爬虫,也可以防止一些恶意的访问。
#禁止Scrapy等爬虫工具的抓取
if ($http_user_agent ~* "Scrapy|Sogou web spider|Baiduspider") {
return 403;
}
#禁止指定UA及UA为空的访问
if ($http_user_agent ~ "FeedDemon|JikeSpider|Indy Library|Alexa Toolbar|AskTbFXTV|AhrefsBot|CrawlDaddy|CoolpadWebkit|Java|Feedly|UniversalFeedParser|ApacheBench|Microsoft URL Control|Swiftbot|ZmEu|oBot|jaunty|Python-urllib|lightDeckReports Bot|YYSpider|DigExt|YisouSpider|HttpClient|MJ12bot|heritrix|EasouSpider|LinkpadBot|Ezooms|^$" )
{
return 403;
}
#禁止非GET|HEAD|POST方式的抓取
if ($request_method !~ ^(GET|HEAD|POST)$) {
return 403;
}
url重写(重定向)
在 web
服务中,通常会通过重定向功能,将一个域名的请求转发到另一个域名上。
在nginx
中可在server
中配置,也可以通过location
中的rewrite
来配置。
在server中配置
server {
listen 80;
server_name oldSite.com;
# 301 指定为临时重定向,也可设置成301 永久重定向
return 302 http://newSite.com;
}
将域名 oldSite.com
的所有请求,重定向到新网址newSite.com
上。
在浏览器的network
中可以看到在请求oldSite.com
(本文是localhost:8081
)时返回的状态码是302,在响应头上还携带上重定向的地址(Location
字段),浏览器会根据新地址重新发送请求来获取资源。
上面的设置有点问题,就是当访问的域名后边带有资源路径时同样会定位到http://newSite.com
,并不会携带路径,需要进行配置。
server {
listen 80;
server_name oldSite.com;
return 302 http://newSite.com$request_uri;
}
除了重定向域名外,还可以指定重定向到 http
或 https
协议,也可通过 $scheme
参数继承用户来访时使用的协议类型。
server {
listen 80;
server_name oldSite.com;
return 302 $scheme://newSite.com;
}
也可以使用rewrite
关键字
server {
listen 80;
server_name oldSite.com;
rewrite ^ http://newSite.com redirect;
}
301与302状态的区别:
- 301 永久跳转,当用户或搜索引擎向网站服务器发出浏览请求时,服务器返回的HTTP数据流中头信息中的状态码的一种,表示本网页永久性转移到另一个地址。
- 302 临时跳转,也是状态码的一种,意义是暂时转向到另外一个网址
在location中配置
rewrite
只能在server
、location
、if
块中使用。
rewrite
语法: rewrite regex replacement [flag];
flag
有以下几个值:
last
: 完成重写指令,之后搜索相应的URI
或location
break
: 完成重写指令redirect
: 返回302临时重定向,地址栏会显示跳转后的地址permanent
: 返回301永久重定向,地址栏会显示跳转后的地址
location ~ .* {
rewrite $(.*) http://newSite.com$1 redirect;
}
将所有的访问资源重定向到newSite.com
中。
gzip压缩
启用gzip
压缩功能, 可以使网站的css
、js
、html
等静态资源在传输时进行压缩,经过gzip
压缩后资源可以变为原来的30%甚至更小,尽管这样会消耗一定的cpu
资源,但是会节约大量的出口带宽来提高访问速度。
gzip
的压缩页面需要浏览器和服务器双方都支持,实际上就是服务器端压缩,传到浏览器后解压并解析。浏览器那里不需要我们担心,因为目前的大多数浏览器都支持解析gzip
。
注意:不建议压缩图片和大文件,图片文件本身就会有压缩,所以就算开启gzip后,压缩前和压缩后大小没有多大区别,所以开启了反而会白白的浪费CPU
资源。
#开启gzip
gzip on;
#低于1kb的资源不压缩
gzip_min_length 1k;
#压缩级别1-9,越大压缩率越高,同时消耗cpu资源也越多,建议设置在5左右。
gzip_comp_level 5;
#需要压缩哪些响应类型的资源,多个空格隔开。不建议压缩图片.
gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
#配置禁用gzip条件,支持正则。此处表示ie6及以下不启用gzip(因为ie低版本不支持)
gzip_disable "MSIE [1-6]\.";
#是否添加“Vary: Accept-Encoding”响应头
gzip_vary on;