Nginx
Nginx
1.1Nginx 是什么,做什么事情(5 大应用场景)
Nginx (engine x) 是一个高性能的 HTTP 和反向代理 web 服务器,同时也提供了 IMAP/POP3/SMTP 服务。Nginx 是由伊戈尔·赛索耶夫为俄罗斯访问量第二的 Rambler.ru 站点(俄文:Рамблер)开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日
Nginx是一款轻量级的 Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在 BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上 nginx 的并发能力在同类型的网页服务器中表现较好。
Nginx 可以作为静态页面的 web 服务器,同时还支撑 CGI 协议的动态语言,比如:perl、php 等。但是不支持 java,Java 程序只能通过与 tomcat 配合完成,Nginx 专为性能优化而开发,性能是其中最重要的考量,实现上非常注重效率,能经受高负载的考验,有报告表明能支持 5 万个并发连接数。
1.1 正向代理
Nginx 不仅可以做反向代理,实现负载均衡,还能用作正向代理进行上网等功能。
如果把局域网外的 Internet 想象成一个巨大的资源库,则局域网中的客户端要访问 Internet,则需要通过代理服务器来访问,这种代理服务器就称为正向代理。
即:在我们的客户端配置代理服务器,通过代理服务器进行互联网的访问
Nginx 本身也是一个静态资源的服务器,当只有静态资源的时候,就可以使用 Nginx 来做服务器,如果一个网站只是静态页面的话,那么就可以通过这种方式来实现部署。
场景一:HTTP 服务器
1、 首先在文档根目录 Docroot(/usr/local/var/www) 下创建 html 目录, 然后在 html 中放一个 test.html;
2、 配置 nginx.conf 中的 server
user mengday staff;
http {
server {
listen 80;
server_name localhost;
client_max_body_size 1024M;
# 默认location
location / {
root /usr/local/var/www/html;
index index.html index.htm;
}
}
}3、访问测试
http://localhost/指向/usr/local/var/www/index.html, index.html 是安装 nginx 自带的 htmlhttp://localhost/test.html指向/usr/local/var/www/html/test.html
注意:如果访问图片出现 403 Forbidden 错误,可能是因为 nginx.conf 的第一行 user 配置不对
默认是#user nobody; 是注释的
linux 下改成 user root;
macos 下改成 user 用户名 所在组;
然后重新加载配置文件或者重启,再试一下就可以了, 用户名可以通过 who am i 命令来查看。
场景二:静态服务器
在公司中经常会遇到静态服务器,通常会提供一个上传的功能,其他应用如果需要静态资源就从该静态服务器中获取。
1、在 /usr/local/var/www 下分别创建 images 和 img 目录,分别在每个目录下放一张 test.jpg
2、 配置 nginx.conf 中的 server
http {
server {
listen 80;
server_name localhost;
set $doc_root /usr/local/var/www;
# 默认location
location / {
root /usr/local/var/www/html;
index index.html index.htm;
}
location ^~ /images/ {
root $doc_root;
}
location ~* \.(gif|jpg|jpeg|png|bmp|ico|swf|css|js)$ {
root $doc_root/img;
}
}
}自定义变量使用 set 指令,语法 set 变量名值; 引用使用变量名值; 引用使用变量名; 这里自定义了 doc_root 变量。
静态服务器 location 的映射一般有两种方式:
- 使用路径,如 /images/ 一般图片都会放在某个图片目录下,
- 使用后缀,如 .jpg、.png 等后缀匹配模式
访问 http://localhost/test.jpg 会映射到 $doc_root/img
访问 http://localhost/images/test.jpg 当同一个路径满足多个 location 时,优先匹配优先级高的 location,由于 ^~ 的优先级大于 ~, 所以会走 /images/ 对应的 location
1.2 反向代理
反向代理,其实客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,再返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的代理服务器地址,隐藏里真是的服务器 IP 地址

