少年: Nginx了解下_nginx

少年: Nginx了解下_服务器_02

Nginx简介

传统的 Web 服务器,每个客户端连接作为一个单独的进程或线程处理,需在切换任务时将 CPU 切换到新的任务并创建一个新的运行时上下文,消耗额外的内存和 CPU 时间,当并发请求增加时,服务器响应变慢,从而对性能产生负面影响。

少年: Nginx了解下_html_03

因此导致我们迫切需要几个高性能的Web服务器。目前常见的应用服务器:Apache/Microsoft IIS/Tomcat/Lighttpd/Nginx这几种,目前主流就是Apache跟Nginx两个Web服务器了。

Apache


Apache仍然是时长占用量最高的web服务器,据最新数据统计,市场占有率目前是50%左右。主要优势在于一个是比较早出现的一个Http静态资源服务器,同时又是开源的。所以在技术上的支持以及市面上的各种解决方案都比较成熟。Apache支持的模块非常丰富。


Nginx


Nginx是俄罗斯人编写的一款高性能的HTTP和反向代理服务器,Nginx 是开源、高性能、高可靠的 Web 和反向代理服务器,而且支持热部署,几乎可以做到 7 * 24 小时不间断运行,即使运行几个月也不需要重新启动,还能在不间断服务的情况下对软件版本进行热更新。性能是 Nginx 最重要的考量,其占用内存少、并发能力强、能支持高达 5w 个并发连接数,最重要的是,Nginx 是免费的并可以商业化,配置使用也比较简单。


选择Nginx的理由也很简单:第一,它可以支持5W高并发连接,第二,内存消耗少,第三,成本低,如果采用F5、NetScaler等硬件负载均衡设备的话,需要大几十万。而Nginx是开源的,可以免费使用并且能用于商业用途。

Nginx 使用场景:



  1. 反向代理
  2. 缓存跟负载均衡
  3. 静态资源服务,通过本地文件系统提供服务;
  4. Keepalived + Nginx 实现高可用


正向代理和反向代理

正向代理

意思是一个位于客户端和原始服务器(origin server)之间的服务器, 为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。比较通俗的例子。

反向代理

反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。对于用户来说只知道这个网址的存在是不知道若干server的!

少年: Nginx了解下_html_04

负载均衡

一般情况下,客户端发送多个请求到服务器,服务器处理请求,其中一部分可能要操作一些资源比如数据库、静态资源等,服务器处理完毕后,再将结果返回给客户端。这种模式对于早期的系统来说,功能要求不复杂,且并发请求相对较少的情况下还能胜任,成本也低。随着信息数量不断增长,访问量和数据量飞速增长,以及系统业务复杂度持续增加,这种做法已无法满足要求,并发量特别大时,服务器容易崩,比如我们部署的Tomcat服务是有服务瓶颈的。

很明显这是由于服务器性能的瓶颈造成的问题,除了堆机器之外,最重要的做法就是负载均衡(Load Balance)。请求爆发式增长的情况下,单个机器性能再强劲也无法满足要求了,这个时候集群的概念产生了,单个服务器解决不了的问题,可以使用多个服务器,然后将请求分发到各个服务器上,将负载分发到不同的服务器,这就是负载均衡,核心是「分摊压力」。Nginx 实现负载均衡,一般来说指的是将请求转发给服务器集群。

少年: Nginx了解下_nginx_05

动静分离

为了加快网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度,降低原来单个服务器的压力。

一般来说,都需要将动态资源和静态资源分开,由于 Nginx 的高并发和静态资源缓存等特性,经常将静态资源部署在 Nginx 上。如果请求的是静态资源,直接到静态资源目录获取资源,如果是动态资源的请求,则利用反向代理的原理,把请求转发给对应后台应用去处理,从而实现动静分离。

使用前后端分离后,可以很大程度提升静态资源的访问速度,即使动态服务不可用,静态资源的访问也不会受到影响。

少年: Nginx了解下_服务器_06

Nginx安装

一般情况下有两种安装方式

1. 自动化安装
# 切换至root用户
sudo su root
apt-get install nginx

少年: Nginx了解下_html_07

查看nginx是否安装成功

少年: Nginx了解下_html_08

启动nginx

少年: Nginx了解下_nginx_09

启动后,在网页重输入ip地址(重要:可能需要关闭防火墙或者开发指定端口才可以正常访问哦),即可看到nginx的欢迎页面。至此nginx安装成功

少年: Nginx了解下_html_10

nginx文件安装完成之后的文件位置



  • /usr/sbin/nginx:主程序
  • /etc/nginx:存放配置文件
  • /usr/share/nginx:存放静态文件
  • /var/log/nginx:存放日志


