HTTP
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。HTTP是一个基于TCP/IP通信协议
来传递数据(HTML 文件, 图片文件, 查询结果等)。
http工作原理
1、HTTP 工作原理
HTTP协议工作于客户端-服务端架构上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。
Web服务器有:Nginx,Apache服务器,IIS服务器(Internet Information Services)等。
Web服务器根据接收到的请求后,向客户端发送响应信息。
HTTP默认端口号为80,但是你也可以改为8080或者其他端口。HTTP三点注意事项:
-HTTP是无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
-HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。
-HTTP是无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
2.HTTP协议通信流程
1/87
http消息结构
消息结构:
HTTP是基于客户端/服务端(C/S)的架构模型,通过一个可靠的链接来交换信息,是一个无状态的请求/响应协议。
一个HTTP"客户端"是一个应用程序(Web浏览器或其他任何客户端),通过连接到服务器达到向服务
器发送一个或多个HTTP的请求的目的。
一个HTTP"服务器"同样也是一个应用程序(通常是一个Web服务,如Apache Web服务器或IIS服务器等),通过接收客户端的请求并向客户端发送HTTP响应数据。
HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。
客户端请求
客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行(request line)、请求头部(header)、空行和请求数据四个部分组成,下图给出了请求报文的一般格式。
服务器响应消息
HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。
2/87
下面实例是一点典型的使用GET来传递数据的实例:客户端请求:
Connected to www.testpm.cn (47.244.247.240) port 80 (#0)
GET /hello.txt HTTP/1.1 # 请求方式与版本协议。
User-Agent: curl/7.29.0 #用什么客户端访问
Host: www.testpm.cn #主机名,域名。主机和端口号,
Accept: / #匹配什么文件类型,“*” 是通用匹配。匹配所有类型
服务端响应:
< HTTP/1.1 200 OK #请求返回的状态码
<Server: nginx/1.16.0 #请求的服务和版本号
<Date: Thu, 04 Jul 2019 08:19:40 GMT
<Content-Type: text/plain #文本类型,有html,plain:普通文本
<Content-Length: 12
<Last-Modified: Thu, 04 Jul 2019 08:13:25 GMT
<Connection: keep-alive #是否支持长连接
<ETag: "5d1db525-c" #标识,每次访问如果与最开始的一样返回304否则校验不一致返回200
<Accept-Ranges: bytes
HTTP 请求方法
根据HTTP标准,HTTP请求可以使用多种请求方法。
HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
3/87
HTTP 响应头信息
HTTP请求头提供了关于请求,响应或者其他的发送实体的信息。在本章节中我们将具体来介绍HTTP响应头信息。
4/87
应答头 说明
Allow 服务器支持哪些请求方法(如GET、POST等)。
Content-Encoding 文档的编码(Encode)方法。只有在解码之后才可以得到Content-Type头指
定的内容类型。利用gzip压缩文档能够显著地减少HTML文档的下载时间。
Java的GZIPOutputStream可以很方便地进行gzip压缩,但只有Unix上的
Netscape和Windows上的IE 4、IE 5才支持它。因此,Servlet应该通过查看
Accept-Encoding头(即request.getHeader("Accept-Encoding"))检查浏览器是
否支持gzip,为支持gzip的浏览器返回经gzip压缩的HTML页面,为其他浏览器
返回普通页面。
Content-Length 表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。如果你
想要利用持久连接的优势,可以把输出文档写入 ByteArrayOutputStream,完
成后查看其大小,然后把该值放入Content-Length头,最后通过
byteArrayStream.writeTo(response.getOutputStream()发送内容。
Content-Type 表示后面的文档属于什么MIME类型。Servlet默认为text/plain,但通常需要显
式地指定为text/html。由于经常要设置Content-Type,因此
HttpServletResponse提供了一个专用的方法setContentType。
Date 当前的GMT时间。你可以用setDateHeader来设置这个头以避免转换时间格式
的麻烦。
Expires 应该在什么时候认为文档已经过期,从而不再缓存它?
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)。
HTTP 状态码
当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应浏览器的请求。
HTTP状态码的英文为HTTP Status Code。
下面是常见的HTTP状态码:
5/87
•200 - 请求成功
•301 - 资源(网页等)被永久转移到其它URL
•404 - 请求的资源(网页等)不存在
•500 - 内部服务器错误
HTTP状态码分类
HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。HTTP状态码共分为5种类型:
HTTP状态码列表:
6/87
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,返回信息会包括新的U
浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
302 Found 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有
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 客户端请求信息的先决条件错误
状态码 状态码英文名称 中文描述
7/87
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协议的版本,无法完成处理
状态码 状态码英文名称 中文描述
apache虚拟主机
创建apache虚拟主机
1.安装apache服务 yum -y install httpd httpd-tools httpd-devel mod_ssl (支持https认证) systemctl start httpd
systemctl enable httpd 2.创建虚拟主机的配置文件 /etc/httpd/conf.d/ 下创建.conf的虚拟主机配置文件 (主配置文件在/etc/httpd/ conf/httpd.conf)
分类:
基于 端口
基于ip
基于域名
第一种:基于域名的虚拟主机 vim /etc/httpd/conf.d/web.conf < VirtualHost *:80 >
Servername www.blackmed.cn serverAlias blackmed.cn DocumentRoot /web1
</VirtualHost >
<Directory "/wed1" > Require all granted
</Directory >
<VirtualHost *:80 >
ServerName www.blackcloud.cn
ServerAlias blackcloud.cn
DocumentRoot /web2
</VirtualHost >
<Directory " /web2 "> Require all granted
</Directory>
3.创建网站发布目录和网站
mkdir /web1 /web2
8/87
注意:一般的公司都是基于域名创建虚拟主机基于ip创建的虚拟主机,其他的相同,ip不同
基于端口创建的虚拟主机,其他的相同,端口不同
Nginx
简介
Nginx (engine x) 是一个高性能的 HTTP 和 反向代理 服务,也是一个IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于
2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。
Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
在高连接并发的情况下,Nginx是Apache服务器不错的替代品。
创始人伊戈尔·赛索耶夫
9/87
nginx功能
Nginx 是一个高性能的 Web 和反向代理服务器, 它具有有很多非常优越的特性:
单机环境下参考服务器配置。 并发连接数在7000+ -8000左右。 集群模式20000+
作为 Web 服务器:相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效率,这
点使 Nginx 尤其受到虚拟主机提供商的欢迎。能够支持高达 50,000 个并发连接数的响应,感谢 Nginx 为我们选择了 epoll and kqueue 作为开发模型.
作为负载均衡服务器:Nginx 既可以在内部直接支持 Rails 和 PHP,也可以支持作为 HTTP代理服务器对外进行服务。Nginx 用 C 编写, 不论是系统资源开销还是 CPU 使用效率都比 Perlbal 要好的多。
作为邮件代理服务器: Nginx 同时也是一个非常优秀的邮件代理服务器(最早开发这个产品的目的之
一也是作为邮件代理服务器),Last.fm 描述了成功并且美妙的使用经验。
Nginx 安装非常的简单,配置文件 非常简洁(还能够支持perl语法),Bugs非常少的服务器: Nginx 启
动特别容易,并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动。你还能够在 不间断服务的情况下进行软件版本的升级。
异步,非阻塞
$ pstree |grep nginx
|-+= 81666 root nginx: master process nginx
| |--- 82500 nobody nginx: worker process
| --- 82501 nobody nginx: worker process
1个master进程,2个work进程
10/87
注意:Input/Output====I/O
每进来一个request,会有一个worker进程去处理。但不是全程的处理,处理到什么程度呢?处理到可能发生阻塞的地方,比如向上游(后端)服务器转发request,并等待请求返回。那么,这个处理的worker不会这么一直等着,他会在发送完请求后,注册一个事件:“如果upstream返回了,告诉我一声,我再接着干”。于是他就休息去了。这就是异步。此时,如果再有request 进来,他就可以很快再按这种方式处理。这就是非阻塞和IO多路复用。而一旦上游服务器返回了,就会触发这个事件,worker才会来接手,这个request才会接着往下走。这就是异步回调。
客户(发送方)向收款员(接收方)付款(发送请求)后在等待收款员找零的过程中,还可以做其他
事情,比如打电话、聊天等;而收款员在等待收款机处理交易(IO操作)的过程中还可以帮助客户将商品打包,当收款机产生结果后,收款员给客户结账(响应请求)。在四种方式中,这种方式是发送方和接收方通信效率最高的一种。
同步与异步的重点在消息通知的方式上,也就是调用结果通知的方式。
同步:当一个同步调用发出去后,调用者要一直等待调用结果的通知后,才能进行后续的执行。异步:当一个异步调用发出去后,调用者不能立即得到调用结果的返回。
同步取快递:小明收到快递将送达的短信,在楼下一直等到快递送达。
异步取快递:小明收到快递将送达的短信,快递到楼下后,小明再下楼去取。异步取快递,小明知道快递到达楼下有两种方式:
1、不停的电话问快递小哥到了没有,即主动轮询;
2、快递小哥到楼下后,打电话通知小明,然后小明下楼取快递,即回调通知。
阻塞与非阻塞在于进/线程等待消息时候的行为,也就是在等待消息的时候,当前进/线程是挂起还是非挂起状态。
-阻塞阻塞调用在发出去后,在消息返回之前,当前进/线程会被挂起,直到有消息返回,当前进/线程才会被激活
-非阻塞非阻塞调用在发出去后,不会阻塞当前进/线程,而会立即返回。
阻塞取快递:小明收到快递即将送达的信息后,什么事都不做,一直专门等快递。
非阻塞取快递:小明收到快递即将送达的信息后,等快递的时候,还一边敲代码、一边刷微信。
总结: 异步非阻塞:小明收到信息后,边刷着微博,边等快递员通知他取快递。
I/O多路复用 epoll()
epoll能更高效的检查大量fd,UNIX中提供了类似功能的kqueue调用。epoll可以理解为event poll,不同于忙轮询和无差别轮询,当连接有I/O流事件产生的时候,epoll就会去告
诉进程哪个连接有I/O流事件产生,然后进程就去处理这个事件。此时我们对这些流的操作都是有意义的。(复杂度降低到了O(k),k为产生I/O事件的流的个数,也有认为O(1)的)
小明家楼下有一个收发室,每次有快递到了,就先代收并做了标记;然后通知小明去取送给小明的快递。
nginx 的内部技术架构
Nginx服务器,以其处理网络请求的高并发、高性能及高效率,获得了行业界的广泛认可,近年已稳居web服务器部署排名第二的位置,并被广泛用于反向代理和负载均衡。
Nginx是如何实现这些目标的呢?答案就是其独特的内部技术架构设计。看懂下面这张图,就明白了
Nginx的内部技术架构。
简要说明几点:
1)nginx启动时,会生成两种类型的进程,一个是主进程(Master),一个(windows版本的目前只有一
11/87
个)或多个工作进程(Worker)。主进程并不处理网络请求,主要负责调度工作进程,也就是图示的三
项:加载配置、启动工作进程及非停升级。所以,nginx启动以后,查看操作系统的进程列表,我们就能看到至少有两个nginx进程。
2)服务器实际处理网络请求及响应的是工作进程(worker),在类unix系统上,nginx可以配置多个worker,而每个worker进程都可以同时处理数以千计的网络请求。
3)模块化设计。nginx的worker,包括核心和功能性模块,核心模块负责维持一个运行循环(run-loop),执行网络请求处理的不同阶段的模块功能,如网络读写、存储读写、内容传输、外出过滤,以及将请求发往上游服务器等。而其代码的模块化设计,也使得我们可以根据需要对功能模块进行适当的选择和修改,编译成具有特定功能的服务器。
4)事件驱动、异步及非阻塞,可以说是nginx得以获得高并发、高性能的关键因素,同时也得益于对
Linux、Solaris及类BSD等操作系统内核中事件通知及I/O性能增强功能的采用,如kqueue、epoll及event ports。5)代理(proxy)设计,可以说是nginx深入骨髓的设计,无论是对于HTTP,还是对于FastCGI、
memcache、Redis等的网络请求或响应,本质上都采用了代理机制。所以,nginx天生就是高性能的代理服务器
nginx安装部署
nginx部署-Yum安装
访问nginx的官方网站:http://www.nginx.org/ Nginx版本类型 Mainline version: 主线版,即开发版
Stable version: 最新稳定版,生产环境上建议使用的版本
Legacy versions: 遗留的老版本的稳定版
Yum安装nginx
配置Yum源的官网:http://nginx.org/en/linux_packages.html
1、配置nginx的Yum源 Installation instructions
Before you install nginx for the first time on a new machine, you need to set up the nginx packages repository. Afterward, you can install and update nginx from the repository.
安装说明
在新计算机上首次安装nginx之前,需要设置nginx软件包存储库。 之后,您可以从存储库安装和更新nginx。
To set up the yum repository, create the file named /etc/yum.repos.d/nginx.repo with the following contents:
[nginx-stable] name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=1
enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key
[nginx-mainline] name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/ gpgcheck=1
enabled=0
12/87
gpgkey=https://nginx.org/keys/nginx_signing.key
yum install yum-utils -y yum-config-manager --enable nginx-mainline yum install nginx -y
这里我们用稳定版本 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/s/enforcing/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
nginx编译安装
1、安装编译环境
yum -y install gcc gcc-c++ make ncurses ncurses-devel
2、安装pcre软件包(使nginx支持http rewrite模块) yum install -y pcre pcre-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/ [root@localhost ~]# cd /usr/local/nginx-1.16.0/
13/87
[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 && make install
编译参数
[root@localhost ~]#/usr/local/nginx/sbin/nginx -V
--with-cc-opt='-g -O2 -fPIE -fstack-protector //设置额外的参数将被添加到CFLAGS变量。(FreeBSD或者ubuntu使用)
--param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now'
--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-path=/var/lock/nginx.lock //指定lock文件
--pid-path=/run/nginx.pid //指定pid文件
--http-client-body-temp-path=/var/lib/nginx/body //设定http客户端请求临时文件路径
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi //设定http fastcgi临时文件路径
--http-proxy-temp-path=/var/lib/nginx/proxy //设定http代理临时文件路径
--http-scgi-temp-path=/var/lib/nginx/scgi //设定http scgi临时文件路径
--http-uwsgi-temp-path=/var/lib/nginx/uwsgi //设定http uwsgi临时文件路径
--with-debug //启用debug日志
--with-pcre-jit //编译PCRE包含“just-in-time compilation”
--with-ipv6 //启用ipv6支持
--with-http_ssl_module //启用ssl支持
--with-http_stub_status_module //获取nginx自上次启动以来的状态
--with-http_realip_module //允许从请求标头更改客户端的IP地址值,默认为关
--with-http_auth_request_module //实现基于一个子请求的结果的客户端授权。如果该子请求返回的
2xx响应代码,所述接入是允许的。如果它返回401或403中,访问被拒绝与相应的错误代码。由子请求返回的任何其他响应代码被认为是一个错误。
--with-http_addition_module //作为一个输出过滤器,支持不完全缓冲,分部分响应请求
--with-http_dav_module //增加PUT,DELETE,MKCOL:创建集合,COPY和MOVE方法 默认关闭,需
编译开启
--with-http_geoip_module //使用预编译的MaxMind数据库解析客户端IP地址,得到变量值
--with-http_gunzip_module //它为不支持“gzip”编码方法的客户端解压具有“Content-Encoding:
gzip”头的响应。
--with-http_gzip_static_module //在线实时压缩输出数据流
--with-http_image_filter_module //传输JPEG/GIF/PNG 图片的一个过滤器)(默认为不启用。gd库要用
到)
--with-http_spdy_module //SPDY可以缩短网页的加载时间
--with-http_sub_module //允许用一些其他文本替换nginx响应中的一些文本
--with-http_xslt_module //过滤转换XML请求
--with-mail //启用POP3/IMAP4/SMTP代理模块支持
--with-mail_ssl_module //启用ngx_mail_ssl_module支持启用外部模块支持
14/87
nginx部署
nginx.conf的组成:nginx.conf一共由三部分组成,分别为:全局块、events块、http块。在http块中又包含http全局块、多个server块。每个server块中又包含server全局块以及多个location块。在统一配置块中嵌套的配置快,各个之间不存在次序关系。
worker_processes 4; #设置nginx启动进程的数量,一般设置成与逻辑cpu数量相同 error_log logs/error.log; #指定错误日志 worker_rlimit_nofile 102400; #设置一个nginx进程能打开的最大文件数 pid /var/run/nginx.pid;
events {
worker_connections 1024; #设置一个进程的最大并发连接数
}
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配置文件是否正确
[root@localhost ~]# /usr/local/nginx/sbin/nginx -t [root@localhost ~]# mkdir -p /tmp/nginx
启动nginx服务
[root@localhost ~]# /usr/local/nginx/sbin/nginx
通过 nginx 命令控制 nginx 服务
nginx -c /path/nginx.conf # 以特定目录下的配置文件启动nginx:
nginx -s reload # 修改配置后重新加载生效
nginx -s reopen # 重新打开日志文件
nginx -s stop # 快速停止nginx
nginx -s quit # 完整有序的停止nginx
nginx -t # 测试当前配置文件是否正确
nginx -t -c /path/to/nginx.conf # 测试特定的nginx配置文件是否正确
15/87
注意:
nginx -s reload 命令加载修改后的配置文件,命令下达后发生如下事件
1.Nginx的master进程检查配置文件的正确性,若是错误则返回错误信息,nginx继续采用原配置文件进行工作(因为worker未受到影响)
2.Nginx启动新的worker进程,采用新的配置文件
3.Nginx将新的请求分配新的worker进程
4.Nginx等待以前的worker进程的全部请求已经都返回后,关闭相关worker进程
5.重复上面过程,知道全部旧的worker进程都被关闭掉
实现nginx开机自启
[root@localhost ~]# vim /etc/init.d/nginx #!/bin/sh
#
#nginx - this script starts and stops the nginx daemon
#
#chkconfig: - 85 15
#description: Nginx is an HTTP(S) server, HTTP(S) reverse \
#proxy and IMAP/POP3 proxy server
#processname: nginx
#config: /etc/nginx/nginx.conf
#config: /etc/sysconfig/nginx
#pidfile: /var/run/nginx.pid
#Source function library.
. /etc/rc.d/init.d/functions
#Source networking configuration.
. /etc/sysconfig/network
#Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
nginx="/usr/local/nginx/sbin/nginx" prog=$(basename $nginx)
NGINX_CONF_FILE="/etc/nginx/nginx.conf"
[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
lockfile=/var/lock/nginx
make_dirs() {
user=nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -
options=$nginx -V 2>&1 | grep 'configure arguments:'
for opt in $options; do
if [ echo $opt | grep '.*-temp-path'
]; then value=echo $opt | cut -d "=" -f 2
16/87
if [ ! -d "$value" ]; then
mkdir -p $value && chown -R $user $value
fi
fi done
}
start() {
[ -x $nginx ] || exit 5
[ -f $NGINX_CONF_FILE ] || exit 6 make_dirs
echo -n $"Starting $prog: "
daemon $nginx -c $NGINX_CONF_FILE retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile return $retval
}
stop() {
echo -n $"Stopping $prog: " killproc $prog -QUIT retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile return $retval
}
restart() {
configtest || return $? stop
sleep 1 start
}
reload() {
configtest || return $?
echo -n $"Reloading $prog: " killproc $nginx -HUP RETVAL=$?
echo
}
force_reload() { restart
}
configtest() {
$nginx -t -c $NGINX_CONF_FILE
}
rh_status() { status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case "$1" in
17/87
start)
rh_status_q && exit 0 $1
;;
stop)
rh_status_q || exit 0 $1
;;
restart|configtest) $1
;;
reload)
rh_status_q || exit 7 $1
;;
force-reload) force_reload
;;
status) rh_status
;;
condrestart|try-restart) rh_status_q || exit 0
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}" exit 2
esac
添加权限
chmod +x /etc/init.d/nginx
重新加载系统启动文件
systemctl daemon-reload
启动并设置开机自启 systemctl start nginx
[root@localhost ~]# /sbin/chkconfig nginx on ---开机启动
nginx自带变量
nginx 日志文件分为 log_format 和 access_log 两部分 log_format 定义记录的格式,其语法格式为 access_log 样式名称 样式详情
log_format main 'remote_addr - remote_user [time_local] "request" ' 'status body_bytes_sent "$http_referer" ' '"http_user_agent" "http_x_forwarded_for"';
18/87
nginx虚拟主机
什么是虚拟主机?
虚拟主机是一种特殊的软硬件技术,它可以将网络上的每一台计算机分成多个虚拟主机,每个虚拟主
机可以独立对外提供www服务,这样就可以实现一台主机对外提供多个web服务,每个虚拟主机之间是独立的,互不影响。
nginx可以实现虚拟主机的配置,nginx支持三种类型的虚拟主机配置。1、基于域名的虚拟主机 (server_name来区分虚拟主机——应用:外部网站)2、基于ip的虚拟主机, (一块主机绑定多个ip地址)
3、基于端口的虚拟主机 (端口来区分虚拟主机——应用:公司内部网站,外部网站的管理后台)
19/87
基于域名
1、 基于域名的虚拟主机
[root@localhost ~]# cat /etc/nginx/nginx.conf 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;
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
[root@nginx]# nginx -s reload
4.客户端配置路由映射
10.0.105.199 web.testpm.com 10.0.105.199 web.1000phone.com 5. 测试访问浏览器输入:http://web.testpm.com/
浏览器输入:http://web.1000phone.com/
20/87
基于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 / {
21/87
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、补充
[root@localhost ~]# ifconfig ens33:1 10.0.105.201/24 down 重启一下nginx [root@localhost ~]# systemctl restart nginx
基于端口
[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;
22/87
}
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
错误解决
一. 问题描述: 配置完 nginx 两个虚拟机后,客户端能够访问原始的server ,新增加的 server 虚拟机 不能够访问,报错如下页面
解决过程:
[root@localhost ~]# cat /var/log/nginx/error.log
2017/06/15 04:00:57 [error] 6702#0: *14 "/root/html/index.html" is forbidden (13: Permission denied), client:
10.219.24.1, server: web.1000phone.com, request: "GET / HTTP/1.1", host: "web.1000phone.com" 2.检查权限
[root@localhost html]# ll
drwxr-xr-x. 2 root root 4096 Jun 15 03:59 html [root@localhost nginx]# ll
total 8
-rw-r--r--. 1 root root 537 Jun 15 03:59 50x.html -rw-r--r--. 1 root root 616 Jun 15 03:51 index.html
说明:发现目录权限没有问题
3.检查nginx启动进程 [root@localhost nginx]# ps -ef | grep nginx
root 2079 1 0 12:16 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx -c /etc/nginx/
nginx.conf
nobody 2080 2079 0 12:16 ? 00:00:00 nginx: worker process
nobody 2081 2079 0 12:16 ? 00:00:00 nginx: worker process
nobody 2082 2079 0 12:16 ? 00:00:00 nginx: worker process
说明:发现nginx的work process是 nobody 的4.修改 nginx.conf 文件
23/87
打开nginx.conf文件所在的目录,查看文件的属性 (root root) [root@nginx]# ll
drwxr-xr-x. 2 root root 4096 Jun 15 04:08 conf 在nginx.conf文件的第一行加上 user root root; [root@nginx]# cat conf/nginx.conf
user root;
5.重新 reload nginx进程
nginx Proxy 代理
1、代理原理反向代理产生的背景:
在计算机世界里,由于单个服务器的处理客户端(用户)请求能力有一个极限,当用户的接入请求蜂拥而入时,会造成服务器忙不过来的局面,可以使用多个服务器来共同分担成千上万的用户请求,这些服务器提供相同的服务,对于用户来说,根本感觉不到任何差别。
反向代理服务的实现:
需要有一个负载均衡设备(即反向代理服务器)来分发用户请求,将用户请求分发到空闲的服务器上。服务器返回自己的服务到负载均衡设备。
负载均衡设备将服务器的服务返回用户。
24/87
2、正/反向代理的区别
那么问题来了,很多人这时会问什么是反向代理?为什么叫反向代理?什么是正向代理?我们来举例说明
• 正向代理:举例:
贷款
正向代理的过程隐藏了真实的请求客户端,服务器不知道真实的客户端是谁,客户端请求的服务都被代理服务器代替请求。我们常说的代理也就是正向代理,正向代理代理的是请求方,也就是客户端;比如
我们要访问youtube,可是不能访问,只能先安装个FQ软件代你去访问,通过FQ软件才能访问,FQ软件就叫作正向代理。
正向代理中,proxy和client同属一个LAN
25/87
反向代理:
反向代理的过程隐藏了真实的服务器,客户不知道真正提供服务的人是谁,客户端请求的服务都被代理服务器处理。反向代理代理的是响应方,也就是服务端;我们请求www.baidu.com时这www.baidu.com就是反向代理服务器,真实提供服务的服务器有很多台,反向代理服务器会把我们的请求分转发到真实提供
服务的各台服务器。Nginx就是性能非常好的反向代理服务器,用来做负载均衡。访问www.baidu.com是正向代理的过程
反向代理中,proxy和server同属一个LAN
正向代理和反向代理对比示意图两者的区别在于代理的对象不一样:
正向代理中代理的对象是客户端,proxy和client同属一个LAN,对server透明;反向代理中代理的对象是服务端,proxy和server同属一个LAN,对client透明。
26/87
27/87
nginx proxy
1、代理模块 ngx_http_proxy_module
2、代理配置
代理
Syntax: proxy_pass URL; #代理的后端服务器URL
Default: —
Context: location, if in location, limit_except
缓冲区
Syntax: proxy_buffering on | off;
Default: proxy_buffering on; #缓冲开关
Context: http, server, location
proxy_buffering开启的情况下,nignx会把后端返回的内容先放到缓冲区当中,然后再返回给客户端(边收边传,不是全部接收完再传给客户端)。
Syntax: proxy_buffer_size size;
Default: proxy_buffer_size 4k|8k; #缓冲区大小
Context: http, server, location
Syntax: proxy_buffers number size;
Default: proxy_buffers 8 4k|8k; #缓冲区数量
Context: http, server, location
Syntax: proxy_busy_buffers_size size;
Default: proxy_busy_buffers_size 8k|16k;#忙碌的缓冲区大小控制同时传递给客户端的buffer数量
Context: http, server, location
头信息
Syntax: proxy_set_header field value;
Default: proxy_set_header Host $proxy_host; #设置真实客户端地址 proxy_set_header Connection close;
Context: http, server, location
超时
Syntax: proxy_connect_timeout time;
Default: proxy_connect_timeout 60s; #链接超时
Context: http, server, location
Syntax: proxy_read_timeout time;
Default: proxy_read_timeout 60s;
Context: http, server, location
3、启用 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;
28/87
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 REMOTE-HOST $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;
proxy_buffering on; proxy_buffer_size 32k; proxy_buffers 4 128k; proxy_busy_buffers_size 256k; proxy_max_temp_file_size 256k;
}
}
重新加载nginx配置文件
[root@nginx-server ~]# nginx -s reload
c、nginx proxy 具体配置详解
proxy_pass :真实服务器的地址,可以是ip也可以是域名和url地址 proxy_redirect :如果真实服务器使用的是的真实IP:非默认端口。则改成IP:默认端口。proxy_set_header:重新定义或者添加发往后端服务器的请求头
proxy_set_header X-Real-IP :启用客户端真实地址(否则日志中显示的是代理在访问网站) proxy_set_header X-Forwarded-For:记录代理地址
proxy_connect_timeout::后端服务器连接的超时时间发起三次握手等候响应超时时间proxy_send_timeout:后端服务器数据回传时间就是在规定时间之内后端服务器必须传完所有的数据 proxy_read_timeout :nginx接收upstream(上游/真实) server数据超时, 默认60s, 如果连续的60s内没有收到
1个字节, 连接关闭。像长连接
proxy_buffering on;开启缓存proxy_buffer_size:proxy_buffer_size只是响应头的缓冲区 proxy_buffers 4 128k; 内容缓冲区域大小
proxy_busy_buffers_size 256k; 从proxy_buffers划出一部分缓冲区来专门向客户端传送数据的地方 proxy_max_temp_file_size 256k;超大的响应头存储成文件。
注意:
29/87
2.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
30/87
扩展1
nginx 负载均衡
随着网站、应用访问量的增加,一台服务器已经不能满足应用的需求,而需要多台服务器集群,这时就会用到负载均衡
upstream标签
负载均衡配置: upstream testapp {
server 10.0.105.199:8081; server 10.0.105.202:8081;
}
server {
....
location / {
proxy_pass http://testapp; #请求转向 testapp 定义的服务器列表
}
upstream mysvr {
server http://10.0.105.199:8081; server http://10.0.105.202:8081;
}
server {
....
location / {
proxy_pass http://mysvr; #请求转向mysvr 定义的服务器列表
}
负载均衡算法
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;
31/87
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七层和四层方法
所谓四层就是基于IP+端口的负载均衡;七层就是基于URL等应用层信息的负载均衡。
所谓的四层、七层负载均衡,就是在对后台的服务器进行负载均衡时,依据四层的信息或七层的信息来决定怎么样转发流量。
七层负载均衡:准备三台机器:
一台代理服务器两台WEB服务器
配置代理服务器的nginx配置文件 worker_processes 4;
32/87
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;
}
}
upstream testapp {
server 10.0.105.202:8081 weight=2 max_fails=2 fail_timeout=2s; server 10.0.105.199:8081 weight=2 max_fails=2 fail_timeout=2s;
}
server {
listen 81;
server_name www.app.com; charset utf-8;
#access_log logs/host.access.log main; location / {
proxy_pass http://testapp; 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;
33/87
}
}
}
四层负载均衡(练习)
nginx在1.9.0的时候,增加了一个 stream 模块,用来实现四层协议(网络层和传输层)的转发、代
理、负载均衡等。stream模块的用法跟http的用法类似,允许我们配置一组TCP或者UDP等协议的监听,然后通过proxy_pass来转发我们的请求,通过upstream添加多个后端服务,实现负载均衡。
#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;
}
}
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来判断。因此可以避
34/87
免上述ip_hash中来自同一局域网的客户端和前段代理导致负载失衡的情况。(需要引入第三方模块才能实现 sticky)
下载地址:https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/08a395c66e42.zip
下载后进行编译安装语法: 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定义路径
nginx动静分离
为了加快网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度。降低
原来单个服务器的压力。 在动静分离的tomcat的时候比较明显,因为tomcat解析静态很慢,其实这些原理的话都很好理解,简单来说,就是使用正则表达式匹配过滤,然后交个不同的服务器。
静态分离部署
一:实验环境
准备一个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;
35/87
}
#静态资源加载
location ~ .*.(html|gif|jpg|png|bmp|swf|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;
}
}
2.单独的静态配置 server {
listen 80;
server_name localhost;
location ~ .(html|jpg|png|js|css|gif|bmp|jpeg) { root /home/www/nginx;
}
}
3.动态资源配置:
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常量定义
}
}
nginx 防盗链
两个网站 A 和 B, A网站引用了B网站上的图片,这种行为就叫做盗链。 防盗链,就是要防止A引用B的图片。
36/87
防盗链部署
1、nginx 防止网站资源被盗用模块 ngx_http_referer_module
HTTP Referer是Header的一部分,当浏览器向Web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器借此可以获得一些信息用于处理,例如防止未经允许的网站盗链
图片、文件等。因此HTTP Referer头信息是可以通过程序来伪装生成的,所以通过Referer信息防盗链并非100%可靠,但是,它能够限制大部分的盗链情况.
[root@nginx-server ~]# vim /etc/nginx/nginx.conf
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
3.实战演练
准备两台机器,一张图片配置nginx配置文件,并上传图片
[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;
}
}
}
•none : 允许没有http_refer的请求访问资源;
•blocked : 允许不是http://开头的,不带协议的请求访问资源---被防火墙过滤掉的;
•server_names : 只允许指定ip/域名来的请求访问资源(白名单);
重载nginx服务
[root@nginx-server ~]# nginx -s reload -c /etc/nginx/nginx.conf
qf.com ----192.168.1.11 制作localhost本地解析。配置nginx访问页面创建页面
[root@nginx-server nginx]# vim index.html <html>
<head>
<meta charset="utf-8"> <title>qf.com</title>
</head>
<body style="background-color:red;">
<img src="https://cache.yisu.com/upload/information/20200217/33/1966.jpg"/> </body>
</html>
测试不带http_refer:
[root@nginx-server nginx]# curl -I "https://cache.yisu.com/upload/information/20200217/33/1966.jpg" HTTP/1.1 200 OK
Server: nginx/1.16.0
Date: Thu, 27 Jun 2019 16:21:13 GMT
Content-Type: image/png
37/87
Content-Length: 235283
Last-Modified: Thu, 27 Jun 2019 11:27:11 GMT
Connection: keep-alive
ETag: "5d14a80f-39713"
Accept-Ranges: bytes
测试带非法http_refer:
[root@nginx-server nginx]# curl -e http://www.baidu.com -I "http:/192.168.1.10/test.jpg" HTTP/1.1 403 Forbidden
Server: nginx/1.16.0
Date: Thu, 27 Jun 2019 16:22:32 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
测试带合法的http_refer:
[root@nginx-server nginx]# curl -e http://192.168.1.10 -I "https://cache.yisu.com/upload/information/20200217/33/1966.jpg" HTTP/1.1 200 OK
Server: nginx/1.16.0
Date: Thu, 27 Jun 2019 16:23:21 GMT
Content-Type: image/jpeg
Content-Length: 27961
Last-Modified: Thu, 27 Jun 2019 12:28:51 GMT
Connection: keep-alive
ETag: "5d14b683-6d39"
Accept-Ranges: bytes
如果用户直接在浏览器输入你的图片地址,那么图片显示正常,因为它符合none这个规则。
nginx的rewrite
Rewirte
1、什么是Rewrite
Rewrite对称URL Rewrite,即URL重写,就是把传入Web的请求重定向到其他URL的过程。
• URL Rewrite最常见的应用是URL伪静态化,是将动态页面显示为静态页面方式的一种技术。比如http:// www.123.com/news/index.php?id=123 使用URLRewrite 转换后可以显示为 https://cache.yisu.com/upload/information/20200217/33/1992.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地址;
39/87
$server_port 请求到达的服务器端口号;
Rewrite flag
rewrite 指令根据表达式来重定向URI,或者修改字符串。可以应用于server,location, if环境下每行rewrite指令最后跟一个flag标记,支持的flag标记有:
last 相当于Apache里的[L]标记,表示完成rewrite。默认为last。
break 本条规则匹配完成后,终止匹配,不再匹配后面的规则
redirect 返回302临时重定向,浏览器地址会显示跳转后的URL地址
permanent 返回301永久重定向,浏览器地址会显示跳转后URL地址
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:
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:
root /html;
if ($host ~* testpm.com ) {
rewrite .* http://jd.com permanent;
}
40/87
}
例4:
root /html;
if ( $host ~* testpm.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:
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;
}
41/87
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实现泛解析
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;
}
}
return
42/87
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/
43/87
last、break
[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。
44/87
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;
}
if ($host ~ "^(.).vip9999.top$" ) { set $user $1;
return 301 https://www.vip9999.top/$user;
}
}
server {
listen 443 ssl;
server_name www.vip9999.top;
location / {
root /usr/share/nginx/html;
} index index.php index.html;
#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;
}
ssl on;
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;
}
nginx的localtion
Nginx 的 HTTP 配置主要包括三个区块,结构如下:
http { # 这个是协议级别
include mime.types;
45/87
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路径即可 ~ 表示区分大小写的正则匹配 ~ 表示不区分大小写的正则匹配 !~ 表示区分大小写不匹配的正则 !~ 表示不区分大小写不匹配的正则 / 通用匹配,任何请求都会匹配到
@内部服务跳转
3、location 配置示例本地解析域名host
1)、没有修饰符 表示:必须以指定模式开始
server {
listen 80; server_name qf.com;
location /abc {
root /home/www/nginx;
index 2.html;
}
那么,如下是对的: http://qf.com/abc http://qf.com/abc?p1 http://qf.com/abc/
如下是错的 http://qf.com/abcde
2)、=表示:必须与指定的模式精确匹配 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;
}
46/87
location = /abc {
root /usr/share/nginx/html; index index.html index.htm;
}
}
那么,如下是对的: http://qf.com/abc http://qf.com/abc?p1 http://qf.com/abc/
http://qf.com/abcde
3)、~ 表示:指定的正则表达式要区分大小写 server {
server_name qf.com; location ~ ^/abc$ {
……
}
}
那么,如下是对的: http://qf.com/abc http://qf.com/abc?p1=11&p2=22 http://qf.com/ABC http://qf.com/abc/ http://qf.com/abcde
4)、~ 表示:指定的正则表达式不区分大小写 server {
server_name qf.com; location ~ ^/abc$ {
……
}
}
那么,如下是对的: http://qf.com/abc http://qf..com/ABC http://qf..com/abc?p1=11&p2=22
如下是错的: http://qf..com/abc/ http://qf..com/abcde
5)、^~ :类似于无修饰符的行为,也是以指定模式开始,不同的是,如果模式匹配,那么就停止搜索其他模式了6)、@ :定义命名 location 区段,这些区段客户段不能访问,只可以由内部产生的请求来访问,如try_files
或error_page等
查找顺序和优先级1:带有“=“的精确匹配优先2:没有修饰符的精确匹配
3:正则表达式按照他们在配置文件中定义的顺序
4:带有“^~”修饰符的,开头匹配
5:带有“~” 或“~*” 修饰符的,如果正则表达式与URI匹配
6:没有修饰符的,如果指定字符串与URI开头匹配
= 大于 ^~ 大于 ~|~|!~|!~ 大于 /
多个location配置的情况下匹配顺序为:首先匹配 =,其次匹配^~, 其次是按正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。
(1)=:表示完全匹配;
(2)^~:匹配URI的前缀,并且后面的正则表达式不再匹配,如果一个URI同时满足两个规则的话,匹配最长的规则;
47/87
(3)~:匹配正则表达式,大小写敏感;
(4)~*:匹配正则表达式,大小写不敏感;优先级:(1)> (2) > (3) = (4)
localtion匹配段
location 区段匹配示例
location = / {
}
location / {
[ configuration B ]
}
location ^~ /images/ {
[ configuration C ]
}
location ~* .(gif|jpg|jpeg)$ {
}
各请求的处理如下例:
/ → configuration A /documents/document.html → configuration B /images/1.gif → configuration C /documents/1.jpg → configuration D
root 、alias 指令区别
root 、alias 指令区别
location /img/ {
alias /var/www/image/;
}
#若按照上述配置的话,则访问/img/目录里面的文件时,ningx会自动去/var/www/image/目录找文件 location /img/ {
root /var/www/image;
}
#若按照这种配置的话,则访问/img/目录下的文件时,nginx会去/var/www/image/img/目录下找文件。
• alias 是一个目录别名的定义,
48/87
•root 则是最上层目录的定义。
•还有一个重要的区别是alias后面必须要用“/”结束,否则会找不到文件的,而root则可有可无
nginx 日志配置
nginx 日志介绍
nginx 有一个非常灵活的日志记录模式,每个级别的配置可以有各自独立的访问日志, 所需日志模块
ngx_http_log_module 的支持,日志格式通过 log_format 命令来定义,日志对于统计和排错是非常有利的,下面总结了 nginx 日志相关的配置 包括 access_log、log_format、open_log_file_cache、rewrite_log、error_log。
总结:
Nginx中通过access_log和error_log指令配置访问日志和错误日志,通过log_format我们可以自定义日志格式。如果日志文件路径中使用了变量,我们可以通过open_log_file_cache 指令来设置缓存,提升性能。其他的根据自己的使用场景定义。详细的日志配置信息可以参考Nginx官方文档
access.log
#关闭访问日志 access_log off;
•path 指定日志的存放位置。
•format 指定日志的格式。默认使用预定义的combined。
•buffer 用来指定日志写入时的缓存大小。默认是64k。
•gzip 日志写入前先进行压缩。压缩率可以指定,从1到9数值越大压缩比越高,同时压缩的速度也越慢。默认是1。
•flush 设置缓存的有效时间。如果超过flush指定的时间,缓存中的内容将被清空。
•if 条件判断。如果指定的条件计算为0或空字符串,那么该请求不会写入日志。
作用域:
可以应用access_log指令的作用域分别有http,server,location,limit_except。也就是说,在这几个作用域外使用该指令,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
49/87
该例子指定日志的写入路径为/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变量。
自定义日志格式的使用: 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"';
使用log_format指令定义了一个main的格式,并在access_log指令中引用了它。假如客户端有发起请求:https://qf.com/,我们看一下我截取的一个请求的日志记录:
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都对应了一个-,这是因为这几个变量为空。
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。
基本用法:
error_log /var/logs/nginx/nginx-error.log
配置段:main, http, mail, stream, server, location作用域。
例子中指定了错误日志的路径为:/var/logs/nginx/nginx-error.log,日志级别使用默认的 error。
50/87
open_log_file_cache
open_log_file_cache 指令
每一条日志记录的写入都是先打开文件再写入记录,然后关闭日志文件。如果你的日志文件路径中使用了变量,如 access_log /var/logs/$host/nginx-access.log,为提高性能,可以使用open_log_file_cache指令设置日志文件描述符的缓存。
语法:
open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
默认值:
open_log_file_cache off;
•max 设置缓存中最多容纳的文件描述符数量,如果被占满,采用LRU算法将描述符关闭。
•inactive 设置缓存存活时间,默认是10s。
•min_uses 在inactive时间段内,日志文件最少使用几次,该日志文件描述符记入缓存,默认是1次。
•valid:设置多久对日志文件名进行检查,看是否发生变化,默认是60s。
•off:不使用缓存。默认为off。
open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2; 配置段:http、server、location作用域中。
例子中,设置缓存最多缓存1000个日志文件描述符,20s内如果缓存中的日志文件描述符至少被被访问2次,才不会被缓存关闭。每隔1分钟检查缓存中的文件描述符的文件名是否还存在。
rewrite.log
rewrite_log 指令
由ngx_http_rewrite_module模块提供的。用来记录重写日志的。对于调试重写规则建议开启,启用时将在error log中记录notice级别的重写日志。
基本语法: rewrite_log on | off;
默认值: rewrite_log off;
配置段: http, server, location, if作用域。
nginx的日志轮转
[root@192 ~]# rpm -ql nginx |grep log /etc/logrotate.d/nginx
51/87
/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 access log 分析
nginx 的 access log 中可以记录很多有价值的信息,通过分析 access log,可以收集到很多指标1.制作nginx的日志切割,每天凌晨切割并压缩。
PV:PV(访问量): 即Page View, 即页面浏览量或点击量,用户每次刷新即被计算一次。
UV:UV(独立访客):即Unique Visitor,访问您网站的一台电脑客户端为一个访客。00:00-24:00内相同的客户端只被计算一次。
面试:
1.根据访问IP统计UV awk '{print $1}' access.log|sort | uniq -c |wc -l 2.统计访问URL统计PV
awk '{print $7}' access.log|wc -l 3.查询访问最频繁的URL
awk '{print $7}' access.log|sort | uniq -c |sort -n -k 1 -r|more 4.查询访问最频繁的IP awk '{print $1}' access.log|sort | uniq -c |sort -n -k 1 -r|more 5.查询访问最频繁的前10的IP
awk '{print $1}' access.log|sort | uniq -c |sort -n -k 1 -r|head -n 10
nginx 的平滑升级(了解)
1、为什么要对 nginx 平滑升级
随着 nginx 越来越流行,并且 nginx 的优势也越来越明显,nginx 的版本迭代也来时加速模式,1.9.0版本的nginx更新了许多新功能,例如 stream 四层代理功能,伴随着 nginx 的广泛应用,版本升级必然越来越快,线上业务不能停,此时 nginx 的升级就是运维的工作了。
52/87
nginx 方便地帮助我们实现了平滑升级。其原理简单概括,就是:(1)在不停掉老进程的情况下,启动新进程。
(2)老进程负责处理仍然没有处理完的请求,但不再接受处理请求。(3)新进程接受新请求。
(4)老进程处理完所有请求,关闭所有连接后,停止。 这样就很方便地实现了平滑升级。一般有两种情况下需要升级 nginx,一种是确实要升级 nginx 的版本,另一种是要为 nginx 添加新的模块。
2、nginx 平滑升级原理多进程模式下的请求分配方式
nginx 默认工作在多进程模式下,即主进程(master process)启动后完成配置加载和端口绑定等动作,fork出指定数量的工作进程(worker process),这些子进程会持有监听端口的文件描述符(fd),并通
过在该描述符上添加监听事件来接受连接(accept)。信号的接收和处理
nginx 主进程在启动完成后会进入等待状态,负责响应各类系统消息,如SIGCHLD、SIGHUP、SIGUSR2等。
Nginx信号简介:主进程支持的信号
•TERM, INT: 立刻退出
•QUIT: 等待工作进程结束后再退出
•KILL: 强制终止进程
•HUP: 重新加载配置文件,使用新的配置启动工作进程,并逐步关闭旧进程。
•USR1: 重新打开日志文件
•USR2: 启动新的主进程,实现热升级
•WINCH: 逐步关闭工作进程
工作进程支持的信号
•TERM, INT: 立刻退出
•QUIT: 等待请求处理结束后再退出
•USR1: 重新打开日志文件
nginx 平滑升级实战1
1、查看现有的 nginx 编译参数
[root@nginx-server ~]# cd /usr/local/nginx/sbin/nginx -V
2、按照原来的编译参数安装 nginx 的方法进行安装,只需要到 make,千万不要 make install 。如果make install 会将原来的配置文件覆盖
53/87
[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
nginx 平滑升级实战2
1、安装配置 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
54/87
[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
3、访问验证
[root@localhost nginx-1.6.3]# elinks 10.0.105.189
4、升级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
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编码嵌入;如下:
55/87
[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,iVBORw0KGgoAAAANSUhEUgAAAV4AAACMCAYAAAA0qsGKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFn
eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh7cmVTek5UY3prYzlkIj8
+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwI
+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4Qz6opAAAU5klEQVR42uxd3XXjthKe
+Oy7dCsQU4GUAnLEfc7DKhWI20CsrcDcCiynAcsVhH7I81InBaxUQagKIlXga9wML2Ga4B9ACiC/7xyeXeuHpDD4PswMBuA
f0PLAH1j+nosXg//9fCkY1bju6fXI3k9DtK/MZoUsAl//fJ7ufACQE9CK0R2xf/ONM4142OZe33/
ekR8JGhywGqPFwA6xIqPdQ/XWvJx/3ocX48dH+eK73kQaqBL2JzjFV7QS0cHwtD
+vdsNi9kfPYluHnMW4ITF1yv5bMCfC2A68HdswtslILz9IWQRu9dMJ5jChIX/7xIB3vJ7j3zvPswI/kJ49XFQvC7ItkC/
NpZSEKJ1x2JnI9bcF8Lc62d+7Sf+/zcmuwezgr8QXrOGWzARv7NoAO3TChGnFGYO3O+EB4dDAWnT1x7o31yx
+HsDE4O/EN7mSEuP8ghqjKhAOXxu208O3vucSRsWvCfE9lf+/z0PLFOYG/xtC5urGroK6
+IS0RA4Ema02yBkz9EELpTV4iYV9vD48Nnr0U1r3FFW5iZXP0T8+o4HlpjJjkEa/
IXwtjScxx5PmWEBNXakX6lwoazcS0fM0kUYgWTTpkjTCqvcvRz43DGfO+a/
Ib7gL1INFYgKXlvlRASohymLjo7oitDxM2UlZ7oiJr6/ZQEWk2NPLc8zk4RVxpnP/cTedUwoOwN/
ByS8fgfnPFJx8XwgiQC8l/qiG2t4lQJf2VvpiiwHtq0Q4H2L7wth/aYQ1kAS30eIL/
gLj7c8JC4LUyLwpRfRPbIYhjWus2IPVlyvrKg
+YfuFVFydIITgC6c0muKxQnzTz6AUEfx1XniXCFOsJkBb0d1TdV7U52v8Q/+Wpd3W6A8iNSAmvcTk2HcW4pDeVh9s
+dwmxXfDAwnx4ADxBX8rYevkmtdRmJIgzWBEdNuWiz1VhOQLFsdlge0its9Z4Rmnk2pLSYjvWBi3kned1uZGLQaPR76
+LABnejvhFvH5zyPuI+AvhLd0NFwgzdAIopOvNYhTtvhAvHcv/
X2hbOlu0tAbWvG9igEiXSARUFalkPDfMTUvP9sVeOxn6XwzykrPILzgr1Ophi46bVQyWiLNUI0Fe3xtcGGbnktIJYtuOukWUrua
+07GdpJUN
+AcVBOveSqvPXQwb466jwmh5xnxUEXiHNUAtTTY9iVSG6a8kO6aSbiVA94Wt/5HOn6YKdJJZfWopvpBCHB/7/3Yi9XvDXUe
+6nZBKJ8GeJPENCvpCExR5tWfKctmzkaYcwF8Hhdd0eLZThM4rifQJ9FWZYtDp1KqUgfCI7iViBdRfFUBAb2tvfbb/g0b/
mhZ42On5bmlcJWbgL4RXORoKo03g7VZio5FiuJS07TYnzn3n52TxjTQHmBkVV2uElNULj6mPgb
+OCq9J72BP1VvIIb9bDI/0dhvblojeUrLPtYgTsLc04XtIqP2+Dnf0fkJJTjksaTx7PIO/8HiVSwxT4j/RuAvdq9IEpj2V/
HmDK//GFWWLM3S9p53itdPIvF7w10HhNbGfaoqTwnCbCsMC/3ZunR3HVIQIpNTFE10/
N5dQtopN4EBZRUJTLBWiE0opiWDg/
Qb8dVR4TY6WZaFuatgYGtuJtxtVtL2Ja3SFneF2k73ecOD9Bvx1VHhN5cHKSlAm8HY79XYvCuGVQ8Q92TsTrZMzrOP1DjnX
+nWUjKpWMtOkWhEOG7sMcoxrntZk0iUa6QeXVRpRVOAz5YZngr4PCa9ITKDLKgton5XXrWV3BlPTzkHEN+9o
+E23a6z1Lg82ShvmYePB35MKrMoqOxxWRuUkD28mj+ztVaYZ0Uu2Z7J+JjjW/
H1SIyWagfQf8dVB4fUPnCRUjnrw8NW54vmWNTjeE1Um6gqB6NItL3q4J4V3T+9VscgojoOEB/
HVQeBfUfoVUfrRMKgSlScghDFJnEYE4/3dyuyZYeKW6a
+zjGqSMHWmPveb3i8Q19dQmNKxJNvDXUeE15QGoRsvUcJcGYcqiRUjjcjrChBAcKoT3RO6sq
+8i3RB1EJqDvw7y92ZApFeNlm3WdS
+o3dMJxk6eWNGWE8e83bJBpC7m9H4STU43DEl4wV8HhddUmBJWvH6pabgxiq6JNAMpiLNwMM1gQnhVghQNLN0A/
joqvCY8rQdSb6Yhb5Z8HoLROoBv4Bz7kjY1KWZ9Iemobw8t3QD
+Oiq8up3vUmO0LBtRZSOPUXRNCe9hYMJbNpg0STcUPZvtYrDdwV8H
+Xtt4TURppStcqm7IYsw6uNIRdeU53WuEN6jg+1y7qhtY/53Rm6XIYK/
jgqvbt1oWd6nzmiZPsTxjsYLUztKxYr2nRgM3fuGCQ/
56/87
dr2grl71e8LclPjjuaW00Rst0O8AZjRumPK7zwNIMpgYLv0LQXfZ4wV8HPd5A09NS7ddZZ7QUr32H6BolfpGweoZFzEXhndH7
J3VNaNlo6UF038HEVn4HCG/jwc3ldAP466jwBprf35QYzaZHy7hAoL7OP2Zb+BWi7lq6AfwdofA+KDysac6gIXS1N
+Gtmji7ONxGewPnKPJo4x4HQPAXwvu/3FDbpHhVsfUE3q62J9YGVTW8h6G384TeL6Q4Oyq84K+jwrvR/
K6qbOlWMu6GAFsEByj2euXBaOnQ7wB/HRReT6OTiVngneK9be7/Z/C8V4+3yjtx2R4Hg30/j1Mu1LYd4K
+jwqszkgUloc9S6shjeDaabUgqhMblVIMpEfAq2s2Fygbw10Hh2XmQYllCXjZUCG9XWwxcOPdQ2tqlvgr
+Oiq8wmhtcn5VCfk00b8nux8bbiOwcu+6wiuLkW/5/YO/
jgrvRsPgVQl53TAIALpONbgO8NdB4Q1aelfiUeCqp9LuaoQyQD+INd
+3Gab6VdGkVJILu232dsFfR4W3TYhStsJlXiOUAdToOrSdookrkeQ8QJuFF/x1THh9aleCEpJ6O7i7XIiCcNA
+LNAEgxmgwV8HhbfNaCYS7dsaIQom1ACX4Dl4z+Cvg8LbZrS8lIQ2+RAlAJcBh5XXdk8P/HVUeMOW36kTomwJ
+zEAbsP2rSHBXweFt81oWTdEORIm1IBhwbZ9LcBfR4W3acOWhR5bersBMlIMAGCXtwv
+WiC8bUbLQBF6iHPJhdZfCTW7AGCbtwv+WiC8TUdLsf9mUaH1NPf6HikGALDO2wV/
LRDepqOl2JFIVWi9oyz3hSoGALDP2wV/
LRHeXcPPi23hispqhDE/5f5OYDIA6BTgr4PCK0a0Jmu6VfkeUXpynwtldjAXAHQK8NdB4c3vrVkFVb4nnxc6EnYe6wIxmsAqn
ah7fDlgN8BfR4V31+CzXxTGWOWMj7yQO+HtkLeANLmU91wgYDYA/HVQeFdUv/
xEGGOr6NyykZAXGkd46wJMDio2en/gr4PC2yQhrzLGlN7X
+6lKVACz6KuNsSm6PbYAfwcgvCHVKz8pS7ILo81z4Rc8sX5gygPzegzXYQtzAH8dFF7RwLc1PxsoOpYwvFxk/
ZmQjHfRy/Is8eC6gGfoPHsFh74F8NdB4U3DizoQyfhIYUw5Gf9ASMYPycsaCgG9nq7T50AF/joqvHVDlLJk/Db3OSTj
+4epkHBRg+ho6/J26XOgAn8dFN66IcqRijfFEJ0tpiwZr/oc4I7wVgmryzneRYdtfY12AX8dFN6pIuwoMppf02g
+zHBV7DsMx48DaB9TT4Y4aL5vaoAEfx0U3l2Njlh4BvRE6hUwQH8wQXhV2HquEGbbYTJFUtTPlxXvmwb466Dw5rd5KwtlD
zVha2FhlNjKBryWg+oexkDMJ76Mh7dM3jPVWIetcCBv46KLx180IqCKM9wmhWC+/FwHn8Hr1H1zzeQ8VAFXc8eIC/
luFDjc9EDUJFkbN6KXlf5Je+D6DdXhq8J7ydhDvrgdvTthAtrhmGNvV4xXnvHPZ4uxRe+dxJh78B/
LWQv1Ue746aP20UeIsZt+Etew7/sCAFlglvF6kG1z3eaYft24fwgr+W8vemIsRYo907wZKNmJAd5TiRod9UJjgLR+3Uh/
B2kWoAfy3m702Jd/KI9u1lNP0mjZ4eXaf0KiEze/MWieuppkc81DTDXhEdyLWwXdw7+Gsxf286DrGAenikrHZSeJ
+HK3jCJrxeXyHqAvORCm9c0U5dTFSBv5bz9wZtZg22Eik9Hkm3PV5/15FYxRXCPHThjSqEN0bXHx9/
Ibz2QISeGx41hfFE6c4t9bfj08FAusFXnNe0mPUBE4PEReHRQnhHzt+bkvDohwEeHw01ctk1/
sPXEYfYn7TJXggrSaxScq5J/URX29INswJxdVF4p4ZSI0Xt6VFW3nWibioawF/L
+QuP1zzO3PFjHu38Bsab5wTrs5QG6CNvZyK1kfcUE8oWaLiSajB1n0gzgL+F/IXw2gfZK9yx0UUYE/
Rw7YT0dysLFB5Y6hF7IxHek0J4VxBe8BfC2z1CalYPOlV4oX2lG3S93nmBuMYK4bEVJu5Rlbb5VOMzwMD5C
+HtHk091UQhWn2tQIpIf5JtVSJCtqcbFmRmN7VtRbscCbt7jZa/dZYMvwzo+HYFwzUh8aXAcNcgZ6j5/
U1BZzxJHt90QEQrwp6KJ81WOW51DfDXUv7e1OiETxj0KhFLnUOXKDZgp+n1zgo828iRdIOJewsVIei65zQD
+Gspf29qGg/lKHreT93RMlSEvtdAaID0qk5p64MRfQNphiMVT5qtanjEXYkv
+GsZf5Hj7R4bqt7vNt3n9FxiuH3P963r9QrvzpP+PlC2L8Gc7KzpNZFmCGukX3agxbj5C+HtHgdu/KcCA1749QWp1
+wHPYampoUoL0Jbi71ej/R389qTunZ3Ltkcwjty/kJ4+0HCBpjmQqcpv64KO0V4urwiWUXI/
GzQ642kzpt/79oIOzxHAG8X/
IXwuoGFZKwtXa/0qE6oVZWySHHOeb2hJW1twtt9puLcbv7cW3Rt8BfC279Xtavh7flM4gmHMtcUqETz
+kt6O7EkOuFJ8np9C+yiK4YXUqdO5LZ7ov4m1QCL+fsBbdl76C4M9zdl+cBDzjsKKCu2fiA7cqFbKWxq6/V6POqf
+Tf9IZ37mhNtgiSfDBAyqeHthqAA+AvhvY7hPBaagMXsvsB7emZBii269xWLy6TFdyfcSVPvNmJPQIjSnH/
rNQaYKennXPclHvMW3i74C+G1Bweyt5ZVhTN3tLarh6YscgH/veEOLIT3lttk1/NvEtfTqdu9kHrBRd6ThrcL/
v4fyPECTUf8LxrfX0vCm24YfbpSymFjIMWwIvWkp
+ztPsDbBSC8gA62pLcM9TEnviv2HCcs7H2Ib1AQIjbFl5JQMqS3dbvwdgEIL2BEuHTqex
+ltEJaoH6UxHfV8b3rPoH3idR53UUuDN0QdiEDILyAQQHTeTT5mrLJioSynf6F
+P7RkZcYGhLdoOT9HWUTkHvCggkAwgsYRJqj1RHfJWUTFen5vvJ7d2TuMfcei/
yd5nmeK0R3m0sxrNBNAAivufxhWcH9mMiWiqVO2kF4h/
eULcsUXumP7C0KEfvGotlGgKd8vr9JfyP5pwrbivducxEBUgzg7+iFd0P6Eyop8o9tjnKh6mJE7ZpOkOnu
+zrjNEC6wEII5k+UbULyrUHYni7XTAx4uXXSC4vcvT0QHusD/pbgh6eX93v//vznb0MzmmjMdQfnlQkpX
+PCxktGRo6A9HOoeewpywWTQnyn3N4L9ownBq//pcJDmnJKZCbdr08A
+JvDX7/8PhrhnTJp5x1e40jZXpyxFNLKr48tHIzIzHPLrokTkzJu0L/GanPwt6Hw3gxcAA4dG434/
DF3khW93ex7jOFmWh724PBveObfANEFfzvBUIU39VT68rpk4wWUbaO4pHGUE/n0Ni+W5mk/Uv9PztD1cj9S
+Yq0ItG91PgOAP4OWnhD+jfPOOn5unPKdirypdfX5N6+DE2RbggS5F6PuS0
+k/4j47sWXHGPHlVvTLQo8HTF9xLoJfg7RuFNd5q6u+I9TCTifpZevyczz/
OyOSyMmDBFE1E7FqfPlnnAsuDW8Wx8pBfAXwjv
+9BvbcG9pMYTZJTznI807DIz0THF4od0pzFPIcBCqH7itrlc4T7T52R9bCC4qSf2TfLEniG64O+YhTct+5hbdE/
pstcDva1vjQcuvkKcfmVBK9s6L31vKonwscP7OvI1fqUsjxfX/
G6afpA9MXEu5HTB39YYSx2vDaP5mMJTj1MPc04tbEj9FNaicH5B2YbT0wakPHK7HpjMBz7atnXI9z6RvOWAsDgC/
G3Rp8ZUx2uT8RKJwEcax+q2LWXLaJ/InZ26Vnzv8qx6uk8DvFzwtxV/x1LHaxPSPQ3SnKYYPXcj
+N1pSZmYxFpT9uDMqcWCG3OYOZO83F+RWgB/TfIXwtsfDvR2ZnRN43jUd8xpg6/
sMYhc6T9kz54WUx4gEhbcpSS4XylLmwDgrzH+Qnj7hSCw/OicWxp2mZkM4en
+SNlkhei43ymbaPN6FtuA7SEGgfuch6sKbggvF+iCv0PK8YoGeHTUoB/JricKd41U1PLlQ0fu3LHh9phyqJgeRZN1J/
ZgdhBb8LcL/g55cs1V411YEA4jI5vHNguoeHnokbLqhITqrQ7z
+JB3LJuUtHvEYhsTAP52yF9UNQA2Qgjkio8uazrTbSajEQ50wBUhC
+8HNAdgCdKa25D/9ql9Pe9FEtWY3tb0AsDVUejxAgAAAN0BVQ0AAAAQXgAAAAgvAAAAAOEFAABwF/8VYAAXRwSpGfHzm
57/87
class="layout-img"> <p class="layout-tip">哎呀,找不到该页面啦!</p>
<p id="tips">请检查您的网络连接是否正常或者输入的网址是否正确</p> </div>
</div>
</div>
</div>
</body>
</html>
nginx流量控制
流量限制 (rate-limiting),是Nginx中一个非常实用,却经常被错误理解和错误配置的功能。我们可以用来限制用户在给定时间内HTTP请求的数量。请求,可以是一个简单网站首页的GET请求,也可以是登录表单的 POST 请求。流量限制可以用作安全目的,比如可以减慢暴力密码破解的速率。通过将传入请求的速
率限制为真实用户的典型值,并标识目标URL地址(通过日志),还可以用来抵御 DDOS ***。更常见的情况,该功能被用来保护上游应用服务器不被同时太多用户请求所压垮。
1、Nginx如何限流
Nginx的”流量限制”使用漏桶算法(leaky bucket algorithm),该算法在通讯和分组交换计算机网络中广泛使用,用以处理带宽有限时的突发情况。就好比,一个桶口在倒水,桶底在漏水的水桶。如果桶口倒水的速率大于桶底的漏水速率,桶里面的水将会溢出;同样,在请求处理方面,水代表来自客户端的请求,水
桶代表根据”先进先出调度算法”(FIFO)等待被处理的请求队列,桶底漏出的水代表离开缓冲区被服务器处理的请求,桶口溢出的水代表被丢弃和不被处理的请求。
2、配置基本的限流
“流量限制”配置两个主要的指令,limit_req_zone和limit_req,如下所示: limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
limit_req_zone指令设置流量限制和共享内存区域的参数,但实际上并不限制请求速率。所以需要通过添加limit_req指令,将流量限制应用在特定的location或者server块。在上面示例中,我们对/login/请求进行流量限制。现在每个IP地址被限制为每秒只能请求10次/login/,更准确地说,在前一个请求的100毫秒内不能请求该URL。
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配置(真实的WEB服务器): server {
listen 80; server_name localhost; location /login {
root /usr/share/nginx/html; index index.html index.html;
}
58/87
}
limit_req_zone指令定义了流量限制相关的参数,而limit_req指令在出现的上下文中启用流量限制(示例中,对于”/login/”的所有请求)。
limit_req_zone指令通常在HTTP块中定义,使其可在多个上下文中使用,它需要以下三个参数:
• Key - 定义应用限制的请求特性。示例中的 Nginx 变量$binary_remote_addr,保存客户端IP地址的二进制形
式。这意味着,我们可以将每个不同的IP地址限制到,通过第三个参数设置的请求速率。(使用该变量是因为比字符串形式的客户端IP地址$remote_addr,占用更少的空间)
• Zone - 定义用于存储每个IP地址状态以及被限制请求URL访问频率的共享内存区域。保存在内存共享区域的信息,意味着可以在Nginx的worker进程之间共享。定义分为两个部分:通过zone=keyword标识区域的名
字,以及冒号后面跟区域大小。16000个IP地址的状态信息,大约需要1MB,所以示例中区域可以存储
160000个IP地址。
• Rate - 定义最大请求速率。在示例中,速率不能超过每秒10个请求。Nginx实际上以毫秒的粒度来跟踪请
求,所以速率限制相当于每100毫秒1个请求。因为不允许”突发情况”(见下一章节),这意味着在前一个请求100毫秒内到达的请求将被拒绝。(1秒(s)=1000毫秒(ms))
处理突发
如果我们在100毫秒内接收到2个请求,怎么办?对于第二个请求,Nginx将给客户端返回状态码503。这可能并不是我们想要的结果,因为应用本质上趋向于突发性。相反地,我们希望缓冲任何超额的请求,然后及时地处理它们。我们更新下配置,在limit_req中使用burst参数:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/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 burst=20; 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;
}
}
burst参数定义了超出zone指定速率的情况下(示例中的mylimit区域,速率限制在每秒10个请求,或每100毫秒一个请求),客户端还能发起多少请求。上一个请求100毫秒内到达的请求将会被放入队列,我们将队列大小设置为20。
59/87
这意味着,如果从一个给定IP地址发送21个请求,Nginx会立即将第一个请求发送到上游服务器群,然
后将余下20个请求放在队列中。然后每100毫秒转发一个排队的请求,只有当传入请求使队列中排队的请求数超过20时,Nginx才会向客户端返回503。
nginx流量限制(高级)
通过将基本的“流量限制”与其他Nginx功能配合使用,我们可以实现更细粒度的流量限制。
1、白名单
下面这个例子将展示,如何对任何不在白名单内的请求强制执行“流量限制”: http {
include /etc/nginx/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;
geo $limit {
default 1;
10.0.0.0/24 0;
192.168.0.0/24 0;
}
map $limit $limit_key { 0 "";
1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=req_zone:10m rate=5r/s;
server {
listen 80; server_name localhost; location / {
limit_req zone=req_zone burst=10 nodelay; root /usr/share/nginx/html;
index index.html index.hml;
}
}
include /etc/nginx/conf.d/*.conf;
}
这个例子同时使用了geo和map指令。geo块将给在白名单中的IP地址对应的$limit变量分配一个值0,给其它不在白名单中的分配一个值1。然后我们使用一个映射将这些值转为key,如下:
•如果$limit变量的值是0,$limit_key变量将被赋值为空字符串
•如果$limit变量的值是1,$limit_key变量将被赋值为客户端二进制形式的IP地址
两个指令配合使用,白名单内IP地址的$limit_key变量被赋值为空字符串,不在白名单内的被赋值为客户端的IP地址。当limit_req_zone后的第一个参数是空字符串时,不会应用“流量限制”,所以白名单内的IP地
址(10.0.0.0/24和192.168.0.0/24 网段内)不会被限制。其它所有IP地址都会被限制到每秒5个请求。limit_req
指令将限制应用到/的location块,允许在配置的限制上最多超过10个数据包的突发,并且不会延迟转发。
60/87
流量控制相关功能
1、配置日志记录
默认情况下,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的值
默认情况下,Nginx以error级别来记录被拒绝的请求,如上面示例中的[error]所示(Ngin以较低级别记录延时请求,一般是info级别)。如要更改Nginx的日志记录级别,需要使用limit_req_log_level指令。这里,我
们将被拒绝请求的日志记录级别设置为warn:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/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 burst=20 nodelay; 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;
}
}
2、发送到客户端的错误代码
一般情况下,客户端超过配置的流量限制时,Nginx响应状态码为503(Service Temporarily Unavailable)。可以使用limit_req_status指令来设置为其它状态码(例如下面的404状态码): limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/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 burst=20 nodelay; 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;
61/87
}
}
nginx访问控制
1、nginx 访问控制模块(1)基于IP的访问控制:http_access_module
(2)基于用户的信任登录:http_auth_basic_module
基于IP的访问控制
2、基于IP的访问控制
1)、配置语法
Syntax:allow address | CIDR | unix: | all; default:默认无Context:http,server,location,limit_except
Syntax:deny address | CIDR | unix: | all; default:默认无Context:http,server,location,limit_except
3、配置测试
修改/etc/nginx/conf.d/access_mod.conf内容如下: server {
listen 80; server_name localhost; location ~ ^/admin {
root /home/www/html; index index.html index.hml; deny 192.168.1.8;
allow all;
}
}
#需要注意:
如果先允许访问,在定义拒绝访问。那么拒绝访问不生效。
虚拟机宿主机IP为192.168.1.8,虚拟机IP为192.168.1.11,故这里禁止宿主机访问,允许其他所有IP访
62/87
问。 宿主机访问http://192.168.1.11/admin,显示403 Forbidden。 当然也可以反向配置,同时也可以使用IP
网段的配置方式,如allow 192.168.1.0/24;,表示满足此网段的IP都可以访问。
4、指定location拒绝所有请求
如果你想拒绝某个指定URL地址的所有请求,而不是仅仅对其限速,只需要在location块中配置deny all指令:
server {
listen 80; server_name localhost; location /foo.html {
root /home/www/html; deny all;
}
}
基于用户的信任登录
1、配置语法
Syntax:auth_basic string | off;
default:auth_basic off;
Context:http,server,location,limit_except
Syntax:auth_basic_user_file file; default:默认无Context:http,server,location,limit_except
file:存储用户名密码信息的文件。
2、配置示例
配置auth_mod.conf,内容如下: server {
listen 80; server_name localhost; location ~ ^/admin {
root /home/www/html; index index.html index.hml;
auth_basic "Auth access test!"; auth_basic_user_file /etc/nginx/auth.conf;
}
}
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
[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、访问测试
63/87
5、局限性
(1)用户信息依赖文件方式(2)操作管理机械,效率低下
6、解决方法
(1)Nginx结合LUA实现高效验证(2)Nginx和LDAP打通,利用nginx-auth-ldap模块
(3)Nginx只做中间代理,具体认证交给应用。
nginx变量(了解)
nginx变量简介:
•所有的 Nginx变量在 Nginx 配置文件中引用时都须带上 $ 前缀
•在 Nginx 配置中,变量只能存放一种类型的值,有且也只存在一种类型,那就是字符串类型
•nginx可以使用变量简化配置与提高配置的灵活性,所有的变量值都可以通过这种方式引用:
64/87
nginx 变量的定义和使用:nginx中的变量分为两种,自定义变量与内置预定义变量
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
添加模块:
[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 #启动
65/87
[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
二:使用配置 $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
使用大括号插值
在“变量插值”的上下文中,还有一种特殊情况,即当引用的变量名之后紧跟着变量名的构成字符时(比如后跟字母、数字以及下划线),我们就需要使用特别的记法来消除歧义,例如:
server {
listen 80;
server_name localhost; location /test-brace {
set $first "hello "; echo "${first}world";
}
}
输出
[root@192 conf.d]# nginx -s reload [root@192 conf.d]# curl localhost/test-brace hello world
66/87
这里,我们在 echo 配置指令的参数值中引用变量 first 的时候,后面紧跟着 world 这个单词,所以如果直接写作 "firstworld" 则 Nginx “变量插值”计算引擎会将之识别为引用了变量 firstworld. 为了解决这个难题,Nginx 的字符串记法支持使用花括号在 之后把变量名围起来,比如这里的 ${first}。
内置预定义变量
内置预定义变量即无需声明就可以使用的变量,通常包括一个http请求或响应中一部分内容的值,以下为一些常用的内置预定义变量
67/87
$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系统调用的值
$httpHEADER HTTP请求头中的内容,HEADER为HTTP请求中的内容转为小写,-变为(破折
号变为下划线),例如:$http_user_agent(Uaer-Agent的值);
$sent_httpHEADER 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。
变量名 定义
68/87
$uri 请求中的当前URI(不带请求参数,参数位于args),不同于浏览器传递
的args),不同于浏览器传递的args),不同于浏览器传递的request_uri
的值,它可以通过内部重定向,或者使用index指令进行修改。不包括协议和主机名,例如/foo/bar.html
变量名 定义
uri vs request_uri
由 ngx_http_core 模块提供的内建变量 uri,可以用来获取当前请求的 URI(不含请求参数), 而 request_uri 则用来获取请求最原始的 URI (包含请求参数)。
server {
listen 80;
server_name localhost; location /test-uri {
echo "uri = $uri";
echo "request_uri = $request_uri";
}
}
输出:
[root@192 conf.d]# nginx -s reload [root@192 conf.d]# curl localhost/test-uri uri = /test-uri
request_uri = /test-uri
[root@192 conf.d]# curl "localhost/test-uri?a=3&b=4" uri = /test-uri
request_uri = /test-uri?a=3&b=4
[root@192 conf.d]# curl "localhost/test-uri/hello%20world?a=3&b=4" uri = /test-uri/hello world
request_uri = /test-uri/hello%20world?a=3&b=4
arg_XXX
另一个特别常用的内建变量其实并不是单独一个变量,而是有无限多变种的一群变量,即名字以 arg_ 开头的所有变量,我们估且称之为 arg_XXX 变量群。
一个例子是 arg_name,这个变量的值是当前请求中名为 name 的参数的值,而且还是未解码的原始形式的值。
server {
listen 80;
server_name localhost; location /test-arg {
echo "name: $arg_name";
echo "class: $arg_class";
69/87
}
}
输出:
[root@192 conf.d]# nginx -s reload [root@192 conf.d]# curl localhost/test-arg name:
class:
[root@192 conf.d]# curl "localhost/test-arg?name=Tom&class=3" name: Tom
class: 3
[root@192 conf.d]# curl "localhost/test-arg?name=hello%20world&class=9" name: hello%20world
class: 9
$arg_XXX 不区分大小写
其实 $arg_name 不仅可以匹配 name 参数,也可以匹配 NAME 参数,抑或是 Name,Nginx 会在匹配参数名之前,自动把原始请求中的参数名调整为全部小写的形式。
[root@192 conf.d]# curl "localhost/test-arg?NAME=Marry" name: Marry
class:
[root@192 conf.d]# curl "localhost/test-arg?Name=Jimmy&class=DSfef" name: Jimmy
class: DSfef
nginx 监控
1、nginx的基础监控
•进程监控
•端口监控
注意: 这两个是必须要加在zabbix监控,加触发器有问题及时告警。 web 服务器 nginx 以其高性能与抗并发能力越来越多的被用户使用
nginx 提供了 ngx_http_stub_status_module,ngx_http_reqstat_module模块,这个模块提供了基本的监控功能
2、监控的主要指标
1)、基本活跃指标Accepts(接受)、Handled(已处理)、Requests(请求数)是一直在增加的计数器。
Active(活跃)、Waiting(等待)、Reading(读)、Writing(写)随着请求量而增减。
70/87
名称 描述 指标类型
Accepts(接受) NGINX 所接受的客户端连接数 资源: 功能
Handled(已处理) 成功的客户端连接数 资源: 功能
Dropped(已丢弃,计算得出) 丢弃的连接数(接受 - 已处理) 工作:错误*
Requests(请求数) 客户端请求数 工作:吞吐量
2)、每秒请求数 -- QPS 通过持续的 QPS 监控,可以立刻发现是否被恶意***或对服务的可用性进行评估。虽然当问题发生
时,通过 QPS 不能定位到确切问题的位置,但是他却可以在第一时间提醒你环境可能出问题了。
3)、请求处理时间请求处理时间也可以被记录在 access log 中,通过分析 access log,统计请求的平均响应时间,通过持
续观察,可以发现上游服务器的问题
3、指标的收集通过在编译时加入 nginx 的 ngx_http_stub_status_module 模块我们可以实时监控以下基本的指标:
1)、nginx Stub Status 监控模块安装
先使用命令查看是否已经安装这个模块:
[root@localhost ~]# nginx -V
如果没有此模块,需要重新安装,编译命令如下:
./configure –with-http_stub_status_module 具体的使用方法是在执行 ./configure 时,指定 --with-http_stub_status_module,然后通过配置: server {
listen 80; server_name localhost; location /nginx-status {
stub_status on;
access_log on;
}
}
nginx 状态查看
配置完成后在浏览器中输入http://10.0.105.207/nginx-status 查看(或者用 curl localhost/ nginx_status),显示信息如下:
Active connections: 2
server accepts handled requests 26 26 48
Reading: 0 Writing: 1 Waiting: 1
Active connections:2 #当前nginx处理请求的数目(活跃的连接数)
server accepts handled requests 26 26 48
nginx总共处理了26个连接,成功创建26次握手,也就是成功的连接数connection. 总共处理了48个请求
失败连接=(总连接数-成功连接数)(相等表示中间没有失败的), Reading : nginx读取到客户端的Header信息数。请求头 -----速度快。 Writing :nginx返回给客户端的Header信息数。响应头
Waiting :开启keep-alive的情况下,意思就是Nginx说已经处理完正在等候下一次请求指令的驻留连接。
#可以nginx有多少的长连接。相当于空闲的。可以把超时时间改的短一点。 ---------监控的对象通常,一个连接在同一时间只接受一个请求。在这种情况下,Active 连接的数目 == Waiting 的连接 + Reading 请求 + Writing
71/87
HTTPS
https简介
HTTPS(全称:HyperText Transfer Protocol over Secure Socket Layer),其实 HTTPS 并不是一个新鲜协议,Google 很早就开始启用了,初衷是为了保证数据安全。 近些年,Google、Baidu、Facebook 等这样的互
联网巨头,不谋而合地开始大力推行 HTTPS, 国内外的大型互联网公司很多也都已经启用了全站 HTTPS,这也是未来互联网发展的趋势。
一、加密算法
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值不被修改。
72/87
二:HTTPS 协议介绍
• HTTP 协议(HyperText Transfer Protocol,超文本传输协议):是客户端浏览器或其他程序与Web服务器之
间的应用层通信协议 。
• HTTPS 协议(HyperText Transfer Protocol over Secure Socket Layer):可以理解为HTTP+SSL/TLS, 即
HTTP 下加入 SSL 层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL,用于安全的 HTTP 数据传输。
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)维护数据的完整性,确保数据在传输过程中不被改变。
https工作原理
HTTP请求过程中,客户端与服务器之间没有任何身份确认的过程,数据全部明文传输,“裸奔”在互联网上,所以很容易遭到***的***。
客户端发出的请求很容易被***截获,如果此时***冒充服务器,则其可返回任意信息给客户端,而不被客户端察觉。
HTTP 传输面临的风险有:
73/87
•窃听风险:***可以获知通信内容。
•篡改风险:***可以修改通信内容。
•冒充风险:***可以冒充他人身份参与通信。
那有没有一种方式既可以安全的获取公钥,又能防止***冒充呢? 那就需要用到终极武器了:SSL 证书(申购)
•证书:.crt, .pem
•私钥:.key
•证书请求文件:.csr
服务器发送了一个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)使用对称加密密钥传输数据,并校验数据的完整性
所以通过发送SSL证书的形式,既解决了公钥获取问题,又解决了***冒充问题,一箭双雕,HTTPS加密过程也就此形成
相比HTTP,HTTPS 传输更加安全(1) 所有信息都是加密传播,***无法窃听。
(2) 具有校验机制,一旦被篡改,通信双方会立刻发现。(3) 配备身份证书,防止身份被冒充。
HTTPS 缺点:
1.SSL 证书费用很高,以及其在服务器上的部署、更新维护非常繁琐
2.HTTPS 降低用户访问速度(多次握手)
3.网站改用HTTPS 以后,由HTTP 跳转到 HTTPS 的方式增加了用户访问耗时(多数网站采用302跳转)
4.HTTPS 涉及到的安全算法会消耗 CPU 资源,需要增加大量机器(https访问过程需要加解密)
74/87
#国家;match表示申请者的申请信息必须与此一致
#州、省
#组织名、公司名
75/87
= match = match
= match
构建私有的 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 检查安装 openssl,如果未安装
[root@https-ca ~]# rpm -qa openssl
[root@https-ca ~]# yum install openssl openssl-devel
查看配置文件
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策略生效
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
76/87
-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
8、客户端CA 证书申请及签名安装 openssl
[root@nginx-server ~]# yum install openssl openssl-devel
客户端生成私钥文件
[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]#
客户端用私钥加密生成证书请求
[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发起认证请求的文件,是中间文件。
最后把生成的请求文件(/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
77/87
root@10.0.105.181's password:
www.qf.com.csr 100% 997 331.9KB/s 00:00
9.CA 签署证书
[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
=========================================================
注意:可能遇到的问题
[root@https-ca private]# cd
[root@https-ca ~]# openssl ca -in /etc/pki/CA/private/www.qf.com.csr -out /etc/pki/CA/certs/www.qf.com.ctr - days 365
Using configuration from /etc/pki/tls/openssl.cnf Check that the request matches the signature Signature ok
The organizationName field needed to be the same in the CA certificate (CA) and the request (QF)
因为默认使用/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
=========================================================
78/87
查看生成的证书的信息
[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
将生成的证书发放给请求客户端
[root@https-ca ~]# cd /etc/pki/CA/certs/
[root@https-ca certs]# scp www.qf.com.ctr 10.0.105.199:/etc/pki/CA/certs/
root@10.0.105.199's password:
www.qf.com.ctr 100% 4422 998.3KB/s 00:00
10.测试:
nginx-client(充当服务端): [root@localhost ~]# cd /etc/pki/ [root@localhost pki]# ls
CA ca-trust java nssdb nss-legacy rpm-gpg rsyslog tls [root@localhost pki]# cd CA/
[root@localhost CA]# ls certs crl newcerts private [root@localhost CA]# cd certs/ [root@localhost certs]# ls www.qf.com.crt [root@localhost certs]# pwd /etc/pki/CA/certs [root@localhost certs]# ls www.qf.com.ctr [root@localhost certs]# pwd /etc/pki/CA/certs
[root@localhost certs]# find / -name .key /etc/pki/tls/private/www.qf.com.key /usr/share/doc/openssh-7.4p1/PROTOCOL.key [root@localhost certs]# find / -name .ctr
还是在这台机器安装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
浏览器测试访问:
79/87
CA吊销证书
1、知道客户端吊销的证书的serial [root@https-ca ~]# openssl x509 -in /etc/pki/tls/cert.pem -noout -serial -subject serial=5EC3B7A6437FA4E0
subject= /CN=ACCVRAIZ1/OU=PKIACCV/O=ACCV/C=ES
2、吊销证书
先根据客户提交的serial与subject信息,对比检验是否与index.txt文件中的信息一致;然后
[root@https-ca ~]# openssl ca -revoke /etc/pki/CA/newcerts/01.pem
3、生成吊销证书的编号第一次吊销一个证书时才需要执行
[root@https-ca ~]# echo 01 > /etc/pki/CA/crlnumber
80/87
4、更新证书吊销列表
[root@https-ca ~]# openssl ca -gencrl -out thisca.crl
5、查看证书吊销列表
[root@https-ca ~]# openssl crl -in /root/thisca.crl -noout -text
nginx的https部署实战
1.申请证书与认证
2.证书下载与配置
3.问题分析与总结
1、证书申请(具体上课操作演示)
2、域名验证(具体上课操作演示)
3、证书下载与配置(具体上课操作演示)
[root@xiaoxuan 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 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;
}
}
性能优化
当我需要进行性能优化时,说明我们服务器无法满足日益增长的业务。性能优化是一个比较大的课题,需要从以下几个方面进行探讨
•当前系统结构瓶颈
•了解业务模式
•性能与安全
1、当前系统结构瓶颈
首先需要了解的是当前系统瓶颈,用的是什么,跑的是什么业务。里面的服务是什么样子,每个服务最大支持多少并发。比如针对nginx而言,我们处理静态资源效率最高的瓶颈是多大?
可以通过查看当前cpu负荷,内存使用率,进程使用率来做简单判断。还可以通过操作系统的一些工
81/87
具来判断当前系统性能瓶颈,如分析对应的日志,查看请求数量。也可以通过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
注意:
82/87
可以看到root和,root代表是root用户,代表的是所有用户,后面的数字就是文件句柄大小。大家可以根据个人业务来进行设置。
4、进程局部性修改:worker_rlimit_nofile 是在进程上面进行限制。 [root@nginx-server ~]# vim /etc/nginx/nginx.conf
user 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;
}
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;
}
cpu的亲和配置
cpu的亲和能够使nginx对于不同的work工作进程绑定到不同的cpu上面去。就能够减少在work间不断
切换cpu,把进程通常不会在处理器之间频繁迁移,进程迁移的频率小,来减少性能损耗。 https://nginx.org/en/docs/ngx_core_module.html#worker_cpu_affinity
查看物理cpu
[root@nginx-server ~]# cat /proc/cpuinfo | grep "physical id" | sort|uniq | wc -l
查看cpu核心数
83/87
[root@nginx-server ~]# cat /proc/cpuinfo|grep "cpu cores"|uniq
查看cpu使用率
[root@nginx-server ~]#top 回车后按 1
worker_processes
[root@nginx-server ~]# vim /etc/nginx/nginx.conf 将刚才查看到自己cpu * cpu核心就是worker_processes
worker_processes 2; #根据自己cpu核心数配置/这里也可以设置为auto
cpu
通过下面命令查看nginx进程配置在哪个核上
[root@nginx-server ~]# ps -eo pid,args,psr |grep [n]ginx
3004 nginx: master process /usr/ 3
3005 nginx: worker process 3
在nginx 1.9版本之后,就帮我们自动绑定了cpu; worker_cpu_affinity auto;
通用配置优化
#将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 {
include /etc/nginx/mime.types;
84/87
default_type application/octet-stream;
charset 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; #如果做静态资源服务器可以打开 #tcp_nodeny on; #当nginx做动态的服务时可以选择打开
keepalive_timeout 65;
########
#Gzip module
gzip on; #文件压缩默认可以打开 gzip_disable "MSIE [1-6]."; #对于有些浏览器不能识别压缩,需要过滤如ie6 gzip_http_version 1.1;
include /etc/nginx/conf.d/*.conf;
}
压力测试
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 是否开启长连接
参数解释
85/87
-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
内容解释
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
86/87
99% 1593
100% 1619 (longest request)
87/87
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。