Nginx安装部署与配置管理

一、HTTP 介绍

HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。

HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 音视频文件等)。

1、HTTP 工作原理

HTTP协议工作于客户端-服务端架构上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。

可以实现 Web服务器 软件有:

  • 一般部署在 Linux 环境下的有

    • Nginx,Apache 推出的 HTTPD 软件包处理静态页面(HTM、 CSS文件、JavaScript 文件、 图片文件等)
    • Tomcat 一般用于处理 Java 语言编写的动态网站。
  • Windos Server 环境下

    • IIS服务器(Internet Information Services)是 微软开发的部署在 Windows Server 操作系统上的一个服务。

Web服务器根据接收到的请求后,向客户端发送响应信息。

HTTP协议规定,服务的默认端口号为80,但是你也可以改为8080或者其他端口。

HTTP三点注意事项:

  • HTTP是无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
  • HTTP是无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

以下图表展示了HTTP协议通信流程:

Nginx安装部署与配置管理_第1张图片

2、HTTP 消息结构

HTTP是基于客户端/服务端(C/S)的架构模型,通过一个可靠的链接来交换信息,是一个无状态的请求/响应协议。

一个HTTP"客户端"是一个应用程序(Web浏览器或其他任何客户端),通过连接到服务器达到向服务器发送一个或多个HTTP的请求的目的。

一个HTTP"服务器"同样也是一个应用程序(通常是一个Web服务,如Apache Web服务器或IIS服务器等),通过接收客户端的请求并向客户端发送HTTP响应数据。

HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。

3、客户端请求消息

客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行(request line)、请求头部(header)、空行和请求数据四个部分组成,下图给出了请求报文的一般格式。
Nginx安装部署与配置管理_第2张图片

4、服务器响应消息

HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。

Nginx安装部署与配置管理_第3张图片

实例

看公共课项目代码

5、HTTP 请求方法

根据HTTP标准,HTTP请求可以使用多种请求方法。

HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。

HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qfx4q7aS-1591978467549)(assets/1561896279402.png)]

6、HTTP 响应头信息

应答头 说明
Allow(掌握) 服务器支持哪些请求方法(如GET、POST等)。
Content-Encoding(掌握) 文档的字符编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型。可以利用gzip对响应内容进行压缩,这样能够显著地减少HTML文档的下载时间,通样也节省了网络流量。Java的GZIPOutputStream可以很方便地进行gzip压缩。但是也比较旧的浏览器(比如 IE4 之前的浏览器)不支持 gzip, 因此,Servlet应该通过查看Accept-Encoding头(即request.getHeader(“Accept-Encoding”))检查浏览器是否支持gzip,为支持gzip的浏览器返回经gzip压缩的HTML页面,为其他浏览器返回普通页面。
Content-Length(掌握) 表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。如果你想要利用持久连接的优势,可以把输出文档写入 ByteArrayOutputStream,完成后查看其大小,然后把该值放入Content-Length头,最后通过byteArrayStream.writeTo(response.getOutputStream()发送内容。
Content-Type(重点掌握) 表示POST请求或者响应的文档内容属于什么MIME类型。Servlet默认为text/plain,但通常需要显式地指定为text/html。由于经常要设置Content-Type,因此HttpServletResponse提供了一个专用的方法setContentType。
Date(掌握) 当前的GMT时间。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦。
Expires 告诉客户端,应该在什么时候认为文档已经过期,从而不再缓存它,而发送一次新的HTTP请求。
Last-Modified 文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,只有改动时间迟于指定时间的文档才会返回,否则返回一个304(Not Modified)状态。Last-Modified也可用setDateHeader方法来设置。
Location(掌握) 表示客户应当到哪里去提取文档。Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。
Refresh 表示浏览器应该在多少时间之后刷新文档,以秒计。除了刷新当前文档之外,你还可以通过setHeader(“Refresh”, “5; URL=http://host/path”)让浏览器读取指定的页面。 注意这种功能通常是通过设置HTML页面HEAD区的<META HTTP-EQUIV=“Refresh” CONTENT=“5;URL=http://host/path">实现,这是因为,自动刷新或重定向对于那些不能使用CGI或Servlet的HTML编写者十分重要。但是,对于Servlet来说,直接设置Refresh头更加方便。 注意Refresh的意义是"N秒之后刷新本页面或访问指定页面”,而不是"每隔N秒刷新本页面或访问指定页面"。因此,连续刷新要求每次都发送一个Refresh头,而发送204状态代码则可以阻止浏览器继续刷新,不管是使用Refresh头还是<META HTTP-EQUIV=“Refresh” …>。 注意Refresh头不属于HTTP 1.1正式规范的一部分,而是一个扩展,但Netscape和IE都支持它。
Server(掌握) 服务器名字。Servlet一般不设置这个值,而是由Web服务器自己设置。
Set-Cookie 设置和页面关联的Cookie。Servlet不应使用response.setHeader(“Set-Cookie”, …),而是应使用HttpServletResponse提供的专用方法addCookie。参见下文有关Cookie设置的讨论。
WWW-Authenticate 客户应该在Authorization头中提供什么类型的授权信息?在包含401(Unauthorized)状态行的应答中这个头是必需的。例如,response.setHeader(“WWW-Authenticate”, “BASIC realm=\“executives\””)。 注意Servlet一般不进行这方面的处理,而是让Web服务器的专门机制来控制受密码保护页面的访问(例如.htaccess)。

7、HTTP 状态码

当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应浏览器的请求。

HTTP状态码的英文为HTTP Status Code。

注意:状态码及其包含的含义,只是 HTTP 协议中规定的而已。实际开发网站时,大家都遵守这样的规定,这样便于沟通传递信息。

下面是常见的HTTP状态码及其含义:

  • 200 - 请求成功
  • 301 - 资源(网页等)被永久转移到其它URL
  • 302 - 请求的资源被临时重定向到其他 URL
  • 403 - 无权获取请求的资源
  • 404 - 请求的资源(网页等)不存在
  • 500 - 内部服务器错误(一般是开发写的程序代码出现了错误)

HTTP状态码分类

HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型。HTTP状态码共分为5种类型:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aTmhy4ux-1591978467554)(assets/1561896413177.png)]

HTTP状态码列表:

状态码 状态码英文名称 中文描述
100 Continue 继续。客户端应继续其请求
101 Switching Protocols 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议
200 OK 请求成功。一般用于GET与POST请求
201 Created 已创建。成功请求并创建了新的资源
202 Accepted 已接受。已经接受请求,但未处理完成
203 Non-Authoritative Information 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本
204 No Content 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档
205 Reset Content 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域
206 Partial Content 部分内容。服务器成功处理了部分GET请求
300 Multiple Choices 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择
301 Moved Permanently 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
302 Found 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI
303 See Other 查看其它地址。与301类似。使用GET和POST请求查看
304 Not Modified 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
305 Use Proxy 使用代理。所请求的资源必须通过代理访问
306 Unused 已经被废弃的HTTP状态码
307 Temporary Redirect 临时重定向。与302类似。使用GET请求重定向
400 Bad Request 客户端请求的语法错误,服务器无法理解
401 Unauthorized 请求要求用户的身份认证
402 Payment Required 保留,将来使用
403 Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求
404 Not Found 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
405 Method Not Allowed 客户端请求中的方法被禁止
406 Not Acceptable 服务器无法根据客户端请求的内容特性完成请求
407 Proxy Authentication Required 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权
408 Request Time-out 服务器等待客户端发送的请求时间过长,超时
409 Conflict 服务器完成客户端的PUT请求是可能返回此代码,服务器处理请求时发生了冲突
410 Gone 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置
411 Length Required 服务器无法处理客户端发送的不带Content-Length的请求信息
412 Precondition Failed 客户端请求信息的先决条件错误
413 Request Entity Too Large 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息
414 Request-URI Too Large 请求的URI过长(URI通常为网址),服务器无法处理
415 Unsupported Media Type 服务器无法处理请求附带的媒体格式
416 Requested range not satisfiable 客户端请求的范围无效
417 Expectation Failed 服务器无法满足Expect的请求头信息
500 Internal Server Error 服务器内部错误,无法完成请求
501 Not Implemented 服务器不支持请求的功能,无法完成请求
502 Bad Gateway 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
503 Service Unavailable 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
504 Gateway Time-out 充当网关或代理的服务器,未及时从远端服务器获取请求
505 HTTP Version not supported 服务器不支持请求的HTTP协议的版本,无法完成处理

二、nginx 服务

1、nginx 介绍

Nginx安装部署与配置管理_第4张图片

Nginx (engine x) 是一个轻量级,高性能的 HTTP 和 反向代理 服务,也是一个IMAP/POP3/SMTP服务(这是初衷)。因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。

创始人伊戈尔·赛索耶夫
Nginx安装部署与配置管理_第5张图片

2、为什么选择 nginx

Nginx 是一个高性能的 Web 和反向代理服务器, 它具有很多非常优越的特性:

单机环境下。 并发连接数在7000+ -8000左右。 集群模式20000+

作为 Web 服务器:相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效率,这点使 Nginx 尤其受到虚拟主机提供商的欢迎。能够支持高达 50,000 个并发连接数(官方宣称)的响应。

作为负载均衡服务器:Nginx 既可以在内部直接支持 PHP,也可以支持作为 HTTP代理服务器 对外进行服务。

作为邮件代理服务器: Nginx 同时也是一个非常优秀的邮件代理服务器(最早开发这个产品的目的之一也是作为邮件代理服务器)。

Nginx 安装非常的简单,配置文件 非常简洁(还能够支持Perl语言的语法),Bug非常少的服务器: Nginx 启动特别容易,并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动。你还能够在 不间断服务的情况下进行软件版本的升级。

3、高并发实现方式

1、I/O multiplexing【多并发】

第一种方法就是最传统的多线程并发模型 (每进来一个新的I/O流会分配一个新的线程管理。)

Nginx安装部署与配置管理_第6张图片
第二种方法就是I/O多路复用 (单个线程,通过记录跟踪每个I/O流(sock)的状态,来同时管理多个I/O流 。)

I/O multiplexing 这里面的 multiplexing 指的其实是在单个线程通过记录跟踪每一个Sock(I/O流)的状态来同时管理多个I/O流。发明它的原因,是尽量多的提高服务器的吞吐能力。在同一个线程里面, 通过拨开关的方式,来同时传输多个I/O流
Nginx安装部署与配置管理_第7张图片

2、一个请求到来了,nginx使用epoll接收请求的过程是怎样的?

ngnix会有很多连接进来, epoll会把他们都监视起来,然后像拨开关一样,谁有数据就拨向谁,然后调用相应的代码处理。

  • epoll.

epoll 可以说是I/O 多路复用最新的一个实现,epoll 修复了poll 和select绝大部分问题, 比如:

• epoll 现在是线程安全的。

• epoll 现在不仅告诉你socket组里面数据,还会告诉你具体哪个socket有数据,你不用自己去找了。

3、异步,非阻塞

$ pstree |grep nginx
|-+= 81666 root nginx: master process nginx
| |— 82500 nobody nginx: worker process
| — 82501 nobody nginx: worker process

1个master进程,2个work进程

​ 每进来一个request,会有一个worker进程去处理。但不是全程的处理,处理到什么程度呢?处理到可能发生阻塞的地方,比如向上游(后端)服务器转发request,并等待请求返回。那么,这个处理的worker不会这么一直等着,他会在发送完请求后,注册一个事件:“如果upstream返回了,告诉我一声,我再接着干”。于是他就休息去了。这就是异步。此时,如果再有request 进来,他就可以很快再按照相同的这种方式处理。这就是非阻塞和IO多路复用。而一旦上游服务器返回了,就会触发这个事件,worker才会来接手,这个request才会接着往下走。这就是异步回调。

nginx安装部署和配置管理

1、nginx部署-Yum安装

访问nginx的官方网站:http://www.nginx.org/

Nginx版本类型

Mainline version: 主线版,即开发版

Stable version: 最新稳定版,生产环境上建议使用的版本

Legacy versions: 遗留的老版本的稳定版
Nginx安装部署与配置管理_第8张图片
Yum安装nginx

配置Yum源的官网:http://nginx.org/en/linux_packages.html

1、配置nginx的Yum源

安装说明

在新计算机上首次安装nginx之前,需要设置nginx软件包存储库。 之后,您可以从存储库安装和更新nginx。

RHEL/CENTOS

Install the prerequisites:

sudo yum install yum-utils -y
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
sudo yum install nginx -y

这里我们用稳定版本

[root@nginx-server yum.repos.d]# yum install -y nginx

[root@nginx-server yum.repos.d]# nginx -V    //格式化打印
nginx version: nginx/1.16.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'

[root@nginx-server yum.repos.d]# nginx -v
nginx version: nginx/1.16.0

关闭防火墙和selinux:**

[root@nginx-server ~]# getenforce
Enforcing

[root@nginx-server ~]# sed -i ‘/SELINUX=/ c /SELINUX=disabled/’ /etc/selinux/config

[root@nginx-server ~]# systemctl stop firewalld
[root@nginx-server ~]# systemctl disable firewalld

启动并设置开机启动

[root@nginx-server ~]# systemctl start nginx
[root@nginx-server ~]# systemctl enable nginx

浏览器输入ip访问:
Nginx安装部署与配置管理_第9张图片

2、nginx 编译安装与配置使用

1、安装编译环境

yum -y install gcc gcc-c++

2、安装pcre软件包(使nginx支持http rewrite模块)

yum install -y pcre pcre-devel gd-devel

3、安装openssl-devel(使nginx支持ssl)

yum install -y openssl openssl-devel

4、安装zlib

yum install -y zlib zlib-devel

5、创建用户nginx

useradd nginx

passwd nginx

6、安装nginx

[root@localhost ~]# wget http://nginx.org/download/nginx-1.16.0.tar.gz
[root@localhost ~]# tar xzf nginx-1.16.0.tar.gz -C /usr/local/src/
[root@localhost ~]# cd /usr/local/src/nginx-1.16.0/
[root@localhost nginx-1.16.0]# ./configure --prefix=/usr/local/nginx --group=nginx --user=nginx --sbin-path=/usr/local/nginx/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/tmp/nginx/client_body --http-proxy-temp-path=/tmp/nginx/proxy --http-fastcgi-temp-path=/tmp/nginx/fastcgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-pcre --with-http_realip_module --with-stream
[root@localhost nginx-1.16.0]# make -j 2 && make install

7、Nginx 编译参数

# 查看 nginx 安装的模块
[root@localhost ~]#/usr/local/nginx/sbin/nginx -V
//指定程序的安装目录
--prefix=/usr/local/nginx    
//指定配置文件路径
--conf-path=/etc/nginx/nginx.conf 
//指定访问日志
--http-log-path=/var/log/nginx/access.log   
//指定错误日志
--error-log-path=/var/log/nginx/error.log

//指定lock文件
--lock-path=/var/lock/nginx.lock    

//指定pid文件
--pid-path=/run/nginx.pid                        

//设定http客户端请求临时文件路径
--http-client-body-temp-path=/var/lib/nginx/body  

//设定http fastcgi 模块文件路径
//用于转发 PHP 编写的 web 应用程序的请求(动态网站)
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi    

//设定http代理临时文件路径
--http-proxy-temp-path=/var/lib/nginx/proxy    

//设定http scgi临时文件路径
--http-scgi-temp-path=/var/lib/nginx/scgi  

//设定 http uwsgi 模块的文件路径
//用于转发 Python 编写的 web 应用程序的请求(动态网站)
--http-uwsgi-temp-path=/var/lib/nginx/uwsgi

//启用debug日志
--with-debug

//编译PCRE包含“just-in-time compilation”
--with-pcre-jit

//启用ipv6支持
--with-ipv6

//启用ssl支持
--with-http_ssl_module

//获取nginx自上次启动以来的状态
--with-http_stub_status_module

//允许从请求标头更改客户端的IP地址值,默认为关
--with-http_realip_module

//实现基于一个子请求的结果的客户端授权。
// 如果该子请求返回的2xx响应代码,所述接入是允许的。
//如果它返回401或403中,访问被拒绝与相应的错误代码。
//由子请求返回的任何其他响应代码被认为是一个错误。
--with-http_auth_request_module

