一、简介
1、Nginx服务目录结构介绍
安装完成后,在安装路径下就会有Nginx目录信息
nginx
├── client_body_temp
├── conf #nginx服务配置文件目录
│ ├── fastcgi.conf #fastcgi配置文件
│ ├── fastcgi.conf.default
│ ├── fastcgi_params #fastcgi参数配置文件
│ ├── fastcgi_params.default
│ ├── koi-utf
│ ├── koi-win
│ ├── mime.types
│ ├── mime.types.default
│ ├── nginx.conf #nginx服务的主配置文件
│ ├── nginx.conf.default #nginx服务的默认配置文件
│ ├── scgi_params
│ ├── scgi_params.default
│ ├── uwsgi_params
│ ├── uwsgi_params.default
│ └── win-utf
├── fastcgi_temp
├── html #编译安装nginx默认的首页配置文件目录
│ ├── 50x.html #错误页面配置文件
│ └── index.html #默认的首页配置文件
├── logs
│ ├── access.log #访问日志文件
│ ├── error.log
│ └── nginx.pid
├── proxy_temp
├── sbin #命令目录
│ └── nginx #Nginx服务启动命令
├── scgi_temp #临时目录
└── uwsgi_temp
2、Nginx服务主配置文件介绍
nginx 默认的主配置文件去掉注释之后就是下面这样
[root@VM_175_78_centos 20:15 conf]$ egrep -v "#" nginx.conf
worker_processes 1; #工作进程数
events { #事件
worker_connections 1024; #并发数,单位时间内最大连接数
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server { #虚拟主机标签
listen 80; #监听的端口号
server_name localhost; #服务器主机名
location / {
root html; #默认站点目录
index index.html index.htm; #默认首页文件
}
error_page 500 502 503 504 /50x.html; #错误页面文件
location = /50x.html {
root html;
}
}
}
上边的文件可以理解为一下几部分:
... #全局块
events {
#events块 ...
}
http #http块
{ ... #http全局块
server #server块
{ ... #server全局块
location [PATTERN] #location块 { ... }
location [PATTERN] { ... }
}
server { ... }
... #http全局块
}
1、全局块:配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。
2、events块:配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。
3、http块:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。
4、server块:配置虚拟主机的相关参数,一个http中可以有多个server。
5、location块:配置请求的路由,以及各种页面的处理情况。
二、配置
1.HTTP服务器(包含动静分离)
Nginx本身也是一个静态资源的服务器,当只有静态资源的时候,就可以使用Nginx来做服务器,同时现在也很流行动静分离,就可以通过Nginx来实现。
静态资源服务器:
server {
listen 80;
server_name localhost;
client_max_body_size 1024M;
location / {
root e:wwwroot;
index index.html;
}
}
动静分离的服务器:
server {
listen 80;
server_name localhost;
location / {
root e:wwwroot;
index index.html;
}
# 所有静态请求都由nginx处理,存放目录为html
location ~ .(gif|jpg|jpeg|png|bmp|swf|css|js)$ {
root e:wwwroot;
}
# 所有动态请求都转发给tomcat处理
location ~ .(jsp|do)$ {
proxy_pass http://test;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html { root e:wwwroot; }
}
这样我们就可以吧HTML以及图片和css以及js放到wwwroot目录下,而tomcat只负责处理jsp和请求。
2.正向代理
正向代理,意思是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。
resolver 114.114.114.114 8.8.8.8;
server {
resolver_timeout 5s;
listen 81;
access_log e:wwwrootproxy.access.log;
error_log e:wwwrootproxy.error.log;
location / {
proxy_pass http://$host$request_uri;
}
}
3.反向代理
反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
server {
listen 80;
server_name localhost;
client_max_body_size 1024M;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host:$server_port;
}
}
4.代理指令解读
resolver
Syntax: resolver address ... [valid=time] [ipv6=on|off];
Default: —
Context: http, server, location
- address: DNS服务器IP地址, 如果不指定端口号, 默认使用53; 从1.1.7版本开始, 该指令支持多个IP地址.- time: 设置数据包在网络中的有效时间
resolver_timeout
Syntax: resolver_timeout time;
Default: resolver_timeout 30s;
Context: http, server, location
设置DNS服务器域名解析超时时间.
proxy_pass(正向)
Syntax: proxy_pass URL;
Default: —
Context: location, if in location, limit_except
设置被代理服务器的协议和地址,在正向代理中,该指令的配置相对固定: proxy_pass http://$http_host$request_uri;
注: proxy_pass不仅用于正向代理,更主要是应用于反向代理服务,后面还有关于它的详细叙述.
proxy_pass(反向)
Syntax: proxy_pass URL;
Default: —
Context: location, if in location, limit_except
同正向代理, 该指令用来配置被代理服务器地址,可以是主机名称/IP地址+端口号等形式:
proxy_pass http://localhost:8000/uri/;
upstream
Syntax: upstream name { ... }
Default: —
Context: http
如果被代理的是一组服务器的话, 可以使用upstream指令配置一组后端服务器.Defines a group of servers. Servers can listen on different por ts. In addition, servers listening on TCP and UNIX-domain sockets can be mixed.
注意: 对于proxy_pass/server指令后的URL中是否包含URI, Nginx有不同的处理方式:
1. 如果URL中不包含URI, 则Nginx不会改变原地址的URI;
2. 如果URL中包含了URI, 则Nginx会使用新的URI 代替 原来的URI.
其他反向代理指令
指令 | 描述 |
proxy_pass_request_headers on | off; | Indicates whether the header fields of the original request are passed to the proxied server. |
proxy_pass_request_body on | off; | Indicates whether the original request body is passed to the proxied server. |
proxy_set_header field value; | Allows redefining or appending fields to the request header passed to the proxied server. |
proxy_set_body value; | Allows redefining the request body passed to the proxied server. |
proxy_hide_header field; | The proxy_hide_header directive sets additional fields that will not be passed. |
proxy_pass_header field; | Permits passing “Date”, “Server”, “X-Pad” and “X-Accel-…” header fields from a proxied server to a client. |
proxy_bind address [transparent] | off; | Makes outgoing connections to a proxied server originate from the specified local IP address. |
proxy_connect_timeout time; | Defines a timeout for establishing a connection with a proxied server. |
proxy_read_timeout time; | Defines a timeout for reading a response from the proxied server. |
proxy_send_timeout time; | Sets a timeout for transmitting a request to the proxied server. |
proxy_http_version 1.0 | 1.1; | Sets the HTTP protocol version for proxying. By default, version 1.0 is used. |
proxy_method method; | Specifies the HTTP method to use in requests forwarded to the proxied server instead of the method from the client request. |
proxy_ignore_client_abort on | off; | Determines whether the connection with a proxied server should be closed when a client closes the connection without waiting for a response. |
proxy_ignore_headers field ...; | Disables processing of certain response header fields from the proxied server. |
proxy_redirect default | off | redirect replacement; | Sets the text that should be changed in the “Location” and “Refresh” header fields of a proxied server response. |
proxy_intercept_errors on | off; | Determines whether proxied responses with codes greater than or equal to 300 should be passed to a client or be redirected to nginx for processing with the error_page directive. |
proxy_headers_hash_max_size size; | Sets the maximum size of hash tables used by the proxy_hide_header and proxy_set_header directives. |
proxy_headers_hash_bucket_size size; | Sets the bucket size for hash tables used by the proxy_hide_header and proxy_set_header directives. |
proxy_next_upstream [flag]; | Specifies in which cases a request should be passed to the next server, detail |
proxy_ssl_session_reuse on | off; | Determines whether SSL sessions can be reused when working with the proxied server. |
Proxy-Buffer
Proxy Buffer启用后,Nginx会将被代理的服务器的响应数据异步地传递给客户端:
Nginx首先尽可能地从后端服务器那里接收响应数据放在*Buffer*中,如果在接收过程中发现*Buffer*已经装满,Nginx会将部分接收到的数据临时存放到磁盘的临时文件中.当一次响应数据被万千接收或*Buffer*已经装满时,Nginx开始向客户端传输数据.此时Nginx处于`BUSY`状态.
而当Proxy Buffer关闭时, Nginx只要接收到响应数据就会同步地传递给客户端,不会读取完整响应数据.
指令 | 描述 |
proxy_buffering on | off; | Enables or disables buffering of responses from the proxied server. |
proxy_buffers number size; | Sets the number and size of the buffers used for reading a response from the proxied server, for a single connection. |
proxy_buffer_size size; | Sets the size of the buffer used for reading the first part of the response received from the proxied server. |
proxy_busy_buffers_size size; | When buffering of responses from the proxied server is enabled, limits the total size of buffers that can be busy sending a response to the client while the response is not yet fully read. |
proxy_temp_path path [level1 [level2 [level3]]]; | Defines a directory for storing temporary files with data received from proxied servers. |
proxy_temp_file_write_size size; | Limits the size of data written to a temporary file at a time, when buffering of responses from the proxied server to temporary files is enabled. |
proxy_max_temp_file_size size; | This directive sets the maximum size of the temporary file. |
注意: Proxy Buffer配置是针对每一个请求起作用,而不是全局概念,即每个请求都会按照这些指令来配置各自的Buffer, Nginx不会生成一个公共的Proxy Buffer供代理请求使用.
5.负载均衡
负载均衡的原理是利用一定的分配策略将网络负载平衡地分摊到网络集群的各个节点, 使得单个重负载任务能够分担到多个单元上并行处理,或使得大量的并发访问数据流量分摊到多个节点上分别处理,从而减少用户的等待响应时间.
nginx配置负载均衡首先要声明链接池,然后再将用链接池代理请求
http {
## ...
upstream proxy_servs { # 声明链接池
server 10.45.156.170:80 weight=5;
server 10.45.156.171:80 weight=2;
server 10.45.156.172:80; #默认weight=1
}
server {
location ~* \.(do|jsp|jspx)?$ {
proxy_pass http://proxy_servs; # 将链接池进行代理
}
## ...
}
}
a.加权轮询
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
upstream backserver {
server 192.168.0.14 weight=10;
server 192.168.0.15 weight=5;
}
b.ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
upstream backserver {
ip_hash;
server 192.168.0.14:88;
server 192.168.0.15:80;
}
c.fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
upstream backserver {
server server1;
server server2;
fair;
}
d.url_hash(第三方)
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
upstream backserver {
server squid1:3128;
server squid2:3128;
hash $request_uri;
hash_method crc32;
}
6.虚拟主机
nginix的虚拟主机的配置和apache类似,主要是根据监听的端口,访问的域名不同来配置虚拟机
a.基于端口号的
server {
listen 8080; # 监听8080端口
server_name localhost;
client_max_body_size 1024M;
location / {
root /www/html/8080; #访问的目录是/www/html/8080
index index.html;
}
}
server {
listen 8000; # 监听8080端口
server_name localhost;
client_max_body_size 1024M;
location / {
root /www/html/8000; #访问的目录是/www/html/8000
index index.html;
}
}
b.基于域名
server {
listen 80;
server_name www.test1.com; #服务器主机名
location / {
root htm/test1; #默认站点目录
index index.html index.htm;
}
}
server {
listen 80;
server_name www.test2.com; #服务器主机名
location / {
root html/test2; #默认站点目录
index index.html index.htm;
}
}
7.防盗链
如果服务器的图片被别的网站盗链,将影响服务器的带宽以及访问速度,这时我们就需要设置图片文件或视频文件的防盗链功能;防盗链的思想就是先设置白名单,然后过滤不符合白名单的就返回403,或者其他的图片。
# 防盗链
server {
listen 80;
server_name www.fangdaolian.com;
location ~* \.(gif|jpg|png|jpeg)$ {
root html/fangdaolian;
expires 30d;
# 设置白名单,每个白名单用空格隔开
valid_referers www.fangdaolian.com *.baidu.com *.google.com;
# 过滤
if ($invalid_referer) {
# rewrite ^/ http://ww4.sinaimg.cn/bmiddle/051bbed1gw1egjc4xl7srj20cm08aaa6.jpg;
# 返回403
return 403;
}
}
}
8.从定向
server {
listen 80;
location / {
# 通过代理的方式
#proxy_pass http://www.baidu.com;
# 另一种方式
if ($host == "www.old.com"){
rewrite ^/(.*)$ http://www.new.com/$1 permanent;
}
}
}
9.屏蔽USER_AGENT和反爬虫
#禁止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;
}
# 针对特殊的user_agent的访问
if ($http_user_agent ~ "Mozilla/4.0\ \(compatible;\ MSIE\ 6.0;\ Windows\ NT\ 5.1;\ SV1;\ .NET\ CLR\ 1.1.4322;\ .NET\ CLR\ 2.0.50727\)") {
return 404;
}
10.nginx内置变量
$args 请求中的参数;
$binary_remote_addr 远程地址的二进制表示
$body_bytes_sent 已发送的消息体字节数
$content_length HTTP请求信息里的"Content-Length";
$content_type 请求信息里的"Content-Type";
$document_root 针对当前请求的根路径设置值;
$document_uri 与$uri相同;
$host 请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名;
$hostname $http_cookie cookie 信息
$http_post
$http_referer 引用地址
$http_user_agent 客户端代理信息
$http_via 最后一个访问服务器的Ip地址。
$http_x_forwarded_for 相当于网络访问路径。
$is_args
$limit_rate 对连接速率的限制;
$nginx_version
$pid
$query_string 与$args相同;
$realpath_root
$remote_addr 客户端地址;
$remote_port 客户端端口号;
$remote_user 客户端用户名,认证用;
$request 用户请求$request_body
$request_body_file 发往后端的本地文件名称
$request_completion
$request_filename 当前请求的文件路径名
$request_method 请求的方法,比如"GET"、"POST"等;
$request_uri 请求的URI,带参数;
$scheme 所用的协议,比如http或者是https,比如rewrite^(.+)$$scheme://example.com$1redirect;
$sent_http_cache_control 1
$sent_http_connection
$sent_http_content_length
$sent_http_content_type
$sent_http_keep_alive
$sent_http_last_modified
$sent_http_location
$sent_http_transfer_encoding
$server_addr 服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费);
$server_name 请求到达的服务器名;
$server_port 请求到达的服务器端口号;
$server_protocol 请求的协议版本,"HTTP/1.0"或"HTTP/1.1";
$uri 请求的URI,可能和最初的值有不同,比如经过重定向之类的