Skip to content

Nginx 介绍

Nginx 是一款轻量级的 Web 服务器、反向代理服务器,是由俄罗斯的程序设计师 Igor Sysoev 所开发,使用 C 语言开发,由于它的内存占用少,启动速度极快,具有高并发的能力,在互联网项目中被广泛地应用。 它的功能丰富,可作为 HTTP 服务器,静态资源服务器,也可作为反向代理服务器,邮件服务器等。支持FastCGISSLVirtual HostURL RewriteGzip等功能。并且支持很多第三方的模块扩展。Nginx 在全球网站中的市场份额为 33.5%,位居第二,仅次于 Apache。

Nginx 核心功能

  • 反向代理:反向代理是指以代理服务器来接受客户端的连接请求,然后将请求转发给内部网络上的服务器,并将从内部服务器上得到的结果返回给客户端,此时代理服务器对外就表现为一个服务器。
  • 负载均衡:负载均衡,即把请求分摊到多个操作单元上进行执行,例如 Web 服务器、FTP 服务器、数据库服务器等,从而共同完成工作任务。
  • 限流:每秒钟可以处理 HTTP 和 HTTPS 请求。

反向代理

什么是代理

说到代理,首先我们要明确一个概念,所谓代理就是一个代表、一个渠道;此时就涉及到两个角色,一个是被代理角色,一个是目标角色,被代理角色通过这个代理访问目标角色完成一些任务的过程称为代理操作过程;如同生活中随处可见的中介,我们可以通过中介买到房子,中介就是代理,被代理的就是买房子的人,而我们就是目标角色。

正向代理

说到正向代理,应该很多人都接触过,也听过它的名字,那就是我们熟知的 VPN:VPN 通俗的讲就是一种中转服务,当我们电脑接入 VPN 后,我们对外 IP 地址就会变成 VPN 服务器的公网 IP,我们请求或接受任何数据都会通过这个 VPN 服务器后传入到我们本机,隐藏了本机的地址。那么这样做有什么好处呢?VPN 利用低成本的公共网络作为企业骨干网,同时又克服了公共网络缺乏保密性的弱点,在 VPN 网络中,位于公共网络两端的网络在公共网络上传输信息时,其信息都是经过安全处理的,可以保证数据的完整性、真实性和私有性。

这里的 VPN 就是做正向代理的。正向代理服务器位于客户端和服务器之间,为了向服务器获取数据,客户端要向代理服务器发送一个请求,并指定目标服务器,代理服务器将目标服务器返回的数据转交给客户端。这里客户端是要进行一些正向代理的设置的。

反向代理

反向代理,对比正向代理来说其实就是反过来了,正向代理是隐藏用户的信息,而反向代理是隐藏真实的服务器信息。

反向代理和正向代理的区别就是:正向代理代理的是客户端,反向代理代理的是服务器。

  • 举例子
bash

location ^~ /user {
    proxy_set_header name jsopy;
    proxy_pass  http://192.168.1.115:5000;
}

负载均衡

利用反向代理可以作为内部负载均衡(load balance) 的手段.

举个例子来说, 比如我现在开发了一个 java web 的博客网站, 我把它直接部署它到 tomcat 服务器上, 让 tomcat 监听 80 端口, 直接对外服务. 一开始访问量也不大, 所以这样也是没有问题的,但是当用户增多,访问量上来的时候,一个 tomcat 进程处理不过来了,那现在怎么办呢?于是我想到了再起一个 tomcat 进程,但是这样又多了一个问题,我只有一个 80 端口,那么我只能起一个其他的端口,这样做的话显然是有问题的,用户在访问的时候不可能有的访问 80 端口,有的人在访问的时候用其他端口吧。

基于以上的问题,我们可以想到可以用 Nginx 的反向代理来实现两个 tomcat 进程的负载均衡,那么我们只需要代理两个 tomcat 进程,配置负载均衡策略,将入口交给 Nginx 来管理,那么用户在访问同一个地址的时候就可以将请求分发到不同的 tomcat 上以实现负载均衡。

  • 举个例子
