百度百科
看百度百科的解释,第一句话就是错的。“Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器”,从语法来看,去掉形容词就是:Nginx是服务器,nginx怎么会是服务器呢,nginx只是一个工具,一个中间件,可以用来做反向代理,做什么反向代理?做web服务器的反向代理。这句话是有语病的,典型的句式杂糅(两个句子塞在一句话中表达,导致表述不清),会误导初学者。后面的解释也不准确(“Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器”),起码不够通俗,绕来绕去
基于此做一点补充:
Nginx是一个中间件。由一个俄罗斯人开发(2004年),开发背景是解决C10k问题(10000并发量),随着nginx的不断迭代,现在主要用来做反向代理和负载均衡,由于nginx配置简单、占用内存少、并发能力强等优点广受欢迎,据统计,世界范围内的web网站,平均2个就有一个使用了nginx,充分证明了nginx的优秀和重要。
理解反向代理不得不说正向代理,正向代理:通过代理服务器屏蔽用户信息的过程。其特点是:目标服务器不知道请求用户的信息,比如请求IP。
总结发现,通过简单分类,这里面涉及到三种类型的机器,分别是:用户机器、代理机器、目标服务机器
我们上网的一般过程是,客户端发出请求,服务器接收、处理请求并做出响应,客户端接收响应展示给用户。仿佛不需要代理了,这个理解是对的,那么什么场景会用到正向代理?
比如国内用户需要访问google,但是由于政策原因没有开通防火墙,国内用户访问不了google,这时还需要访问google的资源,怎样实现?可以通过在用户和google之间增加一台服务器,这台服务器开通google的防火墙,用它来接收用户的请求,并将请求转发给google,goolge接收请求响应给代理服务器,代理服务器再响应给用户。
这个过程中google不知道真实的用户信息,只知道代理服务器的请求信息(比如ip等),通过代理服务器屏蔽用户信息的过程就是正向代理
理解了正向代理后,就好理解反向代理了。反向代理:通过代理屏蔽目标服务的过程。其特点是:用户不知道真实的目标服务。
反向代理的场景:
一个tomcat处理500个并发,这时并发量有5000,需要搭建10个tomcat集群。这10个集群就代表10个服务,用户通过访问代理服务器,代理服务器再把请求转发给10个服务中的某一个。
对用户来说,请求的是代理服务器,用户不知道代理服务器会将请求下发给集群中谁。通过代理服务器屏蔽服务的过程就是反向代理。
通过nginx反向代理了10个服务,高并发的用户请求按什么策略下发给这10服务。使每一台机器都能饱和工作的过程就是负载均衡。
nginx 负载均衡默认的策略是:轮询+权重
nginx除了默认的轮询策略,还有一种hash策略,使用hash的优点是可以保存用户请求session(实际应用中使用较少)
配置负载均衡一定会用到反向代理,用到反向代理不一定使用负载均衡
直接下载nginx tar包,地址:https://nginx.org/en/download.html
tar -xvzf nginx-1.16.1.tar.gz
#重命名
mv nginx-1.16.1 nginx
cd nginx
#安装
make install
#查看安装目录
whereis nginx
#配置ssl模块,用于Https服务(可选),进入nginx下载后的解压目录(不是安装目录)
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
启动、停止nginx
cd /usr/local/nginx/sbin/ #进入nginx解压目录
./nginx #启动
./nginx -s stop #停止(先查出nginx进程id再使用kill命令强制杀掉进程)
./nginx -s quit #停止(待nginx进程处理任务完毕进行停止)
./nginx -s reload #重新加载配置文件
./nginx -V #查看版本
./nginx -t #检查配置文件
Nginx配置,在/usr/local/nginx/conf(nginx安装目录)下的nginx.conf
#Nginx用户及组:用户 组。window下不指定
#user nobody;
#工作进程:数目。根据硬件调整,通常等于CPU数量或者2倍于CPU。
worker_processes 1;
#错误日志:存放路径。
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid(进程标识符):存放路径。
#pid logs/nginx.pid;
events {
#每个工作进程的最大连接数量。根据硬件调整,和前面工作进程配合起来用,尽量大,但
是别把cpu跑到100%就行。每个进程允许的最多连接数,理论上每台nginx服务器的最大连 接数为。worker_processes*worker_connections
worker_connections 1024;
#keepalive超时时间。
keepalive_timeout 60;
}
#设定http服务器
http {
#文件扩展名与文件类型映射表
include mime.types;
#默认文件类型
default_type application/octet-stream;
#默认编码
#charset utf-8;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
#开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on
sendfile on;
#开启目录列表访问,合适下载服务器,默认关闭。
autoindex on;
#该指令必须在sendfile打开的状态下才会生效,主要是用来提升网络包的传输'效率'
#tcp_nopush on;
#长连接超时时间,单位是秒
keepalive_timeout 65;
#开启gzip压缩输出
#gzip on;
#虚拟主机的配置,可配置多个
server {
listen 80;
#域名可以有多个,用空格隔开
server_name localhost;
location / {
#可配置在 server与location中,基于ROOT路径+URL中路径去寻找指定文件。
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
# server {
# listen 8080;
# 域名可以有多个,用空格隔开
# server_name localhost;
# location /tomcat {
# root html;
# index index.html index.htm;
# }
# }
}
上述配置中的events、http、server、location、upstream等属于配置项块。而
worker_processes 、worker_connections、include、listen 属于配置项块中的属性。其中server块嵌套于http块,其可以直接继承访问Http块当中的参数。
配置块 | 名称开头用大口号包裹其对应属性 |
---|---|
属性 | 基于空格切分属性名与属性值,属性值可能有多个项,都以空格进行切分,如:access_log logs/host.access.log main |
参数 | 其配置在块名称与大括号间,其值如果有多个也是通过空格进行拆 |
注:如果配置项值中包括语法符号,比如空格符,那么需要使用单引号或双引号括住配置项值,否则Nginx会报语法错误。eg:
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
创建一个站点目录:mkdir -p /home/zyz/soft/web/app1
放入一个静态文件:index.html
配置nginx.conf
#添加一个server 或原有修改
server {
listen 8081;
server_name localhost;
location /project1 {
#alias 指定站点别名,基于alias 路径+ URL移除location前缀后的路径来寻找文件。
alias /home/zyz/soft/web/app1;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
访问规则如下:
URL:http://192.168.2.50:8081/project1/index.html
最终寻址:/home/zyz/soft/web/app1/index.html
or
server {
listen 8081;
server_name localhost;
location /project1 {
#可配置在 server与location中,基于ROOT路径+URL中路径去寻找指定文件。
root /home/zyz/soft/web/app1;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
防问规则如下:
URL:http://192.168.2.50:8081/project1/index.html
最终寻址:/home/zyz/soft/web/app1/project1/index.html
location /download {
limit_rate 1m; #限制每S下载速度
limit_conn addr 1;#连接数量
limit_rate_after 30m; #对30m上的数据限制
}
在配置文件目录下如:/usr/local/nginx/conf下创建黑名单文件ip.black
touch /usr/local/nginx/conf/ip.black
#在其中输入黑名单ip
eg:
allow 192.168.2.9;
deny 192.168.2.51;
#开放指定IP 段
allow 192.168.0.0/24;
在http模块中引入配置文件: include ip.black;
通过proxy_pass 可以把请求代理至后端服务,但是为了实现更高的负载及性能, 我们的后端服务通常是多个, 这个是时候可以通过upstream 模块实现负载均衡。
upstream backend {
server 192.168.2.9:9990;
server 192.168.2.9:9991;
}
server {
listen 8083;
#超过下述时间无响应自动转发到其他服务器
proxy_connect_timeout 1;
#后端服务器数据回传时间_就是在规定时间之内后端服务器必须传完所有的数据
proxy_send_timeout 1;
#连接成功后_等候后端服务器响应时间_其实已经进入后端的排队之中等候处理(也可
以说是后端服务器处理请求的时间)
proxy_read_timeout 1;
server_name localhost;
location / {
proxy_pass http://backend;
}
}
upstream 相关参数:
server 反向服务地址加端口
weight 权重
max_fails 失败多少次 认为主机已挂掉则,踢出
fail_timeout 踢出后重新探测时间,在单位周期为fail_timeout设置的时间,中达到max_fails次数,这个周期次数内,如果后端同一个节点不可用,那么接将把节点标记为不可用,并等待下一个周期(同样时常为fail_timeout)再一次去请求,判断是否连接是否成功。如果成功,将恢复之前的轮询方式,如果不可用将在下一个周期(fail_timeout)再试一次。
backup 备用服务,Nginx默认判断失败节点状态以connect refuse和timeout状态为准,不以HTTP错误状态进行判断失败,所有非备机都宕机或者不可用的情况下,就只能使用带backup标准的备机。
max_conns 允许最大连接数
ll+weight: 轮询加权重 (默认)
ip_hash : 基于Hash 计算 ,用于保持session 一至性,不与backup一起使用
url_hash: 静态资源缓存,节约存储,加快速度(第三方)
least_conn :最少链接(第三方)
least_time :最小的响应时间,计算节点平均响应时间,然后取响应最快的那个,分配更高权重(第三方)
eg:
upstream backend {
server 192.168.2.9:9990 weight=1 max_fails=1 fail_timeout=5;
server 192.168.2.9:9991 weight=2;
server 192.168.2.9:9992 weight=1 backup;
}