卸载nginx

# 彻底卸载nginx
apt-get --purge autoremove nginx
#查看nginx的版本号
nginx -v

少年: Nginx了解下_服务器_11

2. 源码安装

安装依赖包

apt-get install gcc
apt-get install libpcre3 libpcre3-dev
apt-get install zlib1g zlib1g-dev
# Ubuntu14.04的仓库中没有发现openssl-dev,由下面openssl和libssl-dev替代
#apt-get install openssl openssl-dev
sudo apt-get install openssl
sudo apt-get install libssl-dev

安装nginx

cd /usr/local
mkdir nginx
cd nginx
wget http://nginx.org/download/nginx-1.13.7.tar.gz
tar -xvf nginx-1.13.7.tar.gz

少年: Nginx了解下_html_12

编译nginx

# 进入nginx目录
cd /usr/local/nginx/nginx-1.13.7
# 执行命令
./configure
# 执行make命令
make
# 执行make install命令
make install

此时在/usr/local/nginx目录下主要文件如下:



  • Conf 配置文件
  • Html 静态网页文件
  • Logs 日志文件
  • Sbin 二进制程序


启动nginx

#进入nginx启动目录
cd /usr/local/nginx/sbin
# 启动nginx
./nginx
3. 防火墙

安装之后开启 Nginx,如果系统开启了防火墙,那么需要设置一下在防火墙中加入需要开放的端口,下面列举几个常用的防火墙操作(没开启的话不用管这个):

systemctl start firewalld  # 开启防火墙
systemctl stop firewalld # 关闭防火墙
systemctl status firewalld # 查看防火墙开启状态,显示running则是正在运行
firewall-cmd --reload # 重启防火墙,永久打开端口需要reload一下
# 添加开启端口,--permanent表示永久打开,不加是临时打开重启之后失效
firewall-cmd --permanent --zone=public --add-port=8888/tcp
# 查看防火墙,添加的端口也可以看到
firewall-cmd --list-all

然后设置 Nginx 的开机启动:

systemctl enable nginx

启动 Nginx (其他命令后面有详细讲解):

systemctl start nginx

然后访问你的 IP,这时候就可以看到 Nginx 的欢迎页面了~ Welcome to nginx!

Nginx 常用命令

Nginx 的命令在控制台中输入 nginx -h 就可以看到完整的命令,这里列举几个常用的命令:


nginx -s reload # 向主进程发送信号,重新加载配置文件,热重启
nginx -s reopen # 重启 Nginx
nginx -s stop # 快速关闭
nginx -s quit # 等待工作进程处理完成后关闭
nginx -T # 查看当前 Nginx 最终的配置
nginx -t -c <配置路径> # 检查配置是否有问题,如果已经在配置目录,则不需要-c


systemctl 是 Linux 系统应用管理工具 systemd 的主命令,用于管理系统,我们也可以用它来对 Nginx 进行管理,相关命令如下:


systemctl start nginx # 启动 Nginx
systemctl stop nginx # 停止 Nginx
systemctl restart nginx # 重启 Nginx
systemctl reload nginx # 重新加载 Nginx,用于修改配置后
systemctl enable nginx # 设置开机启动 Nginx
systemctl disable nginx # 关闭开机启动 Nginx
systemctl status nginx # 查看 Nginx 运行状态


Nginx 配置语法

​nginx.conf​​结构图可以这样概括:

少年: Nginx了解下_服务器_13

main        # 全局配置,对全局生效
├── events # 配置影响 Nginx 服务器或与用户的网络连接
├── http # 配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置
│ ├── upstream # 配置后端服务器具体地址,负载均衡配置不可或缺的部分
│ ├── server # 配置虚拟主机的相关参数,一个 http 块中可以有多个 server 块
│ ├── server
│ │ ├── location # server 块可以包含多个 location 块,location 指令用于匹配 uri
│ │ ├── location
│ │ └── ...
│ └── ...
└── ...

一个 Nginx 配置文件的结构就像上图 nginx.conf 显示的那样,配置文件的语法规则:



  1. 配置文件由指令与指令块构成;
  2. 每条指令以 ; 分号结尾,指令与参数间以空格符号分隔;
  3. 指令块以 {} 大括号将多条指令组织在一起;
  4. include 语句允许组合多个配置文件以提升可维护性;
  5. 使用 # 符号添加注释,提高可读性;
  6. 使用 $ 符号使用变量;
  7. 部分指令的参数支持正则表达式;


典型配置

Nginx 的典型配置:

user  nginx;                        # 运行用户,默认即是nginx,可以不进行设置
worker_processes 1; # Nginx 进程数,一般设置为和 CPU 核数一样
error_log /var/log/nginx/error.log warn; # Nginx 的错误日志存放目录
pid /var/run/nginx.pid; # Nginx 服务启动时的 pid 存放位置

events {
use epoll; # 使用epoll的I/O模型(如果你不知道Nginx该使用哪种轮询方法,会自动选择一个最适合你操作系统的)
worker_connections 1024; # 每个进程允许最大并发数
}

http { # 配置使用最频繁的部分,代理、缓存、日志定义等绝大多数功能和第三方模块的配置都在这里设置
# 设置日志模式
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 /var/log/nginx/access.log main; # Nginx访问日志存放位置

sendfile on; # 开启高效传输模式
tcp_nopush on; # 减少网络报文段的数量
tcp_nodelay on;
keepalive_timeout 65; # 保持连接的时间,也叫超时时间,单位秒
types_hash_max_size 2048;

include /etc/nginx/mime.types; # 文件扩展名与类型映射表
default_type application/octet-stream; # 默认文件类型

include /etc/nginx/conf.d/*.conf; # 加载子配置项

server {
listen 80; # 配置监听的端口
server_name localhost; # 配置的域名

location / {
root /usr/share/nginx/html; # 网站根目录
index index.html index.htm; # 默认首页文件
deny 172.168.22.11; # 禁止访问的ip地址,可以为all
allow 172.168.33.44; # 允许访问的ip地址,可以为all
}

error_page 500 502 503 504 /50x.html; # 默认50x对应的访问页面
error_page 400 404 error.html; # 同上
}
}

server 块可以包含多个 location 块,location 指令用于匹配 uri,语法:

location [ = | ~ | ~* | ^~] uri {
...
}

指令后面:


= 精确匹配路径,用于不含正则表达式的 uri 前,如果匹配成功,不再进行后续的查找;
^~ 用于不含正则表达式的 uri; 前,表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找;
~ 表示用该符号后面的正则去匹配路径,区分大小写;
~* 表示用该符号后面的正则去匹配路径,不区分大小写。跟 ~ 优先级都比较低,如有多个location的正则能匹配的话,则使用正则表达式最长的那个;


如果 uri 包含正则表达式,则必须要有 ~ 或 ~* 标志

Location匹配规则:

少年: Nginx了解下_html_14

Rewrite

​rewrite​​是实现URL重定向的重要指令,他根据regex(正则表达式)来匹配内容跳转到replacement,结尾是flag标记

少年: Nginx了解下_nginx_15

少年: Nginx了解下_nginx_16

Nginx 核心流程

少年: Nginx了解下_服务器_17

url = 域名+端口+path+param

匹配过程:


1、域名(ip)+端口 ----》定位虚拟机
2、path与location部分匹配, path = 匹配path + 剩余path
3、root:在目录里找path1+path2路径
alias:在目录里找path2路径
若url以/结尾,认为是目录,执行index;否则认为path路径到达文件
4、 proxy_pass=http://172.17.0.4:8081/
proxy_pass= ip:port/
ip:port/时,转发ip+端口+path2路径
ip:port 时,转发ip+端口+path1+path2路径


nginx执行过程验证


server {
listen 80;
server_name process.sowhat.com;
#后台服务原始路径:172.17.0.4:8081/nginx/sowhat/getInfo
#无/,访问路径:http://process.sowhat.com/nginx/sowhat/getInfo
location /nginx/sowhat { #匹配路径/nginx/sowhat,剩余路径/getInfo
proxy_pass http://172.17.0.4:8081;#此处未关闭,​​传递整个路径​​/nginx/sowhat/getInfo到目标ip:port
// proxy_pass http://172.17.0.4:8081/nginx/sowhat;
}
#有/,访问路径:http://process.sowhat.com/dynamic/nginx/sowhat/getInfo
location /dynamic {#匹配路径/dynamic,剩余路径/nginx/sowhat/getInfo
proxy_pass http://172.17.0.4:8081/;#此处关闭,​​只传递​​/nginx/sowhat/getInfo到目标ip:port
}
#访问路径:http://process.sowhat.com/static/a.html —b.html/c.html
location /static { # 匹配路径/static,剩余路径/a.html
# root html/;# ​​root声明​​,在html文件夹,​​查找/static/a.html​​文件
}
#访问路径:http://process.sowhat.com/target/a.html —b.html/c.html
location /target {#匹配路径/target,剩余路径/a.html
alias html/static/;# ​​alias声明​​,在html/static/文件夹,​​查找a.html​​文件
}
}


点缀

1、index执行时机


Root/alias时,若页面请求以/结尾,则认为path只到目录
此时启动index,找目录内的index文件


2、if语句,内置变量:简单的if判断,没有else

3、​​跨域​​:A域名页面,访问B域名,在B服务里加配置:W3C要求,不可跨域,又提出了如何跨域。


​CORS​​是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服AJAX只能同源使用的限制。
简单请求:
浏览器在跨源AJAX请求的头信息之中,自动在添加一个Origin字段(本次请求来自哪个源 )。
服务器根据这个值,在许可范围内,则在头信息包含 Access-Control-Allow-Origin 。
复杂请求:
会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求OPTIONS


4、防盗链:自己域名,被其它域名页面访问。防君子:一些文件只可在固定域名访问,不可保存本地跟新网页打开这样的操作。

5、缓存:​​缓存浏览器​​。nginx告诉浏览可以缓存:减少nginx压力

6、压缩: gzip :服务器跟浏览器协商采用何种压缩


对输出到客户端的内容进行压缩,以减小传输文件体积,减少对网络带宽的占用。服务器端要压缩,客户端必须解压缩,这都将占用cpu时间。不过,由于传输内容减小了,传输过程中,各网卡、路由器、交换机对数据包的处理时间也会缩短。​​gzip​​压缩是就在这里赢得了时间。
必须满足以下几个条件:
1、客户端发送的HTTP报头必须含有 ​​Accept-Encoding​​ 字段,且其值包含 ​​gzip​​ 这个压缩类型。一般浏览器都会发 ​​Accept-Encoding:gzip, deflate, sdch​​ 这样的报头。
2、服务器启用了gzip压缩,那么响应头会包含 Content-Encoding:gzip, 客户端根据这个来判断服务器返回的内容是否真正为gzip压缩过的内容。
gzip压缩对文本文件压缩效果非常好(40%~80%),而对图片文件效果甚微。
实际应用中可以考虑对js、html、css格式的文件开启gzip压缩。


7、https配置。

nginx 秘钥生成过程


1、创建服务器私钥,命令会让你输入一个口令:
openssl genrsa -des3 -out server.key 1024
2、创建签名请求的证书(CSR):
openssl req -new -key server.key -out server.csr
3、在加载SSL支持的Nginx并使用上述私钥时除去必须的口令:
openssl rsa -in server.key -out server_nopass.key
4、最后标记证书使用上述私钥和CSR:
openssl x509 -req -days 365 -in server.csr -signkey server_nopass.key -out server.crt


nginx.Conf文件中:


ssl_certificate /etc/nginx/conf.d/server.crt;
ssl_certificate_key /etc/nginx/conf.d/server_nopass.key;
少年: Nginx了解下_服务器_18


8、keepalived来配置nginx主备

Keepalived功能:


管理LVS负载均衡软件
实现LVS集群节点的健康检查
作为系统网络服务的高可用性(failover)


少年: Nginx了解下_服务器_19

工作中nginx常用模式:

少年: Nginx了解下_nginx_20

Nginx工作模式

​Nginx​​因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。

nginx横空出世之前,Apache服务器一直占据web服务器的垄断地位,所以就用对比的方式来解释nginx那么强! ​​IO多路复用​

两者性能差别的主要原因在于网络IO模型选择不同,apache使用了​​select​​,而nginx使用了​​epoll​​模型!

举个例子:一个万人村里面选村长,有两种方式:


①,让每个人在纸条上写下自己的名字,然后前村长去收集纸条(一个线程去遍历),然后得到村长推荐候选人的名单(需要处理的连接),这就相当于select模型,去轮询每一个连接,并对需要进行处理的连接进行处理!
②,每个人都可以毛遂自荐(每个连接都有可能活跃),想要竞选的在旁边站成一排(事件触发,放入队列中),然后就在这几个人中选择(几个待处理的任务),相当于只要对少量的事件进行处理!


一个是从上万人中循环得到几个进行处理,一个是几个自己站出来直接处理,这种效率相差不是一般的大吧?

​nginx是基于epoll模型开发​​的,而epoll是基于JAVA NIO的同步非阻塞开发,在高并发情况下能支持更多的连接!

nginx是​​事件驱动​​的,一个主进程跟多个工作进程组成的工作模式,主线程负责循环分配事件,多个工作线程负责事件的处理!

少年: Nginx了解下_nginx_21

参考

一文nginx

ubuntu下安装nginx

nginx下Location跟Rewrite总结

所有本文资料汇总