bash

http {
    upstream server1{
        server 127.0.0.1:8080 weight=3;
        server 127.0.0.1:8081 weight=2;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://server1;
        }
    }
}

其中 weight 是权重,当机器的配置不一样的时候可以控制流向每个机器的流量占比。

限流

Nginx 限流就是限制用户请求的速度,防止服务器过载的情况 限流一般有 3 种 正常限制访问频率(正常流量) 突发限制访问频率(突发流量) 限制并发连接数 Nginx 的限流都是基于漏桶流算法,后面会说到

  • 举个例子
bash

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

    server {
        listen 80;

        location / {
            limit_req zone=one burst=5;
        }
    }
}

Nginx 基础使用以及配置文件介绍

Nginx 基本命令

bash
nginx -s stop :强制关闭Nginx,可能不保存相关信息,并迅速终止web服务。
pkill nginx :强制关闭nginx
nginx -s quit :平稳关闭Nginx,保存相关信息,有安排的结束web服务。
nginx -s reload :重新加载配置而不用重启服务。
nginx -s reopen :重新打开日志文件。
nginx -c filename :为 Nginx 指定一个配置文件,来代替缺省的。
nginx -t :不运行,而仅仅测试配置文件。nginx 将检查配置文件的语法的正确性,并尝试打开配置文件中所引用到的文件。
nginx -v:显示 nginx 的版本。
nginx -V:显示 nginx 的版本,编译器版本和配置参数。

Nginx 配置文件结构

bash

main                                # 全局配置
events {                            # nginx工作模式配置

}
http {                                # http设置
....
server {                        # 服务器主机配置
    ....
    location {                    # 路由配置
        ....
    }
    location path {
        ....
    }
    location otherpath {
        ....
    }
}
server {
    ....

    location {
        ....
    }
}
upstream name {                    # 负载均衡配置
    ....
}
}
  • main(全局设置):设置影响多个指令块的环境参数,比如 worker processes 和包含的模块。
  • events(事件模块):影响 Nginx 服务器或与用户的网络连接。比如 worker connections 用于 nginx 工作模式的配置
  • http(HTTP 设置):代理、缓存和日志等功能。这将使用由许多指令控制的 http 块。
  • server(虚拟主机):可以包含的指令取决于它们是否在 http 块中。
  • location(定位):服务器块的指令块,用于匹配客户端请求的 URI
  • upstream(负载均衡服务器设置):upstream 指令块定义了一组后端服务器,可由 proxy_pass 指令在 location 块中使用。

Nginx 配置文件详解

main 全局配置

bash

user nobody nobody; # 指定运行 Nginx 的用户和组
worker_processes 2;  # 指定 Nginx 进程数,建议设置为等于 CPU 总核心数。
error_log logs/error.log warn; # 错误日志路径,级别可以是:[ debug | info | notice | warn | error | crit ]
error_log logs/error.log notice # 错误日志路径,级别可以是:[ debug | info | notice | warn | error | crit ]
error_log logs/error.log info # 错误日志路径,级别可以是:[ debug | info | notice | warn | error | crit ]
pid logs/nginx.pid  # 指定进程(PID)文件路径

events 事件模块

bash

event {
  worker_connections 1024;
  multi_accept on;
  use epoll;
}
  • worker_connections 指定最大可以同时接收的连接数量,这里一定要注意,最大连接数量是和 worker processes 共同决定的。

  • multi_accept 配置指定 nginx 在收到一个新连接通知后尽可能多的接受更多的连接

  • use epoll 配置指定了 Nginx 使用的 I/O 模型,如果我们在 Linux 平台上,那么开启 epoll 模型,这个将大大提高 Nginx 的性能。

http 模块