//作为一个输出过滤器,支持不完全缓冲,分部分响应请求
--with-http_addition_module

//增加PUT,DELETE,MKCOL:创建集合,COPY和MOVE方法 默认关闭,需编译开启
--with-http_dav_module

//使用预编译的MaxMind数据库解析客户端IP地址,得到变量值
--with-http_geoip_module

//它为不支持“gzip”编码方法的客户端解压具有“Content-Encoding: gzip”头的响应。
--with-http_gunzip_module

//在线实时压缩输出数据流
--with-http_gzip_static_module

//传输JPEG/GIF/PNG 图片的一个过滤器)(默认为不启用。gd库要用到)
--with-http_image_filter_module

//SPDY可以缩短网页的加载时间
--with-http_spdy_module

//允许用一些其他文本替换nginx响应中的一些文本
--with-http_sub_module

//过滤转换XML请求
--with-http_xslt_module

//启用POP3/IMAP4/SMTP代理模块支持
--with-mail

//启用ngx_mail_ssl_module支持启用外部模块支持
--with-mail_ssl_module

8、修改配置文件/etc/nginx/nginx.conf

# 全局参数设置
user nginx;  #设置nginx使用的用户
worker_processes  4;          #设置nginx启动进程的数量,一般设置成与逻辑cpu数量相同 
error_log  logs/error.log;    #指定错误日志 
worker_rlimit_nofile 1024;  #设置一个nginx进程能打开的最大文件数 
pid        /var/run/nginx.pid; 
events { 
    worker_connections  1024; #设置一个进程的最大并发连接数 
}
# http 服务相关设置 
http { 
    include      mime.types; 
    default_type  application/octet-stream; 
    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;    #设置访问日志的位置和格式 
    sendfile          on; #是否调用sendfile函数输出文件,一般设置为on,若nginx是用来进行磁盘IO负载应用时,可以设置为off,降低系统负载 
    gzip              on;      #是否开启gzip压缩,将注释去掉开启 
    keepalive_timeout  65;     #设置长连接的超时时间
# 虚拟服务器的相关设置 
    server { 
        listen      80;        #设置监听的端口 
        server_name  localhost;        #设置绑定的主机名、域名或ip地址 
        charset koi8-r;        # 设置编码字符 
        location / { 
            root  /var/www/nginx;           #设置服务器默认网站的根目录位置,需要手动创建
            index  index.html index.htm;    #设置默认打开的文档 
            } 
        error_page  500 502 503 504  /50x.html; #设置错误信息返回页面 
        location = /50x.html { 
            root  html;        #这里的绝对位置是/usr/local/nginx/html
        } 
    } 
 }
nginx.conf的组成:nginx.conf一共由三部分组成,分别为:
- 全局块
- events块
- http块。

在http块中又包含
- http全局块
- 多个server块

每个server块中又包含
- server全局块
- 以及多个location块

在统一配置块中嵌套的配置块之间不存在次序关系。

检测nginx配置文件是否正确

[root@localhost ~]# /usr/local/nginx/sbin/nginx -t
[root@localhost ~]# mkdir -p /tmp/nginx

10、启动nginx服务

[root@localhost ~]# /usr/local/nginx/sbin/nginx

11、通过 nginx 命令控制 nginx 服务

nginx -c /path/nginx.conf  	     # 以特定目录下的配置文件启动nginx:
nginx -s reload            	 	 # 修改配置后重新加载生效
nginx -s stop  				 	 # 快速停止nginx
nginx -s quit  				  	 # 完整有序的停止nginx
nginx -t    					 # 测试当前配置文件是否正确
nginx -t -c /path/to/nginx.conf  # 测试特定的nginx配置文件是否正确

注意:
nginx -s reload 命令加载修改后的配置文件,命令下达后发生如下事件
1. Nginx的master进程检查配置文件的正确性,若是错误则返回错误信息,nginx继续采用原配置文件进行工作(因为worker未受到影响)
2. Nginx启动新的worker进程,采用新的配置文件
3. Nginx将新的请求分配新的worker进程
4. Nginx等待以前的worker进程的全部请求已经都返回后,关闭相关worker进程
5. 重复上面过程,知道全部旧的worker进程都被关闭掉

12、nginx 日志文件详解

​ nginx 日志文件分为 log_formataccess_log 两部分

​ log_format 定义记录的格式,其语法格式为

​ log_format 样式名称 样式详情

​ 配置文件中默认有

log_format  main  'remote_addr - remote_user [time_local] "request" '
                  'status body_bytes_sent "$http_referer" '
                  '"http_user_agent" "http_x_forwarded_for"';

Nginx安装部署与配置管理_第10张图片
在这里插入图片描述

3、使用 limit_rate 限制客户端传输数据的速度

1、编辑/etc/nginx/nginx.conf

location / {
            root   /var/www/nginx/;
            index  index.html index.htm;
            limit_rate  2k;  #对每个连接的限速为2k/s
        }

重启服务

注意要点:

  • ​ 配置文件中的每个语句要以 ; 结尾

    7、nginx 虚拟机配置

什么是虚拟主机?
虚拟主机是一种特殊的软硬件技术,它可以将网络上的每一台计算机分成多个虚拟主机,每个虚拟主机可以独立对外提供www服务,这样就可以实现一台主机对外提供多个web服务,每个虚拟主机之间是独立的,互不影响。

Nginx安装部署与配置管理_第11张图片
nginx可以实现虚拟主机的配置,nginx支持三种类型的虚拟主机配置。
1、基于域名的虚拟主机 (server_name来区分虚拟主机——应用:外部网站)
2、基于ip的虚拟主机, (一块主机绑定多个ip地址)
3、基于端口的虚拟主机 (端口来区分虚拟主机——应用:公司内部网站,外部网站的管理后台)

1、 基于域名的虚拟主机

1、配置通过域名区分的虚拟机

[root@localhost ~]# cat /etc/nginx/nginx.conf
user nginx;
worker_processes  auto;

#error_log  logs/error.log;
worker_rlimit_nofile 102400;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;
    
    server {
        listen       80;
        server_name  web.testpm.com;
        location / {
            root   /var/www/nginx/;
            index  index.html index.htm;
            limit_rate	2k;
        	}
        }
    
    server {
        listen       80;
        server_name  web.1000phone.com;
        location / {
            root   /1000phone/html;
            index  index.html index.htm;
        	}
        }
}

2、 为 域名为 web.1000phone.com 的虚拟机,创建 index 文件

[root@localhost ~]# mkdir -p /1000phone/html
[root@localhost ~]# vim /1000phone/html/index.html
<html>
<p>
this is my 1000phone
</p>
</html>

3、重新加载配置文件

# 如果编译安装的执行
[root@nginx]# /usr/local/nginx/sbin/nginx -s reload
# 如果 yum 安装的执行
[root@nginx]# nginx -s reload

4、客户端配置路由映射
在 C:\Windows\System32\drivers\etc\hosts 文件中添加两行(linux:/etc/hosts)

10.0.105.199 web.testpm.com
10.0.105.199 web.1000phone.com

5、 测试访问

浏览器输入:http://web.testpm.com/

浏览器输入:http://web.1000phone.com/

2、 基于ip的虚拟主机

[root@localhost ~]# ip a 
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:17:f1:af brd ff:ff:ff:ff:ff:ff
    inet 10.0.105.199/24 brd 10.0.105.255 scope global dynamic ens33
       valid_lft 81438sec preferred_lft 81438sec
    inet6 fe80::9d26:f3f0:db9c:c9be/64 scope link 
       valid_lft forever preferred_lft forever
