• 返回首页

    Nginx教程——By Bug

    参考资料

    视频:https://www.bilibili.com/video/BV1ov41187bq

    官方文档nginx documentation

    Nginx介绍

    背景介绍

    Nginxs是一个具有高性能的【HTTP】和【反向代理】的【web服务器】,同时也是一个【POP3/SMTP/IMAP代理服务器】,是 Igor Sysoev使用C语言编写的

    Web服务器

    HTTP

    POP3/SMTP/IMAP代理服务器

     

    Nginx的优点

    1. 速度快,并发更高 单次请求或高并发请求的环境下,nginx都会比其他web服务器相应的速度更加快。

    2. 配置简单,扩展性强 Nginx极具扩展性,它本身就是由很多个模块构成的,这些模块的使用可以通过配置文件的配置来进行添加。这些模块由官方或第三方提供。如有需要,完全可以开发自己业务需要的模块

    3. 高可靠性 Nginx采用的是多线程模式运行,其中有一个master主进程和N个worker进程,worker的数量可以手动设置,每个worker之间都是独立提供服务的,master可以在一个worker运行出错时,快速拉起新的worker进程提供服务

    4. 热部署 互联网项目要求7*24小时进行服务提供,Nginx提供了热部署功能,在不停止Nginx的情况下,对Nginx进行文件升级,更新配置,更改日志等操作

    5. 成本低,BSD许可证 BSD是一个开源的许可证,世界上由许多开源许可证。 目前较为流行的许可证:GPL,BSD,MIT,Mozilla,Apache,LGPL

     

    Nginx的功能和常用功能

    Nginx提供的基本功能服务从大体上归纳为“基本HTTP服务”、“高级HTTP服务”和"邮件服务"等三大类。

     

    Nginx环境准备

    Nginx官网:https://nginx.org/

    nginx文档:nginx documentation

    准备linux系统

    下载源码包(稳定版Stable version)

     

    Nginx安装

    1. 通过源码安装

      准备工作 GCC编译器

      PCRE

      zlib

      OpenSSL

      源代码简单安装

      1. 下载源码

      2. 解压缩

      3. 进入资源文件进行简单配置

      4. 编译

      5. 安装

         

      源代码复杂安装

      这种安装方式通过 ./configure 来对编译参数进行设置,需要我们进行手动指定

      PATH:是和路径相关的配置信息

      with:是启动模块,默认是关闭的

      without:是关闭模块,默认是开启的

      –prefix=PATH 指向Nginx的安装目录,默认值为/usr/local/nginx

       

      –sbin-path=PATH 指向(执行)程序文件(nginx)的路径,默认值为<prefix>/sbin/nginx

       

      –modules-path=PATH

      指向Nginx动态模块安装目录,默认值为<prefix>/modules

       

      –conf-path=PATH 指向配置文件(nginx.conf)的路径,默认值为<prefix>/conf/nginx.conf

       

      –error-log-path=PATH 指向错误日志文件的路径,默认值为<prefix>/logs/error.log

       

      –http-log-path=PATH 指向访问日志文件的路径,默认值为<prefix>/logs/access.log

       

      –pid-path=PATH 指向Nginx启动后进行ID的文件路径,默认值为<prefix>/logs/nginx.pid

       

      –lock-path=PATHcd

      指向Nginx锁文件的存放路径,默认值为<prefix>/logs/nginx.lock

       

    2. 通过yum安装

      1. 安装yum-utils

      2. 配置文件nginx.repo

        输入下面内容

      3. yum在线安装

      4. 查找nginx安装位置

     

    nginx卸载

    1. 关闭nginx进程

    2. 将nginx删除

    3. 清除编译的环境

     

    nginx启停

    1. Nginx服务的信号控制

      信号

      信号作用
      TERM/INT立即关闭整个服务
      QUIT关闭整个服务(处理完当前请求后关闭)
      HUP重读配置文件并使用服务对新配置项生效
      USR1重新打开日志文件,可用来进行日志切割
      USR2平滑升级到最新的nginx
      WINCH所有子进程不再接受处理新连接,相当于关闭work进程

      调用命令:kill -signal(信号) PID(进程id)

       

    2. nginx的命令行控制 通过nginx安装目录的sbin下的nginx控制

     

    Nginx平滑升级

    1. 使用Nginx服务信号进行版本升级

      1. 进入旧版本的Nginx目录,对Nginx可执行文件进行备份,防止升级失败,便于版本回退

      2. 切换到新版本目录,进行编译,将新版本编译后的objs下的nginx文件拷贝到原安装目录下的sbin目录中

      3. 发信号USR2给正在运行的旧版本Nginx的master进程

      4. 发信号QUIT给正在运行的旧版本Nginx的master进程

    2. 使用Nginx安装目录下的make命令进行升级

      1. 进入旧版本的Nginx目录,对Nginx可执行文件进行备份,防止升级失败,便于版本回退

      2. 切换到新版本目录,进行编译,将新版本编译后的objs下的nginx文件拷贝到原安装目录下的sbin目录中

      3. 进入安装目录,执行make upgrade

      4. 查看是否

         

    nginx.conf配置文件

    默认的三大块

     

    全局块

    user指令

    user指令:用于配置运行Nginx服务器的worker进程的用户和用户组

    语法user username [group]
    默认值nobody
    位置全局块

    当访问权限不足时,网页会报403错误

     

    工作进程的两个指令

    其他配置指令

     

    events块

     

    HTTP块

    定义MIME-Type

    MIME-Type是网络资源的媒体类型。nginx作为web服务器,也需要能够识别前端请求的资源类型

    在Nginx的配置文件中的两行默认配置

     

    自定义服务日志

    Nginx中的日志类型分为access.log和error.log日志 access.log:记录用户的所有访问请求 error.log:记录nginx运行的错误信息 nginx服务器支持对日志的格式,大小,输出等进行设置,需要使用以下两个指令

    1. access_log 设置用户访问日志的相关数据

      语法access_log path路径[format输出格式][buffer=size文件大小]
      默认值access_log logs/access.log combined
      位置http、server、location
    2. log_format 设置日志的输出格式

      语法log_format name [escap=default|json|none...] string...;
      默认值log_format combined '...'
      位置http

     

    其他配置指令

    1. sendfile:设置nginx服务器是否使用sendfile()传输文件,该属性可以大大提高nginx处理静态资源的性能

      语法sendfile on/off
      默认值off
      位置http、server、location
    2. keeplive_timeout:设置长连接的超时时间

      • HTTP是一种无状态协议,客户端向服务端发送一个TCP请求,服务端响应完成后断开连接

      • 如果客户端向服务端发送了多个请求,每个请求都要重新建立一次连接,效率和性能较低,使用keeplive模式,可以告诉服务端,完成一个请求后,保持这个tcp请求打开状态,若列收到这个客户端的其他请求,就利用这个未关闭的连接,不需要再次建立一个新的连接,提升效率,但是这个连接也不能一直保持下去,会严重影响服务端的性能,所以就要设置超时时间。

      语法keeplive_timeout time
      默认值75秒
      位置http、server、location
    3. keeplive_requests:设置一个连接使用的最大次数

      语法keeplive_requests number
      默认值100
      位置http、server、location

       

    server块

    三种匹配方式的匹配执行顺序

     

     

    location块

    location用来设置请求的URI

    uri变量是待匹配的请求字符串,可以不包含正则表达式,也可以包含正则表达式。那么bginx服务器在搜索匹配location时,是先使用不包含正则表达式的进行匹配,找到一个匹配度最高的一个。然后再通过包含正则表达式的进行匹配,如果能匹配到直接访问,如果能匹配到直接访问,如果匹配不到,才使用匹配度最高的的那个location进行处理请求。

     

    属性介绍

     

    root/alias指令

    root:设置请求的根目录

    alias:用来更来location的URI

     

    root和alias的区别:

     

    例如:使用以下地址访问指定资源

    可以使用以下配置

     

    index指令

    index:设置网站的默认首页。

    index后可以跟多个设置,在访问的时候,如没有指定具体的访问资源,则会进行查找,找到第一个为止

     

     

    error_page指令

    error_page:设置网站的错误页面。

    当出现对应的相应code后,如何来处理。

    =[response]的作用是用来将相应代码更改为另一个。

    例如:

    1. 跳转到指定地址。

    2. 指定重定向地址

    3. 使用location的@完成错误信息展示

       

    静态资源优化配置

    nginx对静态资源进行优化,可以从下面的三个属性配置进行优化。

    1. sendfile,用来开启高效的文件传输模式。

      请求静态资源的过程:客户端通过网络接口向服务端发送请求,操作系统将这些请求传递到服务端应用程序。服务端应用程序会处理这些请求,请求处理完成后,操作系统还需要将处理得到的结果通过网络传递回去

    2. tcp_nopush,该指令必须在sendfile开启的状态下才能生效,主要用来提升网卡的传输“效率”。

       

    3. tcp_nodelay,该指令必须在keep-alive连接开启的状态下才生效,用来提高网络包传输的“时效性”。

     

    静态资源压缩

    Gzip模块配置

    下面的指令都是ngx_http_gzip_module模块,该模块会在nginx安装的时候内置在nginx的安装环境中,我们可以直接使用这些指令

    1. gzip指令:该指令用于开启或关闭gzip功能。

      注意:该指令只有在打开时,下面的指令才有效果。

    2. gzip_types指令:该指令可以根据响应页的MIME类型选择性的开启Gzip压缩功能。

      所选择的值可以从mime.types文件中进行查找,也可以使用 “*” 代表所有(生产环境中不建议使用)

    3. gzip_comp_level指令:该指令用于设置Gzip压缩程度,等级从1-9,等级越高,压缩程度越高,效率越低。

      例如:

    4. gzip_vary指令:该指令用于设置使用Gzip进行压缩发生是否携带“Vary:Accept-Encoding”头域的响应头部。主要告诉接收方,所发送的数据经过了Gzip压缩处理。

    5. gzip_buffer指令:该指令用来设置缓冲区的数量和大小。

      number:指定nginx服务器向系统中申请缓存空间的个数。

      size:指的是每个缓存空间的大小。

      主要实现的是number个size大小的内存空间。这个值的设定一般会和服务器的操作系统有关。所以一般不建议设置,使用默认值即可。

    6. gzip_disable指令:针对不同客户端发起的请求,可以选择性地开启或关闭Gzip功能。

      regex:根据客户端的浏览器标志(user-agent)来设置。支持使用正则表达式,指定的浏览器标志不使用Gzip,该指令一般用来排除一些明显不支持Gzip的浏览器

    7. gzip_http_version指令:针对不同的HTTP协议版本,可以选择性地开启或关闭Gzip功能。

      这个属性一般不做设置,使用默认即可。

    8. gzip_min_length指令:该指令针对数据传输大小,可以选择性的开启或关闭Gzip功能。

      Gzip压缩功能对大数据的压缩效果比较明显。但是要压缩比较小的数据,可能会出现越压缩数据越大的情况,因此,我们需要根据相应内容的大小来决定是否使用Gzip压缩功能,相应页面的大小,可以从头信息中的Content-Length来获取。但是如果使用了Chunk编码动态压缩,这个指令将被忽略。

      建议设置为1k以上。

    9. gzip_proxied指令:该指令设置是否对服务端返回的结果进行压缩。

      • off:关闭Nginx服务器对后台服务器返回结果的Gzip压缩

      • expired:启用压缩,如果header头中包含“Expires"头信息

      • no-cache:启用压缩,如果header头中包含"Cache-Control:no-cache”头信息

      • no-store:启用压缩,如果header头中包含"Cache-Control:no-store”头信息

      • private:启用压缩,如果header头中包含"Cache-Control:private"头信息

      • no_last_modified:启用压缩,如果header头中不包含"Last-Modified"头信息

      • no_etag:启用压缩,如果header头中不包含“ETag”头信息

      • auth:启用压缩,如果header头中包含"Authorization"头信息

      • any:无条件启用压缩

     

    Gzip和sendfile共存问题

    当开启sendfile后,读取磁盘上的静态资源文件的时候,可以减少拷贝的次数。可以不经过用户进程,将静态文件通过网络发送。但Gzip需要对资源进行压缩,需要经过用户进程的操作,所以需要解决这两个的共存问题。

    可以使用ngx_http_gzip_static_module模块的gzip相关的header返回.gz文件的内容;

    nginx默认没有ngx_http_gzip_static_module模块,需要手动进行添加。

    手动添加模块的方法

    1. 查询当前安装的nginx配置参数

    2. 将nginx安装目录下sbin目录中的nginx二进制文件更名(备份)

    3. 进入nginx安装目录

    4. 执行make clean清理之前的编译内容

    5. 使用configure来配置参数

    6. 使用make命令进行编译

    7. 在obj目录下会生成一个nginx二进制可执行文件,将其移动到nginx安装目录下的sbin目录中

    8. 执行更新命令

       

    静态资源缓存处理

    缓存介绍

    什么是缓存?

    什么是web缓存

    web缓存的分类

    浏览器缓存

    为什么使用浏览器缓存?

     

    浏览器缓存的执行流程

    在HTTP协议中和页面缓存相关的字段。

    header说明
    Expires缓存过期的日期和时间
    Cache-Control设置和缓存相关的配置信息
    Last-Modified请求资源最后修改时间
    ETag请求变量的实体标签的当前值,如:文件的MD5值

     

     

    浏览器缓存配置

    expires指令

    该指令用来控制缓存页面的作用,可以通过该指令控制HTTP应答中的“Expires”和“Cache-Control”

     

    add_header指令

    该指令用来添加指定的响应头和响应值。

     

    Cache-Control作为响应头信息,可以设置以下值

    说明
    must-revalidate可缓存但必须再向源服务器进行确认
    no-cache缓存前必须确认其有效性
    no-store不缓存请求或响应的任何内容
    no-transform代理不可更改媒体类型
    public可向任意方提供响应的缓存
    private仅向特定用户返回响应
    prxy-revalidate要求中间缓存服务器对缓存的响应有效性在进行确认
    max-age=<秒>响应最大Age值
    s-maxage=<秒>公共缓存服务器的最大Age值

     

    nginx的跨域问题

    同源策略

    浏览器的同源策略:是一种约定,是浏览器最核心也是最基本的安全功能。如果浏览器少了同源策略,浏览器的正常功能都会受到影响。

    同源:协议、域名、端口相同即为同源

     

    跨域问题

    解决方案

    使用add_header指令,添加头部信息

    在此处用来解决跨域问题,添加两个头部信息,一个是Access-Control-Allow-Origin,Access-Contro-Allow-Methods

     

    静态资源防盗链

    什么是资源盗链?

    资源盗链指的是此内容不在自己的服务器上,通过技术是手段绕过别人的限制,将别人的资源放在自己的页面上展示给用户。以此来盗取网站的空间和流量。

     

    防盗链原理和实现

    valid_referers指令: nginx会通过查看referer字段和valid_referers后面的内容进行匹配,如果匹配到了就将$valid_referers变量置为0,如果没有匹配到,就将$valid_referers置为1,匹配过程不区分大小写。

    问题:Referer的限制比较粗,比如随意加一个Referer,上面的方法是无法进行限制的。所以,需要使用Nginx的第三方模块ngx_http_accesskey_module

     

    Rewrite功能

    Rewrite介绍

    Rewrite是Nginx服务器提供的一个重要功能,是Web服务器产品在几乎必备的功能,主要作用是实现URL重写。

    注意:Nginx服务器是Rewrite功能的实现依赖于PCRE的支持,因此在编译安装Nginx之前,需要安装PCRE库。Nginx使用的是ngx_http_rewrite_module模块来解析和处理Rewrite功能的相关配置。

    Rewrite的相关指令

    Rewrite的应用场景

    Rewrite指令

    set指令

    该指令用来设置一个新的变量

    variable:变量名称,该变量名要用$作为变量的第一个字符,且不要与Nginx服务器预设的全局变量同名

    value:变量的值,可以是字符串,其他变量,或者变量的组合。

    Rewrite常用全局变量

    变量说明
    $args变量中存放了请求URL中的请求参数。比如http://192.168.200.133/server?arg1=value1&args2=value2中 的"arg1=value1&arg2=value2",功能和$query_string一样。
    $http_user_agent变量存储的是用户访问服务的代理信息(如果通过浏览器访问,记录的是浏览器的相关版本信息)
    $host变量存储的是访问服务器的server_name值
    $document_uri变量存储的是当前访问地址的URI。比如http://192.168.200.133/server?id=10&name=zhangsan中的"/server",功能和$uri一样
    $document_root变量存储的是当前请求对应location的root值,如果未设置,默认指向Nginx自带html目录所在位置
    $content_length变量存储的是请求头中的Content-Length的值
    $content_type变量存储的是请求头中的Content-Type的值
    $http_cookie变量存储的是客户端的cookie信息,可以通过add_header Set-Cookie'cookieName=cookieValue'来添加cookie数据
    $limit_rate变量中存储的是Nginx服务器对网络连接速率的限制,也就是Nginx配置中对limit_rate指令设置的值,默认是0,不限制。
    $remote_addr变量中存储的是客户端的IP地址
    $remote_port变量中存储了客户端与服务端建立连接的端口号
    $remote_user变量中存储了客户端的用户名,需要有认证模块才能获取
    $scheme变量中存储了访问协议
    $server_addr变量中存储了服务端的地址
    $server_name变量中存储了客户端请求到达的服务器的名称
    $server_port变量中存储了客户端请求到达服务器的端口号
    $server_protocol变量中存储了客户端请求协议的版本,比如"HTTP/1.1"
    $request_body_file变量中存储了发给后端服务器的本地文件资源的名称
    $request_method变量中存储了客户端的请求方式,比如"GET","POST"等
    $request_filename变量中存储了当前请求的资源文件的路径名
    $request_uri变量中存储了当前请求的URI,并且携带请求参数,比如http://192.168.200.133/server?id=10&name=zhangsan中的"/server?id=10&name=zhangsan"

     

    if指令

    该指令用来进行条件判断,并根据条件判断的结果选择不同的Nginx配置

    condition为判断条件,可以使用以下几种写法

    1. 变量名。如果变量名对应的值为空字符串或"0",结果都为else,反之为true。

    2. 使用”=“或”!=“比较变量与值是否相等

      注意:与其他编程语言不同的是,这里的字符串不需要加” “,并且等号前后要加空格。

    3. 使用正则表达式对变量进行匹配,成功返回true失败返回false,变量与正则表达式之间使用”~“,”~*“,”!~“,”!~*“来连接。 ”~“:代表匹配正则表达式过程中区分大小写 ”~*“:代表匹配正则表达式过程中不区分大小写 ”!~“和”!~*“:刚好和上面取相反值,如果匹配上返回false,反之返回true

      注意:正则表达式字符串一般不需要加引号,但如果字符串中包含“}”,“;”等符号时,需要加引号。

    4. 判断请求的文件是否存在使用“-f”或“!-f”

    5. 判断请求的目录是否存在使用"-d"和"!-d"

    6. 判断请求的目录或者文件是否存在使用"-e"和"!-e"

    7. 判断请求的文件是否可执行使用"-x"和"!-x"

     

    break指令

    该指令用于中断当前相同作用域中的其他Nginx配置。与该指令处于同一作用域的Nginx配置中,位于它前面的指令配置生效,位于后面的指令配置无效。并且break还有另外一个功能就是终止当前的匹配并把当前的URI在本location进行重定向访问处理。

     

    return指令

    该指令用于完成请求的处理,直接向客户端返回。在return之后的所有nginx配置都是无效的。

     

    rewrite指令

    该指令通过正则表达式的使用改变URI。可以同时存在一个或多个,按照顺序一次对URL进行匹配处理。

    flag:用来设置rewrite对url的处理行为,可选值如下

     

    rewrite_log指令

    该指令配置是否开启URL重写日志的输出功能。

    开启后,URL重写的相关日志将以notice级别输出到error_log指令配置的日志文件汇总。

     

    rewrite案例

    域名跳转

    效果:当我们访问京东网站时,输入www.jd.com,可以进入对应的网站,当输入www.360buy.comwww.jingdong.com时,也可以跳转到www.jd.com

    示例:

     

    域名镜像

    镜像网站指定是将一个完全相同的网站分别放置到几台服务器上,并分别使用独立的URL进行访问。其中一台服务器上的网站叫主站,其他的为镜像网站。镜像网站和主站没有太大的区别,可以把镜像网站理解为主站的一个备份节点。可以通过镜像网站提供网站在不同地区的响应速度。镜像网站可以平衡网站的流量负载、可以解决网络宽带限制、封锁等。而我们所说的域名镜像和网站镜像比较类似,上述案例中,将www.itheima.comwww.itheima.cn都能跳转到www.itcast.cn,那么www.itcast.cn我们就可以把它起名叫主域名,其他两个就是我们所说的镜像域名,当然如果我们不想把整个网站做镜像,只想为其中某一个子目录下的资源做镜像,我们可以在location块中配置rewrite功能,比如:

     

    独立域名

    一个完整的项目包含多个模块,比如购物网站有商品搜索模块、商品详情模块和购物车 模块等,那么我们如何为每一个模块设置独立的域名。

     

    目录自动添加“/”

    例子:

    在访问服务时,输入xxx/dir和访问xxx/dir/有什么区别?

    如果不加”/“,Nginx服务器内部会自动做一个301的重定向,重定向的地址会有一个指令server_name_in_redirecton|off;来决定重定向的地址:

    注意!这个参数在Nginx 0.8.48版本前默认值为on,之后版本为off,可以不用设置,如果使用0.8.48以前的版本,可以通过rewrite来解决这个问题。

     

    目录合并

    搜索引|擎优化(SEO)是一种利用搜索引擎的搜索规则来提高目的网站在有关搜索引擎内排名的方式。我们在创建自己的站点时,可以通过很多中方式来有效的提供搜索引擎优化的程度。其中有一项就包含URL的目录层级一般不要超过三层,否则的话不利于搜索引擎的搜索也给客户端的输入带来了负担,但是将所有的文件放在一个目录下又会导致文件资源管理混乱并且访问文件的速度也会随着文件增多而慢下来,这两个问题是相互矛盾的,那么使用rewrite如何解决上述问题?

    举例,网站中有一个资源文件的访问路径时/server/11/22/33/44/20.html,也就是说20.html存在于第5级目录下,如果想要访问该资源文件,客户端的URL地址就要写成http://192.168.200.133/server/11/22/33/44/20.html但是这个是非常不利于SEO搜索引擎优化的,同时客户端也不好记.使用rewrite我们可 以进行如下配置:

     

    防盗链

    在rewrite中的防盗链和之前将的原理其实都是一样的,只不过通过rewrite可以将防盗链的功能进行完善下,当出现防盗链的情况,我们可以使用rewrite将请求转发到自定义的一张图片和页面,给用户比较好的提示信息。下面我们就通过根据文件类型实现防盗链的一个配置实例:

     

    代理

    Nginx即可以实现正向代理,也可以实现反向代理

    正向代理代理的对象是客户端,反向代理代理的是服务端

    正向代理

    1. 准备两台服务器

    2. 配置服务端的nginx

    3. 配置代理服务器的nginx

    4. 在客户端配置代理服务器

       

     

    反向代理

    Nginx反向代理模块的指令是由ngx_http_proxy_module模块进行解析,这个模块在安装Nginx时已经被安装Nginx。

    反向代理的常用指令

    其他指令可以参考:https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html

    proxy_pass指令

    这个指令用来设置被代理的服务器地址,可以是主机名称,IP地址+端口号形式

    URL:要设置的被代理服务器地址,包括传输协议,主机名称/IP地址+端口,URI等

    例如:

    http://192.168.1.123/;是否需要加”/“?如果添加了”/“,location后的内容就不会被拼接到url后。

     

    proxy_set_header指令

    该指令用来更改Nginx服务器接收到的客户端的请求头信息,然后将新的请求头发送给代理的服务器。

    注意!如果想要看到结果,必须在被代理的服务器上来获取添加的头信息。

    被代理的服务器

    代理服务器

    在实际开发中,可以将客户端真实的IP端口等信息发送给服务端

     

    proxy_redirect指令

    该指令用来重置头信息中的”Location“和”Refresh“的值。

    在使用Nginx做反向代理功能时,有时会出现重定向的url不是我们想要的url,这时候就可以使用proxy_redirect进行url重定向设置了。proxy_redirect功能比较强大,其作用是对发送给客户端的URL进行修改!!

    在重定向后,服务端的IP地址会暴露在客户端,可以使用proxy_redirect将location值改为代理服务器。

    服务端

    代理服务器

    客户端
    代理服务器
    服务器一
    服务器二
    服务器三

    服务器1,2,3可以是内容一样的,也可以是内容不一样的。

    1. 如果内容一样,负载均衡策略进行分发。

    2. 如果内容不一样,可以根据用户的请求来分发到不同的服务器。

     

    反向代理优化

    反向代理值:Buffer和cache

    Buffer和cache的区别

    proxy_buffering

    该指令用来开启或关闭代理服务器的缓冲区

     

    proxy_buffers

    该指令用来指定单个连接从代理服务器读取响应的缓存区的个数和大小。

     

    proxy_buffer_size

    该指令用来设置从被代理服务器获取的第一部分响应数据的大小。保持与proxy_buffers中的size大小一致即可。也可以小一点。

     

    proxy_busy_buffers_size

    用来限制同时处于BUSY状态的缓冲区大小。

     

    proxy_temp_path

    当缓冲区满后,仍未被Nginx服务器完全接受,响应的数据会被临时存放在磁盘文件上,该指令用来设置文件的路径

    注意:path最大设置三层

     

    proxy_temp_file_write_size

    设置磁盘上缓冲文件的大小

     

    通用网站的设置

     

     

    Nginx安全控制

    Nginx反向代理如何来提升web服务器的安全?

    安全隔离

    什么是安全隔离?

    通过代理分开了客户端到应用程序服务器端的连接,实现了安全措施。在反向代理之前设置防火墙,仅留一个入口供代理服务器访问。

     

    SSL配置

    使用SSL对流量进行加密

    HTTPS是一种通过计算机网络进行安全通信的传输协议。它经由HTTP进行通信,利用SSL/TLS建立全通信,加密数据包,确保数据的安全性。

    上述这两个是为网络通信提供安全及数据完整性的一种安全协议,TLS和SSL在传输层和应用层对网络连接进行加密。

    为什么要使用https: http协议是明文传输数据,存在安全问题,而https是加密传输,相当于http+ss1,并且可以防止流量劫持。

    Nginx要想使用SSL,需要满足一个条件即需要添加一个模块--with-http_ss1_module,而该模块在编译的过程中需要OpenSSL的支持。

     

    nginx添加SSL支持

    添加--with-http_ss1_module模块

    SSL指令

    展示的是部分指令,更多指令请参阅官方文档。

    ssl

    该指令用来指定服务器开启HTTPS,可以使用 listen 443 ssl,

     

    ssl_certificate

    为当前主机指定一个带有PEM格式证书的证书

     

    ssl_certificate_key

    用来指定PEM secret key文件的路径

     

    ssl_session_cache

    该指令用来配置SSL会话的缓存

     

    ssl_session_timeout

    开启ssl会话功能后,设置客户端能够反复使用存储在缓存中的会话参数时间。

     

    ssl_ciphers

    指出允许的密码,密码指定为OpenSSL支持的格式

    可以使用openssl ciphers查看openssl支持的格式

     

    ssl_prefer_server_ciphers

    该指令指定是否服务器密码优先客户端密码。

     

    如何获取SSL证书?

    1. 通过阿里、腾讯等云服务商购买

    2. 使用openssl生成证书

       

    开启SSL实例

     

     

    ##

     

     

    负载均衡

    什么是负载均衡

    负载均衡(Load Balancing) 是一种分配网络或应用流量的技术,用于在多台服务器之间均匀分配工作负载,从而提高应用的可用性、可靠性和扩展性。其主要目的是避免单一服务器的负载过重,防止服务器出现瓶颈或故障,确保整个系统的稳定运行。

     

    系统扩展可以分为纵向扩展和横向扩展

     

    负载均衡的主要作用如下

     

    负载均衡常用方式

    用户手动选择

    在下载站上,一些下载地址提供不同线路,服务器连接等,让用户自己选择进行下载,实现负载均衡

     

    DNS轮询

    DNS:域名系统(服务)协议(DNS)是一种分布式网络目录服务,主要用于域名与IP地址的相互转换。

    大多域名注册商都支持对同一个主机名添加多条A记录,这就是DNS轮询,DNS服务器将解析请求按照A记录的顺序,随机分配到不同的IP上,这样就能完成简单的负载均衡。DNS轮询的成本非常低,在一些不重要的服务器,被经常使用。

    优点:

    缺点:

     

    四层/七层负载均衡

    OSI协议(开放系统互联(Open System Interconnection)),它是由ISO(国际标准化组织)定义的。

    对于OSI,人们按照功能不同,分工不同,人为的将OSI的分为七层。

    分层功能
    应用层网络服务与最终用户的一个接口(可理解为人机交互界面)
    表示层数据的表示,安全,压缩
    会话层建立,管理,终止会话
    传输层定义传输数据的协议端口号,以及流控和差错校验
    网络层进行逻辑地址寻址,实现不同网络之间的路径选择
    数据链路层建立逻辑连接,进行硬件地址寻址,差错校验等功能
    物理层建立,维护,断开物理连接

     

    四层负载均衡

    指的是OSI七层模型中的传输层,主要是基于IP+PORT的负载均衡

    实现四层负载均衡方式

     

    七层负载均衡

    指的是在应用层,主要基于虚拟的URL或主机IP的负载均衡

    实现七层负载均衡方式

     

    四层和七层负载均衡的区别

    四层负载均衡数据包是在底层就进行了分发,而七层负载均衡数据包则在最顶端进行分发,所以四层负载均衡的效率比七层负载均衡的要高 四层负载均衡不识别域名,而七层负载均衡识别域名。

     

    七层负载均衡

    Nginx要实现负载均衡需要用proxy_pass代理模块配置。Nginx默认安装支持这个模块。Nginx的负载均衡是在Nginx的反向代理基础上把用户的请求根据指定的算法发到一组【upstream虚拟服务池】。

     

    七层负载均衡指令

    七层负载均衡流程

    proxy_pass
    proxy_pass
    proxy_pass
    客户端
    Nginx负载均衡
    192.168.11.12:8080
    web服务一
    192.168.11.13:8081
    web服务二
    192.168.11.13:8082
    web服务三
    192.168.11.13:8083

    配置示例

     

    负载均衡状态

    代理服务器的负载均衡调度中有以下几种状态

    状态介绍
    down当前的server暂时不参与负载均衡
    backup预留的备份服务器
    max_fails允许请求失败的次数
    fail_timeout经过max_fails次失败后,服务暂停时间
    max_conns限制最大的接收连接数

     

     

    负载均衡策略

    Nginx的upstream支持以下几种分配算法

    算法名称说明
    轮询默认方式
    weight权重方式
    ip_hash依据IP分配方式
    least_conn依据最少连接方式
    url_hash依据URL分配方式
    fair依据响应时间方式

     

    示例

    这个策略适合请求处理时间长短不一而造成服务器过载的情况。

     

    四层负载均衡

    Nginx在1.9之后,增加了一个stream模块,用来实现四层协议的转发、代理、负载均衡等。stream模块的用法跟http的用法类似,允许我们配置一组TCP或者UDP等协议的监听,然后通过proxy_pass来转发我们的请求,通过upstream添加多个后端服务,实现负载均衡。四层协议负载均衡的实现,一般都会用到LVS、HAProxy、F5等,要么很贵要么配置很麻烦,而Nginx的配置相对来说更简单,更能快速完成工作。

    添加stream模块支持

    Nginx默认是没有编译这个模块的,需要使用到stream模块,那么需要在编译的时候加上--with-stream。

    完成添加--with-stream的实现步骤:

     

    四层负载均衡指令

    示例

     

     

    Nginx缓存集成

    缓存介绍

    缓存就是数据交换的缓冲区(称作:Cache)当用户要获取数据的时候,会先从缓存中去查询获取数据,如果缓存中有就会直接返回给用户,如果缓存中没有,则会发请求从服务器重新查询数据,将数据返回给用户的同时将数据放入缓存,下次用户就会直接从缓存中获取数据

    客户端
    缓存
    web服务

    缓存使用的场景有很多,例如

    场景作用
    操作系统磁盘缓存减少磁盘机械操作
    数据库缓存减少文件系统的IO操作
    应用程序缓存减少对数据库的查询
    Web服务器缓存减少对应用服务器请求次数
    浏览器缓存减少与后台的交互次数

    缓存的优点

    缓存的缺点

    客户端
    web服务器
    应用服务器
    数据库

    Nginx作为Web服务器,Nginx作为Web缓存服务器,它介于客户端和应用服务器之间,当用户通过浏览器访问一个URL时,Web缓存服务器会去应用服务器获取要展示给用户的内容,将内容缓存到自己的服务器上,当下一次请求到来时,如果访问的是同一个URL,Web缓存服务器就会直接将之前缓存的内容返回给客户端,而不是向应用服务器再次发送请求。web缓存降低了应用服务器、数据库的负载,减少了网络延迟,提高了用户访问的响应速度,增强了用户的体验。

     

    web缓存服务

    Nginx是从0.7.48版开始提供缓存功能。Nginx是基于ProxyStore来实现的,其原理是把URL及相关组合当做Key,在使用MD5算法对Key进行哈希,得到硬盘上对应的哈希目录路径,从而将缓存内容保存在该目录中。它可以支持任意URL连接,同时也支持404/301/302这样的非200状态码。Nginx即可以支持对指定URL或者状态码设置过期时间,也可以使用purge命令来手动清除指定URL的缓存。

     

    Nginx缓存相关命令

    Module ngx_http_proxy_module

    Nginx的web缓存服务主要是使用ngx_http_proxy_module模块相关指令集来完成,

     

    Nginx缓存清除

    方法一:手动删除对应的缓存目录

    方法二:使用第三方扩展模块

    nginx_cache_purge,这是一个第三方扩展模块,需要进行安装

    1. 下载nginx_cache_purge模块的资源包,并上传到服务器。

    2. 对资源文件进行解压缩

    3. 查询Nginx的配置操作

    4. 使用./configure进行参数配置

    5. 使用make进行编译

    6. 对原二进制可执行文件进行备份,出现问题时进行还原。

    7. 将编译后的objs中的二进制可执行文件拷贝到nginx的sbin目录下

    8. 使用make upgrade升级

     

    设置资源不缓存

    在生产环境下,并不是所有的数据都适合进行缓存的,你如一些经常发生变化的数据,如果进行缓存,可能会导致出现用户显示的数据和服务器实时数据不一致的问题。所以对于这些数据,在缓存的过程中就需要进行过滤,不进行缓存。

    相关指令

     

    以上两个指令都可以有一个或多个条件,这些条件中至少有一个不为空且不为0,则条件成立。

    说明

     

    配置实例

     

    服务器集群搭建

    Nginx与Tomcat部署

    Nginx在高并发场景和处理静态资源是非常高性能的,但是在实际项目中除了静态资源还有就是后台业务代码模块,一般后台业务都会被部署在Tomcat,weblogic或者是websphere等web服务器上。那么如何使用Nginx接收用户的请求并把请求转发到后台web服务器?

    客户端请求
    Nginx服务器
    Tomcat服务器

     

    直接访问tomcat就可以实现访问,为什么还要加入Nginx?

    1. 使用Nginx实现动静分离

    2. 使用Nginx搭建Tomcat集群

     

     

     

    Nginx实现动静分离

    动静分离介绍

    动静分离是指将动态内容和静态内容分开处理的一种方式。通常,动态内容是指由服务器端处理的,例如动态生成的网页、数据库查询等。静态内容是指不需要经过服务器端处理的,例如图片、CSS、JavaScript文件等。通过将动态内容和静态内容分开处理,可以提高服务器的性能和响应速度。

    在动静分离中,通常将Nginx作为前端服务器,将静态内容直接由Nginx处理并返回给客户端,而动态内容则交给后端服务器(如应用服务器)处理。Nginx可以通过配置来指定哪些请求是静态内容,这样它就可以直接从磁盘中读取并返回相应的文件,而不需要将请求转发给后端服务器。

     

    为什么使用动态分离

    Nginx在处理静态资源的时候,效率是非常高的,而且Nginx的并发访问量也是名列前茅,而Tomcat则相对比较弱一些,所以把静态资源交个Nginx后,可以减轻Tomcat服务器的访问压力并提高静态资源的访问速度。动静分离以后,降低了动态资源和静态资源的耦合度。如动态资源岩机了也不影响静态资源的展示。

     

    如何实现动静分离

    实现动静分离的方式很多,比如静态资源可以部署到CDN、Nginx等服务器上,动态资源可以部署到Tomcat,weblogic或者websphere上。

     

    需求:

    image-20250127182006086

    动静分离就是根据一定规则静态资源的请求全部请求Nginx服务器,后台数据请求转发到Web应用服务器上。从而达到动静分离的目的。目前比较流行的做法是将静态资源部署在Nginx上,而Web应用服务器只处理动态数据请求。这样减少Web应用服务器的并发压力。具体如下图所示:

    1633743657(1).png

    配置Nginx动静分离

    Nginx配置如下所示:

    示例2

    在Nginx 下 创建 static 目录,将图片,js, css 等文件 拷贝到该目录下

     

    Nginx搭建Tomcat集群

    Tomcat集群能带来什么:

    提高服务的性能,例如计算处理能力、并发能力等,以及实现服务的高可用性 提供项目架构的横向扩展能力,增加集群中的机器就能提高集群的性能 Tomcat集群实现方式:

    Tomcat集群的实现方式有多种,最简单的就是通过Nginx负载进行请求转发来实现

     

    Tomcat单机架构图: img

    如果这一台Tomcat的真的宕机了,整个系统就会不完整,所以如何解决上述问题,一台服务器容易岩机,那就多搭建几台Tomcat服务器,这样的话就提升了后的 服务器的可用性。这也就是我们常说的集群,搭建Tomcat的集群需要用到了Nginx的反向代理和负载均衡

     

    常见的Tomcat集群解决方案:

    采用 nginx 中的 ip hash policy 来保持某个ip始终连接在某一个机器上 优点:可以不改变现有的技术架构,直接实现横向扩展,省事。但是缺陷也很明显,在实际的生产环境中,极少使用这种方式 缺点:1.单止服务器请求(负载)不均衡,这是完全依赖 ip hash 的结果。2.客户机ip动态变化频繁的情况下,无法进行服务,因为可能每次的ip hash都不一样,就无法始终保持只连接在同一台机器上。 采用redis或memchche等nosql数据库,实现一个缓存session的服务器,当请求过来的时候,所有的Tomcat Server都统一往这个服务器里读取session信息。这是企业中比较常用的一种解决方案,所以大致的Tomcat集群的架构图如下:

    img

     

     

    Nginx高可用解决方案

    在Tomcat集群中,如果负责Nginx发生故障,依然会造成服务无法访问问题。

    为解决这一问题,需要两台以上的Nginx服务器对外提供服务,这样的话就可以解决其中一台宕机了,另外台还能对外提供服务,但是如果是两台Nginx服务器的话,会有两个IP地址,用户改访问那台服务器,如何判断那台服务器时好的,那台服务器时出现故障的?

     

    keepalived

    为解决以上问题,可以使用keepalived来解决。

    什么是keepalived?

    Keepalived是集群管理中保证集群高可用的一个服务软件,用来防止单点故障。它可以自动检测集群中服务器的健康状况,比如主从模式时,当主服务器发生故障时,Keepalived会根据服务器的VRRP优先级来选举一个从服务器成为主服务器,实现主从的无缝切换,保证持续的提供服务,并且Keepalived也会及时的通过邮件通知到相关负责人进行维护出现问题的服务器。 Keepalived软件起初是专为LVS负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点的状态,后来又加入了可以实现高可用的VRRP功能。因此,Keepalived除了能够管理LVS软件外,还可以作为其他服务(例如:Nginx、Haproxy、MySQL等)的高可用解决方案软件。
    Keepalived软件主要是通过VRRP协议实现高可用功能的。VRRP是Virtual Router Redundancy Protocol(虚拟路由器冗余协议)的缩写,VRRP出现的目的就是为了解决静态路由单点故障问题的,它能够保证当个别节点宕机时,整个网络可以不间断地运行。所以,Keepalived一方面具有配置管理LVS的功能,同时还具有对LVS下面节点进行健康检查的功能,另一方面也可实现系统网络服务的高可用功能。(因此Keepalived在给Nginx,Haproxy做高可用的时候,仅仅 只是用了keepalived的VRRP协议。)

     

    示例:

    img

     

    keepalived安装

    1. 进入keepalived官网,下载keepalived

    2. 将下载好的资源上传到服务器

    3. 将keepalived压缩包进行解压缩操作。

    4. 进入解压好的文件夹,对keepalived配置,编译,安装

       

     

     

     

     

     

    Nginx制作下载站点

    ubuntu安装包下载_开源镜像站-阿里云

    该网站主要供用户来下载相关资源的网站,叫做下载网站。

     

    如何制作下载站?

    在nginx中使用模块ngx_autoindex_module来实现该功能,该模块处理以斜杠(“/”)结尾的请求,并生成目录列表

    Nginx在编译时,会自动加载该模块,但该模块默认为关闭,需要手动进行开启。

    1. autoindex 开启或关闭目录列表输出

       

    2. autoindex_exact_size: 对应HTML格式指定是否在目录列表展示文件的大小 默认on,显示文件具体大小,单位bytes 设为off,显示文件的大概大小,单位:KB,MB或GB

       

    3. autoindex_format 设置目录的格式

      该指令在1.7.9后可用

    4. autoindex_localtime 设置HTML格式,是否在目录列表是显示时间。 默认值为off,显示的文件时间为GMT时间 改为on后,显示服务器时间

     

    配置实例

     

    用户认证模块

    对于系统资源的访问,我们往往需要限制访问权限,对用户进行认证。认证判断用户是否为合法用户,如果是合法用户就放行操作,否则就拒绝访问。

    Nginx使用ngx_htto_auth_basic_module模块来实现该功能,它允许通过使用"HTTP基本身份协议"验证用户名和密码来限制对资源的访问。默认情况下,Nginx安装了这个模块。

    相关指令

    实现步骤实例:

    1. 在Nginx.conf中的配置如下

    2. 使用htpasswd工具生成

      操作示例:

       

     

     

    Nginx扩展模块

    nginx是可扩展的,可用于处理各种使用场景,下面介绍的是使用lua扩展Nginx的功能

    Lua简介

    概念

    Lua是一种轻量小巧的脚本语言,用C语言编写并以源码形式开发。设计的目的是为了嵌入其他应用程序,从而为应用程序提供灵活的扩展和定制功能

    特征

    和其他语言相比,Lua有其自身的特点:

    1. 轻量级

    2. 可扩展

    3. 支持面向过程的编程和函数式编程。

     

    应用场景

    Lua在不同场景的系统中得到大量应用,应用场景如下:

     

    Lua安装

    官网

    The Programming Language Lua

    使用wget下载压缩包

    编译和安装

     

    Lua案例和使用

    lua交互式编程可以使用lua -ilua启用

    在命令行输出Hello world

    Lua语法

    Lua注释

     

    标识符

    Lua定义变量名以一个字母A到Z或a到z或下划线_开头后加上0个或多个字母,下划线,数字(0到9)。这块建议大家最好不要使用 下划线加大写字母的标识符,因为Lua的保留字也是这样定义的,容易发生冲突。注意Lua是区分大小写字母的。

     

    常用关键字

    andbreakdoelse
    elseifendfalsefor
    functionifinlocal
    nilnotorrepeat
    returnthentrueuntil
    whilegoto  

     

    运算符

    Lua支持算术运算符,关系运算符,逻辑运算符,其他运算符。 使用方法和其他编程语言类似,这里不再过多赘述。

    特殊:

     

    全局变量

    在Lua语言中,全局变量无需声明即可使用

    在默认情况下,变量总是认为是全局的,如果未提前赋值,默认为nil

    若想要声明一个局部变量,需要使用local来声明

     

    Lua数据类型

    Lua中有八种数据类型

     

    使用type()可以输出变量的数据类型。

     

    Lua控制结构

    Lua语言提供了一组精简且常用的控制结构,包括用于条件执行的证以及用于循环的while、repeat和for。所有的控制结构语法上都有一个显式的终结符:end用于终结if、for及while结构,until用于终结repeat结构。

    条件判断

     

    循环

    ngx_lua

    淘宝开发的ngx_lua模块通过将lua解释器集成进Nginx,可以采用lua脚本实现业务逻辑,由于lua的紧凑、快速以及内建协程,所以在保证高并发服务能力的同时极大地降低了业务逻辑实现成本。

    ngx_lua模块环境

     

    ngx_lua指令

    img

    注意:*的作用

    init_by_lua*
    init_worker_by_lua*
    set_by_lua*
    rewrite_by_lua*
    access_by_lua*
    content_by_lua*
    header_filter_by_lua*
    body_filter_by_lua*
    log_by_lua*
    balancer_by_lua*
    ssl_certificate_by_*
    需求:

    实现代码

     

    ngx_lua操作Redis

    Redis在系统中经常作为数据缓存、内存数据库使用,在大型系统中扮演着非常重要的作用。在Nginx核心系统中,Redis是常备组件。Nginx支持3种方法访问Redis,分别是HttpRedis模块、HttpRedis2Module、lua-resty-redis库。这三种方式中HttpRedis模块提供的指令少,功能单一,适合做简单缓存,HttpRedis2Module模块比HttpRedis模块操作更灵活,功能更强大。而Lua-resty-redis库是OpenResty提供的一个操作Redis的接口库,可根据自己的业务情况做一些逻辑处理,适合做复杂的业务逻辑。

     

     

    ngx_lua操作Mysql

    在ngx_lua中,Mysql的访问方式有两种

    1. 使用ngx_lua模块和lua_resty_mysql模块,这两个模块在OpenRestry安装时就默认安装了。

    2. 使用drizzle_nginx_module(HttpDrizzleModule)模块,需要单独进行安装。

     

    lua_resty_mysql

    lua_resty_mysql是OpenRestry开发的模块,使用灵活,功能强大,适合复杂的业务场景,同时支持存储过程的访问。

    使用lua_resty_mysql实现数据库查询

    1. 准备Mysql环境。

    2. 在Mysql中创建数据库和表,并在表中添加数据。

      相关API

      配置实例

       

     

    lua_cjson

    使用lua_cjson处理查询结果

    read_result()得到的结果res都是table类型,要想在页面上展示,就必须知道table的具体数据结构才能遍历获取。处理起来比较麻烦。可以使用cjson,它可以将table类型转换成json字符串,把json字符串显示在页面上。

    使用方法

    1. 引入cjson

    2. 调用cjson的encode方法进行类型转换

    3. 配置示例

       

    实现数据库增删改

    优化send_query和read_result

    本方法是send_query和read_result组合的快捷方法。

    语法:

    有了该API,上面的代码我们就可以进行对应的优化,如下:

     

     

    综合案例

    使用ngx_lua模块完成Redis缓存预热。

    分析:

    (1)先得有一张表(users)

    (2)浏览器输入如下地址

    (3)从表中查询出符合条件的记录,此时获取的结果为table类型

    (4)使用cjson将table数据转换成json字符串

    (5)将查询的结果数据存入Redis中

     

     

    本教程到此结束,感谢使用!

    文档最后修改时间2025年2月1日

    文档字数:约28700字