作为 web 服务器,http 模块是 nginx 最核心的一个模块,配置项也是比较多的,项目中会设置到很多的实际业务场景,需要根据硬件信息进行适当的配置,常规情况下,使用默认配置即可!这里不做介绍。

server 模块(重点)

srever 模块配置是 http 模块中的一个子模块,用来定义一个虚拟访问主机,也就是一个虚拟服务器的配置信息。

bash

server {
	listen        80;
	server_name localhost    192.168.1.100;
	root        /nginx/www;
	index        index.php index.html index.html;
	charset        utf-8;
	access_log    logs/access.log;
	error_log    logs/error.log;
......
}
  • server 配置虚拟主机的相关参数,一个 http 块中可以有多个 server 块,每个 server 块就相当于一个虚拟主机。
  • listen 指定监听的端口,默认监听 80 端口
  • server_name 用来指定主机头(host-header)和当前虚拟主机名称,多个名称之间用空格隔开
  • root 表示整个 server 虚拟主机内的根目录,所有当前主机中 web 项目的根目录,可以用来做静态服务器
  • index 用户访问 web 网站时的全局首页
  • charset 用于设置 www/路径中配置的网页的默认编码格式
  • access_logerror_log 分别用来指定该虚拟主机的访问日志文件和错误日志文件

location 模块

location 模块是 nginx 配置中出现最多的一个配置,主要用于配置路由访问信息 在路由访问信息配置中关联到反向代理、负载均衡等等各项功能。

bash
location / {
	root    /nginx/www;
	index    index.php index.html index.htm;
    }
  • location / 表示匹配访问根目录
  • root 用于指定访问根目录时,访问虚拟主机的 web 目录
  • index 在不指定访问具体资源时,默认展示的资源文件列表

root 和 alias 的区别

注意

  1. root 会把 location 后面的路径与 root 指定的路径拼接起来
  2. alias 直接把 location 后面的路径替换掉
  • 举例
bash
location /images1 {
    # 简单来说 就是访问images1/xxx.jpg 实际访问的是 /usr/share/nginx/html/test1/images1/xxx.jpg
    # 也就是说 alias后面才是实际的地址, 接的是物理地址 后面没有return
    alias /usr/share/nginx/html/test1/images1/;
}

location /images2 {
    # 简单来说 就是访问images2/xxx.jpg 实际访问的是 root后面加上`images2/xxx.jpg`
    # 实际访问的是 /usr/share/nginx/html/test2/images2/xxx.jpg
    # alias 和 root 只能接物理地址,不能接变量 后面没有return
    root /usr/share/nginx/html/test2/;
}

Nginx 具体使用

静态资源服务

Nginx 可以作为静态 web 服务器来部署静态资源。静态资源指在服务端真实存在并且能够直接展示的一些文件,比如常见的 html 页面、css 文件、 js 文件、图片、视频等资源。相对于 Tomcat, Nginx 处理静态资源的能力更加高效,所以在生产环境下,一般都会 将静态资源部署到 Nginx 中。将静态资源部署到 Nginx 非常简单,只需要将文件复制到 Nginx 安装目录下的 html 目录中,然后访问相应的地址即可下载对应的静态资源。

bash

server {
	listen 80; #监听端口
	server_name localhost; #服务器名称
	location / {  #匹配客户端请求url
		root html; #指定静态资源根目录
		index index.html; #指默认首页
	}
}

通过以上配置文件启动 nginx,那么我们只需要将静态文件例如图片,文件放到 html 目录下面,然后访问 ip 地址加 80 端口加对应的路径就可以访问到服务器中的文件。

反向代理

反向代理就是隐藏真实的服务器地址,保护真实的服务器,用户在访问时访问的是代理服务器。

nginx 中常见的反向代理指令有两个:proxy_passfastcgi_pass,前者使用标准的 HTTP 协议转发,后者使用 FastCGI 协议转发。这里我们以 proxy_pass 为例来做介绍。