[root@localhost ~]# ifconfig ens33:1 10.0.105.201/24
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.105.199  netmask 255.255.255.0  broadcast 10.0.105.255
        inet6 fe80::9d26:f3f0:db9c:c9be  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:17:f1:af  txqueuelen 1000  (Ethernet)
        RX packets 9844  bytes 1052722 (1.0 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 5567  bytes 886269 (865.4 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.105.201  netmask 255.255.255.0  broadcast 10.0.105.255
        ether 00:0c:29:17:f1:af  txqueuelen 1000  (Ethernet)

2、配置通过ip区分的虚拟机
[root@localhost ~]# cat /etc/nginx/nginx.conf
user  root;
worker_processes  4;

#error_log  logs/error.log;
worker_rlimit_nofile 102400;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    server {
        listen       10.0.105.199:80;
        server_name  web.testpm.com;
        location / {
            root   /var/www/nginx/;
            index  index.html index.htm;
            limit_rate	2k;
            {
        }
        
     server {
        listen       10.0.105.201:80;
        server_name  web.testpm.com;
        location / {
            root   /1000phone/html/;
            index  index.html index.htm;
        	}
        }
}
3、重新加载配置文件
[root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload
4、 测试访问
浏览器输入:http://10.0.105.199
浏览器输入:http://10.0.105.201
5、补充
-- 删除绑定的vip
[root@localhost ~]# ifconfig ens33:1 10.0.105.201/24 down
重启一下nginx
[root@localhost ~]# systemctl restart nginx

3、 基于端口的虚拟主机

[root@localhost ~]# cat /etc/nginx/nginx.conf
user  root;
worker_processes  4;

worker_rlimit_nofile 102400;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';


    sendfile        on;

    keepalive_timeout  65;


    server {
        listen       80;
        server_name  web.testpm.com;
        location / {
            root   /var/www/nginx/;
            index  index.html index.htm;
            limit_rate	2k;
        }
        
    
     server {
        listen       8080;
        server_name  web.1000phone.com;
        location / {
            root   /1000phone/html/;
            index  index.html index.htm;
        	}
        }
}
重新加载配置文件:
[root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload
测试访问:
浏览器输入:http://web.testpm.com/
浏览器输入:http://web.1000phone.com:8080
8、nginx Proxy 代理
1、代理原理
  • 反向代理服务的实现:

    需要有一个负载均衡设备(即反向代理服务器)来分发用户请求,将用户请求分发到后端正真提供服务的服务器上。服务器返回自己的服务到负载均衡设备。负载均衡设备将服务器的服务返回用户。
    Nginx安装部署与配置管理_第12张图片

2、正/反向代理的区别
  • 正向代理:

    正向代理的过程隐藏了真实的请求客户端,服务器不知道真实的客户端是谁,客户端请求的服务都被代理服务器代替请求。我们常说的代理也就是正向代理,正向代理代理的是请求方,也就是客户端;

反向代理:

**反向代理的过程隐藏了真实的服务器,客户不知道真正提供服务的人是谁,客户端请求的服务都被代理服务器处理。反向代理代理的是响应方,也就是服务端;**我们请求www.baidu.com时这www.baidu.com就是反向代理服务器,真实提供服务的服务器有很多台,反向代理服务器会把我们的请求分转发到真实提供服务的各台服务器。Nginx就是性能非常好的反向代理服务器,用来做负载均衡。

访问www.baidu.com是正向代理的过程
Nginx安装部署与配置管理_第13张图片

两者的区别在于代理的对象不一样

正向代理中代理的对象是客户端。

反向代理中代理的对象是服务端。

4、知识扩展2
  1. HTTP Server和Application Server的区别和联系

    Apache/nignx是静态服务器(HTTP Server):

    Nginx优点:负载均衡、反向代理、处理静态文件优势。nginx处理静态请求的速度高于apache

    Apache优点:相对于Tomcat服务器来说处理静态文件是它的优势,速度快。Apache是静态解析,适合静态HTML、图片等

    HTTP Server(Nginx/Apache)常用做静态内容服务和代理服务器,将外来请求转发给后面的应用服务(tomcat,jboss,php等)。

    应用服务器(tomcat/jboss/php)是动态服务器(Application Server):

    应用服务器Application Server,则是一个应用执行的容器。它首先需要支持开发语言的 Runtime(对于 Tomcat 来说,就是 Java,若是Ruby/Python 等其他语言开发的应用也无法直接运行在 Tomcat 上)。

5、nginx Proxy 配置

1、代理模块

ngx_http_proxy_module

2、启用 nginx proxy 代理

环境两台nginx真实服务器

a、nginx-1 启动网站(内容)(作为网站服务器)

nginx-1的ip:10.0.105.199
已经编译安装好,检查nginx是否启动是否可以访问

b、nginx-2 启动代理程序

nginx-2的ip:10.0.105.202
配置nginx的yum源直接yum安装
启动
编辑nginx的配置文件:
[root@nginx-server ~]# vim /etc/nginx/conf.d/default.conf
server {
    server {
    listen       80;
    server_name  localhost;

    location / {
    proxy_pass http://10.0.105.199:80;
    proxy_redirect default;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    proxy_connect_timeout 30;
    proxy_send_timeout 60;
    proxy_read_timeout 60;
    }
}
重新加载nginx配置文件
[root@nginx-server ~]# nginx -s reload

# /usr/local/nginx/sbin/nginx -s reload

c、nginx proxy 具体配置详解

proxy_pass :真实服务器的地址,可以是ip也可以是域名和url地址
proxy_redirect :如果真实服务器使用的是的真实IP:非默认端口。则改成IP:默认端口。
proxy_set_header:重新定义或者添加发往后端服务器的请求头
proxy_set_header X-Real-IP $remote_addr;#只记录连接服务器的上一个ip地址信息。
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #通过这个选项可以记录真正客户端机器的ip地址

proxy_connect_timeout::后端服务器连接的超时时间发起三次握手等候响应超时时间
proxy_send_timeout:后端服务器数据回传时间,就是在规定时间之内后端服务器必须传完所有的数据
proxy_read_timeout :nginx接收upstream(上游/真实) server数据超时, 默认60s, 如果连续的60s内没有收到1个字节, 连接关闭。像长连接

注意:proxy_pass http:// 填写nginx-1服务器的地址。

d、 使用PC客户端访问nginx-2服务器地址
浏览器中输入http://10.0.105.202 (也可以是nginx-2服务器的域名)

成功访问nginx-1服务器页面
e、 观察nginx-1服务器的日志

10.0.105.202 - - [27/Jun/2019:15:54:17 +0800] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" "10.0.105.207"

10.0.105.202 代理服务器地址

10.0.105.207 客户机地址。

访问成功。 记录了客户机的IP和代理服务器的IP

6、Nginx负载均衡

1、upstream配置

首先给大家说下 upstream 这个配置的,这个配置是写一组被代理的服务器地址,然后配置负载均衡的算法.

upstream testapp { 
      server 10.0.105.199:8081;
      server 10.0.105.202:8081;
    }
 server {
        ....
        location / {         
           proxy_pass  http://testapp;  #请求转向 testapp 定义的服务器列表         
        } 
1、负载均衡算法

upstream 支持4种负载均衡调度算法

A、轮询(默认):每个请求按时间顺序逐一分配到不同的后端服务器;

B、ip_hash:每个请求按访问IP的hash结果分配,同一个IP客户端固定访问一个后端服务器。可以保证来自同一ip的请求被打到固定的机器上,可以解决session问题。

C、url_hash:按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器。

D、fair:这是比上面两个更加智能的负载均衡算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx本身是不支持 fair的,如果需要使用这种调度算法,必须下载Nginx的 upstream_fair模块。

2、配置实例

1、热备:如果你有2台服务器,当一台服务器发生事故时,才启用第二台服务器给提供服务。服务器处理请求的顺序:AAAAAA突然A挂啦,BBBBBBBBBBBBBB…

upstream myweb { 
      server 172.17.14.2:8080; 
      server 172.17.14.3:8080 backup;  #热备     
    }

2、轮询:nginx默认就是轮询其权重都默认为1,服务器处理请求的顺序:ABABABABAB…

upstream myweb { 
      server 172.17.14.2:8080; 
      server 172.17.14.3:8080;      
    }

3、加权轮询:跟据配置的权重的大小而分发给不同服务器不同数量的请求。如果不设置,则默认为1。下面服务器的请求顺序为:ABBABBABBABBABB…

upstream myweb { 
      server 172.17.14.2:8080 weight=1;
      server 172.17.14.3:8080 weight=2;
}

4、ip_hash:nginx会让相同的客户端ip请求相同的服务器。

upstream myweb { 
      server 172.17.14.2:8080; 
      server 172.17.14.3:8080;
      ip_hash;
    }

5、nginx负载均衡配置状态参数

  • down,表示当前的server暂时不参与负载均衡。
  • backup,预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻。
  • max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。
  • fail_timeout,在经历了max_fails次失败后,暂停服务的时间单位秒。max_fails可以和fail_timeout一起使用。
 upstream myweb { 
      server 172.17.14.2:8080 weight=2 max_fails=2 fail_timeout=2;
      server 172.17.14.3:8080 weight=1 max_fails=2 fail_timeout=1;    
    }

如果你像跟多更深入的了解 nginx 的负载均衡算法,nginx官方提供一些插件大家可以了解下。

3、nginx配置7层协议

举例讲解下什么是7层协议,什么是4层协议。

(1)7层协议

OSI(Open System Interconnection)是一个开放性的通行系统互连参考模型,他是一个定义的非常好的协议规范,共包含七层协议。直接上图,这样更直观些:
Nginx安装部署与配置管理_第14张图片

好,详情不进行仔细讲解,可以自行百度!

(3)协议配置

这里我们举例,在nginx做负载均衡,负载多个服务,部分服务是需要7层的,部分服务是需要4层的,也就是说7层和4层配置在同一个配置文件中。

准备三台机器:

代理服务IP:10.0.105. --配置本地host解析域名;

后端服务器IP:nginx-a :10.0.105.199/nginx-b:10.0.105.202(yum安装)后端服务器将nginx服务启动

配置代理服务器的nginx配置文件

worker_processes  4;

worker_rlimit_nofile 102400;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    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        on;
    keepalive_timeout  65;
    gzip  on;

    upstream testweb {
	ip_hash;
	server 10.0.105.199:80 weight=2 max_fails=2 fail_timeout=2s;
	server 10.0.105.202:80 weight=2 max_fails=2 fail_timeout=2s;
     }
    server {
        listen       80;
        server_name  www.test.com;
        charset utf-8;
        #access_log  logs/host.access.log  main;
        location / {
	    proxy_pass http://testweb;
         proxy_set_header Host $host:$server_port;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        	}

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        	}
	}
}

202服务器yum安装的创建新的配置文件:

[root@nginx-server ~]# cd /etc/nginx/conf.d/
[root@nginx-server conf.d]# cp default.conf test.conf
[root@nginx-server conf.d]# cat test.conf 
server {
    listen       80;
    server_name  localhost;

    location / {
         root   /usr/share/nginx/html;
         index  index.html index.htm;
    }
}
[root@nginx-server ~]# nginx -s reload

浏览器测试访问:

http://www.test.com/

4层协议方法(扩展)

(2)4层协议

TCP/IP协议
之所以说TCP/IP是一个协议族,是因为TCP/IP协议包括TCP、IP、UDP、ICMP、RIP、TELNETFTP、SMTP、ARP、TFTP等许多协议,这些协议一起称为TCP/IP协议。

从协议分层模型方面来讲,TCP/IP由四个层次组成:网络接口层、网络层、传输层、应用层。

Nginx安装部署与配置管理_第15张图片

nginx在1.9.0的时候,增加了一个 stream 模块,用来实现四层协议(网络层和传输层)的转发、代理、负载均衡等。stream模块的用法跟http的用法类似,允许我们配置一组TCP或者UDP等协议的监听.

配置案例:

#4层tcp负载 
stream {
			upstream myweb {
                hash $remote_addr consistent;
                server 172.17.14.2:8080;
                server 172.17.14.3:8080;
        }
        server {
            listen 82;
            proxy_connect_timeout 10s;
            proxy_timeout 30s;
            proxy_pass myweb;
        }
}

9、nginx 会话保持

nginx会话保持主要有以下几种实现方式。

1、ip_hash

ip_hash使用源地址哈希算法,将同一客户端的请求总是发往同一个后端服务器,除非该服务器不可用。

ip_hash语法:

upstream backend {
    ip_hash;
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com down;
}

ip_hash简单易用,但有如下问题:
当后端服务器宕机后,session会丢失;
来自同一局域网的客户端会被转发到同一个后端服务器,可能导致负载失衡;

2、sticky_cookie_insert

使用sticky_cookie_insert,这会让来自同一客户端的请求被传递到一组服务器的同一台服务器。与ip_hash不同之处在于,它不是基于IP来判断客户端的,而是基于cookie来判断。(需要引入第三方模块才能实现)

sticky模块

语法:

upstream backend {
    server backend1.example.com;
    server backend2.example.com;
    sticky_cookie_insert srv_id expires=1h domain=3evip.cn path=/;
}

说明:
expires:设置浏览器中保持cookie的时间
domain:定义cookie的域
path:为cookie定义路径

4、使用后端服务器自身通过相关机制保持session同步,如:使用数据库、redis、memcached 等做session复制

10、nginx 实现动静分离

为了加快网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度。降低原来单个服务器的压力。 简单来说,就是使用正则表达式匹配过滤,然后交个不同的服务器。

1、准备环境

准备一个nginx代理 两个http 分别处理动态和静态。

1.配置nginx反向代理upstream;
upstream static {
        server 10.0.105.196:80 weight=1 max_fails=1 fail_timeout=60s;
        }
upstream php {
        server 10.0.105.200:80 weight=1 max_fails=1 fail_timeout=60s;
        }
     server {
        listen      80;
        server_name     localhost
        #动态资源加载
        location ~ \.(php|jsp)$ {
            proxy_pass http://phpserver;
            proxy_set_header Host $host:$server_port;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                }
        #静态资源加载
        location ~ .*\.(html|jpg|png|css|js)$ {
            proxy_pass http://static;
            proxy_set_header Host $host:$server_port;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                }
        }
静态资源配置
server {
        listen 80;
        server_name     localhost;

        location ~ \.(html|jpg|png|js|css) {
        root /home/www/nginx;
        }
}
动态资源配置:
yum 安装php7.1
[root@nginx-server ~]#rpm -Uvh https://mirror.webtatic.com/yum/el7/epel-release.rpm
[root@nginx-server ~]#rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
[root@nginx-server ~]#yum install php71w-xsl php71w php71w-ldap php71w-cli php71w-common php71w-devel php71w-gd php71w-pdo php71w-mysql php71w-mbstring php71w-bcmath php71w-mcrypt -y
[root@nginx-server ~]#yum install -y php71w-fpm
[root@nginx-server ~]#systemctl start php-fpm
[root@nginx-server ~]#systemctl enable php-fpm
编辑nginx的配置文件:
server {
        listen      80;
        server_name     localhost;
        location ~ \.php$ {
            root           /home/nginx/html;  #指定网站目录
            fastcgi_pass   127.0.0.1:9000;    #指定访问地址
            fastcgi_index  index.php;		#指定默认文件
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name; #站点根目录,取决于root配置项
            include        fastcgi_params;  #包含nginx常量定义
        		}
        }

当访问静态页面的时候location 匹配到 (html|jpg|png|js|css) 通过转发到静态服务器,静态服务通过location的正则匹配来处理请求。

当访问动态页面时location匹配到 .\php 结尾的文件转发到后端php服务处理请求。

11、nginx 防盗链问题

两个网站 A 和 B, B网站引用了A网站上的图片,这种行为就叫做盗链。 防盗链,就是要防止B引用A的图片。

1、nginx 防止网站资源被盗用模块

ngx_http_referer_module

如何区分哪些是不正常的用户?

​ HTTP Referer是Header的一部分,当浏览器向Web服务器发送请求的时候,一般会带上Referer,

告诉服务器我是从哪个页面链接过来的,服务器借此可以获得一些信息用于处理,例如防止未经允许

的网站盗链图片、文件等。因此HTTP Referer头信息是可以通过程序来伪装生成的,所以通过Referer

信息防盗链并非100%可靠,但是,它能够限制大部分的盗链情况.

2. 防盗链配置

配置要点:

[root@nginx-server ~]# vim /etc/nginx/nginx.conf
# 日志格式添加"$http_referer"
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                         '$status $body_bytes_sent "$http_referer" '
                         '"$http_user_agent" "$http_x_forwarded_for"';
# valid_referers 使用方式                         
Syntax: 	valid_referers none | blocked | server_names | string ...;
Default: 	—
Context: server, location
  • none : 允许没有http_refer的请求访问资源;

  • blocked : 允许不是http://开头的,不带协议的请求访问资源—被防火墙过滤掉的;

  • server_names : 只允许指定ip/域名来的请求访问资源(白名单);

    准备两台机器,一张图片

    图片网站服务器:上传图片192.168.1.9
    [root@nginx-server ~]# cp test.jpg /usr/share/nginx/html/
    [root@nginx-server ~]# cd /etc/nginx/conf.d/
    [root@nginx-server conf.d]# cp default.conf default.conf.bak
    [root@nginx-server conf.d]# mv default.conf nginx.conf
    [root@nginx-server conf.d]# vim nginx.conf
    server {
        listen       80;
        server_name  localhost;
        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }
    }
    [root@nginx-server conf.d]# nginx -t
    [root@nginx-server conf.d]# systemctl restart nginx
    

    访问:

    Referer:这个匹配的连接为空 “-”

    盗链机器配置:192.168.1.10
    [root@nginx-client ~]# cd /usr/share/nginx/html/
    [root@nginx-client html]# cp index.html index.html.bak
    [root@nginx-client html]# vim index.html
    <html>
    <head>
        <meta charset="utf-8">
        <title>qf.com</title>
    </head>
    <body style="background-color:red;">
        <img src="http://192.168.1.9/test.jpg"/>
    </body>
    </html>
    [root@nginx-client html]# systemctl restart nginx
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sVJIoXSy-1591978467594)(assets/1567431311856.png)]

    查看服务器日志:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wphvGFiC-1591978467595)(assets/1567432284586.png)]

    Referer记录了:连接是1.10这台机器。

    在图片服务器操作
    [root@nginx-server conf.d]# vim nginx.conf
    server {
        listen       80;
        server_name  localhost;
        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
    
            valid_referers none blocked www.jd.com;  #允许这些访问
                    if ($invalid_referer) {
                       return 403;
                    }
            }
    }
    [root@nginx-server conf.d]# systemctl restart nginx
    

    测试访问:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cfsz9aqV-1591978467597)(assets/1567431693886.png)]

    图片服务器查看日志:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k6bolQGq-1591978467598)(assets/1567431765456.png)]

    上面配置并没有允许192.168.1.10这台机器访问。

    实例二,继续在图片服务器上面操作
    [root@nginx-server html]# vim /etc/nginx/conf.d/nginx.conf #将原来的删除掉
    server {
        listen       80;
        server_name  localhost;
        location ~  .*\.(gif|jpg|png|jpeg)$ {
            root  /usr/share/nginx/html;
    
            valid_referers none blocked *.qf.com 192.168.1.10;
                    if ($invalid_referer) {
                            return 403;
                    }
            }
    
    }
    重载nginx服务
    [root@nginx-server ~]# nginx -s reload
    
    在其中一台机器测试:
    测试不带http_refer:
    [root@nginx-server conf.d]# curl -I "http://192.168.1.9/test.jpg"
    HTTP/1.1 200 OK
    Server: nginx/1.16.1
    Date: Mon, 02 Sep 2019 14:02:56 GMT
    Content-Type: image/jpeg
    Content-Length: 27961
    Last-Modified: Mon, 02 Sep 2019 13:23:12 GMT
    Connection: keep-alive
    ETag: "5d6d17c0-6d39"
    Accept-Ranges: bytes
    
    测试带非法http_refer:
    [root@nginx-server conf.d]# curl -e http://www.baidu.com -I "http://192.168.1.9/test.jpg"
    HTTP/1.1 403 Forbidden
    Server: nginx/1.16.1
    Date: Mon, 02 Sep 2019 14:03:48 GMT
    Content-Type: text/html
    Content-Length: 153
    Connection: keep-alive
    
    测试带合法的http_refer:
    [root@nginx-server conf.d]# curl -e http://www.qf.com -I "http://192.168.1.9/test.jpg"
    HTTP/1.1 200 OK
    Server: nginx/1.16.1
    Date: Mon, 02 Sep 2019 14:04:52 GMT
    Content-Type: image/jpeg
    Content-Length: 27961
    Last-Modified: Mon, 02 Sep 2019 13:23:12 GMT
    Connection: keep-alive
    ETag: "5d6d17c0-6d39"
    Accept-Ranges: bytes
    
    [root@ansible-server conf.d]# curl -e http://192.168.1.10 -I "http://192.168.1.9/test.jpg"
    HTTP/1.1 200 OK
    Server: nginx/1.16.1
    Date: Mon, 02 Sep 2019 14:05:36 GMT
    Content-Type: image/jpeg
    Content-Length: 27961
    Last-Modified: Mon, 02 Sep 2019 13:23:12 GMT
    Connection: keep-alive
    ETag: "5d6d17c0-6d39"
    Accept-Ranges: bytes
    

    如果用户直接在浏览器输入你的图片地址,那么图片显示正常,因为它符合none这个规则。

    在图片服务器查看日志:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PSTdPhY0-1591978467601)(assets/1567434440812.png)]

  • 13、nginx的localtion指令详解

Nginx 的 HTTP 配置主要包括三个区块,结构如下:

http { 						# 这个是协议级别
  include mime.types;
  default_type application/octet-stream;
  keepalive_timeout 65;
  gzip on;
    server {			 # 这个是服务器级别
      listen 80;
      server_name localhost;
        location / {  # 这个是请求级别
          root html;
          index index.html index.htm;
        }
      }
}
1、location 区段
  • location 是在 server 块中配置,根据不同的 URI 使用不同的配置,来处理不同的请求。

  • location 是有顺序的,会被第一个匹配的location 处理。

  • 基本语法如下:

    location [=|~|~*|^~|@] pattern{……}
    

    2、location 前缀含义

    =    表示精确匹配,优先级也是最高的 
    ^~   表示uri以某个常规字符串开头,理解为匹配url路径即可 
    ~    表示区分大小写的正则匹配  
    ~*   表示不区分大小写的正则匹配
    !~   表示区分大小写不匹配的正则
    !~*  表示不区分大小写不匹配的正则
    /    通用匹配,任何请求都会匹配到
    @    内部服务跳转
    

    查找顺序和优先级

    = 大于 ^~  大于 ~|~*|!~|!~* 大于 /
    多个location配置的情况下匹配顺序为:首先匹配 =,其次匹配^~, 其次是按正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。
    

    3、location 配置示例

    3、location 配置示例

    1、没有修饰符 表示:必须以指定模式开始

    server {
        listen       80;
        server_name  localhost;
    
        location  /abc {
            root    /home/www/nginx;
            index   2.html;
            }
    
    那么,如下是对的:
    http://192.168.1.9/abc
    

    2、=表示:必须与指定的模式精确匹配

    server {
        listen       80;
        server_name  localhost;
        access_log  /var/log/nginx/http_access.log  main;
    
        location / {
            root /usr/share/nginx/html;
            index a.html index.htm;
        }
        location = / {
            root /usr/share/nginx/html;
            index b.html index.htm;
        }
    }
    
    测试:
    http://192.168.1.9
    =/
    http://192.168.1.9/a.html
    /
    

    3、~ 表示:指定的正则表达式要区分大小写

    server {
    server_name localhost;
      location ~ /abc {
                    root /home/www/nginx;
                    index 2.html index.html;
            }
    }
    测试访问:
    http://192.168.1.9/abc
    不正确的
    http://192.168.1.9/ABC
    ========================================
    如果将配置文件修改为
          location ~ /ABC {
                root /home/www/nginx;
                index 2.html index.html;
            }
    在创建目录和文件:
    [root@ansible-server html]# cd /home/www/nginx/
    [root@ansible-server nginx]# mkdir ABC
    [root@ansible-server nginx]# vim ABC/2.html
     访问:
     http://192.168.1.9/ABC/
     
     结论:~ 需要区分大小写。而且目录需要根据大小写定义。
    

    4、^~ :类似于无修饰符的行为,也是以指定模式开始,不同的是,如果模式匹配,那么就停止搜索其他模式了。
    5、@ :定义命名 location 区段,这些区段客户段不能访问,只可以由内部产生的请求来访问,如error_page等

location 区段匹配示例

location = / {
  # 只匹配 / 的查询.
  [ configuration A ]
}
location / {
  # 匹配任何以 / 开始的查询,但是正则表达式与一些较长的字符串将被首先匹配。
  [ configuration B ]
}
location ^~ /images/ {
  # 匹配任何以 /images/ 开始的查询并且停止搜索,不检查正则表达式。
  [ configuration C ]
}
location ~* \.(gif|jpg|jpeg)$ {
  # 匹配任何以gif, jpg, or jpeg结尾的文件
  [ configuration D ]
} 
各请求的处理如下例:
	/ → configuration A
	/documents/document.html → configuration B
	/images/1.gif → configuration C
	/documents/1.jpg → configuration D

12、nginx 地址重写 rewrite

1、什么是Rewrite

Rewrite对称URL Rewrite,即URL重写,就是把传入Web的请求重定向到其他URL的过程

  • URL Rewrite最常见的应用是URL伪静态化,是将动态页面显示为静态页面方式的一种技术。比如http://www.123.com/news/index.php?id=123 使用URLRewrite 转换后可以显示为 http://www.123.com/news/123.html
  • 从安全角度上讲,如果在URL中暴露太多的参数,无疑会造成一定量的信息泄漏,可能会被一些黑客利用,对你的系统造成一定的破坏,所以静态化的URL地址可以给我们带来更高的安全性。
  • 实现网站地址跳转,例如用户访问360buy.com,将其跳转到jd.com。例如当用户访问tianyun.com的
    80端口时,将其跳转到443端口。
2、Rewrite 相关指令
  • Nginx Rewrite 相关指令有 if、rewrite、set、return
2.1、if 语句
  • 应用环境

    server,location
    

    语法:

    if (condition) {}
    if 可以支持如下条件判断匹配符号
    ~ 					正则匹配 (区分大小写)
    ~* 				    正则匹配 (不区分大小写)
    !~                  正则不匹配 (区分大小写)
    !~*		            正则不匹配  (不区分大小写)
    -f 和!-f 		    用来判断是否存在文件
    -d 和!-d 		    用来判断是否存在目录
    -e 和!-e 		    用来判断是否存在文件或目录
    -x 和!-x 		    用来判断文件是否可执行
    
    在匹配过程中可以引用一些Nginx的全局变量
    $args				请求中的参数;
    $document_root	    针对当前请求的根路径设置值;
    $host				请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名;
    $limit_rate			对连接速率的限制;
    $request_method		请求的方法,比如"GET""POST";
    $remote_addr		客户端地址;
    $remote_port		客户端端口号;
    $remote_user		客户端用户名,认证用;
    $request_filename   当前请求的文件路径名(带网站的主目录/usr/local/nginx/html/images /a.jpg)
    $request_uri		当前请求的文件路径名(不带网站的主目录/images/a.jpg)
    $query_string$args相同;
    $scheme				用的协议,比如http或者是https
    $server_protocol	请求的协议版本,"HTTP/1.0""HTTP/1.1";
    $server_addr 		服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费);
    $server_name		请求到达的服务器名;
    $document_uri$uri一样,URI地址;
    $server_port 		请求到达的服务器端口号;
    
    2.2、Rewrite flag

    rewrite 指令根据表达式来重定向URI,或者修改字符串。可以应用于server,location, if环境下每行rewrite指令最后跟一个flag标记,支持的flag标记有:

    last 			    相当于Apache里的[L]标记,表示完成rewrite。默认为last。
    break 				本条规则匹配完成后,终止匹配,不再匹配后面的规则
    redirect 			返回302临时重定向,浏览器地址会显示跳转后的URL地址
    permanent 		    返回301永久重定向,浏览器地址会显示跳转后URL地址
    

    redirect 和 permanent区别则是返回的不同方式的重定向:

    对于客户端来说一般状态下是没有区别的。而对于搜索引擎,相对来说301的重定向更加友好,如果我们把一个地址采用301跳转方式跳转的话,搜索引擎会把老地址的相关信息带到新地址,同时在搜索引擎索引库中彻底废弃掉原先的老地址。

    使用302重定向时,搜索引擎(特别是google)有时会查看跳转前后哪个网址更直观,然后决定显示哪个,如果它觉的跳转前的URL更好的话,也许地址栏不会更改。

2.3、Rewrite匹配参考示例

本地解析host文件
# http://www.testpm.com/a/1.html ==> http://www.testpm.com/b/2.html
    location /a {
        root    /html;
        index   1.html index.htm;
        rewrite .* /b/2.html permanent;
        }
    location /b {
        root    /html;
        index   2.html index.htm;
        }
例2:
# http://www.testpm.com/2019/a/1.html ==> http://www.testpm.com/2018/a/1.html
     location /2019/a {
        root    /var/www/html;
        index   1.html index.hml;
        rewrite ^/2019/(.*)$ /2018/$1 permanent;
        }
     location /2018/a {
        root    /var/www/html;
        index   1.html index.htl;
        }

例3:
# http://www.qf.com/a/1.html ==> http://jd.com
location /a {
        root    /html;
        if ($host ~* www.qf.com ) {
        rewrite .* http://jd.com permanent;
        }
        }

例4:
# http://www.qf.com/a/1.html ==> http://jd.com/a/1.html
location /a {
        root /html;
        if ( $host ~* qf.com ){
        rewrite .* http://jd.com$request_uri permanent;
        }
        }

例5: 在访问目录后添加/  (如果目录后已有/,则不加/)
# http://www.tianyun.com/a/b/c
# $1: /a/b
# $2: c
# http://$host$1$2/
location /a/b/c {
        root    /usr/share/nginx/html;
        index   index.html index.hml;
        if (-d $request_filename) {
        rewrite ^(.*)([^/])$ http://$host$1$2/ permanent;
        }
        }

例6:
# http://www.tianyun.com/login/tianyun.html ==>  http://www.tianyun.com/reg/login.html?user=tianyun
	location /login {
        root   /usr/share/nginx/html;
        rewrite ^/login/(.*)\.html$ http://$host/reg/login.html?user=$1;
        }
    location /reg {
        root /usr/share/nginx/html;
        index login.html;

        }

例7:
#http://www.tianyun.com/qf/11-22-33/1.html  ==>  http://www.tianyun.com/qf/11/22/33/1.html
location /qf {
            rewrite ^/qf/([0-9]+)-([0-9]+)-([0-9]+)(.*)$ /qf/$1/$2/$3$4 permanent;
        }

        location /qf/11/22/33 {
                root /html;
                index   1.html;
        }
2.4、set 指令

set 指令是用于定义一个变量,并且赋值

应用环境:

server,location,if

应用示例

例8:
#http://alice.testpm.com ==> http://www.testpm.com/alice
#http://jack.testpm.com ==> http://www.testpm.com/jack

[root@nginx-server conf.d]# cd /usr/share/nginx/html/
[root@nginx-server html]# mkdir jack alice
[root@nginx-server html]# echo "jack.." >> jack/index.html
[root@nginx-server html]# echo "alice.." >> alice/index.html

a. DNS实现泛解析
*   		IN      A			    网站IP
或者本地解析域名host文件
10.0.105.202 www.testpm.com
10.0.105.202 alice.testpm.com
10.0.105.202 jack.testpm.com
编辑配置文件:
server {
    listen       80;
    server_name  www.testpm.com;

    location / {
         root   /usr/share/nginx/html;
         index  index.html index.htm;
         if ( $host ~* ^www.testpm.com$) {
                break;
                }
         if ( $host ~* "^(.*)\.testpm\.com$" ) {
                set $user $1;
                rewrite .* http://www.testpm.com/$user permanent;
                }
        }
    location /jack {
         root /usr/share/nginx/html;
         index  index.html index.hml;
        }
    location /alice {
         root /usr/share/nginx/html;
         index index.html index.hml;
        }
}
2.5、return 指令

return 指令用于返回状态码给客户端

server,location,if

应用示例:

例9:如果访问的.sh结尾的文件则返回403操作拒绝错误
server {
    listen       80;
    server_name  www.testpm.cn;
    #access_log  /var/log/nginx/http_access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        }

    location ~* \.sh$ {
        return 403;
        }
}

例10:80 ======> 443 :80转443端口
server {
    listen       80;
    server_name  www.testpm.cn;
    access_log  /var/log/nginx/http_access.log  main;
    return 301 https://www.testpm.cn$request_uri;
}

server {
    listen 443 ssl;
    server_name www.testpm.cn;
    access_log  /var/log/nginx/https_access.log  main;

    #ssl on;
    ssl_certificate   /etc/nginx/cert/2447549_www.testpm.cn.pem;
    ssl_certificate_key  /etc/nginx/cert/2447549_www.testpm.cn.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
    ssl_prefer_server_ciphers on;

    location / {
        root  /usr/share/nginx/html;
        index index.html index.htm;
    }
}

[root@nginx-server ~]# curl -I http://www.testpm.cn
HTTP/1.1 301 Moved Permanently
Server: nginx/1.16.0
Date: Wed, 03 Jul 2019 13:52:30 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://www.testpm.cn/

3、last,break详解
Nginx安装部署与配置管理_第16张图片

[root@localhost test]# cat /etc/nginx/conf.d/last_break.conf 
server {
    listen       80;
    server_name  localhost;
    access_log  /var/log/nginx/last.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    location /break/ {
        root /usr/share/nginx/html;
        rewrite .* /test/break.html break;
    }
    location /last/ {
        root /usr/share/nginx/html;
        rewrite .* /test/last.html last;
    }
    location /test/ {
        root /usr/share/nginx/html;
        rewrite .* /test/test.html break;
    }

}
[root@localhost conf.d]# cd /usr/share/nginx/html/
[root@localhost html]# mkdir test
[root@localhost html]# echo "last" > test/last.html
[root@localhost html]# echo "break" > test/break.html
[root@localhost html]# echo "test" > test/test.html

http://10.0.105.196/break/break.html
http://10.0.105.196/last/last.html

注意:

  • last 标记在本条 rewrite 规则执行完后,会对其所在的 server { … } 标签重新发起请求;

  • break 标记则在本条规则匹配完成后,停止匹配,不再做后续的匹配;

  • 使用 alias 指令时,必须使用 last;

  • 使用 proxy_pass 指令时,则必须使用break。

    4、Nginx 的 https ( rewrite )

    server {
            listen       80;
            server_name  *.vip9999.top vip9999.top;
    
            if ($host ~* "^www.vip9999.top$|^vip9999.top$" ) {
                    return 301 https://www.vip9999.top$request_uri;
            }
        }
    
        # Settings for a TLS enabled server.
        server {
            listen       443 ssl;
            server_name  www.vip9999.top;
            
            ssl_certificate cert/214025315060640.pem;
            ssl_certificate_key cert/214025315060640.key;
            ssl_session_cache shared:SSL:1m;
            ssl_session_timeout  10m;
            ssl_ciphers HIGH:!aNULL:!MD5;
            ssl_prefer_server_ciphers on;
    
            #pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
            location ~ \.php$ {
                root           /usr/share/nginx/html;
                fastcgi_pass   127.0.0.1:9000;
                fastcgi_index  index.php;
                fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
                include        fastcgi_params;
                }
            }
    
14、nginx 日志配置
1、nginx 日志介绍

nginx 有一个非常灵活的日志记录模式,每个级别的配置可以有各自独立的访问日志, 所需日志模块 ngx_http_log_module 的支持,日志格式通过 log_format 命令来定义,日志对于统计和排错是非常有利的,下面总结了 nginx 日志相关的配置 包括 access_loglog_formatrewrite_logerror_log

# 设置访问日志
access_log path [format [buffer=size] [gzip[=level]] [flush=time];
# 关闭访问日志
access_log off; 
  • path 指定日志的存放位置。
  • format 指定日志的格式。默认使用预定义的combined
  • buffer 用来指定日志写入时的缓存大小。默认是64k。
  • gzip 日志写入前先进行压缩。压缩率可以指定,从1到9数值越大压缩比越高,同时压缩的速度也越慢。默认是1。
  • flush 设置缓存的有效时间。如果超过flush指定的时间,缓存中的内容将被清空。

作用域:

可以应用access_log指令的作用域分别有httpserverlocation,也就是说,在这几个作用域外使用该指令,Nginx会报错。

access_log /var/logs/nginx-access.log

该例子指定日志的写入路径为/var/logs/nginx-access.log,日志格式使用默认的combined

access_log /var/logs/nginx-access.log buffer=32k gzip flush=1m

该例子指定日志的写入路径为/var/logs/nginx-access.log,日志格式使用默认的combined,指定日志的缓存大小为 32k,日志写入前启用 gzip 进行压缩,压缩比使用默认值 1,缓存数据有效时间为1分钟。

3、log_format 指令

Nginx 预定义了名为 combined 日志格式,如果没有明确指定日志格式默认使用该格式:

log_format combined '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';

如果不想使用Nginx预定义的格式,可以通过log_format指令来自定义。

语法

log_format name [escape=default|json] string ...;
  • name 格式名称。在 access_log 指令中引用。
  • escape 设置变量中的字符编码方式是json还是default,默认是default
  • string 要定义的日志格式内容。该参数可以有多个。参数中可以使用Nginx变量。

log_format 指令中常用的一些变量:

$remote_addr, $http_x_forwarded_for   #记录客户端IP地址
$remote_user                    #记录客户端用户名称
$request                   #记录请求的URL和HTTP协议
$status                     #记录请求状态
$body_bytes_sent      #发送给客户端的字节数,不包括响应头的大小
$bytes_sent               #发送给客户端的总字节数
$connection               #连接的序列号
$connection_requests  #当前通过一个连接获得的请求数量。
$msec                      #日志写入时间。单位为秒,精度是毫秒。
$pipe                       #如果请求是通过HTTP流水线(pipelined)发送,pipe值为“p”,否则为“.”。
$http_referer            #记录从哪个页面链接访问过来的,可以根据该参数进行防盗链设置
$http_user_agent      #记录客户端浏览器相关信息
$request_length        #请求的长度(包括请求行,请求头和请求正文)。
$request_time           #请求处理时间,单位为秒,精度毫秒; 从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。
$time_iso8601           #ISO8601标准格式下的本地时间。
$time_local               #通用日志格式下的本地时间。

自定义日志格式的使用:

access_log /var/logs/nginx-access.log main

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';
注意:
注:如果Nginx位于负载均衡器,nginx反向代理之后,web服务器无法直接获取到客户端真实的IP地址。
$remote_addr获取的是反向代理的IP地址。反向代理服务器在转发请求的http头信息中,可以增加X-Forwarded-For信息,用来记录客户端IP地址。

使用log_format指令定义了一个main的格式,并在access_log指令中引用了它。客户端发起请求访问:http://192.168.246.154/,看一下请求的日志记录:

10.0.105.207 - - [01/Jul/2019:10:44:36 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" "-"

我们看到最终的日志记录中$remote_user$http_referer$http_x_forwarded_for都对应了一个-,这是因为这几个变量为空。

面试时:注意日志里面的ip地址一定要在第一列。

5、error_log 指令

错误日志在Nginx中是通过error_log指令实现的。该指令记录服务器和请求处理过程中的错误信息。

语法

配置错误日志文件的路径和日志级别。

error_log file [level];
Default:	
error_log logs/error.log error;

file 参数指定日志的写入位置。

level 参数指定日志的级别。level可以是debug, info, notice, warn, error, crit, alert,emerg中的任意值。可以看到其取值范围是按紧急程度从低到高排列的。只有日志的错误级别等于或高于level指定的值才会写入错误日志中。默认值是error

扩展日志级别:
 debug级别:低级别,包含的信息非常详细
 info级别:稍微的高一点了。用的多一些。
 notice 和warning
 notice:相当于提示
 warning:警告 和warn 一样
 err和error 一样。
 crit:比较严重了
 alert:告警,很严重
 emerg: 恐慌级别, 级别最高的

基本用法

error_log /var/logs/nginx/nginx-error.log

配置段: http, server, location作用域。

例子中指定了错误日志的路径为:/var/logs/nginx/nginx-error.log,日志级别使用默认的 error

7、rewrite_log 指令

ngx_http_rewrite_module模块提供的。用来记录重写日志的。对于调试重写规则建议开启,启用时将在error log中记录notice级别的重写日志。
基本语法:

rewrite_log on | off;

默认值: 
rewrite_log off;

配置段: http, server, location, if作用域。

8、nginx 日志配置总结

Nginx中通过access_logerror_log指令配置访问日志和错误日志,通过log_format我们可以自定义日志格式。

详细的日志配置信息可以参考Nginx官方文档

9、单独开启server的访问日志

[root@nginx-client ~]# cd /etc/nginx/conf.d/
[root@nginx-client conf.d]# vim nginx.conf
server {
    listen       80;
    server_name  localhost;

    charset koi8-r;
    access_log  /var/log/nginx/test.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    location /admin {
        root /usr/share/nginx/html;
        index index.html index.htm;
        }
}
[root@nginx-client conf.d]# nginx -s reload
访问
[root@nginx-client conf.d]# curl -I http://192.168.1.10

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NeU16wf8-1591978467604)(assets/1567612056482.png)]