反向代理应该是 Nginx 使用最多的功能了,反向代理 (Reverse Proxy) 方式是指以代理服务器来接受 internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 internet 上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
简单来说就是真实的服务器不能直接被外部网络访问,所以需要一台代理服务器,而代理服务器能被外部网络访问的同时又跟真实服务器在同一个网络环境,当然也可能是同一台服务器,端口不同而已。
反向代理通过 proxy_pass 指令来实现
启动一个 Java Web 项目,端口号为 8081,做如下配置当我们访问 localhost 的时候,就相当于访问 localhost:8081 了
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://localhost:8081;
proxy_set_header Host $host:$server_port;
# 设置用户ip地址
proxy_set_header X-Forwarded-For $remote_addr;
# 当请求服务器出错去寻找其他服务器
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
}
}1.3 负载均衡
15 个请求,通过反向代理服务器,把请求平均分配到集群中的服务器去处理。
负载均衡通过 upstream 指令来实现
场景三:负载均衡
同一个项目分别使用 8081 和 8082 端口启动项目,使用负载均衡
1. RR(round robin : 轮询 默认)
每个请求按时间顺序逐一分配到不同的后端服务器,也就是说第一次请求分配到第一台服务器上,第二次请求分配到第二台服务器上,如果只有两台服务器,第三次请求继续分配到第一台上,这样循环轮询下去,也就是服务器接收请求的比例是 1:1, 如果后端服务器 down 掉,能自动剔除。轮询是默认配置,不需要太多的配置
upstream web_servers {
server localhost:8081;
server localhost:8082;
}
server {
listen 80;
server_name localhost;
#access_log logs/host.access.log main;
location / {
proxy_pass http://web_servers;
# 必须指定Header Host
proxy_set_header Host $host:$server_port;
}
}访问地址仍然可以获得响应 http://localhost/api/user/login?username=zhangsan&password=111111 ,这种方式是轮询的
2. 权重
指定轮询几率,weight 和访问比率成正比,也就是服务器接收请求的比例就是各自配置的 weight 的比例,用于后端服务器性能不均的情况,比如服务器性能差点就少接收点请求,服务器性能好点就多处理点请求。
upstream test {
server localhost:8081 weight=1;
server localhost:8082 weight=3;
server localhost:8083 weight=4 backup;
}示例是 4 次请求只有一次被分配到 8081 上,其他 3 次分配到 8082 上。backup 是指热备,只有当 8081 和 8082 都宕机的情况下才走 8083
3. ip_hash
上面的 2 种方式都有一个问题,那就是下一个请求来的时候请求可能分发到另外一个服务器,当我们的程序不是无状态的时候 (采用了 session 保存数据),这时候就有一个很大的很问题了,比如把登录信息保存到了 session 中,那么跳转到另外一台服务器的时候就需要重新登录了,所以很多时候我们需要一个客户只访问一个服务器,那么就需要用 iphash 了,iphash 的每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。
upstream test {
ip_hash;
server localhost:8080;
server localhost:8081;
}4. fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。这个配置是为了更快的给用户响应
upstream backend {
fair;
server localhost:8080;
server localhost:8081;
}5. url_hash(第三方)
按访问 url 的 hash 结果来分配请求,使每个 url 定向到同一个后端服务器,后端服务器为缓存时比较有效。在 upstream 中加入 hash 语句,server 语句中不能写入 weight 等其他的参数,hash_method 是使用的 hash 算法
upstream backend {
hash $request_uri;
hash_method crc32;
server localhost:8080;
server localhost:8081;
}以上 5 种负载均衡各自适用不同情况下使用,所以可以根据实际情况选择使用哪种策略模式,不过 fair 和 url_hash 需要安装第三方模块才能使用。
1.4 动静分离
为加快网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度,降低原来单个服务器的压力。
Nginx 动静分离简单来说就是把动态跟静态请求分开,不能理解成只是单纯把动态页面和静态页面物理分离。严格意义上来说应该是动态请求跟静态请求分开,可以理解成使用 Nginx 处理静态页面,Tomcat 处理动态页面。动静分离从目前实现角度大致分成两种:
- 纯粹把静态文件独立成单独的域名,放在独立的服务器上,也就是目前主流推崇的方案。
- 动态跟静态混合在一起发布,通过 Nginx 来分开。
upstream web_servers {
server localhost:8081;
server localhost:8082;
}
server {
listen 80;
server_name localhost;
set $doc_root /usr/local/var/www;
location ~* \.(gif|jpg|jpeg|png|bmp|ico|swf|css|js)$ {
root $doc_root/img;
}
location / {
proxy_pass http://web_servers;
# 必须指定Header Host
proxy_set_header Host $host:$server_port;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root $doc_root;
}
}通过 location 指定不同的后缀名实现不同的请求转发,通过 expire 参数设置,可以使浏览器缓存过期时间,减少与服务器之前的请求和流量。具体 Expires 定义:是给一个资源设定一个过期时间,即无需去服务器端验证,直接通过浏览器自身确认是否过期即可,所以不会产生额外的流量。此种方法适合不经常变动的资源(如果经常更新不建议用 Expires 来缓存)。
例如:设置 3d,标识这个 3 天之内访问这个 URL,发送一个请求对比服务器该文件最后更新时间没有变化,则不会从服务器抓取,返回状态码 304,如果有修改,则直接从服务器重新下载,返回状态 200
1.5 安装
1.2 常用命令
使用命令的前提条件要进入 nginx 的目录里:cd /usr/local/nginx/sbin
- 查看 nginx 版本号·
./nginx -v - 启动 nginx
./nginx - 关闭 nginx
./nginx -s stop - 重新加载 nginx
./nginx -s reload
1.3 配置文件
配置文件位置/usr/local/nginx/conf/里的 nginx.conf
由三部分组成,分别是全局块、events 块、http 块
全局块
从配置文件开始到 events 块之间的内容,主要会设置一些影响 nginx 服务器整体运行的配置指令,主要包括配置运行 Nginx 服务器的用户(组)允许生成 worker process 数,进程 PID 存放路径、日志存放路径和类型以及配置文件的引入等
worker_provesses 1; #Nginx服务器并发处理服务器的关键配置,worker_provesser值越大,可以支持的并发数量也越多,但会受到硬件、软件等设备的制约events 块
events 块设计的指令主要影响 Nginx 服务器与用户的网络连接(常用的设置包括是否开启对多 work process 下的网络连接进行序列化,是否同时接收多个网络连接,选取那些事件驱动模型来处理连接请求,每个 work process 可以同时支持的最大连接数量等)
work_connections 1024; #支持最大连接数,这个对Nginx的性能影响较大,在实际应用中灵活配置http 块
这个模块是 Nginx 服务器配置中最频繁的部分,代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里。
注意:http 块也可以包括 http 全局块和 server 块
- http 块
http 全局块配置的指令包括文件引入、MIME-TYPE 定义、日志自定义、连接超时时间、单链接请求上限等 - server 块
这块和虚拟主机有密切关系,虚拟机从用户角度看和一台独立的硬件主机是完全一样的,该技术的生产是为了节省互联网服务器硬件成本。
每个 http 块可以包括多个 server 块,而每个 server 块就相当于一个虚拟主机
而每个 server 块也分为全局 server 块,以及可以同时包含多个 location 块- 全局 server 块
最常见的配置是本虚拟主机的监听配置和本虚拟主机的名称和 IP - location 块
一个 server 块可以配置多个 location 块
这个块主要作用时基于 Nginx 服务器接收的请求字符串(例如 server_name/uri-string),对虚拟主机名称(也可以是 IP 别名)之外的字符串(例如:前面的/uri-string)进行匹配,对特定的请求进行处理。地址定向、数据缓存和应答控制等功能,还有许多第三方模块也在这里进行。
- 全局 server 块