proxy_pass 有两种配置写法: 1、直接指向要代理的地址,可以是一台具体的主机(ip),也可以是一个具体的网址 2、可以搭配负载均衡指向一组服务器(参考负载均衡)

如下面的配置所示 最简单的一个反向代理配置

bash

server {
	listen 80;
	server_name localhost;
	location / {
		proxy_pass http://ddosi.top; #反向代理配置,将请求转发到指定服务
	}
}

负载均衡

早期的网站流量和业务功能都比较简单,单台服务器就可以满足基本需求,但是随着互联网的发展,业务流量越来越大并且业务逻辑也越来越复杂,单台服务器的性能及单点故障问题就凸显出来了,因此需要多台服务器组成应用集群,进行性能的水平扩展以及避免单点故障出现。那么这时候 Nginx 就可以作为一个负载均衡服务器。

负载均衡基础配置:

bash
upstream loadServer{ #upstream指令可以定义一组服务器
	server 192.168.137.101:8080 weight=10; #可以设置权重,默认都是1,数值越大,分配的流量越多
	server 192.168.137.101:8081 weight=5;
}
server {
	listen 80;
	server_name localhost;
	location / {
		proxy_pass http://loadServer;
	}
}

多个服务器负载均衡

  • 通过 cookie 来区分去对应哪个服务器
bash
upstream version1.0_server {
    server 192.168.1.115:5000;
}

upstream version2.0_server {
    server 192.168.1.115:5001;
}

upstream default {
    server 192.168.1.115:5000;
}
server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

set $group "default";
if ($http_cookie ~* "version=1.0"){
    set $group version1.0_server;
}

if ($http_cookie ~* "version=2.0"){
    set $group version2.0_server;
}

location ^~ /user {
    proxy_set_header name jsopy;
    proxy_pass http://$group;
 }
}

负载均衡策略

  • 轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器。
bash
upstream backserver {
 server http://ddosi.top/;
 server 192.168.0.100;
}
  • weight(权重)

weight 的值越大分配,到的访问概率越高,只要用于服务器配置不一样,承受的流量不一样的情况。

bash

upstream backserver {
 server http://ddosi.top/ weight=2;
 server 192.168.0.100 weight=3;
}
  • ip_hash

每个请求按访问 IP 的哈希结果分配,使来自同一个 IP 的访客固定访问一台后端服务器,并且可以有效解决动态网页存在的 session 共享问题

bash
upstream backserver {
 ip_hash;
 server http://ddosi.top/ weight=2;
 server 192.168.0.100 weight=3;
}
  • 热备

如果你有 2 台服务器,当一台服务器发生事故时,才启用第二台服务器给提供服务

bash

upstream backserver {
 server http://ddosi.top/;
 server 192.168.0.100 backup;
}
  • fair(第三方)

第三方插件,必须安装 upstream_fair 模块。

bash
upstream backserver {
 fair;
 server http://ddosi.top/;
 server 192.168.0.100;
}

限流

Nginx 提供了限制请求频率的模块,可以通过 ngx_http_limit_req_module 来实现。以下是一个简单的配置示例,该配置将请求限制在每秒 1 个请求,超过限制的请求将被拒绝。

bash

http {
    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;

    server {
        location / {
            limit_req zone=mylimit burst=5;
            proxy_pass http://my_upstream;
        }
    }
}

limit_req_zone: 指令定义了一个速率限制区域,其中$binary_remote_addr 用于识别每个请求的 IP 地址,mylimit:10m 是这个区的名字和内存大小,rate=1r/s 设置了允许的平均请求速率。 limit_req: 指令应用了速率限制区域到具体的 location,burst=5 定义了允许的突发请求数,即当请求超过限制时,允许的额外请求数。。

这个配置将导致对于每个 IP 地址,Nginx 只处理每秒 1 个请求,超过这个速率的请求将会收到 503 错误。