当我们访问的这个server的时候日志将会输出到test.access.log.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DK2BGGUG-1591978467607)(assets/1567612351854.png)]

9、nginx的日志轮转

[root@192 ~]# rpm -ql nginx |grep log
/etc/logrotate.d/nginx
/var/log/nginx
[root@192 ~]# vim /etc/logrotate.d/nginx
/var/log/nginx/*.log {           #指定需要轮转处理的日志文件
        daily     #日志文件轮转周期,可用值为: daily/weekly/yearly
        missingok               # 忽略错误信息
        rotate 7               # 轮转次数,即最多存储7个归档日志,会删除最久的归档日志
        minsize 5M	       #限制条件,大于5M的日志文件才进行分割,否则不操作
        dateext             # 以当前日期作为命名格式
        compress         # 轮循结束后,已归档日志使用gzip进行压缩
        delaycompress    # 与compress共用,最近的一次归档不要压缩
        notifempty         # 日志文件为空,轮循不会继续执行
        create 640 nginx nginx     #新日志文件的权限
        sharedscripts     #有多个日志需要轮询时,只执行一次脚本
        postrotate    # 将日志文件转储后执行的命令。以endscript结尾,命令需要单独成行
                if [ -f /var/run/nginx.pid ]; then    #判断nginx的PID。# 默认logrotate会以root身份运行
                        kill -USR1 cat /var/run/nginx.pid
                fi
        endscript
}

执行命令:
[root@192 nginx]# /usr/sbin/logrotate -f /etc/logrotate.conf
创建计划任务:
[root@192 nginx]# crontab -e
59 23 * * * /usr/sbin/logrotate -f /etc/logrotate.conf

作业:编写一个nginx的切割脚本。

15、nginx 的平滑升级

1、为什么要对 nginx 平滑升级

随着 nginx 越来越流行,并且 nginx 的优势也越来越明显,nginx 的版本迭代也来时加速模式,1.9.0版本的nginx更新了许多新功能,例如 stream 四层代理功能,伴随着 nginx 的广泛应用,版本升级必然越来越快,线上业务不能停,此时 nginx 的升级就是运维的工作了

nginx 方便地帮助我们实现了平滑升级。其原理简单概括,就是:
(1)在不停掉老进程的情况下,启动新进程。
(2)老进程负责处理仍然没有处理完的请求,但不再接受处理请求。
(3)新进程接受新请求。
(4)老进程处理完所有请求,关闭所有连接后,停止。
这样就很方便地实现了平滑升级。一般有两种情况下需要升级 nginx,一种是确实要升级 nginx 的版本,另一种是要为 nginx 添加新的模块

Nginx信号简介

主进程支持的信号

  • TERM, INT: 立刻退出
  • QUIT: 等待工作进程结束后再退出
  • KILL: 强制终止进程
  • HUP: 重新加载配置文件,使用新的配置启动工作进程,并逐步关闭旧进程。
  • USR1: 重新打开日志文件
  • USR2: 启动新的主进程,实现热升级
  • WINCH: 逐步关闭工作进程

工作进程支持的信号

  • TERM, INT: 立刻退出
  • QUIT: 等待请求处理结束后再退出
  • USR1: 重新打开日志文件
3、nginx 平滑升级实战

1、查看现有的 nginx 编译参数

[root@nginx-server ~]# cd /usr/local/nginx/sbin/nginx -V

按照原来的编译参数安装 nginx 的方法进行安装,只需要到 make,千万不要 make install 。如果make install 会将原来的配置文件覆盖

[root@nginx-server ~]# cd /usr/local/nginx-1.16.0/
[root@nginx-server nginx-1.16.0]# ./configure --prefix=/usr/local/nginx --group=nginx --user=nginx --sbin-path=/usr/local/nginx/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/tmp/nginx/client_body --http-proxy-temp-path=/tmp/nginx/proxy --http-fastcgi-temp-path=/tmp/nginx/fastcgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-pcre --with-http_realip_module --with-stream --with-http_image_filter_module
[root@nginx-server nginx-1.16.0]# make
3、备份原 nginx 二进制文件

备份二进制文件和 nginx 的配置文件(期间nginx不会停止服务)

[root@nginx-server nginx-1.16.0]# mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx_$(date +%F)

4、复制新的nginx二进制文件,进入新的nginx源码包

[root@nginx-server nginx-1.16.0]# cp /usr/local/nginx-1.16.0/objs/nginx /usr/local/nginx/sbin/

5、测试新版本的nginx是否正常

[root@nginx-server nginx-1.16.0]# /usr/local/nginx/sbin/nginx -t

6、给nginx发送平滑迁移信号(若不清楚pid路径,请查看nginx配置文件)

[root@nginx-server ~]# kill -USR2 `cat /var/run/nginx.pid`

7、查看nginx pid,会出现一个nginx.pid.oldbin

[root@nginx-server ~]# ll /var/run/nginx.pid*
-rw-r--r-- 1 root root 5 Jul  1 11:29 /var/run/nginx.pid
-rw-r--r-- 1 root root 5 Jul  1 09:54 /var/run/nginx.pid.oldbin

8、从容关闭旧的Nginx进程

[root@nginx-server ~]# kill -WINCH `cat /var/run/nginx.pid.oldbin`

9、此时不重载配置启动旧的工作进程

[root@nginx-server ~]# kill -HUP `cat /var/run/nginx.pid.oldbin`

10、结束工作进程,完成此次升级

[root@nginx-server ~]# kill -QUIT `cat /var/run/nginx.pid.oldbin`

11、验证Nginx是否升级成功

[root@nginx-server ~]# /usr/local/nginx/sbin/nginx -V

4、升级实验

1、安装配置1.6版本的 nginx,重新开启一台机器

[root@localhost ~]# yum install -y gcc gcc-c++ pcre-devel openssl-devel zlib-devel
[root@localhost ~]# tar xzf nginx-1.6.3.tar.gz -C /usr/local/
[root@localhost ~]# cd /usr/local/nginx-1.6.3
[root@localhost nginx-1.6.3]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module
[root@localhost nginx-1.6.3]# make && make install
[root@localhost nginx-1.6.3]# useradd -M -s /sbin/nologin nginx
[root@localhost nginx-1.6.3]# /usr/local/nginx/sbin/nginx -t 
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@localhost nginx-1.6.3]# /usr/local/nginx/sbin/nginx 
[root@localhost nginx-1.6.3]# netstat -lntp
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      13989/nginx: master

2、查看版本和模块

[root@localhost nginx-1.6.3]# /usr/local/nginx/sbin/nginx -V 
nginx version: nginx/1.6.3
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) 
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module
[root@localhost nginx-1.6.3]# echo "nginx1.6" > /usr/local/nginx/html/index.html
[root@localhost nginx-1.6.3]# yum install -y elinks

4、访问验证

[root@localhost nginx-1.6.3]# elinks 10.0.105.189

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XGR5eCqh-1591978467610)(assets/1567517823293.png)]

5、升级nginx

将 nginx 版本进行升级 并在不影响业务的情况下添加 SSL 和 pcre 模块

[root@localhost ~]# tar xzf nginx-1.12.2.tar.gz -C /usr/local/
[root@localhost ~]# cd /usr/local/nginx-1.12.2/
[root@localhost nginx-1.12.2]# ./configure --prefix=/usr/local/nginx --user=nginx --group=ngiinx --with-http_stub_status_module --with-http_ssl_module --with-pcre
[root@localhost nginx-1.12.2]# make
[root@localhost nginx-1.12.2]# cd
[root@localhost ~]# mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx_lod
[root@localhost ~]# cp /usr/local/nginx-1.12.2/objs/nginx /usr/local/nginx/sbin/
[root@localhost ~]# mv /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf.bak
[root@localhost ~]# kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
[root@localhost ~]# ls /usr/local/nginx/logs/
access.log  error.log  nginx.pid
[root@localhost ~]# ps aux | grep nginx 
root      13989  0.0  0.0  24860   952 ?        Ss   13:55   0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx     13990  0.0  0.1  25284  1720 ?        S    13:55   0:00 nginx: worker process
root      16525  0.0  0.0 112708   976 pts/2    S+   14:09   0:00 grep --color=auto nginx

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-029Wf8fy-1591978467614)(assets/1567519462609.png)]

16、nginx 错误页面配置

nginx错误页面包括404 403 500 502 503 504等页面,只需要在server中增加以下配置即可:

#error_page  404 403 500 502 503 504  /404.html;
                location = /404.html {
                        root   /usr/local/nginx/html;
                }

注意:

/usr/local/nginx/html/ 路径下必须有404.html这个文件!!!

404.html上如果引用其他文件的png或css就会有问题,显示不出来,因为其他文件的访问也要做配置;
为了简单,可以将css嵌入文件中,图片用base编码嵌入;如下:

[root@localhost html]# vim 404.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
        <title>404</title>
        <style>
            .layout-table{display:table;height:100%;width:100%;vertical-align: middle;margin-top:150px}
            .layout-table-cell{display: table-cell;vertical-align: middle;text-align:center}
            .layout-tip{font-size:28px;color:#373737;margin: 0 auto;margin-top:16px;border-bottom: 1px solid #eee;padding-bottom: 20px;width: 360px;}
            #tips{font-size:18px;color:#666666;margin-top:16px;}
        </style>
    </head>
    <body class="layui-layout-body">
        <div class="layui-layout layui-layout-admin">
            
            <div class="layui-body">
                <div class="layout-table">
                    <div class="layout-table-cell">
                        <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAV4AAACMCAYAAAA0qsGKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkIwRDQ0ODRFMzMyODExRThBQ0Q5Q0UyNkNCMkE4MDk0IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkIwRDQ0ODRGMzMyODExRThBQ0Q5Q0UyNkNCMkE4MDk0Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6QjBENDQ4NEMzMzI4MTFFOEFDRDlDRTI2Q0IyQTgwOTQiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6QjBENDQ4NEQzMzI4MTFFOEFDRDlDRTI2Q0IyQTgwOTQiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4Qz6opAAAU5klEQVR42uxd3XXjthKe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" class="layout-img">
                        <p class="layout-tip">哎呀,找不到该页面啦!</p>
                        <p id="tips">请检查您的网络连接是否正常或者输入的网址是否正确</p>
                    </div>
                </div>
            </div>
        </div>
        
    </body>
</html>

展示效果;

Nginx安装部署与配置管理_第17张图片

17、nginx 流量控制

流量限制 (rate-limiting),我们可以用来限制用户在给定时间内HTTP请求的数量。流量限制可以用作安全目的,比如可以减慢暴力密码破解的速率。还可以用来抵御 DDOS 攻击。更常见的情况是该功能被用来保护上游应用服务器不被同时太多用户请求所压垮。

1、Nginx如何限流

Nginx的”流量限制”使用漏桶算法(leaky bucket algorithm),就好比,一个桶口在倒水,桶底在漏水的水桶。如果桶口倒水的速率大于桶底的漏水速率,桶里面的水将会溢出;同样,在请求处理方面,水代表来自客户端的请求,水桶代表根据”先进先出调度算法”(FIFO)等待被处理的请求队列,桶底漏出的水代表离开缓冲区被服务器处理的请求,桶口溢出的水代表被丢弃和不被处理的请求。

2、配置基本的限流

“流量限制”配置两个主要的指令,limit_req_zonelimit_req,如下所示:

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;
        upstream myweb {
                server 10.0.105.196:80 weight=1 max_fails=1 fail_timeout=1;
                }
        server {
                listen 80;
                server_name localhost;

                location /login {
                        limit_req zone=mylimit;
                        proxy_pass http://myweb;
                        proxy_set_header Host $host:$server_port;
                        proxy_set_header X-Real-IP $remote_addr;
                        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                        }
        }
10.0.105.196配置:
server {
        listen 80;
        server_name localhost;
        location /login {
                root    /usr/share/nginx/html;
                index   index.html index.html;
                }
}

limit_req_zone指令设置流量限制和内存区域的参数,但实际上并不限制请求速率。所以需要通过添加limit_req指令启用流量限制,应用在特定的location或者server块。(示例中,对于”/login/”的所有请求)。

limit_req_zone指令通常在HTTP块中定义,使其可在多个上下文中使用,它需要以下三个参数:

  • Key - 定义应用限制的请求特性。示例中的 Nginx 变量$binary_remote_addr,保存客户端IP地址的二进制形式。
  • Zone - 定义用于存储每个IP地址状态以及被限制请求URL访问频率的内存区域。通过zone=keyword标识区域的名字(自定义),以及冒号后面跟区域大小。16000个IP地址的状态信息,大约需要1MB。
  • Rate - 连接请求。在示例中,速率不能超过每秒1个请求。
3、配置流量控制的日志

默认情况下,Nginx以error级别来记录被拒绝的请求,如要更改Nginx的日志记录级别,需要使用limit_req_log_level指令。这里,我们将被拒绝请求的日志记录级别设置为warn

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;
        upstream myweb {
                server 10.0.105.196:80 weight=1 max_fails=1 fail_timeout=1;
                }
        server {
                listen 80;
                server_name localhost;

                location /login {
                        limit_req zone=mylimit;
                        limit_req_log_level warn;
                        proxy_pass http://myweb;
                        proxy_set_header Host $host:$server_port;
                        proxy_set_header X-Real-IP $remote_addr;
                        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                        }
        }

默认情况下,Nginx会在日志中记录由于流量限制而延迟或丢弃的请求,如下所示:

2019/02/13 04:20:00 [error] 120315#0: *32086 limiting requests, excess: 1.000 by zone "mylimit", client: 192.168.1.2, server: nginx.com, request: "GET / HTTP/1.0", host: "nginx.com"

日志条目中包含的字段:

  • limiting requests - 表明日志条目记录的是被“流量限制”请求
  • excess - 每毫秒超过对应“流量限制”配置的请求数量
  • zone - 定义实施“流量限制”的区域
  • client - 发起请求的客户端IP地址
  • server - 服务器IP地址或主机名
  • request - 客户端发起的实际HTTP请求
  • host - HTTP报头中host的值
4、发送到客户端的错误代码

一般情况下,客户端超过配置的流量限制时,Nginx响应状态码为503(Service Temporarily Unavailable)。可以使用limit_req_status指令来设置为其它状态码(例如下面的404状态码):

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;
	upstream myweb {
        	server 10.0.105.196:80 weight=1 max_fails=1 fail_timeout=1;
		}
	server {
        	listen 80;
        	server_name localhost;
		
        	location /login {
			limit_req zone=mylimit;
			limit_req_log_level warn;
			limit_req_status 404;
                	proxy_pass http://myweb;
                        proxy_set_header Host $host:$server_port;
	            	proxy_set_header X-Real-IP $remote_addr;
            		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                	}
	}

18、nginx 访问控制

1、nginx 访问控制模块

(1)基于IP的访问控制:http_access_module
(2)基于用户的信任登录:http_auth_basic_module

2、基于IP的访问控制

1、配置语法

Syntax:allow address | CIDR | unix: | all;
default:默认无
Context:http,server,location

Syntax:deny address | CIDR | unix: | all;
default:默认无
Context:http,server,location
===================================================
allow    允许     //ip或者网段
deny    拒绝     //ip或者网段
2、配置测试

编辑/etc/nginx/conf.d/access_mod.conf内容如下:

[root@192 ~]# vim /etc/nginx/conf.d/access_mod.conf
server {
        listen 80;
        server_name localhost;
        location  / {
                root /usr/share/nginx/html;
                index index.html index.hml;
                deny 192.168.1.8;
                allow all;
                }
}
[root@192 ~]# nginx -t
[root@192 ~]# nginx -s reload

#需要注意:
1.按顺序匹配,已经被匹配的ip或者网段,后面不再被匹配。
2.如果先允许所有ip访问,在定义拒绝访问。那么拒绝访问不生效。
3.默认为allow all

宿主机IP为192.168.1.8,虚拟机IP为192.168.1.11,故这里禁止宿主机访问,允许其他所有IP访问。
宿主机访问http://192.168.1.11,显示403 Forbidden
当然也可以反向配置,同时也可以使用IP网段的配置方式,如allow 192.168.1.0/24;,表示满足此网段的IP都可以访问。

3、指定location拒绝所有请求

如果你想拒绝某个指定URL地址的所有请求,只需要在location块中配置deny all指令:

[root@192 ~]# vim /etc/nginx/conf.d/access_mod.conf
server {
        listen 80;
        server_name localhost;
        location  / {
                root /usr/share/nginx/html;
                index index.html index.hml;
                deny all;    #拒绝所有
                }
}

[root@192 ~]# nginx -t
[root@192 ~]# nginx -s reload
3、基于用户的信任登录

(2)基于用户的信任登录模块:http_auth_basic_module

有时我们会有这么一种需求,就是你的网站的某些页面不希望公开,我们希望的是某些特定的客户端可以访问。那么我们可以在访问时要求进行身份认证,就如给你自己的家门加一把锁,以拒绝那些不速之客。

1、配置语法
Syntax:auth_basic string | off;
default:auth_basic off;
Context:http,server,location

Syntax:auth_basic_user_file file;
default:默认无
Context:http,server,location
file:存储用户名密码信息的文件。
2、配置示例
[root@192 ~]# vim /etc/nginx/conf.d/auth_mod.conf 
server {
	listen 80;
	server_name localhost;
	location ~ /admin {
		root /var/www/html;
		index index.html index.hml;
		auth_basic "Auth access test!";
		auth_basic_user_file /etc/nginx/auth_conf;
		}
}

[root@192 ~]# nginx -t
[root@192 ~]# nginx -s reload
[root@192 ~]# mkdir /var/www/html    #创建目录
[root@192 ~]# vim /var/www/html/index.html    #创建文件

auth_basic不为off,开启登录验证功能,auth_basic_user_file加载账号密码文件。

3、建立口令文件

[root@192 ~]# yum install -y httpd-tools #htpasswd 是开源 http 服务器 apache httpd 的一个命令工具,用于生成 http 基本认证的密码文件
[root@192 ~]# htpasswd -cm /etc/nginx/auth_conf user10 # -c 创建解密文件,-m MD5加密
[root@192 ~]# htpasswd -m /etc/nginx/auth_conf user20
[root@192 ~]# cat /etc/nginx/auth_conf 
user10:$apr1$MOa9UVqF$RlYRMk7eprViEpNtDV0n40
user20:$apr1$biHJhW03$xboNUJgHME6yDd17gkQNb0

4、访问测试
Nginx安装部署与配置管理_第18张图片

19、nginx 变量

Nginx的配置文件使用语法的就是一门微型的编程语言。既然是编程语言,一般也就少不了“变量”这种东西。

1、nginx变量简介
  • 所有的 Nginx变量在 Nginx 配置文件中引用时都须带上 $ 前缀

  • 在 Nginx 配置中,变量只能存放一种类型的值,而且也只存在一种类型,那就是字符串类型

  • 所有的变量值都可以通过这种方式引用:

    $变量名
    
    2、nginx 变量的定义和使用

    nginx中的变量分为两种,自定义变量与内置预定义变量

    1、自定义变量

    1、声明变量
    可以在sever,http,location等标签中使用set命令声明变量,语法如下

    set $变量名 变量值
    

    注意:

    • nginx 中的变量必须都以$开头
    • nginx 的配置文件中所有使用的变量都必须是声明过的,否则 nginx 会无法启动并打印相关异常日志

    nginx安装echo模块

    查看已经安装的nginx的版本
    [root@192 ~]# nginx -V 
    上传或者下载一个相同版本的nginx包
    [root@192 ~]# ls
    anaconda-ks.cfg  nginx-1.16.0.tar.gz
    下载echo模块的安装包
    [root@192 ~]# wget https://github.com/openresty/echo-nginx-module/archive/v0.61.tar.gz
    [root@192 ~]# ls
    anaconda-ks.cfg  nginx-1.16.0.tar.gz  v0.61.tar.gz
    解压到相同路径下:
    [root@192 ~]# tar xzf nginx-1.16.0.tar.gz -C /usr/local/
    [root@192 ~]# tar xzf v0.61.tar.gz -C /usr/local/
    安装编译工具
    [root@192 ~]# cd /usr/local/
    [root@192 local]# yum -y install pcre pcre-devel openssl openssl-devel gcc gcc-c++   zlib zlib-devel gd-devel
    添加模块:
    [root@192 local]# cd nginx-1.16.0/
    添加上原来已经有的参数和新添加的模块:
    [root@192 nginx-1.16.0]# ./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' --add-module=/usr/local/echo-nginx-module-0.61
    [root@192 nginx-1.16.0]# make -j2  #编译,不要make install 否则会覆盖原来的文件
    [root@192 nginx-1.16.0]# mv /usr/sbin/nginx /usr/sbin/nginx_bak #将原来的nignx备份
    [root@192 nginx-1.16.0]# cp objs/nginx /usr/sbin/  拷贝nignx
    [root@192 nginx-1.16.0]# systemctl restart nginx  #启动
    [root@192 nginx-1.16.0]# nginx -V  查看模块是否添加成功
    nginx version: nginx/1.16.0
    built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) 
    built with OpenSSL 1.0.2k-fips  26 Jan 2017
    TLS SNI support enabled
    configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' --add-module=/usr/local/echo-nginx-module-0.61
    

    2、配置 $foo=hello

[root@192 ~]# cd /etc/nginx/conf.d/
[root@192 conf.d]# vim echo.conf
server {
        listen 80;
        server_name     localhost;
        location /test {
                set $foo hello;
                echo "foo: $foo";
        }
}

输出

[root@192 conf.d]# nginx -s reload
[root@192 conf.d]# curl localhost/test
foo: hello

Nginx 变量的创建只能发生在 Nginx 配置加载的时候,或者说 Nginx 启动的时候。而赋值操作则只会发生在请求实际处理的时候。这意味着不创建而直接使用变量会导致启动失败。

2、内置预定义变量

内置预定义变量即无需声明就可以使用的变量,通常包括一个http请求或响应中一部分内容的值,以下为一些常用的内置预定义变量

变量名 定义
$arg_PARAMETER GET请求中变量名PARAMETER参数的值。
$args 这个变量等于GET请求中的参数。例如,foo=123&bar=blahblah;这个变量只可以被修改
$binary_remote_addr 二进制码形式的客户端地址。
$body_bytes_sent 传送页面的字节数
$content_length 请求头中的Content-length字段。
$content_type 请求头中的Content-Type字段。
$cookie_COOKIE cookie COOKIE的值。
$document_root 当前请求在root指令中指定的值。
$document_uri 与$uri相同。
$host 请求中的主机头(Host)字段,如果请求中的主机头不可用或者空,则为处理请求的server名称(处理请求的server的server_name指令的值)。值为小写,不包含端口。
$hostname 机器名使用 gethostname系统调用的值
$http_HEADER HTTP请求头中的内容,HEADER为HTTP请求中的内容转为小写,-变为_(破折号变为下划线),例如:$http_user_agent(Uaer-Agent的值);
$sent_http_HEADER HTTP响应头中的内容,HEADER为HTTP响应中的内容转为小写,-变为_(破折号变为下划线),例如: $sent_http_cache_control, $sent_http_content_type…;
$is_args 如果$args设置,值为"?",否则为""。
$limit_rate 这个变量可以限制连接速率。
$nginx_version 当前运行的nginx版本号。
$query_string 与$args相同。
$remote_addr 客户端的IP地址。
$remote_port 客户端的端口。
$remote_user 已经经过Auth Basic Module验证的用户名。
$request_filename 当前连接请求的文件路径,由root或alias指令与URI请求生成。
$request_body 这个变量(0.7.58+)包含请求的主要信息。在使用proxy_pass或fastcgi_pass指令的location中比较有意义。
$request_body_file 客户端请求主体信息的临时文件名。
$request_completion 如果请求成功,设为"OK";如果请求未完成或者不是一系列请求中最后一部分则设为空。
$request_method 这个变量是客户端请求的动作,通常为GET或POST。包括0.8.20及之前的版本中,这个变量总为main request中的动作,如果当前请求是一个子请求,并不使用这个当前请求的动作。
$request_uri 这个变量等于包含一些客户端请求参数的原始URI,它无法修改,请查看$uri更改或重写URI。
$scheme 所用的协议,比如http或者是https,比如rewrite ^(.+)$ $scheme://example.com$1 redirect;
$server_addr 服务器地址,在完成一次系统调用后可以确定这个值,如果要绕开系统调用,则必须在listen中指定地址并且使用bind参数。
$server_name 服务器名称。
$server_port 请求到达服务器的端口号。
$server_protocol 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
$uri 请求中的当前URI(不带请求参数,参数位于args),不同于浏览器传递的args),不同于浏览器传递的args),不同于浏览器传递的request_uri的值,它可以通过内部重定向,或者使用index指令进行修改。不包括协议和主机名,例如/foo/bar.html

20、nginx 监控

1、nginx的基础监控
  • 进程监控
  • 端口监控

注意: 这两个是必须要加在zabbix监控,加触发器有问题及时告警。

nginx 提供了 ngx_http_stub_status_module.这个模块提供了基本的监控功能

2、监控的指标
1、基本活跃指标

Accepts(接受)、Handled(已处理)、Requests(请求数)是一直在增加的计数器。Active(活跃)、Waiting(等待)、Reading(读)、Writing(写)随着请求量而增减。

2、每秒请求数 – QPS

通过持续的 QPS 监控,可以立刻发现是否被恶意攻击或对服务的可用性进行评估。虽然当问题发生时,通过 QPS 不能定位到确切问题的位置,但是他可以在第一时间提醒你环境可能出问题了

3、服务器错误率

通过监控固定时间间隔内的错误代码(4XX代码表示客户端错误,5XX代码表示服务器端错误)。

4、请求处理时间

请求处理时间也可以被记录在 access log 中,通过分析 access log,统计请求的平均响应时间。 ----$request_time 变量

3、指标的收集

通过在编译时加入 nginxngx_http_stub_status_module 模块我们可以实时监控以下基本的指标:

1、nginx Stub Status 监控模块安装

先使用命令查看是否已经安装这个模块:

# -V大写会显示版本号和模块等信息、v小写仅显示版本信息
[root@localhost ~]# nginx -V

注意:是如果没有此模块,需要重新安装,编译命令如下:

./configure –with-http_stub_status_module

具体的使用方法是在执行 ./configure 时,指定 --with-http_stub_status_module,然后通过配置:

[root@localhost ~]# vim /etc/nginx/conf.d/status.conf 
server {
        listen 80;
        server_name localhost;
        location /nginx-status {
                stub_status     on;
                access_log      on;
                }
}
2、nginx 状态查看

配置完成后在浏览器中输入http://10.0.105.207/nginx-status 查看显示信息如下:

Active connections: 2 
server accepts handled requests
 26 26 48 
Reading: 0 Writing: 1 Waiting: 1 
3、Stub Status 参数说明

Nginx安装部署与配置管理_第19张图片

connection    #连接数,tcp连接                             
request		  #http请求,GET/POST/DELETE/UPLOAD

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rTSgrIqM-1591978467624)(assets/1567697012994.png)]

nginx总共处理了26个连接,成功创建26次握手,也就是成功的连接数connection. 总共处理了48个请求

失败连接=(总连接数(accepts)-成功连接数(handled))(相等表示中间没有失败的),
Reading : nginx读取到客户端的Header信息数。请求头 -----速度快。

​ Writing :nginx返回给客户端的Header信息数。响应头

​ Waiting :开启keep-alive的情况下,意思就是Nginx说已经处理完正在等候下一次请求指令的驻留连接。

也可以通过ngx_req_status_module能够统计Nginx中请求的状态信息。需要安装第三方模块

安装模块:

tengine官方说req-status模块默认安装。但是并没有。从github引入第三方模块解决该问题
yum与编译安装的nginx扩展模块安装:
[root@nginx-server ~]# yum install -y unzip
1. 安装,先查看一下当前编译安装nginx的版本
[root@localhost nginx-1.16.0]# nginx -V  
下载或者上传一个和当前的nginx版本一样的nginx的tar包。
[root@nginx-server ~]# tar xzf nginx-1.16.0.tar.gz -C /usr/local/
2.下载ngx_req_status_module 模块, 这是第三方模块需要添加
[root@nginx-server ~]# wget https://github.com/zls0424/ngx_req_status/archive/master.zip -O ngx_req_status.zip
[root@nginx-server ~]# unzip ngx_req_status.zip
[root@nginx-server ~]# cp -r ngx_req_status-master/ /usr/local/ #与解压的nginx在同一级目录下
[root@nginx-server ~]# cd /usr/local/nginx-1.16.0/
[root@nginx-server nginx-1.16.0]# yum -y install pcre pcre-devel openssl openssl-devel gcc gcc-c++   zlib zlib-devel
[root@nginx-server nginx-1.16.0]# yum -y install patch.x86_64
[root@nginx-server nginx-1.16.0]# patch -p1 < ../ngx_req_status-master/write_filter-1.7.11.patch
[root@localhost nginx-1.16.0]# ./configure 添加上原来的参数 --add-module=/usr/local/ngx_req_status-master
[root@localhost nginx-1.16.0]# make -j2
由于原先已有nginx,所以不能执行make install,否则会覆盖掉以前的配置文件及内容
[root@localhost nginx-1.16.0]# mv /usr/sbin/nginx /usr/sbin/nginx_bak
[root@localhost nginx-1.16.0]# cp objs/nginx /usr/sbin/
[root@localhost nginx-1.16.0]# systemctl restart nginx 
[root@localhost nginx-1.16.0]# nginx -V   
如果发现编译的配置文件有变化就成功了!
=========================
指令介绍
 req_status_zone
语法: req_status_zone name string size
默认值: None
配置块: http
# 定义请求状态ZONE,请求按照string分组来排列,例如:
req_status_zone server_url  $server_name$uri 256k;
#域名+uri将会形成一条数据,可以看到所有url的带宽,流量,访问数

#在location中启用请求状态,你可以指定更多zones。
req_status
语法: req_status zone1[ zone2]
默认值: None
配置块: http, server, location

#在当前位置启用请求状态处理程序
req_status_show
语法: req_status_show on
默认值: None
配置块: location

=============================================
配置如下: 需要在http里面配置。
[root@localhost ~]# vim /etc/nginx/nginx.conf
	req_status_zone server_name $server_name 256k;
    req_status_zone server_addr $server_addr 256k;
    req_status_zone server_url  $server_name$uri 256k;

创建配置文件:
[root@localhost ~]# vim /etc/nginx/conf.d/rep_stat.conf
 server {
        listen 80;
        server_name localhost;
        req_status server_name server_addr server_url;

        location /req-status {
        req_status_show on;
        }
}

[root@localhost ~]# nginx -t
[root@localhost ~]# nginx -s reload 

Nginx安装部署与配置管理_第20张图片
请求状态信息包括以下字段:

  • zone_name - 利用req_status_zone定义的分组标准。例如,按照服务器名称对请求进行分组后;
  • key - 请求按分组标准分组后的分组标识(即组名)。例如按服务器名称分组时,组名可能是localhost;
  • max_active - 该组的最大并发连接数;
  • max_bw - 该组的最大带宽;
  • traffic - 该组的总流量;
  • requests - 该组的总请求数;
  • active - 该组当前的并发连接数;
  • bandwidth - 该组当前带宽。

三、HTTPS 基本原理

https 介绍

HTTPS(全称:HyperText Transfer Protocol over Secure Socket Layer),其实 HTTPS 并不是一个新鲜协议,Google 很早就开始启用了,初衷是为了保证数据安全。 国内外的大型互联网公司很多也都已经启用了HTTPS,这也是未来互联网发展的趋势。

1、加密算法

  1. 对称加密

    A要给B发送数据

    1,A做一个对称密钥
    2,使用密钥给文件加密
    3,发送加密以后的文件和钥匙
    4,B拿钥匙解密

    加密和解密都是使用的同一个密钥。

  2. 非对称加密 ---- 公钥加密,私钥解密

    A要给B发送数据

    1.B做一对非对称的密钥

    2.发送公钥给A

    3.A拿公钥对数据进行加密

    4.发送加密后的数据给B

    5.B拿私钥解密

  3. 哈希算法
    将任意长度的信息转换为较短的固定长度的值,通常其长度要比信息小得多。

    例如:MD5、SHA-1、SHA-2、SHA-256 等

  4. 数字签名
    签名就是在信息的后面再加上一段内容(信息经过hash后的值),可以证明信息没有被修改过。hash值一般都会加密后(也就是签名)再和信息一起发送,以保证这个hash值不被修改。

2、HTTPS 协议介绍

  • HTTP 协议(HyperText Transfer Protocol,超文本传输协议):是客户端浏览器与Web服务器之间的应用层通信协议 。

  • HTTPS 协议(HyperText Transfer Protocol over Secure Socket Layer):可以理解为HTTP+SSL/TLS, 即 HTTP 下加入 SSL 层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL,用于安全的 HTTP 数据传输。
    Nginx安装部署与配置管理_第21张图片

  • 如上图所示 HTTPS 相比 HTTP 多了一层 SSL/TLS

    SSL/TLS :SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层为数据通讯进行加密提供安全支持。

SSL协议可分为两层: SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。相当于连接

​ SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。 相当于通信

SSL协议提供的服务主要有:

ssl:身份认证和数据加密。保证数据完整性
1)认证用户和服务器,确保数据发送到正确的客户机和服务器;

2)加密数据以防止数据中途被窃取;

3)维护数据的完整性,确保数据在传输过程中不被改变。

3、HTTPS 原理

1、HTTP 访问过程

Nginx安装部署与配置管理_第22张图片

如上图所示,HTTP请求过程中,客户端与服务器之间没有任何身份确认的过程,数据全部明文传输,“裸奔”在互联网上,所以很容易遭到黑客的攻击,如下:
Nginx安装部署与配置管理_第23张图片

可以看到,客户端发出的请求很容易被黑客截获,如果此时黑客冒充服务器,则其可返回任意信息给客户端,而不被客户端察觉。

所以 HTTP 传输面临的风险有:

  • 窃听风险:黑客可以获知通信内容。
  • 篡改风险:黑客可以修改通信内容。
  • 冒充风险:黑客可以冒充他人身份参与通信。

那有没有一种方式既可以安全的获取公钥,又能防止黑客冒充呢? 那就需要用到终极武器了:SSL 证书(申购)

  • 证书:.crt, .pem
  • 私钥:.key
  • 证书请求文件:.csr

Nginx安装部署与配置管理_第24张图片

如上图所示,在第 ② 步时服务器发送了一个SSL证书给客户端,SSL 证书中包含的具体内容有:

(1)证书的发布机构CA

(2)证书的有效期

(3)公钥

(4)证书所有者

(5)签名 ----- 签名就可以理解为是钞票里面的一个防伪标签。

客户端在接受到服务端发来的SSL证书时,会对证书的真伪进行校验,以浏览器为例说明如下:

(1)首先浏览器读取证书中的证书所有者、有效期等信息进行一一校验

(2)浏览器开始查找操作系统中已内置的受信任的证书发布机构CA,与服务器发来的证书中的颁发者CA比对,用于校验证书是否为合法机构颁发

(3)如果找不到,浏览器就会报错,说明服务器发来的证书是不可信任的。

(4)如果找到,那么浏览器就会从操作系统中取出 颁发者CA 的公钥,然后对服务器发来的证书里面的签名进行解密

(5)浏览器使用相同的hash算法计算出服务器发来的证书的hash值,将这个计算的hash值与证书中签名做对比

(6)对比结果一致,则证明服务器发来的证书合法,没有被冒充

(7)此时浏览器就可以读取证书中的公钥,用于后续加密了

(8)client与web协商对称加密算法,client生成对称加密密钥并使用web公钥加密,发送给web服务器,web服务器使用web私钥解密

(9)使用对称加密密钥传输数据,并校验数据的完整性

4、所以通过发送SSL证书的形式,既解决了公钥获取问题,又解决了黑客冒充问题,一箭双雕,HTTPS加密过程也就此形成

所以相比HTTP,HTTPS 传输更加安全

(1) 所有信息都是加密传播,黑客无法窃听。

(2) 具有校验机制,一旦被篡改,通信双方会立刻发现。

(3) 配备身份证书,防止身份被冒充。

3、HTTPS 总结

综上所述,相比 HTTP 协议,HTTPS 协议增加了很多握手、加密解密等流程,虽然过程很复杂,但其可以保证数据传输的安全。

HTTPS 缺点:

  1. SSL 证书费用很高,以及其在服务器上的部署、更新维护非常繁琐
  2. HTTPS 降低用户访问速度(多次握手)
  3. 网站改用HTTPS 以后,由HTTP 跳转到 HTTPS 的方式增加了用户访问耗时(多数网站采用302跳转)
  4. HTTPS 涉及到的安全算法会消耗 CPU 资源,需要增加大量机器(https访问过程需要加解密)

4、构建私有的 CA 机构

=========================================================================

CA中心申请证书的流程:

过程:
1。web服务器,生成一对非对称加密密钥(web公钥,web私钥)
2。web服务器使用 web私钥 生成 web服务器的证书请求,并将证书请求发给CA服务器
3。CA服务器使用 CA的私钥 对 web 服务器的证书请求 进行数字签名得到 web服务器的数字证书,并将web服务器的数字证书颁发给web服务器。
4。client访问web服务器,请求https连接,下载web数字证书
5。client下载 CA数字证书(CA身份信息+CA公钥,由上一级CA颁发,也可自签名颁发),验证 web数字证书(CA数字证书中有CA公钥,web数字证书是使用CA私钥签名的)

1、CA 介绍

CA(Certificate Authority)证书颁发机构主要负责证书的颁发、管理以及归档和吊销。证书内包含了拥有证书者的姓名、地址、电子邮件帐号、公钥、证书有效期、发放证书的CA、CA的数字签名等信息。证书主要有三大功能:加密、签名、身份验证。

2、构建私有 CA

1、检查安装 openssl
[root@https-ca ~]# rpm -qa openssl

如果未安装

[root@https-ca ~]# yum install openssl openssl-devel
2、查看配置文件

openssl 配置/etc/pki/tls/openssl.cnf有关CA的配置。如果服务器为证书签署者的身份那么就会用到此配置文件,此配置文件对于证书申请者是无作用的。

[root@https-ca ~]# vim /etc/pki/tls/openssl.cnf
####################################################################
[ ca ]
default_ca      = CA_default            # 默认的CA配置;CA_default指向下面配置块

####################################################################
[ CA_default ]

dir             = /etc/pki/CA           # CA的默认工作目录
certs           = $dir/certs            # 认证证书的目录
crl_dir         = $dir/crl              # 证书吊销列表的路径
database        = $dir/index.txt        # 数据库的索引文件


new_certs_dir   = $dir/newcerts         # 新颁发证书的默认路径

certificate     = $dir/cacert.pem       # 此服务认证证书,如果此服务器为根CA那么这里为自颁发证书
serial          = $dir/serial           # 下一个证书的证书编号
crlnumber       = $dir/crlnumber        # 下一个吊销的证书编号
                                        
crl             = $dir/crl.pem          # The current CRL
private_key     = $dir/private/cakey.pem# CA的私钥
RANDFILE        = $dir/private/.rand    # 随机数文件

x509_extensions = usr_cert              # The extentions to add to the cert

name_opt        = ca_default            # 命名方式,以ca_default定义为准
cert_opt        = ca_default            # 证书参数,以ca_default定义为准


default_days    = 365                   # 证书默认有效期
default_crl_days= 30                    # CRl的有效期
default_md      = sha256                # 加密算法
preserve        = no                    # keep passed DN ordering


policy          = policy_match          #policy_match策略生效

# For the CA policy
[ policy_match ]
countryName             = match         #国家;match表示申请者的申请信息必须与此一致
stateOrProvinceName     = match         #州、省
organizationName        = match         #组织名、公司名
organizationalUnitName  = optional      #部门名称;optional表示申请者可以的信息与此可以不一致
commonName              = supplied
emailAddress            = optional

# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]                     #由于定义了policy_match策略生效,所以此策略暂未生效
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
3、根证书服务器目录

根CA服务器:因为只有 CA 服务器的角色,所以用到的目录只有/etc/pki/CA

网站服务器:只是证书申请者的角色,所以用到的目录只有/etc/pki/tls

4、创建所需要的文件

[root@https-ca ~]# cd /etc/pki/CA/
[root@https-ca CA]# ls
certs  crl  newcerts  private
[root@https-ca CA]# touch index.txt   #创建生成证书索引数据库文件
[root@https-ca CA]# ls
certs  crl  index.txt  newcerts  private
[root@https-ca CA]# echo 01 > serial   #指定第一个颁发证书的序列号
[root@https-ca CA]# ls
certs  crl  index.txt  newcerts  private  serial
[root@https-ca CA]# 
5、创建密钥

在根CA服务器上创建密钥,密钥的位置必须为/etc/pki/CA/private/cakey.pem,这个是openssl.cnf中中指定的路径,只要与配置文件中指定的匹配即可。

[root@https-ca CA]# (umask 066; openssl genrsa -out private/cakey.pem 2048)
Generating RSA private key, 2048 bit long modulus
...........+++
...............+++
e is 65537 (0x10001)
6、生成自签名证书

根CA自签名证书,根CA是最顶级的认证机构,没有人能够认证他,所以只能自己认证自己生成自签名证书。

[root@https-ca CA]# openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -days 7300 -out /etc/pki/CA/cacert.pem -days 7300
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:BEIJING
Locality Name (eg, city) [Default City]:BEIJING
Organization Name (eg, company) [Default Company Ltd]:CA
Organizational Unit Name (eg, section) []:OPT
Common Name (eg, your name or your server's hostname) []:ca.qf.com
Email Address []:
[root@https-ca CA]# ls
cacert.pem  certs  crl  index.txt  newcerts  private  serial
-new: 	生成新证书签署请求
-x509: 	专用于CA生成自签证书
-key: 	生成请求时用到的私钥文件
-days n:	证书的有效期限
-out /PATH/TO/SOMECERTFILE: 	证书的保存路径
7、下载安装证书

/etc/pki/CA/cacert.pem就是生成的自签名证书文件,使用 SZ/xftp工具将他导出到窗口机器中。然后双击安装此证书到受信任的根证书颁发机构

[root@https-ca CA]# yum install -y lrzsz
[root@https-ca CA]# sz cacert.pem

Nginx安装部署与配置管理_第25张图片

Nginx安装部署与配置管理_第26张图片
Nginx安装部署与配置管理_第27张图片

Nginx安装部署与配置管理_第28张图片
Nginx安装部署与配置管理_第29张图片

3、客户端CA 证书申请及签名

1、检查安装 openssl

[root@nginx-server ~]# rpm -qa openssl

如果未安装,安装 openssl

[root@nginx-server ~]# yum install openssl openssl-devel

2、客户端生成私钥文件

[root@nginx-server ~]# (umask 066; openssl genrsa -out /etc/pki/tls/private/www.qf.com.key 2048)
Generating RSA private key, 2048 bit long modulus
..............................+++
..........+++
e is 65537 (0x10001)
[root@nginx-server ~]# cd /etc/pki/tls/private/
[root@nginx-server private]# ls
www.qf.com.key
[root@nginx-server private]#

3、客户端用私钥加密生成证书请求

[root@nginx-server private]# ls ../
cert.pem  certs  misc  openssl.cnf  private
[root@nginx-server private]# openssl req -new -key /etc/pki/tls/private/www.qf.com.key -days 365 -out /etc/pki/tls/www.qf.com.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:BEIJING
Locality Name (eg, city) [Default City]:BEIJING
Organization Name (eg, company) [Default Company Ltd]:QF
Organizational Unit Name (eg, section) []:OPT
Common Name (eg, your name or your server's hostname) []:www.qf.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@nginx-server private]# ls ../
cert.pem  certs  misc  openssl.cnf  private  www.qf.com.csr
[root@nginx-server private]#

CSR(Certificate Signing Request)包含了公钥和名字信息。通常以.csr为后缀,是网站向CA发起认证请求的文件,是中间文件。

在这一命令执行的过程中,系统会要求填写如下信息:
Nginx安装部署与配置管理_第30张图片

最后把生成的请求文件(/etc/pki/tls/www.qf.com.csr)传输给CA ,这里我使用scp命令,通过ssh协议,将该文件传输到CA下的/etc/pki/CA/private/目录

[root@nginx-server private]# cd ../
[root@nginx-server tls]# scp www.qf.com.csr 10.0.105.181:/etc/pki/CA/private
[email protected]'s password: 
www.qf.com.csr                                                           100%  997   331.9KB/s   00:00 

4、在ca服务器上面操作:CA 签署证书

默认使用/etc/pki/tls/openssl.cnf,里面要求其一致,修改organizationName=supplied

修改 /etc/pki/tls/openssl.cnf

[root@https-ca ~]# vim /etc/pki/tls/openssl.cnf
policy          = policy_match
 82 
 83 # For the CA policy
 84 [ policy_match ]
 85 countryName             = match
 86 stateOrProvinceName     = match
 87 organizationName        = supplied
 88 organizationalUnitName  = optional
 89 commonName              = supplied
 90 emailAddress            = optional

2、查看生成的证书的信息

[root@https-ca ~]# openssl ca -in /etc/pki/CA/private/www.qf.com.csr -out /etc/pki/CA/certs/www.qf.com.crt -days 365
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Jul  3 10:12:23 2019 GMT
            Not After : Jul  2 10:12:23 2020 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = BEIJING
            organizationName          = QF
            organizationalUnitName    = OPT
            commonName                = www.qf.com
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                E3:AC:1A:55:2B:28:B9:80:DC:9C:C2:13:70:53:27:AD:3D:44:8F:D3
            X509v3 Authority Key Identifier: 
                keyid:5D:2A:81:B2:E7:8D:D8:88:E5:7B:94:CA:75:65:9C:82:2B:A9:B2:3C

Certificate is to be certified until Jul  2 10:12:23 2020 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

证书通常以.crt为后缀,表示证书文件

1、查看生成的证书的信息

[root@https-ca ~]# openssl x509 -in /etc/pki/CA/certs/www.qf.com.crt -noout -subject
subject= /C=CN/ST=BEIJING/O=QF/OU=OPT/CN=www.qf.com

2、将生成的证书发放给请求客户端

[root@https-ca ~]# cd /etc/pki/CA/certs/
[root@https-ca certs]# scp www.qf.com.crt 10.0.105.199:/etc/pki/CA/certs/
[email protected]'s password: 
www.qf.com.crt                                                           100% 4422   998.3KB/s   00:00 

测试:

在nginx-server端操作:
[root@nginx-server ~]# cd /etc/pki/CA/certs/
[root@nginx-server certs]# ls
www.qf.com.crt
[root@nginx-client certs]#  find / -name *.key
/etc/pki/tls/private/www.qf.com.key
/usr/share/doc/openssh-7.4p1/PROTOCOL.key

还是在这台机器安装nginx并且配置证书:
root@localhost conf.d]# pwd
/etc/nginx/conf.d
[root@localhost conf.d]# vim nginx.conf
server {
        listen       443 ssl;
        server_name  localhost;

        ssl_certificate         /etc/pki/CA/certs/www.qf.com.crt;  #指定证书路径
        ssl_certificate_key  /etc/pki/tls/private/www.qf.com.key;  #指定私钥路径
        ssl_session_timeout  5m;   #配置用于SSL会话的缓存
        ssl_protocols  SSLv2 SSLv3 TLSv1;   #指定使用的协议
        ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; # //密码指定为OpenSSL支持的格式
        ssl_prefer_server_ciphers   on;  #设置协商加密算法时,优先使用服务端的加密,而不是客户端浏览器的。

        location / {
                root /usr/share/nginx/html;
                index index.html index.htm;
                }
}
保存重启
[root@localhost conf.d]# nginx -t 
[root@localhost conf.d]# nginx -s reload

浏览器测试访问:

Nginx安装部署与配置管理_第31张图片

Nginx安装部署与配置管理_第32张图片

阿里云配置证书案例:

1.接着需要把这两个证书文件给复制到服务器当中去,首先需要在服务器创建对应的文件夹,参考命令如下
[root@nginx ~]# cd /etc/nginx/ && mkdir cert
2.在服务器创建完成对应文件夹之后,将证书文件复制到服务器中
[root@nginx ~]# ls
2447549_www.testpm.cn_nginx.zip
[root@nginx ~]# unzip 2447549_www.testpm.cn_nginx.zip
Archive:  2447549_www.testpm.cn_nginx.zip
Aliyun Certificate Download
  inflating: 2447549_www.testpm.cn.pem  
  inflating: 2447549_www.testpm.cn.key   
[root@nginx ~]# ls
2447549_www.testpm.cn.key  2447549_www.testpm.cn_nginx.zip  2447549_www.testpm.cn.pem
[root@nginx ~]# cp 2447549_www.testpm.cn* /etc/nginx/cert/
[root@nginx ~]# cd /etc/nginx/cert/
[root@nginx cert]# mv 2447549_www.testpm.cn.key www.testpm.cn.key 
[root@nginx cert]# mv 2447549_www.testpm.cn.pem www.testpm.cn.pem
证书配置
证书复制完成之后,可以对nginx配置文件进行更改,使用vim命令
[root@nginx ~]# cd /etc/nginx/conf.d/
[root@nginx conf.d]# vim nginx_ssl.conf
[root@nginx conf.d]# cat /etc/nginx/conf.d/nginx_ssl.conf 
server {
    listen 443 ssl;
    server_name www.testpm.cn;
    access_log  /var/log/nginx/https_access.log  main;

    ssl_certificate   /etc/nginx/cert/www.testpm.cn.pem;;
    ssl_certificate_key  /etc/nginx/cert/www.testpm.cn.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
    ssl_prefer_server_ciphers on;

    location / {
        root  /usr/share/nginx/html;
        index index.html index.htm;
    }
}

5、nginx 性能优化

当我需要进行性能优化时,说明我们服务器无法满足日益增长的业务,需要从以下几个方面进行探讨

1、当前系统结构瓶颈

首先需要了解的是当前系统瓶颈,用的是什么,跑的是什么业务。里面的服务是什么样子,每个服务最大支持多少并发。

可以通过查看当前cpu负荷,内存使用率,来做简单判断。还可以通过操作系统的一些工具来判断当前系统性能瓶颈,如分析对应的日志,查看请求数量。也可以通过nginx http_stub_status_module模块来查看对应的连接数,总握手次数,总请求数。

2、了解业务模式

虽然我们是在做性能优化,但还是要熟悉业务,最终目的都是为业务服务的。我们要了解每一个接口业务类型是什么样的业务,比如电子商务抢购模式,这种情况平时流量会很小,但是到了抢购时间,流量一下子就会猛涨。也要了解系统层级结构,每一层在中间层做的是代理还是动静分离,还是后台进行直接服务。

3、性能与安全

性能与安全也是一个需要考虑的因素,往往大家注重性能忽略安全或注重安全又忽略性能。比如说我们在设计防火墙时,如果规则过于全面肯定会对性能方面有影响。如果对性能过于注重在安全方面肯定会留下很大隐患。所以大家要评估好两者的关系,把握好两者的孰重孰轻,以及整体的相关性。权衡好对应的点。

4、系统与nginx性能优化

对相关的系统瓶颈及现状有了一定的了解之后,就可以根据影响性能方面做一个全体的评估和优化。

  • 网络(网络流量、是否有丢包,网络的稳定性都会影响用户请求)
  • 系统(系统负载、内存使用率、系统的稳定性、硬件磁盘是否有损坏)
  • 服务(连接优化、内核性能优化、http服务请求优化都可以在nginx中根据业务来进行设置)
  • 程序(接口性能、处理请求速度、每个程序的执行效率)
  • 数据库、底层服务

上面列举出来每一级都会有关联,也会影响整体性能,这里主要关注的是nginx服务这一层。

1、文件句柄

在linux/unix操作系统中一切皆文件,我们的设备是文件,文件是文件,文件夹也是文件。当我们用户每发起一次请求,就会产生一个文件句柄。文件句柄可以简单的理解为文件句柄就是一个索引。文件句柄就会随着请求量的增多,进程调用频繁增加,那么产生的文件句柄也就会越多。

系统默认对文件句柄是有限制的,不可能会让一个进程无限制的调用句柄。因为系统资源是有限的,所以我们需要限制每一个服务能够使用多大的文件句柄。操作系统默认使用的文件句柄是1024个句柄。

2、设置方式
  • 系统全局性修改
  • 用户局部性修改
  • 进程局部性修改
3、系统全局性修该和用户局部性修改
[root@nginx-server ~]# vim /etc/security/limits.conf 
#*               soft    core            0
#*               hard    rss             10000
#@student        hard    nproc           20
#@faculty        soft    nproc           20
#@faculty        hard    nproc           50
#ftp             hard    nproc           0
#@student        -       maxlogins       4

#root只是针对root这个用户来限制,soft只是发提醒,操作系统不会强制限制,一般的站点设置为一万左右就ok了
root soft nofile 65535
root hard nofile 65535
# *代表通配符 所有的用户
*    soft nofile 25535
*    hard nofile 25535  #hard硬控制,到达设定值后,操作系统会采取机制对当前进程进行限制,这个时候请求就会受到影响

可以看到root*,root代表是root用户,*代表的是所有用户,后面的数字就是文件句柄大小。大家可以根据个人业务来进行设置。

4、进程局部性修改

[root@nginx-server ~]# vim /etc/nginx/nginx.conf
user  nginx;  #运行nginx的用户。可以修改
worker_processes  1;  

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

worker_rlimit_nofile 65535; #进程限制

events {
    worker_connections  1024;  #一个worker进程的并发
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$http_user_agent' '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" '
                      '"$args" "$request_uri"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on; 
    #tcp_nopush     on; 

    keepalive_timeout  65; 

    #gzip  on; 

    include /etc/nginx/conf.d/*.conf;
}

worker_rlimit_nofile 是在进程上面进行限制。

5、cpu的亲和配置

cpu的亲和能够使nginx对于不同的work工作进程绑定到不同的cpu上面去。就能够减少在work间不断切换cpu,来减少性能损耗。nginx 亲和配置

查看物理cpu

[root@nginx-server ~]# cat /proc/cpuinfo | grep "physical id" | sort|uniq | wc -l

查看cpu核心数

[root@nginx-server ~]# cat /proc/cpuinfo|grep "cpu cores"|uniq

查看cpu使用率

[root@nginx-server ~]#top  回车后按 1

6、配置worker_processes

[root@nginx-server ~]# vim /etc/nginx/nginx.conf
将刚才查看到自己cpu * cpu核心就是worker_processes
worker_processes 2; #根据自己cpu核心数配置/这里也可以设置为auto
7、cpu

通过下面命令查看nginx进程配置在哪个核上

[root@nginx-server ~]# ps -eo pid,args,psr |grep [n]ginx

在nginx 1.9版本之后,就帮我们自动绑定了cpu;

worker_cpu_affinity auto;

8、nginx通用配置优化

#将nginx进程设置为普通用户,为了安全考虑
user nginx; 

#当前启动的worker进程,官方建议是与系统核心数一致
worker_processes 2;
#方式一,就是自动分配绑定
worker_cpu_affinity auto;

#日志配置成warn
error_log /var/log/nginx/error.log warn; 
pid /var/run/nginx.pid;

#针对 nginx 句柄的文件限制
worker_rlimit_nofile 35535;
#事件模型
events {
    #使用epoll内核模型
    user epoll;
    #每一个进程可以处理多少个连接,如果是多核可以将连接数调高 worker_processes * 1024
    worker_connections 10240;
}

http {
    server_tokens off;  #隐藏nginx的版本号
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    charset utf-8;  #设置字符集,服务端返回给客户端报文的时候,Nginx强行将报文转码为utf-8

    #设置日志输出格式,根据自己的情况设置
    log_format  main  '$http_user_agent' '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" '
                      '"$args" "$request_uri"';

    access_log  /var/log/nginx/access.log  main;
    
    sendfile        on;   #对静态资源的处理比较有效
    #tcp_nopush     on;   #如果做静态资源服务器可以打开

    keepalive_timeout  65; 

    ########
    #Gzip module
    gzip  on;    #文件压缩默认可以打开.告诉nginx采用gzip压缩的形式发送数据。这将会减少发送的数据量。
    gzip_disable "MSIE [1-6]\."; #对于有些浏览器不能识别压缩,需要过滤如ie6
    gzip_http_version 1.1; #设置识别 http 协议版本,默认是 1.1

    include /etc/nginx/conf.d/*.conf;
}

扩展

ulimit 命令
# -a  显示目前资源限制的设定。
• -c <core文件上限>  设定core文件的最大值,单位为区块。
• -d <数据节区大小>  程序数据节区的最大值,单位为KB。
• -f <文件大小>  shell所能建立的最大文件,单位为区块。
• -H  设定资源的硬性限制,也就是管理员所设下的限制。
• -m <内存大小>  指定可使用内存的上限,单位为KB。
# -n <文件数目>  指定同一时间最多可开启的文件数。
• -p <缓冲区大小>  指定管道缓冲区的大小,单位512字节。
• -s <堆叠大小>  指定堆叠的上限,单位为KB。
• -S  设定资源的弹性限制。
• -t <CPU时间>  指定CPU使用时间的上限,单位为秒。
• -u <程序数目>  用户最多可开启的程序数目。
• -v <虚拟内存大小>  指定可使用的虚拟内存上限,单位为KB


1、ulimit -a       显示系统资源的设置
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 63154
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 63154
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

2、ulimit -n 65535  #修改打开句柄数  ---临时

5、ab接口压力测试工具

ab是Apache超文本传输协议(HTTP)的性能测试工具。其设计意图是描绘当前所安装的Apache的执行性能,主要是显示你安装的Apache每秒可以处理多少个请求。

[root@nginx-server ~]# yum install httpd-tools
[root@nginx-server ~]# ab -n 2000 -c 2 http://127.0.0.1/
-n 总的请求数
-c 并发数
-k 是否开启长连接
-X:指定使用的端口号,例如:"126.10.10.3:88"

1、参数选项

-n:即requests,用于指定压力测试总共的执行次数
-c:即concurrency,用于指定的并发数
-t:即timelimit,等待响应的最大时间(单位:秒)
-b:即windowsize,TCP发送/接收的缓冲大小(单位:字节)
-p:即postfile,发送POST请求时需要上传的文件,此外还必须设置-T参数
-u:即putfile,发送PUT请求时需要上传的文件,此外还必须设置-T参数
-T:即content-type,用于设置Content-Type请求头信息,例如:application/x-www-form-urlencoded,默认值为text/plain
-v:即verbosity,指定打印帮助信息的冗余级别
-w:以HTML表格形式打印结果
-i:使用HEAD请求代替GET请求
-x:插入字符串作为table标签的属性
-y:插入字符串作为tr标签的属性
-z:插入字符串作为td标签的属性
-C:添加cookie信息,例如:"Apache=1234"(可以重复该参数选项以添加多个)
-H:添加任意的请求头,例如:"Accept-Encoding: gzip",请求头将会添加在现有的多个请求头之后(可以重复该参数选项以添加多个)
-A:添加一个基本的网络认证信息,用户名和密码之间用英文冒号隔开
-P:添加一个基本的代理认证信息,用户名和密码之间用英文冒号隔开
-X:指定使用的和端口号,例如:"126.10.10.3:88"
-V:打印版本号并退出
-k:使用HTTP的KeepAlive特性
-d:不显示百分比
-S:不显示预估和警告信息
-g:输出结果信息到gnuplot格式的文件中
-e:输出结果信息到CSV格式的文件中
-r:指定接收到错误信息时不退出程序
-H:显示用法信息,其实就是ab -help

2、内容解释

Server Software:        nginx/1.10.2 (服务器软件名称及版本信息)
Server Hostname:        192.168.1.106(服务器主机名)
Server Port:            80 (服务器端口)

Document Path:          /index1.html. (供测试的URL路径)
Document Length:        3721 bytes (供测试的URL返回的文档大小)

Concurrency Level:      1000 (并发数)
Time taken for tests:   2.327 seconds (压力测试消耗的总时间)
Complete requests:      5000 (的总次数)
Failed requests:        688 (失败的请求数)
Write errors:           0 (网络连接写入错误数)
Total transferred:      17402975 bytes (传输的总数据量)
HTML transferred:       16275725 bytes (HTML文档的总数据量)
Requests per second:    2148.98 [#/sec] (mean) (平均每秒的请求数) 这个是非常重要的参数数值,服务器的吞吐量 #计算公式:总请求数 / 处理这些请求的总完成时间
Time per request:       465.338 [ms] (mean) (所有并发用户(这里是1000)都请求一次的平均时间)
Time  request:       	0.247 [ms] (mean, across all concurrent requests) (单个用户请求一次的平均时间)
Transfer rate:          7304.41 [Kbytes/sec] received 每秒获取的数据长度 (传输速率,单位:KB/s)
...
Percentage of the requests served within a certain time (ms)
  50%    347  ## 50%的请求在347ms内返回 
  66%    401  ## 60%的请求在401ms内返回 
  75%    431
  80%    516
  90%    600
  95%    846
  98%   1571
  99%   1593
  100%   1619 (longest request)

3、示例演示

注意事项

● 测试机与被测试机要分开

● 不要对线上的服务器做压力测试

● 观察测试工具ab所在机器,以及被测试的机器的CPU、内存、网络等都不超过最高限度的75%

[root@nginx-server ~]# ab -n 50 -c 2 http://www.testpm.cn/
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking www.testpm.cn (be patient).....done


Server Software:        nginx/1.16.0
Server Hostname:        www.testpm.cn
Server Port:            80

Document Path:          /
Document Length:        612 bytes

Concurrency Level:      2
Time taken for tests:   2.724 seconds
Complete requests:      50
Failed requests:        0
Write errors:           0
Total transferred:      42250 bytes
HTML transferred:       30600 bytes
Requests per second:    18.35 [#/sec] (mean)
Time per request:       108.968 [ms] (mean)
Time per request:       54.484 [ms] (mean, across all concurrent requests)
Transfer rate:          15.15 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       42   52  17.3     46     137
Processing:    43   54  20.8     47     170
Waiting:       42   53  20.7     47     170
Total:         84  106  28.9     93     219

Percentage of the requests served within a certain time (ms)
  50%     93
  66%     96
  75%    101
  80%    130
  90%    153
  95%    161
  98%    219
  99%    219
 100%    219 (longest request)

你可能感兴趣的:(运维之道)