当前位置: 首页 > news >正文

长沙手机网站首页设计公司深圳罗湖区网站建设

长沙手机网站首页设计公司,深圳罗湖区网站建设,服务器购买一台多少钱,广东私人做网站的联系方式一、HTTP 介绍 HTTP协议是Hyper Text Transfer Protocol#xff08;超文本传输协议#xff09;的缩写,是用于从万维网#xff08;WWW:World Wide Web #xff09;服务器传输超文本到本地浏览器的传送协议。 HTTP是一个基于TCP/IP通信协议来传递数据#xff08;HTML 文件…一、HTTP 介绍 HTTP协议是Hyper Text Transfer Protocol超文本传输协议的缩写,是用于从万维网WWW:World Wide Web 服务器传输超文本到本地浏览器的传送协议。 HTTP是一个基于TCP/IP通信协议来传递数据HTML 文件, 图片文件, 查询结果等。 1、HTTP 工作原理 HTTP协议工作于客户端-服务端架构上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。 Web服务器有NginxApache服务器IIS服务器Internet Information Services等。 Web服务器根据接收到的请求后向客户端发送响应信息。 HTTP默认端口号为80但是你也可以改为8080或者其他端口。 HTTP三点注意事项 HTTP是无连接无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求并收到客户的应答后即断开连接。采用这种方式可以节省传输时间。HTTP是媒体独立的这意味着只要客户端和服务器知道如何处理的数据内容任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。HTTP是无状态HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息则它必须重传这样可能导致每次连接传送的数据量增大。另一方面在服务器不需要先前信息时它的应答就较快。 以下图表展示了HTTP协议通信流程 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LwIHXNE6-1602213757497)(assets/1561893004169.png)] 2、HTTP 消息结构 HTTP是基于客户端/服务端C/S的架构模型通过一个可靠的链接来交换信息是一个无状态的请求/响应协议。 一个HTTP客户端是一个应用程序Web浏览器或其他任何客户端通过连接到服务器达到向服务器发送一个或多个HTTP的请求的目的。 一个HTTP服务器同样也是一个应用程序通常是一个Web服务如Apache Web服务器或IIS服务器等通过接收客户端的请求并向客户端发送HTTP响应数据。 HTTP使用统一资源标识符Uniform Resource Identifiers, URI来传输数据和建立连接。 一旦建立连接后数据消息就通过类似Internet邮件所使用的格式[RFC5322]和多用途Internet邮件扩展MIME[RFC2045]来传送。 3、客户端请求消息 客户端发送一个HTTP请求到服务器的请求消息包括以下格式请求行request line、请求头部header、空行和请求数据四个部分组成下图给出了请求报文的一般格式。 4、服务器响应消息 HTTP响应也由四个部分组成分别是状态行、消息报头、空行和响应正文。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TwJqV4vx-1602213757504)(assets/1561893177737.png)] 实例 下面实例是典型的使用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 GMTContent-Type: text/plain #文本类型有htmlplain:普通文本Content-Length: 12Last-Modified: Thu, 04 Jul 2019 08:13:25 GMTConnection: keep-alive #是否支持长连接ETag: 5d1db525-c #标识每次访问如果与最开始的一样返回304否则校验不一致返回200Accept-Ranges: bytes输出结果: hello world5、HTTP 请求方法 根据HTTP标准HTTP请求可以使用多种请求方法。 HTTP1.0定义了三种请求方法 GET, POST 和 HEAD方法。 HTTP1.1新增了五种请求方法OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JrW8DBqy-1602213757507)(assets/1561896279402.png)] get正常请求资源 post登录界面表单 6、HTTP 响应头信息 HTTP请求头提供了关于请求响应或者其他的发送实体的信息。 在本章节中我们将具体来介绍HTTP响应头信息。 Allow Content-Encoding Content-Type 应答头说明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格林威治时间时间GMT8。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦。Expires应该在什么时候认为文档已经过期从而不再缓存它Last-Modified文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期该请求将被视为一个条件GET只有改动时间迟于指定时间的文档才会返回否则返回一个304Not Modified状态。Last-Modified也可用setDateHeader方法来设置。Location表示客户应当到哪里去提取文档。Location通常不是直接设置的而是通过HttpServletResponse的sendRedirect方法该方法同时设置状态代码为302。Refresh表示浏览器应该在多少时间之后刷新文档以秒计。除了刷新当前文档之外你还可以通过setHeader(“Refresh”, “5; URLhttp://host/path”)让浏览器读取指定的页面。 注意这种功能通常是通过设置HTML页面HEAD区的META HTTP-EQUIV“Refresh” CONTENT“5;URLhttp://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头中提供什么类型的授权信息在包含401Unauthorized状态行的应答中这个头是必需的。例如response.setHeader(“WWW-Authenticate”, “BASIC realm“executives””)。 注意Servlet一般不进行这方面的处理而是让Web服务器的专门机制来控制受密码保护页面的访问例如.htaccess。 7、HTTP 状态码 当浏览者访问一个网页时浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前此网页所在的服务器会返回一个包含HTTP状态码的信息头server header用以响应浏览器的请求。 HTTP状态码的英文为HTTP Status Code。 下面是常见的HTTP状态码 200 - 请求成功301 - 资源网页等被永久转移到其它URL404 - 请求的资源网页等不存在500 - 内部服务器错误 HTTP协议状态码含义 ​ 200  OK服务器成功返回网页   301  永久跳转请求的网页已永久跳转到新位置 403  禁止访问,服务器拒绝请求   404  服务器找不到请求的页面   500  内部服务器错误   502  坏的网关一般是网关服务器请求后端服务时后端服务没有按照http协议正确返回结果   503  服务当前不可用可能因为超载或停机维护   504  网关超时一般是网关服务器请求后端服务时后端服务没有在特定的时间内完成服务 HTTP状态码分类 HTTP状态码由三个十进制数字组成第一个十进制数字定义了状态码的类型后两个数字没有分类的作用。HTTP状态码共分为5种类型 200、301、302、304、400、401、403、404、500、501、502、 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QACpudWc-1602213757509)(assets/1561896413177.png)] HTTP状态码列表: 状态码状态码英文名称中文描述100Continue继续。客户端应继续其请求101Switching Protocols切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议例如切换到HTTP的新版本协议200OK请求成功。一般用于GET与POST请求201Created已创建。成功请求并创建了新的资源202Accepted已接受。已经接受请求但未处理完成203Non-Authoritative Information非授权信息。请求成功。但返回的meta信息不在原始的服务器而是一个副本204No Content无内容。服务器成功处理但未返回内容。在未更新网页的情况下可确保浏览器继续显示当前文档205Reset Content重置内容。服务器处理成功用户终端例如浏览器应重置文档视图。可通过此返回码清除浏览器的表单域206Partial Content部分内容。服务器成功处理了部分GET请求300Multiple Choices多种选择。请求的资源可包括多个位置相应可返回一个资源特征与地址的列表用于用户终端例如浏览器选择301Moved Permanently永久移动。请求的资源已被永久的移动到新URI返回信息会包括新的URI浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替302Found临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI303See Other查看其它地址。与301类似。使用GET和POST请求查看304Not Modified未修改。所请求的资源未修改服务器返回此状态码时不会返回任何资源。客户端通常会缓存访问过的资源通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源305Use Proxy使用代理。所请求的资源必须通过代理访问306Unused已经被废弃的HTTP状态码307Temporary Redirect临时重定向。与302类似。使用GET请求重定向400Bad Request客户端请求的语法错误服务器无法理解401Unauthorized请求要求用户的身份认证402Payment Required保留将来使用403Forbidden服务器理解请求客户端的请求但是拒绝执行此请求404Not Found服务器无法根据客户端的请求找到资源网页。通过此代码网站设计人员可设置您所请求的资源无法找到的个性页面405Method Not Allowed客户端请求中的方法被禁止406Not Acceptable服务器无法根据客户端请求的内容特性完成请求407Proxy Authentication Required请求要求代理的身份认证与401类似但请求者应当使用代理进行授权408Request Time-out服务器等待客户端发送的请求时间过长超时409Conflict服务器完成客户端的PUT请求是可能返回此代码服务器处理请求时发生了冲突410Gone客户端请求的资源已经不存在。410不同于404如果资源以前有现在被永久删除了可使用410代码网站设计人员可通过301代码指定资源的新位置411Length Required服务器无法处理客户端发送的不带Content-Length的请求信息412Precondition Failed客户端请求信息的先决条件错误413Request Entity Too Large由于请求的实体过大服务器无法处理因此拒绝请求。为防止客户端的连续请求服务器可能会关闭连接。如果只是服务器暂时无法处理则会包含一个Retry-After的响应信息414Request-URI Too Large请求的URI过长URI通常为网址服务器无法处理415Unsupported Media Type服务器无法处理请求附带的媒体格式416Requested range not satisfiable客户端请求的范围无效417Expectation Failed服务器无法满足Expect的请求头信息500Internal Server Error服务器内部错误无法完成请求501Not Implemented服务器不支持请求的功能无法完成请求502Bad Gateway作为网关或者代理工作的服务器尝试执行请求时从远程服务器接收到了一个无效的响应503Service Unavailable由于超载或系统维护服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中504Gateway Time-out充当网关或代理的服务器未及时从远端服务器获取请求505HTTP Version not supported服务器不支持请求的HTTP协议的版本无法完成处理 二、nginx 服务 1、nginx 介绍 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SgX0xyEd-1602213757511)(assets/1561897043854.png)] 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服务器不错的替代品。 创始人伊戈尔·赛索耶夫 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QEnmK4UH-1602213757513)(assets/1561897072438.png)] 2、为什么选择 nginx Nginx 是一个高性能的 Web 和反向代理服务器, 它具有有很多非常优越的特性: 单机环境下参考服务器配置。 并发连接数在7000 -8000左右。 集群模式20000 作为 Web 服务器相比 ApacheNginx 使用更少的资源支持更多的并发连接体现更高的效率这点使 Nginx 尤其受到虚拟主机提供商的欢迎。能够支持高达 50,000 个并发连接数的响应感谢 Nginx 为我们选择了 epoll and kqueue 作为开发模型. 作为负载均衡服务器Nginx 既可以在内部直接支持 Rails 和 PHP也可以支持作为 HTTP代理服务器 对外进行服务。Nginx 用 C 编写, 不论是系统资源开销还是 CPU 使用效率都比 Perlbal 要好的多。 作为邮件代理服务器: Nginx 同时也是一个非常优秀的邮件代理服务器最早开发这个产品的目的之一也是作为邮件代理服务器Last.fm 描述了成功并且美妙的使用经验。 Nginx 安装非常的简单配置文件 非常简洁还能够支持perl语法Bugs非常少的服务器: Nginx 启动特别容易并且几乎可以做到7*24不间断运行即使运行数个月也不需要重新启动。你还能够在 不间断服务的情况下进行软件版本的升级。 3、IO多路复用 1、I/O multiplexing【多并发】 第一种方法就是最传统的多进程并发模型 (每进来一个新的I/O流会分配一个新的进程管理。) 第二种方法就是I/O多路复用 (单个线程通过记录跟踪每个I/O流(sock)的状态来同时管理多个I/O流 。) [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fAvOqQpP-1602213757514)(assets/1561897144109.png)] I/O multiplexing 这里面的 multiplexing 指的其实是在单个线程通过记录跟踪每一个Sock(I/O流)的状态来同时管理多个I/O流。发明它的原因是尽量多的提高服务器的吞吐能力。 在同一个线程里面 通过拨开关的方式来同时传输多个I/O流 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4kcCQvCk-1602213757516)(assets/1561897166658.png)] 2、一个请求到来了nginx使用epoll接收请求的过程是怎样的? ngnix会有很多连接进来 epoll会把他们都监视起来然后像拨开关一样谁有数据就拨向谁然后调用相 应的代码处理。 select, poll, epoll 都是I/O多路复用的具体的实现其实是他们出现是有先后顺序的。 I/O多路复用这个概念被提出来以后 相继出现了多个方案 select是第一个实现 (1983 左右在BSD里面实现的)。 select 被实现以后很快就暴露出了很多问题。 • select 会修改传入的参数数组这个对于一个需要调用很多次的函数是非常不友好的。 • select 如果任何一个sock(I/O stream)出现了数据select 仅仅会返回但是并不会告诉你是那个sock上有数据于是你只能自己一个一个的找10几个sock可能还好要是几万的sock每次都找一遍… • select 只能监视1024个链接。 • select 不是线程安全的如果你把一个sock加入到select, 然后突然另外一个线程发现这个sock不用要收 回这个select 不支持的如果你丧心病狂的竟然关掉这个sock, select的标准行为是不可预测的 于是14年以后(1997年一帮人又实现了poll, poll 修复了select的很多问题比如 • poll 去掉了1024个链接的限制于是要多少链接呢 主人你开心就好。 • poll 从设计上来说不再修改传入数组不过这个要看你的平台了所以行走江湖还是小心为妙。 其实拖14年那么久也不是效率问题 而是那个时代的硬件实在太弱一台服务器处理1千多个链接简直就是神一样的存在了select很长段时间已经满足需求。 但是poll仍然不是线程安全的 这就意味着不管服务器有多强悍你也只能在一个线程里面处理一组I/O流。 你当然可以那多进程来配合了不过然后你就有了多进程的各种问题。 于是5年以后, 在2002, 大神 Davide Libenzi 实现了epoll. epoll 可以说是I/O 多路复用最新的一个实现epoll 修复了poll 和select绝大部分问题, 比如 • epoll 现在是线程安全的。 • epoll 现在不仅告诉你sock组里面数据还会告诉你具体哪个sock有数据你不用自己去找了。 3、异步非阻塞 $ pstree |grep nginx |- 81666 root nginx: master process nginx | |— 82500 nobody nginx: worker process | — 82501 nobody nginx: worker process 1个master进程2个work进程 ​ 每进来一个request会有一个worker进程去处理。但不是全程的处理处理到什么程度呢处理到可能发生阻塞的地方比如向上游后端服务器转发request并等待请求返回。那么这个处理的worker不会这么一直等着他会在发送完请求后注册一个事件“如果upstream返回了告诉我一声我再接着干”。于是他就休息去了。这就是异步。此时如果再有request 进来他就可以很快再按这种 方式处理。这就是非阻塞和IO多路复用。而一旦上游服务器返回了就会触发这个事件worker才会来 接手这个request才会接着往下走。这就是异步回调。 4、nginx 的内部技术架构 Nginx服务器以其处理网络请求的高并发、高性能及高效率获得了行业界的广泛认可近年已稳居web服务器部署排名第二的位置并被广泛用于反向代理和负载均衡。 Nginx是如何实现这些目标的呢答案就是其独特的内部技术架构设计。看懂下面这张图就明白了Nginx的内部技术架构。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HUNDe9IZ-1602213757517)(assets/1561897235155.png)] 简要说明几点 1nginx启动时会生成两种类型的进程一个是主进程Master一个windows版本的目前只有一个或多个工作进程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天生就是高性能的代理服务器 5、nginx安装部署和配置管理 1、nginx部署-Yum安装 访问nginx的官方网站http://www.nginx.org/ Nginx版本类型 Mainline version 主线版即开发版 Stable version 最新稳定版生产环境上建议使用的版本 Legacy versions 遗留的老版本的稳定版 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gBiqKe3L-1602213757519)(assets/1561531095060.png)] 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。 RHEL/CENTOS Install the prerequisites: sudo yum install yum-utils -yTo set up the yum repository, create the file named /etc/yum.repos.d/nginx.repo with the following contents: [nginx-stable] namenginx stable repo baseurlhttp://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck1 enabled1 gpgkeyhttps://nginx.org/keys/nginx_signing.key[nginx-mainline] namenginx mainline repo baseurlhttp://nginx.org/packages/mainline/centos/$releasever/$basearch/ gpgcheck1 enabled0 gpgkeyhttps://nginx.org/keys/nginx_signing.keyBy default, the repository for stable nginx packages is used. If you would like to use mainline nginx packages, run the following command: sudo yum-config-manager --enable nginx-mainlineTo install nginx, run the following command: sudo yum install nginx -yWhen prompted to accept the GPG key, verify that the fingerprint matches 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62, and if so, accept it. 当提示您接受GPG密钥时请验证指纹是否匹配573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62如果匹配 请接受它。 这里我们用稳定版本 [rootnginx-server yum.repos.d]# yum install -y nginx[rootnginx-server yum.repos.d]# nginx -V //格式化打印 nginx version: nginx/1.16.0 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) built with OpenSSL 1.0.2k-fips 26 Jan 2017 TLS SNI support enabled configure arguments: --prefix/etc/nginx --sbin-path/usr/sbin/nginx --modules-path/usr/lib64/nginx/modules --conf-path/etc/nginx/nginx.conf --error-log-path/var/log/nginx/error.log --http-log-path/var/log/nginx/access.log --pid-path/var/run/nginx.pid --lock-path/var/run/nginx.lock --http-client-body-temp-path/var/cache/nginx/client_temp --http-proxy-temp-path/var/cache/nginx/proxy_temp --http-fastcgi-temp-path/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path/var/cache/nginx/uwsgi_temp --http-scgi-temp-path/var/cache/nginx/scgi_temp --usernginx --groupnginx --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_SOURCE2 -fexceptions -fstack-protector-strong --paramssp-buffer-size4 -grecord-gcc-switches -m64 -mtunegeneric -fPIC --with-ld-opt-Wl,-z,relro -Wl,-z,now -pie[rootnginx-server yum.repos.d]# nginx -v nginx version: nginx/1.16.0 关闭防火墙和selinux: [rootnginx-server ~]# getenforce Enforcing[rootnginx-server ~]# sed -i /SELINUX/s/enforcing/disabled/ /etc/selinux/config[rootnginx-server ~]# systemctl stop firewalld [rootnginx-server ~]# systemctl disable firewalld启动并设置开机启动 [rootnginx-server ~]# systemctl start nginx [rootnginx-server ~]# systemctl enable nginx 浏览器输入ip访问: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xBI6wUeo-1602213757521)(assets/1561536791743.png)] 6、nginx 编译安装与配置使用 1、安装编译环境 yum -y install gcc gcc-c 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 [rootlocalhost ~]# wget http://nginx.org/download/nginx-1.16.0.tar.gz [rootlocalhost ~]# tar xzf nginx-1.16.0.tar.gz -C /usr/local/ [rootlocalhost ~]# cd nginx-1.16.0 [rootlocalhost ~]# wget https://github.com/openresty/echo-nginx-module/archive/v0.61.tar.gz [rootlocalhost ~]# tar xf v0.61.tar.gz [rootlocalhost nginx-1.16.0]# ./configure --prefix/usr/local/nginx --groupnginx --usernginx --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 # --add-module./echo-nginx-module-0.61 --add-module./ngx_req_status-master [rootlocalhost nginx-1.16.0]# m ake make install7、Nginx 编译参数 # 查看 nginx 安装的模块 [rootlocalhost ~]#/usr/local/nginx/sbin/nginx -V # 模块参数具体功能 --with-cc-opt-g -O2 -fPIE -fstack-protector //设置额外的参数将被添加到CFLAGS变量。FreeBSD或者ubuntu使用 --paramssp-buffer-size4 -Wformat -Werrorformat-security -D_FORTIFY_SOURCE2 --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支持启用外部模块支持8、修改配置文件/etc/nginx/nginx.conf # 全局参数设置 worker_processes 4; #设置nginx启动进程的数量一般设置成与逻辑cpu数量相同 error_log logs/error.log; #指定错误日志 worker_rlimit_nofile 102400; #设置一个nginx进程能打开的最大文件数 pid /var/run/nginx.pid; events { worker_connections 1024; #设置一个进程的最大并发连接数 } # http 服务相关设置 http { include mime.types; default_type application/octet-stream; log_format main remote_addr - remote_user [time_local] request status body_bytes_sent $http_referer http_user_agent http_x_forwarded_for; access_log /var/log/nginx/access.log main; #设置访问日志的位置和格式 sendfile on; #是否调用sendfile函数输出文件一般设置为on若nginx是用来进行磁盘IO负载应用时可以设置为off降低系统负载 gzip on; #是否开启gzip压缩将注释去掉开启 keepalive_timeout 65; #设置长连接的超时时间 # 虚拟服务器的相关设置 server { listen 80; #设置监听的端口 server_name localhost; #设置绑定的主机名、域名或ip地址 charset koi8-r; # 设置编码字符 location / { root /var/www/nginx; #设置服务器默认网站的根目录位置,需要手动创建index index.html index.htm; #设置默认打开的文档 } error_page 500 502 503 504 /50x.html; #设置错误信息返回页面 location /50x.html { root html; #这里的绝对位置是/usr/local/nginx/html} } }nginx.conf的组成:nginx.conf一共由三部分组成分别为全局块、events块、http块。在http块中又包含http全局块、多个server块。每个server块中又包含server全局块以及多个location块。在统一配置块中嵌套的配置快各个之间不存在次序关系。检测nginx配置文件是否正确 [rootlocalhost ~]# /usr/local/nginx/sbin/nginx -t [rootlocalhost ~]# mkdir -p /tmp/nginx10、启动nginx服务 [rootlocalhost ~]# /usr/local/nginx/sbin/nginx11、通过 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配置文件是否正确注意 nginx -s reload 命令加载修改后的配置文件,命令下达后发生如下事件 1. Nginx的master进程检查配置文件的正确性若是错误则返回错误信息nginx继续采用原配置文件进行工作因为worker未受到影响 2. Nginx启动新的worker进程采用新的配置文件 3. Nginx将新的请求分配新的worker进程 4. Nginx等待以前的worker进程的全部请求已经都返回后关闭相关worker进程 5. 重复上面过程知道全部旧的worker进程都被关闭掉12、实现nginx开机自启 [rootlocalhost ~]# 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/nginxlockfile/var/lock/nginxmake_dirs() { # make required directories usernginx -V 21 | grep configure arguments: | sed s/[^*]*--user\([^ ]*\).*/\1/g - options$nginx -V 21 | grep configure arguments: for opt in $options; doif [ echo $opt | grep .*-temp-path ]; thenvalueecho $opt | cut -d -f 2 if [ ! -d $value ]; then# echo creating $value mkdir -p $value chown -R $user $value fifidone } 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 21 } case $1 instart) 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 esacb、添加权限 chmod x /etc/init.d/nginxc、重新加载系统启动文件 systemctl daemon-reloadd、启动并设置开机自启 systemctl start nginx [rootlocalhost ~]# /sbin/chkconfig nginx on ---开机启动10、nginx 日志文件详解 ​ nginx 日志文件分为 log_format 和 access_log 两部分 ​ log_format 定义记录的格式其语法格式为 ​ log_format 样式名称 样式详情 ​ 配置文件中默认有 log_format main remote_addr - remote_user [time_local] request status body_bytes_sent $http_referer http_user_agent http_x_forwarded_for;[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XYu6hXjl-1602213757522)(assets/1561599608585.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6U2dJnE4-1602213757524)(assets/1561599718230.png)] 6、nginx 高级应用 1.使用alias实现虚拟目录 location /test {alias /var/www/qianfeng/;index index.html; #访问http://ip/test时实际上访问是/var/www/qianfeng/index.html}6、通过 stub_status 模块监控 nginx 的工作状态 ​ 1、通过 nginx -V 命令查看是否已安装 stub_status 模块 ​ 2、编辑 /etc/nginx/nginx.conf 配置文件 #添加以下内容 location /nginx-status { stub_status on; access_log /var/log/nginx/nginxstatus.log; #设置日志文件的位置 auth_basic nginx-status; #指定认证机制与location后面的内容相同即可 auth_basic_user_file /etc/nginx/htpasswd; #指定认证的密码文件 }3.创建认证口令文件并添加用户qianfeng和zdgg密码用md5加密 [rootlocalhost ~]# yum install -y httpd-tools #htpasswd 是开源 http 服务器 apache httpd 的一个命令工具用于生成 http 基本认证的密码文件 htpasswd -c -m /etc/nginx/htpasswd qianfeng # -c 创建解密文件-m MD5加密 htpasswd -m /etc/nginx/htpasswd zsgg4、重启服务 5、客户端访问 http://ip/nginx-status 即可 7、使用 limit_rate 限制客户端传输数据的速度 1、编辑/etc/nginx/nginx.conf location / {root /var/www/nginx/;index index.html index.htm;limit_rate 2k; #对每个连接的限速为2k/s}重启服务 注意要点 ​ 配置文件中的每个语句要以 ; 结尾 ​ 使用 htpasswd 命令需要先安装 httpd-tools 7、nginx 虚拟主机配置 什么是虚拟主机 虚拟主机是一种特殊的软硬件技术它可以将网络上的每一台计算机分成多个虚拟主机每个虚拟主机可以独立对外提供www服务这样就可以实现一台主机对外提供多个web服务每个虚拟主机之间是独立的互不影响。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x0rBjLwt-1602213757525)(assets/1561605672295.png)] nginx可以实现虚拟主机的配置nginx支持三种类型的虚拟主机配置。 1、基于域名的虚拟主机 server_name来区分虚拟主机——应用外部网站 2、基于ip的虚拟主机 一台主机绑定多个ip地址 3、基于端口的虚拟主机 端口来区分虚拟主机——应用公司内部网站外部网站的管理后台 1、 基于域名的虚拟主机 1、配置通过域名区分的虚拟机 [rootlocalhost ~]# 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 文件 [rootlocalhost ~]# mkdir -p /1000phone/html [rootlocalhost ~]# vim /1000phone/html/index.html html p this is my 1000phone /p /html3、重新加载配置文件 # 如果编译安装的执行 [rootnginx]# /usr/local/nginx/sbin/nginx -s reload # 如果 yum 安装的执行 [rootnginx]# nginx -s reload4、客户端配置路由映射 在 C:\Windows\System32\drivers\etc\hosts 文件中添加两行(linux:/etc/hosts) 10.0.105.199 web.testpm.com 10.0.105.199 web.1000phone.com5、 测试访问 浏览器输入http://web.testpm.com/ 浏览器输入http://web.1000phone.com/ 6、补充如果配置不能正常访问 问题描述 配置完 nginx 两个虚拟机后客户端能够访问原始的server ,新增加的 server 虚拟机 不能够访问报错如下页面 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ltXJu7wI-1602213757526)(assets/1561607242127.png)] 解决过程 查看报错日志找到错误日志 [rootlocalhost ~]# 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.com2.检查权限 [rootlocalhost html]# ll drwxr-xr-x. 2 root root 4096 Jun 15 03:59 html [rootlocalhost 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启动进程 [rootlocalhost 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 文件 打开nginx.conf文件所在的目录查看文件的属性 root root [rootnginx]# ll drwxr-xr-x. 2 root root 4096 Jun 15 04:08 conf 在nginx.conf文件的第一行加上 user root root; [rootnginx]# cat conf/nginx.conf user root;重新 reload nginx进程 2、 基于ip的虚拟主机 [rootlocalhost ~]# ip a 1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 qdisc noqueue state UNKNOWN qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::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 1000link/ether 00:0c:29:17:f1:af brd ff:ff:ff:ff:ff:ffinet 10.0.105.199/24 brd 10.0.105.255 scope global dynamic ens33valid_lft 81438sec preferred_lft 81438secinet6 fe80::9d26:f3f0:db9c:c9be/64 scope link valid_lft forever preferred_lft forever [rootlocalhost ~]# ifconfig ens33:1 10.0.105.201/24 [rootlocalhost ~]# ifconfig ens33: flags4163UP,BROADCAST,RUNNING,MULTICAST mtu 1500inet 10.0.105.199 netmask 255.255.255.0 broadcast 10.0.105.255inet6 fe80::9d26:f3f0:db9c:c9be prefixlen 64 scopeid 0x20linkether 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 0TX packets 5567 bytes 886269 (865.4 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0ens33:1: flags4163UP,BROADCAST,RUNNING,MULTICAST mtu 1500inet 10.0.105.201 netmask 255.255.255.0 broadcast 10.0.105.255ether 00:0c:29:17:f1:af txqueuelen 1000 (Ethernet)2、配置通过ip区分的虚拟机 [rootlocalhost ~]# cat /etc/nginx/nginx.conf user root; worker_processes 4;#error_log logs/error.log; worker_rlimit_nofile 102400;events {worker_connections 1024; }http {include mime.types;default_type application/octet-stream;log_format main $remote_addr - $remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for;server {listen 10.0.105.199:80;server_name web.testpm.com;location / {root /var/www/nginx/;index index.html index.htm;limit_rate 2k;}server {listen 10.0.105.201:80;server_name web.testpm.com;location / {root /1000phone/html/;index index.html index.htm;}} } 3、重新加载配置文件 [rootlocalhost ~]# /usr/local/nginx/sbin/nginx -s reload 4、 测试访问 浏览器输入http://10.0.105.199 浏览器输入http://10.0.105.201 5、补充 -- 删除绑定的vip [rootlocalhost ~]# ifconfig ens33:1 10.0.105.201/24 down 重启一下nginx [rootlocalhost ~]# systemctl restart nginx3、 基于端口的虚拟主机 [rootlocalhost ~]# cat /etc/nginx/nginx.conf user root; worker_processes 4;worker_rlimit_nofile 102400;events {worker_connections 1024; }http {include mime.types;default_type application/octet-stream;log_format main $remote_addr - $remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for;sendfile on;keepalive_timeout 65;server {listen 80;server_name web.testpm.com;location / {root /var/www/nginx/;index index.html index.htm;limit_rate 2k;}server {listen 8080;server_name web.1000phone.com;location / {root /1000phone/html/;index index.html index.htm;}} } 重新加载配置文件: [rootlocalhost ~]# /usr/local/nginx/sbin/nginx -s reload 测试访问: 浏览器输入http://web.testpm.com/ 浏览器输入http://web.1000phone.com:80808、nginx Proxy 代理 1、代理原理 反向代理产生的背景 在计算机世界里由于单个服务器的处理客户端用户请求能力有一个极限当用户的接入请求蜂拥而入时会造成服务器忙不过来的局面可以使用多个服务器来共同分担成千上万的用户请求这些服务器提供相同的服务对于用户来说根本感觉不到任何差别。 反向代理服务的实现 需要有一个负载均衡设备即反向代理服务器来分发用户请求将用户请求分发到空闲的服务器上。 服务器返回自己的服务到负载均衡设备。 负载均衡设备将服务器的服务返回用户。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nSoNwIJl-1602213757527)(assets/1561616834649.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5NUDxDgj-1602213757529)(assets/1561616855038.png)] 2、正/反向代理的区别 那么问题来了很多人这时会问什么是反向代理为什么叫反向代理什么是正向代理我们来举例说明 正向代理 举例贷款 正向代理的过程隐藏了真实的请求客户端服务器不知道真实的客户端是谁客户端请求的服务都被代理服务器代替请求。我们常说的代理也就是正向代理正向代理代理的是请求方也就是客户端比如我们要访问youtube可是不能访问只能先安装个FQ软件代你去访问通过FQ软件才能访问FQ软件就叫作正向代理。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZbqHP6cZ-1602213757530)(assets/1561616889383.png)] FQ软件就是正向代理 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5przYVVl-1602213757531)(assets/1561617051925.png)] 正向代理中proxy和client同属一个LAN 反向代理 反向代理的过程隐藏了真实的服务器客户不知道真正提供服务的人是谁客户端请求的服务都被代理服务器处理。反向代理代理的是响应方也就是服务端我们请求www.baidu.com时这www.baidu.com就是反向代理服务器真实提供服务的服务器有很多台反向代理服务器会把我们的请求分转发到真实提供服务的各台服务器。Nginx就是性能非常好的反向代理服务器用来做负载均衡。 访问www.baidu.com是正向代理的过程 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BQOgQF8w-1602213757532)(assets/1561617154985.png)] 反向代理中proxy和server同属一个LAN [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qx1D7p1p-1602213757533)(assets/1561617180382.png)] 正向代理和反向代理对比示意图 两者的区别在于代理的对象不一样 正向代理中代理的对象是客户端proxy和client同属一个LAN对server透明 反向代理中代理的对象是服务端proxy和server同属一个LAN对client透明。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zy9w6sjb-1602213757534)(assets/1561618001304.png)] 3、知识扩展1 没有使用LVS时客户端请求直接到反向代理NginxNginx分发到各个服务器服务端响应再由Ngnix返回给客户端这样请求和响应都经过Ngnix的模式使其性能降低这时用LVSNginx解决。 LVSNginx客户端请求先由LVS接收分发给Nginx再由Nginx转发给服务器LVS有三种方式NAT模式Network Address Translation网络地址转换DR模式直接路由模式IP隧道模式路由方式使服务器响应不经过LVS,由Nginx直接返回给客户端。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WReqpSK7-1602213757535)(assets/1561618131640.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Uoz5GkmK-1602213757537)(assets/1561618191407.png)] 4、知识扩展2 HTTP Server和Application Server的区别和联系 Apache/nignx是静态服务器HTTP Server Nginx优点负载均衡、反向代理、处理静态文件优势。nginx处理静态请求的速度高于apache Apache优点相对于Tomcat服务器来说处理静态文件是它的优势速度快。Apache是静态解析适合静态HTML、图片等。 HTTP Server 关心的是 HTTP 协议层面的传输和访问控制所以在 Apache/Nginx 上你可以看到代理、负载均衡等功能 HTTP ServerNginx/Apache常用做静态内容服务和代理服务器将外来请求转发给后面的应用服务tomcatjboss,jetty等。 应用服务器(tomcat/jboss/jetty)是动态服务器Application Server 应用服务器Application Server则是一个应用执行的容器。它首先需要支持开发语言的 Runtime对于 Tomcat 来说就是 Java若是Ruby/Python 等其他语言开发的应用也无法直接运行在 Tomcat 上。 但是事无绝对为了方便应用服务器(如tomcat)往往也会集成 HTTP Server 的功能nginx也可以通过模块开发来提供应用功能只是不如专业的 HTTP Server 那么强大所以应用服务器往往是运行在 HTTP Server 的背后执行应用将动态的内容转化为静态的内容之后通过 HTTP Server 分发到客户端。 常用开源集群软件有lvskeepalivedhaproxynginxapacheheartbeat 常用商业集群硬件有F5, NetscalerRadwareA10等 5、nginx Proxy 配置 1、代理模块 ngx_http_proxy_module2、代理配置 代理 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会把后端返回的内容先放到缓冲区当中然后再返回给客户端 边收边传不是全部接收完再传给客户端)。 Nginx 全局配置中的 tcp_nopush 的作用就是 数据包会累计到一定大小之后才会发送 。而 tcp_nodelay 是尽快发送数据所以若你启用了 buffer建议关闭 tcp_nodelay。Syntax: proxy_buffer_size size; Default: proxy_buffer_size 4k|8k; #缓冲区大小 Context: http, server, locationSyntax: proxy_buffers number size; Default: proxy_buffers 8 4k|8k; #缓冲区数量 Context: http, server, locationSyntax: 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, locationSyntax: proxy_read_timeout time; Default: proxy_read_timeout 60s; Context: http, server, locationSyntax: proxy_send_timeout time; #nginx进程向fastcgi进程发送request的整个过程的超时时间 Default: proxy_send_timeout 60s; Context: http, server, location#buffer 工作原理 1. 所有的proxy buffer参数是作用到每一个请求的。每一个请求会安按照参数的配置获得自己的buffer。proxy buffer不是global而是 request的。2. proxy_buffering 是为了开启response buffering of the proxied server开启后proxy_buffers和proxy_busy_buffers_size参数才会起作用。3. 无论proxy_buffering是否开启proxy_buffer_sizemain buffer都是工作的proxy_buffer_size所设置的buffer_size的作用是用来存储upstream端response的header。4. 在proxy_buffering 开启的情况下Nginx将会尽可能的读取所有的upstream端传输的数据到buffer直到proxy_buffers设置的所有buffer们 被写满或者数据被读取完(EOF)。此时nginx开始向客户端传输数据会同时传输这一整串buffer们。同时如果response的内容很大的话Nginx会接收并把他们写入到temp_file里去。大小由proxy_max_temp_file_size控制。如果busy的buffer 传输完了会从temp_file里面接着读数据直到传输完毕。5. 一旦proxy_buffers设置的buffer被写入直到buffer里面的数据被完整的传输完传输到客户端这个buffer将会一直处 在busy状态我们不能对这个buffer进行任何别的操作。所有处在busy状态的buffer size加起来不能超过proxy_busy_buffers_size所以proxy_busy_buffers_size是用来控制同时传输到客户端的buffer数量的。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的配置文件: [rootnginx-server ~]# vim /etc/nginx/conf.d/default.conf server {server {listen 80;server_name localhost;location / {proxy_pass http://10.0.105.199:80;proxy_redirect default;proxy_set_header Host $http_host;proxy_set_header X-Real-IP $remote_addr;#proxy_set_header 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配置文件 [rootnginx-server ~]# nginx -s reloadc、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_sizeproxy_buffer_size只是响应头的缓冲区 proxy_buffers 4 128k; 内容缓冲区域大小 proxy_busy_buffers_size 256k; 从proxy_buffers划出一部分缓冲区来专门向客户端传送数据的地方 proxy_max_temp_file_size 256k;超大的响应头存储成文件。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sAQns57z-1602213757538)(assets/1561619960959.png)] proxy_set_header X-Real-IP 未配置 Nginxbackend 的日志记录只有192.168.107.112 配置 Nginxbackend 的日志,记录的有192.168.107.16 192.168.107.107 192.168.107.112proxy_buffers 的缓冲区大小一般会设置的比较大以应付大网页。 proxy_buffers当中单个缓冲区的大小是由系统的内存页面大小决定的Linux系统中一般为4k。 proxy_buffers由缓冲区数量和缓冲区大小组成的。总的大小为number*size。 若某些请求的响应过大,则超过_buffers的部分将被缓冲到硬盘(缓冲目录由_temp_path指令指定), 当然这将会使读取响应的速度减慢, 影响用户体验. 可以使用proxy_max_temp_file_size指令关闭磁盘缓冲.注意proxy_pass http:// 填写nginx-1服务器的地址。 d、 使用PC客户端访问nginx-2服务器地址 浏览器中输入http://10.0.105.202 (也可以是nginx-2服务器的域名) 成功访问nginx-1服务器页面 e、 观察nginx-1服务器的日志 (记得打开下面的日志路径,默认为/var/log) 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.20710.0.105.202 代理服务器地址 10.0.105.207 客户机地址。 访问成功。 记录了客户机的IP和代理服务器的IP 6、Nginx负载均衡 1、负载均衡的作用 如果你的nginx服务器给2台web服务器做代理负载均衡算法采用轮询那么当你的一台机器web程序关闭造成web不能访问那么nginx服务器分发请求还是会给这台不能访问的web服务器如果这里的响应连接时间过长就会导致客户端的页面一直在等待响应对用户来说体验就打打折扣这里我们怎么避免这样的情况发生呢。这里我配张图来说明下问题。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-56bBrXZs-1602213757540)(assets/1561622346506.png)] 如果负载均衡中其中web2发生这样的情况nginx首先会去web1请求但是nginx在配置不当的情况下会继续分发请求道web2然后等待web2响应直到我们的响应时间超时才会把请求重新分发给web1这里的响应时间如果过长用户等待的时间就会越长。 下面的配置是解决方案之一。 proxy_connect_timeout 1; #nginx服务器与被代理的服务器建立连接的超时时间默认60秒 proxy_read_timeout 1; #nginx服务器想被代理服务器组发出read请求后等待响应的超时间默认为60秒。 proxy_send_timeout 1; #nginx服务器想被代理服务器组发出write请求后等待响应的超时间默认为60秒。 proxy_ignore_client_abort on; #客户端断网时nginx服务器是否中断对被代理服务器的请求。默认为off。使用upstream指令配置一组服务器作为被代理服务器服务器中的访问算法遵循配置的负载均衡规则同时可以使用该指令配置在发生哪些异常情况时将请求顺次交由下一组服务器处理. proxy_next_upstream timeout; #反向代理upstream中设置的服务器组出现故障时被代理服务器返回的状态值。error|timeout|invalid_header|http_500|http_502|http_503|http_504|http_404|offerror建立连接或向被代理的服务器发送请求或读取响应信息时服务器发生错误。 timeout建立连接想被代理服务器发送请求或读取响应信息时服务器发生超时。 invalid_header:被代理服务器返回的响应头异常。 off:无法将请求分发给被代理的服务器。 http_400…:被代理服务器返回的状态码为400500502等 2、upstream配置 首先给大家说下 upstream 这个配置的这个配置是写一组被代理的服务器地址然后配置负载均衡的算法。这里的被代理服务器地址有2中写法。 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 定义的服务器列表 } 1、负载均衡算法 upstream 支持4种负载均衡调度算法: A、轮询(默认):每个请求按时间顺序逐一分配到不同的后端服务器; B、ip_hash:每个请求按访问IP的hash结果分配同一个IP客户端固定访问一个后端服务器。可以保证来自同一ip的请求被打到固定的机器上可以解决session问题。 C、url_hash:按访问url的hash结果来分配请求使每个url定向到同一个后端服务器。后台服务器为缓存的时候效率。 D、fair:这是比上面两个更加智能的负载均衡算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡也就是根据后端服务器的响应时间来分配请求响应时间短的优先分配。Nginx本身是不支持 fair的如果需要使用这种调度算法必须下载Nginx的 upstream_fair模块。 2、配置实例 1、热备如果你有2台服务器当一台服务器发生事故时才启用第二台服务器给提供服务。服务器处理请求的顺序AAAAAA突然A挂啦BBBBBBBBBBBBBB… upstream myweb { server 172.17.14.2:8080; server 172.17.14.3:8080 backup; #热备 }2、轮询nginx默认就是轮询其权重都默认为1服务器处理请求的顺序ABABABABAB… upstream myweb { server 172.17.14.2:8080;server 172.17.14.3:8080;}3、加权轮询跟据配置的权重的大小而分发给不同服务器不同数量的请求。如果不设置则默认为1。下面服务器的请求顺序为ABBABBABBABBABB… upstream myweb { server 172.17.14.2:8080 weight1;server 172.17.14.3:8080 weight2; }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 weight2 max_fails2 fail_timeout2;server 172.17.14.3:8080 weight1 max_fails2 fail_timeout1; }如果你像跟多更深入的了解 nginx 的负载均衡算法nginx官方提供一些插件大家可以了解下。 3、nginx配置7层协议及4层协议方法扩展 举例讲解下什么是7层协议什么是4层协议。 17层协议 OSIOpen System Interconnection是一个开放性的通行系统互连参考模型他是一个定义的非常好的协议规范共包含七层协议。直接上图这样更直观些 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tKLnLaAu-1602213757542)(assets/1561624521541.png)] 好详情不进行仔细讲解可以自行百度 24层协议 TCP/IP协议 之所以说TCP/IP是一个协议族是因为TCP/IP协议包括TCP、IP、UDP、ICMP、RIP、TELNETFTP、SMTP、ARP、TFTP等许多协议这些协议一起称为TCP/IP协议。 从协议分层模型方面来讲TCP/IP由四个层次组成网络接口层、网络层、传输层、应用层。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eQQ5eJWY-1602213757543)(assets/1561624556568.png)] 3协议配置 这里我们举例在nginx做负载均衡负载多个服务部分服务是需要7层的部分服务是需要4层的也就是说7层和4层配置在同一个配置文件中。 准备三台机器: 代理服务IP:10.0.105. --配置本地host解析域名 后端服务器IP:nginx-a 10.0.105.199/nginx-b10.0.105.202(yum安装)后端服务器将nginx服务启动 配置代理服务器的nginx配置文件 worker_processes 4;worker_rlimit_nofile 102400;events {worker_connections 1024; }http {include mime.types;default_type application/octet-stream;log_format main $remote_addr - $remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for;#access_log logs/access.log main;sendfile on;keepalive_timeout 65;gzip on;upstream testweb {ip_hash;server 10.0.105.199:80 weight2 max_fails2 fail_timeout2s;server 10.0.105.202:80 weight2 max_fails2 fail_timeout2s;}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 weight2 max_fails2 fail_timeout2s;server 10.0.105.199:8081 weight2 max_fails2 fail_timeout2s; }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;}} }浏览器测试访问: http://www.test.com/ http://www.app.com:81/ 202服务器yum安装的创建新的配置文件: [rootnginx-server ~]# cd /etc/nginx/conf.d/ [rootnginx-server conf.d]# cp default.conf test.conf [rootnginx-server conf.d]# cat test.conf server {listen 80;server_name localhost;location / {root /usr/share/nginx/html;index index.html index.htm;} }server {listen 8081;server_name localhost;location / {root /var/www/nginx/html;index index.html index.htm;} } [rootnginx-server ~]# nginx -s reloadnginx在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;} }9、nginx 会话保持 nginx会话保持主要有以下几种实现方式。 1、ip_hash ip_hash使用源地址哈希算法将同一客户端的请求总是发往同一个后端服务器除非该服务器不可用。 ip_hash语法 upstream backend {ip_hash;server backend1.example.com;server backend2.example.com;server backend3.example.com down; }ip_hash简单易用但有如下问题 当后端服务器宕机后session会丢失 来自同一局域网的客户端会被转发到同一个后端服务器可能导致负载失衡 不适用于CDN网络不适用于前段还有代理的情况。 2、sticky_cookie_insert 使用sticky_cookie_insert启用会话亲缘关系这会导致来自同一客户端的请求被传递到一组服务器的同一台服务器。与ip_hash不同之处在于它不是基于IP来判断客户端的而是基于cookie来判断。因此可以避免上述ip_hash中来自同一局域网的客户端和前段代理导致负载失衡的情况。(需要引入第三方模块才能实现) 语法 upstream backend {server backend1.example.com;server backend2.example.com;sticky_cookie_insert srv_id expires1h domain3evip.cn path/; }说明 expires设置浏览器中保持cookie的时间 domain定义cookie的域 path为cookie定义路径 3、jvm_route方式 jvm_route是通过session_cookie这种方式来实现session粘性。将特定会话附属到特定tomcat上从而解决session不同步问题但是无法解决宕机后会话转移问题。如果在cookie和url中并没有session则这只是个简单的round-robin负载均衡。 jvm_route的原理 一开始请求过来没有带session的信息jvm_route就根据round robin的方法发到一台Tomcat上面Tomcat添加上session信息并返回给客户用户再次请求jvm_route看到session中有后端服务器的名称他就把请求转到对应的服务器上 暂时jvm_route模块还不支持fair的模式。jvm_route的工作模式和fair是冲突的。对于某个特定用户当一直为他服务的Tomcat宕机后默认情况下它会重试max_fails的次数如果还是失败就重新启用round robin的方式而这种情况下就会导致用户的session丢失。 4、使用后端服务器自身通过相关机制保持session同步如使用数据库、redis、memcached 等做session复制 9、nginx 实现动静分离 为了加快网站的解析速度可以把动态页面和静态页面由不同的服务器来解析加快解析速度。降低原来单个服务器的压力。 在动静分离的tomcat的时候比较明显因为tomcat解析静态很慢其实这些原理的话都很好理解简单来说就是使用正则表达式匹配过滤然后交个不同的服务器。 1、准备环境 准备一个nginx代理 两个http 分别处理动态和静态。 1.配置nginx反向代理upstream upstream static {server 10.0.105.196:80 weight1 max_fails1 fail_timeout60s;} upstream php {server 10.0.105.200:80 weight1 max_fails1 fail_timeout60s;}server {listen 80;server_name localhost;#动态资源加载location ~ \.(php|jsp)$ {proxy_pass http://php;proxy_set_header Host $host:$server_port;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}#静态资源加载location ~ .*\.(html|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;}}静态资源配置 server {listen 80;server_name localhost;location ~ \.(html|jpg|png|js|css|gif|bmp|jpeg) {root /home/www/nginx;} }动态资源配置: yum 安装php7.1 [rootnginx-server ~]#rpm -Uvh https://mirror.webtatic.com/yum/el7/epel-release.rpm [rootnginx-server ~]#rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm [rootnginx-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 [rootnginx-server ~]#yum install -y php71w-fpm [rootnginx-server ~]#systemctl start php-fpm [rootnginx-server ~]#systemctl enable php-fpm 编辑nginx的配置文件: server {listen 80;server_name localhost;location ~ \.php$ {root /home/nginx/html; #指定网站目录fastcgi_pass 127.0.0.1:9000; #指定访问地址fastcgi_index index.php; #指定默认文件fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; #站点根目录取决于root配置项include fastcgi_params; #包含nginx常量定义}}当访问静态页面的时候location 匹配到 (html|jpg|png|js|css|gif|bmp|jpeg) 通过转发到静态服务器静态服务通过location的正则匹配来处理请求。 当访问动态页面时location匹配到 .\php 结尾的文件转发到后端php服务处理请求。 11、nginx 防盗链问题 两个网站 A 和 B A网站引用了B网站上的图片这种行为就叫做盗链。 防盗链就是要防止A引用B的图片。1、nginx 防止网站资源被盗用模块 ngx_http_referer_module如何区分哪些是不正常的用户 HTTP Referer是Header的一部分当浏览器向Web服务器发送请求的时候一般会带上Referer告诉服务器我是从哪个页面链接过来的服务器借此可以获得一些信息用于处理例如防止未经允许的网站盗链图片、文件等。因此HTTP Referer头信息是可以通过程序来伪装生成的所以通过Referer信息防盗链并非100%可靠但是它能够限制大部分的盗链情况. 比如在www.google.com 里有一个www.baidu.com 链接那么点击这个www.baidu.com 它的header 信息里就有Refererhttp://www.google.com 10、防盗链配置 配置要点 [rootnginx-server ~]# vim /etc/nginx/nginx.conf # 日志格式添加$http_referer log_format main $remote_addr - $remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for; # valid_referers 使用方式 Syntax: valid_referers none | blocked | server_names | string ...; Default: — Context: server, locationnone : 允许没有http_refer的请求访问资源 blocked : 允许不是http://开头的不带协议的请求访问资源 server_names : 只允许指定ip/域名来的请求访问资源白名单 准备两台机器,两张图片(缓存问题) 配置nginx配置文件并上传图片 [rootnginx-server html]# vim /etc/nginx/conf.d/nginx.conf server {listen 80;server_name localhost;location / {root /usr/share/nginx/html;index index.html index.htm;valid_referers none blocked *.qf.com 10.0.105.202;if ($invalid_referer) {return 403;}}location ~ .*\.(gif|jpg|png|jpeg)$ {root /usr/share/nginx/html;valid_referers qf.com 10.0.105.202;if ($invalid_referer) {return 403;}} }重载nginx服务 [rootnginx-server ~]# nginx -s reload -c /etc/nginx/nginx.conf第二台机器客户端 配置nginx访问页面 创建页面 [rootnginx-server nginx]# vim index.html html headmeta charsetutf-8titleqf.com/title /head body stylebackground-color:red;img srchttp://10.0.105.202/test.jpg/ /body /html测试不带http_refer [rootnginx-server nginx]# curl -I http://10.0.105.202/test1.png HTTP/1.1 200 OK Server: nginx/1.16.0 Date: Thu, 27 Jun 2019 16:21:13 GMT Content-Type: image/png Content-Length: 235283 Last-Modified: Thu, 27 Jun 2019 11:27:11 GMT Connection: keep-alive ETag: 5d14a80f-39713 Accept-Ranges: bytes测试带非法http_refer: [rootnginx-server nginx]# curl -e http://www.baidu.com -I http://10.0.105.202/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: [rootnginx-server nginx]# curl -e http://10.0.105.202 -I http://10.0.105.202/test.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: bytes5、其他配置 5.1、匹配域名 # location ~ .*\.(gif|jpg|png|jpeg)$ { # root /usr/share/nginx/html;# valid_referers none blocked qf.com 10.0.105.202; # if ($invalid_referer) { # return 403; # } # }location ~ .*\.(gif|jpg|png|jpeg)$ {root /usr/share/nginx/html;valid_referers 10.0.105.202 *.baidu.com *.google.com;if ($invalid_referer) {rewrite ^/ http://10.0.105.202/test.jpg;#return 403;}}以上所有来自 qf.com 和域名中google和baidu的站点都可以访问到当前站点的图片如果来源域名不在这个列表中那么$invalid_referer等于1在if语句中返回一个403给用户这样用户便会看到一个403的页面如果使用下面的rewrite那么盗链的图片都会显示403.jpg。如果用户直接在浏览器输入你的图片地址那么图片显示正常因为它符合none这个规则。 11、nginx 地址重写 rewrite 1、什么是Rewrite ​ Rewrite对称URL Rewrite即URL重写就是把传入Web的请求重定向到其他URL的过程。 URL Rewrite最常见的应用是URL伪静态化是将动态页面显示为静态页面方式的一种技术。比如 http://www.123.com/news/index.php?id123 使用URLRewrite 转换后可以显示为 http://www.123 .com/news/123.html对于追求完美主义的网站设计师就算是网页的地址也希望看起来尽量简洁明快。 理论上搜索引擎更喜欢静态页面形式的网页搜索引擎对静态页面的评分一般要高于动态页面。所以UrlRewrite可以让我们网站的网页更容易被搜索引擎所收录。从安全角度上讲如果在URL中暴露太多的参数无疑会造成一定量的信息泄漏可能会被一些黑客 利用对你的系统造成一定的破坏所以静态化的URL地址可以给我们带来更高的安全性。实现网站地址跳转例如用户访问360buy.com将其跳转到jd.com。例如当用户访问tianyun.com的 80端口时将其跳转到443端口。 2、Rewrite 相关指令 Nginx Rewrite 相关指令有 if、rewrite、set、return 2.1、if 语句 应用环境 serverlocation语法 if (condition) { … } if 可以支持如下条件判断匹配符号 ~ 正则匹配 (区分大小写) ~* 正则匹配 (不区分大小写) !~ 正则不匹配 (区分大小写) !~* 正则不匹配 (不区分大小写) -f 和!-f 用来判断是否存在文件 -d 和!-d 用来判断是否存在目录 -e 和!-e 用来判断是否存在文件或目录 -x 和!-x 用来判断文件是否可执行在匹配过程中可以引用一些Nginx的全局变量 $args 请求中的参数; $document_root 针对当前请求的根路径设置值; $host 请求信息中的Host如果请求中没有Host行则等于设置的服务器名; $limit_rate 对连接速率的限制; $request_method 请求的方法比如GET、POST等; $remote_addr 客户端地址; $remote_port 客户端端口号; $remote_user 客户端用户名认证用; $request_filename 当前请求的文件路径名带网站的主目录/usr/local/nginx/html/images /a.jpg $request_uri 当前请求的文件路径名不带网站的主目录/images/a.jpg $query_string 与$args相同; $scheme 用的协议比如http或者是https $server_protocol 请求的协议版本HTTP/1.0或HTTP/1.1; $server_addr 服务器地址如果没有用listen指明服务器地址使用这个变量将发起一次系统调用以取得地址(造成资源浪费); $server_name 请求到达的服务器名; $document_uri 与$uri一样URI地址; $server_port 请求到达的服务器端口号;2.2、Rewrite flag rewrite 指令根据表达式来重定向URI或者修改字符串。可以应用于server,location, if环境下每行rewrite指令最后跟一个flag标记支持的flag标记有 last 相当于Apache里的[L]标记表示完成rewrite。默认为last。 break 本条规则匹配完成后终止匹配不再匹配后面的规则 redirect 返回302临时重定向浏览器地址会显示跳转后的URL地址 permanent 返回301永久重定向浏览器地址会显示跳转后URL地址redirect 和 permanent区别则是返回的不同方式的重定向对于客户端来说一般状态下是没有区别的。而对于搜索引擎相对来说301的重定向更加友好如果我们把一个地址采用301跳转方式跳转的话搜索引擎会把老地址的相关信息带到新地址同时在搜索引擎索引库中彻底废弃掉原先的老地址。使用302重定向时搜索引擎(特别是google)有时会查看跳转前后哪个网址更直观然后决定显示哪个如果它觉的跳转前的URL更好的话也许地址栏不会更改那么很有可能出现URL劫持的现像。在做URI重写时有时会发现URI中含有相关参数如果需要将这些参数保存下来并且在重写过程中重新引用可以用到 () 和 $N 的方式来解决。 2.3、Rewrite匹配参考示例 本地解析host文件 # http://www.testpm.com/a/1.html http://www.testpm.com/b/2.htmllocation /a {root /html;index 1.html index.htm;rewrite .* /b/2.html permanent;}location /b {root /html;index 2.html index.htm;} 例2 # http://www.testpm.com/2019/a/1.html http://www.testpm.com/2018/a/1.htmllocation /2019/a {root /var/www/html;index 1.html index.hml;rewrite ^/2019/(.*)$ /2018/$1 permanent;}location /2018/a {root /var/www/html;index 1.html index.htl;}例3 # http://www.qf.com/a/1.html http://jd.comlocation /a {root /html;if ($host ~* www.qf.com ) {rewrite .* http://jd.com permanent;}}例4 # http://www.qf.com/a/1.html http://jd.com/a/1.html location /a {root /html;if ( $host ~* 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$3/ location /a/b/c {root /usr/share/nginx/html;index index.html index.hml;if (-d $request_filename) {rewrite ^(.*)([^/])$ http://$host$1$2/ permanent;}}例6 # http://www.tianyun.com/login/tianyun.html http://www.tianyun.com/reg/login.html?usertianyunlocation /login {root /usr/share/nginx/html;rewrite ^/login/(.*)\.html$ http://$host/reg/login.html?user$1;}location /reg {root /usr/share/nginx/html;index login.html;}例7 #http://www.tianyun.com/qf/11-22-33/1.html http://www.tianyun.com/qf/11/22/33/1.html location /qf {rewrite ^/qf/([0-9])-([0-9])-([0-9])(.*)$ /qf/$1/$2/$3$4 permanent;}location /qf/11/22/33 {root /html;index 1.html;}等 2.4、set 指令 set 指令是用于定义一个变量并且赋值 应用环境: server,location,if应用示例 例8 #http://alice.testpm.com http://www.testpm.com/alice #http://jack.testpm.com http://www.testpm.com/jack[rootnginx-server conf.d]# cd /usr/share/nginx/html/ [rootnginx-server html]# mkdir jack alice [rootnginx-server html]# echo jack.. jack/index.html [rootnginx-server html]# echo alice.. alice/index.htmla. DNS实现泛解析 * IN A 网站IP 或者本地解析域名host文件 10.0.105.202 www.testpm.com 10.0.105.202 alice.testpm.com 10.0.105.202 jack.testpm.com 编辑配置文件: server {listen 80;server_name www.testpm.com;location / {root /usr/share/nginx/html;index index.html index.htm;if ( $host ~* ^www.testpm.com$) {break;}if ( $host ~* ^(.*)\.testpm\.com$ ) {set $user $1;rewrite .* http://www.testpm.com/$user permanent;}}location /jack {root /usr/share/nginx/html;index index.html index.hml;}location /alice {root /usr/share/nginx/html;index index.html index.hml;} }2.5、return 指令 return 指令用于返回状态码给客户端 server,location,if应用示例: 例9如果访问的.sh结尾的文件则返回403操作拒绝错误 server {listen 80;server_name www.testpm.cn;#access_log /var/log/nginx/http_access.log main;location / {root /usr/share/nginx/html;index index.html index.htm;}location ~* \.sh$ {return 403;} }例1080 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:RC4RSA:HIGH:MEDIUM:LOW:SSLv2:EXP;ssl_prefer_server_ciphers on;location / {root /usr/share/nginx/html;index index.html index.htm;} }[rootnginx-server ~]# curl -I http://www.testpm.cn HTTP/1.1 301 Moved Permanently Server: nginx/1.16.0 Date: Wed, 03 Jul 2019 13:52:30 GMT Content-Type: text/html Content-Length: 169 Connection: keep-alive Location: https://www.testpm.cn/3、last,break详解 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OUsakwd0-1602213757545)(assets/1561898537620.png)] [rootlocalhost 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/break/last.html last;}location /test/ {root /usr/share/nginx/html;rewrite .* /test/test.html break;}} [rootlocalhost conf.d]# cd /usr/share/nginx/html/ [rootlocalhost html]# mkdir test [rootlocalhost html]# echo last test/last.html [rootlocalhost html]# echo break test/break.html [rootlocalhost html]# echo test test/test.htmlhttp://10.0.105.196/break/break.html http://10.0.105.196/last/last.html注意 last 标记在本条 rewrite 规则执行完后会对其所在的 server { … } 标签重新发起请求; break 标记则在本条规则匹配完成后停止匹配不再做后续的匹配 使用 alias 指令时必须使用 last 使用 proxy_pass 指令时,则必须使用break。 4、Nginx 的 https ( rewrite ) server {listen 80;server_name *.vip9999.top vip9999.top;if ($host ~* ^www.vip9999.top$|^vip9999.top$ ) {return 301 https://www.vip9999.top$request_uri;}if ($host ~* ^(.*).vip9999.top$ ) {set $user $1;return 301 https://www.vip9999.top/$user;}}# Settings for a TLS enabled server.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:9000location ~ \.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;}5、Apache 的 https ( rewrite ) [rootlocalhost ~]# yum -y install httpd mod_ssl [rootlocalhost ~]# vim /etc/httpd/conf.d/vip9999.conf[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ykvMDafY-1602213757546)(assets/1561898727918.png)] 12、nginx的localtion指令详解 Nginx 的 HTTP 配置主要包括三个区块结构如下 http { # 这个是协议级别include mime.types;default_type application/octet-stream;keepalive_timeout 65;gzip on;server { # 这个是服务器级别listen 80;server_name localhost;location / { # 这个是请求级别root html;index index.html index.htm;}} }1、location 区段 location 是在 server 块中配置根据不同的 URI 使用不同的配置来处理不同的请求。 location 是有顺序的会被第一个匹配的location 处理。 基本语法如下 location [|~|~*|^~|] pattern{……}2、location 前缀含义 表示精确匹配优先级也是最高的 ^~ 表示uri以某个常规字符串开头,理解为匹配url路径即可 ~ 表示区分大小写的正则匹配 ~* 表示不区分大小写的正则匹配 !~ 表示区分大小写不匹配的正则 !~* 表示不区分大小写不匹配的正则 / 通用匹配任何请求都会匹配到内部服务跳转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;}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/abcde3、~ 表示指定的正则表达式要区分大小写 server { server_name qf.com;location ~ ^/abc$ {……} } 那么如下是对的 http://qf.com/abc http://qf.com/abc?p111p222 如下是错的 http://qf.com/ABC http://qf.com/abc/ http://qf.com/abcde4、~* 表示指定的正则表达式不区分大小写 server { server_name qf.com; location ~* ^/abc$ {……} } 那么如下是对的 http://qf.com/abc http://qf.com/ABC http://qf.com/abc?p111p222 如下是错的 http://qf.com/abc/ http://qf.com/abcde5、^~ 类似于无修饰符的行为也是以指定模式开始不同的是如果模式匹配那么就停止搜索其他模式了。 6、 定义命名 location 区段这些区段客户段不能访问只可以由内部产生的请求来访问如try_files或error_page等 查找顺序和优先级 1带有““的精确匹配优先 2没有修饰符的精确匹配 3正则表达式按照他们在配置文件中定义的顺序 4带有“^~”修饰符的开头匹配 5带有“~” 或“~*” 修饰符的如果正则表达式与URI匹配 6没有修饰符的如果指定字符串与URI开头匹配 大于 ^~ 大于 ~|~*|!~|!~* 大于 / 多个location配置的情况下匹配顺序为首先匹配 其次匹配^~, 其次是按正则匹配最后是交给 / 通用匹配。当有匹配成功时候停止匹配按当前匹配规则处理请求。(1) :表示完全匹配; (2) ^~:匹配URI的前缀并且后面的正则表达式不再匹配如果一个URI同时满足两个规则的话匹配最长的规则; (3) ~:匹配正则表达式大小写敏感 (4) ~*:匹配正则表达式大小写不敏感 优先级1 (2) (3) (4)location 区段匹配示例location / {# 只匹配 / 的查询.[ configuration A ] } location / {# 匹配任何以 / 开始的查询但是正则表达式与一些较长的字符串将被首先匹配。[ configuration B ] } location ^~ /images/ {# 匹配任何以 /images/ 开始的查询并且停止搜索不检查正则表达式。[ configuration C ] } location ~* \.(gif|jpg|jpeg)$ {# 匹配任何以gif, jpg, or jpeg结尾的文件但是所有 /images/ 目录的请求将在Configuration C中处理。[ configuration D ] } 各请求的处理如下例/ → configuration A/documents/document.html → configuration B/images/1.gif → configuration C/documents/1.jpg → configuration D4、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 是一个目录别名的定义root 则是最上层目录的定义。还有一个重要的区别是alias后面必须要用“/”结束否则会找不到文件的,而root则可有可无 13、nginx 日志配置 1、nginx 日志介绍 nginx 有一个非常灵活的日志记录模式,每个级别的配置可以有各自独立的访问日志, 所需日志模块 ngx_http_log_module 的支持日志格式通过 log_format 命令来定义日志对于统计和排错是非常有利的下面总结了 nginx 日志相关的配置 包括 access_log、log_format、open_log_file_cache、log_not_found、log_subrequest、rewrite_log、error_log。 # 设置访问日志 access_log path [format [buffersize] [gzip[level]] [flushtime] [ifcondition]]; # 关闭访问日志 access_log off; path 指定日志的存放位置。format 指定日志的格式。默认使用预定义的combined。buffer 用来指定日志写入时的缓存大小。默认是64k。gzip 日志写入前先进行压缩。压缩率可以指定从1到9数值越大压缩比越高同时压缩的速度也越慢。默认是1。flush 设置缓存的有效时间。如果超过flush指定的时间缓存中的内容将被清空。if 条件判断。如果指定的条件计算为0或空字符串那么该请求不会写入日志。 作用域 可以应用access_log指令的作用域分别有httpserverlocationlimit_except。也就是说在这几个作用域外使用该指令Nginx会报错。 access_log /var/logs/nginx-access.log该例子指定日志的写入路径为/var/logs/nginx-access.log日志格式使用默认的combined。 access_log /var/logs/nginx-access.log buffer32k gzip flush1m该例子指定日志的写入路径为/var/logs/nginx-access.log日志格式使用默认的combined指定日志的缓存大小为 32k日志写入前启用 gzip 进行压缩压缩比使用默认值 1缓存数据有效时间为1分钟。 2、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 [escapedefault|json] string ...;name 格式名称。在 access_log 指令中引用。escape 设置变量中的字符编码方式是json还是default默认是default。string 要定义的日志格式内容。该参数可以有多个。参数中可以使用Nginx变量。 log_format 指令中常用的一些变量 $remote_addr, $http_x_forwarded_for #记录客户端IP地址 $remote_user #记录客户端用户名称 $request #记录请求的URL和HTTP协议 $status #记录请求状态 $body_bytes_sent #发送给客户端的字节数不包括响应头的大小 $bytes_sent #发送给客户端的总字节数 $http_referer #记录从哪个页面链接访问过来的,可以根据该参数进行防盗链设置 $http_user_agent #记录客户端浏览器相关信息 $time_local #通用日志格式下的本地时间。自定义日志格式的使用 access_log /var/logs/nginx-access.log mainlog_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都对应了一个-这是因为这几个变量为空。 面试时注意日志里面的ip地址一定要在第一列。 3、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。 4、open_log_file_cache 指令 每一条日志记录的写入都是先打开文件再写入记录然后关闭日志文件。如果你的日志文件路径中使用了变量如 access_log /var/logs/$host/nginx-access.log为提高性能可以使用open_log_file_cache指令设置日志文件描述符的缓存。 语法 open_log_file_cache maxN [inactivetime] [min_usesN] [validtime];默认值: open_log_file_cache off;max 设置缓存中最多容纳的文件描述符数量如果被占满采用LRU算法将描述符关闭。 inactive 设置缓存存活时间默认是10s。 min_uses 在inactive时间段内日志文件最少使用几次该日志文件描述符记入缓存默认是1次。 valid设置多久对日志文件名进行检查看是否发生变化默认是60s。 off不使用缓存。默认为off。 基本用法 open_log_file_cache max1000 inactive20s valid1m min_uses2;配置段:http、server、location作用域中。 例子中设置缓存最多缓存1000个日志文件描述符20s内如果缓存中的日志文件描述符至少被被访问2次才不会被缓存关闭。每隔1分钟检查缓存中的文件描述符的文件名是否还存在。 5、log_not_found 指令 是否在error_log中记录不存在的错误。默认是 基本语法: log_not_found on | off; 默认值: log_not_found on;配置段: http, server, location作用域。 6、log_subrequest 指令 是否在access_log中记录子请求的访问日志。默认不记录 基本语法 log_subrequest on | off;默认值: log_subrequest off;配置段: http, server, location作用域。 7、rewrite_log 指令 由ngx_http_rewrite_module模块提供的。用来记录重写日志的。对于调试重写规则建议开启启用时将在error log中记录notice级别的重写日志。 基本语法: rewrite_log on | off;默认值: rewrite_log off;配置段: http, server, location, if作用域。 8、nginx 日志配置总结 Nginx中通过access_log和error_log指令配置访问日志和错误日志通过log_format我们可以自定义日志格式。如果日志文件路径中使用了变量我们可以通过open_log_file_cache 指令来设置缓存提升性能。其他的根据自己的使用场景定义。 详细的日志配置信息可以参考Nginx官方文档 14、nginx 的平滑升级(了解) 1、为什么要对 nginx 平滑升级 随着 nginx 越来越流行并且 nginx 的优势也越来越明显nginx 的版本迭代也来时加速模式1.9.0版本的nginx更新了许多新功能例如 stream 四层代理功能伴随着 nginx 的广泛应用版本升级必然越来越快线上业务不能停此时 nginx 的升级就是运维的工作了 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: 重新打开日志文件 3、nginx 平滑升级实战 1、查看现有的 nginx 编译参数 [rootnginx-server ~]# cd /usr/local/nginx/sbin/nginx -V2、编译 按照原来的编译参数安装 nginx 的方法进行安装只需要到 make千万不要 make install 。如果make install 会将原来的配置文件覆盖 [rootnginx-server ~]# cd /usr/local/nginx-1.16.0/ [rootnginx-server nginx-1.16.0]# ./configure --prefix/usr/local/nginx --groupnginx --usernginx --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 [rootnginx-server nginx-1.16.0]# make3、备份原 nginx 二进制文件 备份二进制文件和 nginx 的配置文件期间nginx不会停止服务 [rootnginx-server nginx-1.16.0]# mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx_$(date %F)4、复制新的nginx二进制文件进入新的nginx源码包 [rootnginx-server nginx-1.16.0]# cp /usr/local/nginx-1.16.0/objs/nginx /usr/local/nginx/sbin/5、测试新版本的nginx是否正常 [rootnginx-server nginx-1.16.0]# /usr/local/nginx/sbin/nginx -t6、给nginx发送平滑迁移信号若不清楚pid路径请查看nginx配置文件 [rootnginx-server ~]# kill -USR2 cat /var/run/nginx.pid7、查看nginx pid会出现一个nginx.pid.oldbin [rootnginx-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.oldbin8、从容关闭旧的Nginx进程 [rootnginx-server ~]# kill -WINCH cat /var/run/nginx.pid.oldbin9、此时不重载配置启动旧的工作进程 [rootnginx-server ~]# kill -HUP cat /var/run/nginx.pid.oldbin10、结束工作进程完成此次升级 [rootnginx-server ~]# kill -QUIT cat /var/run/nginx.pid.oldbin11、验证Nginx是否升级成功 [rootnginx-server ~]# /usr/local/nginx/sbin/nginx -V4、升级实验 1、安装配置1.6版本的 nginx [rootlocalhost ~]# yum install -y gcc gcc-c pcre-devel openssl-devel zlib-devel [rootlocalhost ~]# tar xzf nginx-1.6.3.tar.gz -C /usr/local/ [rootlocalhost ~]# cd /usr/local/nginx-1.6.3 [rootlocalhost nginx-1.6.3]# ./configure --prefix/usr/local/nginx --usernginx --groupnginx --with-http_stub_status_module [rootlocalhost nginx-1.6.3]# make make install [rootlocalhost nginx-1.6.3]# useradd -M -s /sbin/nologin nginx [rootlocalhost 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 [rootlocalhost nginx-1.6.3]# /usr/local/nginx/sbin/nginx [rootlocalhost 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: master2、查看版本和模块 [rootlocalhost 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 --usernginx --groupnginx --with-http_stub_status_module [rootlocalhost nginx-1.6.3]# echo nginx1.6 /usr/local/nginx/html/index.html [rootlocalhost nginx-1.6.3]# yum install -y elinks4、访问验证 [rootlocalhost nginx-1.6.3]# elinks 10.0.105.1895、升级nginx 将 nginx 版本进行升级 并在不影响业务的情况下添加 SSL 和 pcre 模块 [rootlocalhost ~]# tar xzf nginx-1.12.2.tar.gz -C /usr/local/ [rootlocalhost ~]# cd /usr/local/nginx-1.12.2/ [rootlocalhost nginx-1.12.2]# ./configure --prefix/usr/local/nginx --usernginx --groupngiinx --with-http_stub_status_module --with-http_ssl_module --with-pcre [rootlocalhost nginx-1.12.2]# make [rootlocalhost nginx-1.12.2]# cd [rootlocalhost ~]# mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx_lod [rootlocalhost ~]# cp /usr/local/nginx-1.12.2/objs/nginx /usr/local/nginx/sbin/ [rootlocalhost ~]# mv /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf.bak [rootlocalhost ~]# kill -USR2 cat /usr/local/nginx/logs/nginx.pid [rootlocalhost ~]# ls /usr/local/nginx/logs/ access.log error.log nginx.pid [rootlocalhost ~]# 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 --colorauto nginx15、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编码嵌入如下 [rootlocalhost html]# vim 404.html !DOCTYPE html htmlheadmeta charsetUTF-8 /meta nameviewport contentwidthdevice-width, initial-scale1, maximum-scale1 /title404/titlestyle.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/headbody classlayui-layout-bodydiv classlayui-layout layui-layout-admindiv classlayui-bodydiv classlayout-tablediv classlayout-table-cellimg srcdata:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAV4AAACMCAYAAAA0qsGKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkIwRDQ0ODRFMzMyODExRThBQ0Q5Q0UyNkNCMkE4MDk0IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkIwRDQ0ODRGMzMyODExRThBQ0Q5Q0UyNkNCMkE4MDk0Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6QjBENDQ4NEMzMzI4MTFFOEFDRDlDRTI2Q0IyQTgwOTQiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6QjBENDQ4NEQzMzI4MTFFOEFDRDlDRTI2Q0IyQTgwOTQiLz4gPC9yZGY6RGVzY3JpcHRpb24IDwvcmRmOlJERj4gPC94OnhtcG1ldGEIDw/eHBhY2tldCBlbmQ9InIiPz4Qz6opAAAU5klEQVR42uxd3XXjthKeOy7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 classlayout-imgp classlayout-tip哎呀找不到该页面啦/pp idtips请检查您的网络连接是否正常或者输入的网址是否正确/p/div/div/div/div/body /html展示效果 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XFjg8cyv-1602213757548)(assets/1561964133748.png)] 16、nginx 流量控制 流量限制 (rate-limiting)是Nginx中一个非常实用却经常被错误理解和错误配置的功能。我们可以用来限制用户在给定时间内HTTP请求的数量。请求可以是一个简单网站首页的GET请求也可以是登录表单的 POST 请求。流量限制可以用作安全目的比如可以减慢暴力密码破解的速率。通过将传入请求的速率限制为真实用户的典型值并标识目标URL地址(通过日志)还可以用来抵御 DDOS 攻击。更常见的情况该功能被用来保护上游应用服务器不被同时太多用户请求所压垮。 以下将会介绍Nginx的 流量限制 的基础知识和高级配置”流量限制”在Nginx Plus中也适用。 1、Nginx如何限流 Nginx的”流量限制”使用漏桶算法(leaky bucket algorithm)该算法在通讯和分组交换计算机网络中广泛使用用以处理带宽有限时的突发情况。就好比一个桶口在倒水桶底在漏水的水桶。如果桶口倒水的速率大于桶底的漏水速率桶里面的水将会溢出同样在请求处理方面水代表来自客户端的请求水桶代表根据”先进先出调度算法”(FIFO)等待被处理的请求队列桶底漏出的水代表离开缓冲区被服务器处理的请求桶口溢出的水代表被丢弃和不被处理的请求。 2、配置基本的限流 “流量限制”配置两个主要的指令limit_req_zone和limit_req如下所示 limit_req_zone $binary_remote_addr zonemylimit:10m rate10r/s;upstream myweb {server 10.0.105.196:80 weight1 max_fails1 fail_timeout1;}server {listen 80;server_name localhost;location /login {limit_req zonemylimit;proxy_pass http://myweb;proxy_set_header Host $host:$server_port;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}}10.0.105.196配置: server {listen 80;server_name localhost;location /login {root /usr/share/nginx/html;index index.html index.html;} }limit_req_zone指令定义了流量限制相关的参数而limit_req指令在出现的上下文中启用流量限制(示例中对于”/login/”的所有请求)。 limit_req_zone指令通常在HTTP块中定义使其可在多个上下文中使用它需要以下三个参数 Key - 定义应用限制的请求特性。示例中的 Nginx 变量$binary_remote_addr保存客户端IP地址的二进制形式。这意味着我们可以将每个不同的IP地址限制到通过第三个参数设置的请求速率。(使用该变量是因为比字符串形式的客户端IP地址$remote_addr占用更少的空间)Zone - 定义用于存储每个IP地址状态以及被限制请求URL访问频率的共享内存区域。保存在内存共享区域的信息意味着可以在Nginx的worker进程之间共享。定义分为两个部分通过zonekeyword标识区域的名字以及冒号后面跟区域大小。16000个IP地址的状态信息大约需要1MB所以示例中区域可以存储160000个IP地址。Rate - 定义最大请求速率。在示例中速率不能超过每秒10个请求。Nginx实际上以毫秒的粒度来跟踪请求所以速率限制相当于每100毫秒1个请求。因为不允许”突发情况”(见下一章节)这意味着在前一个请求100毫秒内到达的请求将被拒绝。 当Nginx需要添加新条目时存储空间不足将会删除旧条目。如果释放的空间仍不够容纳新记录Nginx将会返回 503状态码(Service Temporarily Unavailable)。另外为了防止内存被耗尽Nginx每次创建新条目时最多删除两条60秒内未使用的条目。 limit_req_zone指令设置流量限制和共享内存区域的参数但实际上并不限制请求速率。所以需要通过添加 limit_req指令将流量限制应用在特定的location或者server块。在上面示例中我们对/login/请求进行流量限制。 现在每个IP地址被限制为每秒只能请求10次/login/更准确地说在前一个请求的100毫秒内不能请求该URL。 3、处理突发 如果我们在100毫秒内接收到2个请求怎么办对于第二个请求Nginx将给客户端返回状态码503。这可能并不是我们想要的结果因为应用本质上趋向于突发性。相反地我们希望缓冲任何超额的请求然后及时地处理它们。我们更新下配置在limit_req中使用burst参数 limit_req_zone $binary_remote_addr zonemylimit:10m rate10r/s;upstream myweb {server 10.0.105.196:80 weight1 max_fails1 fail_timeout1;}server {listen 80;server_name localhost;location /login {limit_req zonemylimit burst20;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。 这意味着如果从一个给定IP地址发送21个请求Nginx会立即将第一个请求发送到上游服务器群然后将余下20个请求放在队列中。然后每100毫秒转发一个排队的请求只有当传入请求使队列中排队的请求数超过20时Nginx才会向客户端返回503。 4、无延迟的排队 配置burst参数将会使通讯更流畅但是可能会不太实用因为该配置会使站点看起来很慢。在上面的示例中队列中的第20个包需要等待2秒才能被转发此时返回给客户端的响应可能不再有用。要解决这个情况可以在burst参数后添加nodelay参数 limit_req_zone $binary_remote_addr zonemylimit:10m rate10r/s;upstream myweb {server 10.0.105.196:80 weight1 max_fails1 fail_timeout1;}server {listen 80;server_name localhost;location /login {limit_req zonemylimit burst20 nodelay;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;}}使用nodelay参数Nginx仍将根据burst参数分配队列中的位置并应用已配置的速率限制而不是清理队列中等待转发的请求。相反地当一个请求到达“太早”时只要在队列中能分配位置Nginx将立即转发这个请求。将队列中的该位置标记为”taken”(占据)并且不会被释放以供另一个请求使用直到一段时间后才会被释放(在这个示例中是100毫秒后)。 假设如前所述队列中有20个空位从给定的IP地址发出的21个请求同时到达。Nginx会立即转发这个21个请求并且标记队列中占据的20个位置然后每100毫秒释放一个位置。如果是25个请求同时到达Nginx将会立即转发其中的21个请求标记队列中占据的20个位置并且返回503状态码来拒绝剩下的4个请求。 现在假设第一组请求被转发后101毫秒另20个请求同时到达。队列中只会有一个位置被释放所以Nginx转发一个请求并返回503状态码来拒绝其他19个请求。如果在20个新请求到达之前已经过去了501毫秒5个位置被释放所以Nginx立即转发5个请求并拒绝另外15个。 效果相当于每秒10个请求的“流量限制”。如果希望不限制两个请求间允许间隔的情况下实施“流量限制”nodelay参数是很实用的。 注意 对于大部分部署我们建议使用burst和nodelay参数来配置limit_req指令。 5、高级配置示例 通过将基本的“流量限制”与其他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 zonereq_zone:10m rate5r/s;server {listen 80;server_name localhost;location / {limit_req zonereq_zone burst10 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个数据包的突发并且不会延迟转发。 2、location 包含多limit_req指令 我们可以在一个location块中配置多个limit_req指令。符合给定请求的所有限制都被应用时意味着将采用最严格的那个限制。例如多个指令都制定了延迟将采用最长的那个延迟。同样请求受部分指令影响被拒绝即使其他指令允许通过也无济于事。 扩展前面将“流量限制”应用到白名单内IP地址的例子 http {# ...limit_req_zone $limit_key zonereq_zone:10m rate5r/s;limit_req_zone $binary_remote_addr zonereq_zone_wl:10m rate15r/s;server {# ...location / {limit_req zonereq_zone burst10 nodelay;limit_req zonereq_zone_wl burst20 nodelay;# ...}} }白名单内的IP地址不会匹配到第一个“流量限制”而是会匹配到第二个req_zone_wl并且被限制到每秒15个请求。不在白名单内的IP地址两个限制能匹配到所以应用限制更强的那个每秒5个请求。 6、配置流量控制相关功能 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 zonemylimit:10m rate10r/s;upstream myweb {server 10.0.105.196:80 weight1 max_fails1 fail_timeout1;}server {listen 80;server_name localhost;location /login {limit_req zonemylimit burst20 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指令来设置为其它状态码(例如下面的444状态码): limit_req_zone $binary_remote_addr zonemylimit:10m rate10r/s;upstream myweb {server 10.0.105.196:80 weight1 max_fails1 fail_timeout1;}server {listen 80;server_name localhost;location /login {limit_req zonemylimit burst20 nodelay;limit_req_log_level warn;limit_req_status 444;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;}}7、nginx 流量控制总结 以上已经涵盖了Nginx和Nginx Plus提供的“流量限制”的很多功能包括为HTTP请求的不同loation设置请求速率给“流量限制”配置burst和nodelay参数。还涵盖了针对客户端IP地址的白名单和黑名单应用不同“流量限制”的高级配置阐述了如何去日志记录被拒绝和延时的请求。 17、nginx 访问控制 1、nginx 访问控制模块 1基于IP的访问控制http_access_module 2基于用户的信任登录http_auth_basic_module 2、基于IP的访问控制 1、配置语法 Syntaxallow address | CIDR | unix: | all; default默认无 Contexthttpserverlocationlimit_exceptSyntaxdeny address | CIDR | unix: | all; default默认无 Contexthttpserverlocationlimit_except2、配置测试 修改/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;#deny 192.168.1.8;} } #需要注意: 如果先允许访问在定义拒绝访问。那么拒绝访问不生效。虚拟机宿主机IP为192.168.1.8虚拟机IP为192.168.1.11故这里禁止宿主机访问允许其他所有IP访问。 宿主机访问http://192.168.1.11/admin显示403 Forbidden。 当然也可以反向配置同时也可以使用IP网段的配置方式如allow 192.168.1.0/24;表示满足此网段的IP都可以访问。 3、指定location拒绝所有请求 如果你想拒绝某个指定URL地址的所有请求而不是仅仅对其限速只需要在location块中配置deny all指令 server {listen 80;server_name localhost;location /foo.html {root /home/www/html;deny all;} }4、局限性 remote_addr只能记录上一层与服务器直接建立连接的IP地址若中间有代理则记录的是代理的IP地址。 http_x_forwarded_for可以记录每一层级的IP。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kmSgk23O-1602213757549)(assets/1561994965370.png)] 5、解决方法 1采用别的HTTP头信息控制访问如HTTP_X_FORWARD_FOR无法避免被改写 2结合geo模块 3通过HTTP自定义变量传递 3、基于用户的信任登录 1、配置语法 Syntaxauth_basic string | off; defaultauth_basic off; Contexthttpserverlocationlimit_exceptSyntaxauth_basic_user_file file; default默认无 Contexthttpserverlocationlimit_except file存储用户名密码信息的文件。2、配置示例 改名access_mod.conf为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、建立口令文件 [root192 ~]# yum install -y httpd-tools #htpasswd 是开源 http 服务器 apache httpd 的一个命令工具用于生成 http 基本认证的密码文件 [root192 ~]# htpasswd -cm /etc/nginx/auth_conf user10 [root192 ~]# htpasswd -m /etc/nginx/auth_conf user20 [root192 ~]# cat /etc/nginx/auth_conf user10:$apr1$MOa9UVqF$RlYRMk7eprViEpNtDV0n40 user20:$apr1$biHJhW03$xboNUJgHME6yDd17gkQNb04、访问测试 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ykhK3kra-1602213757551)(assets/1561996355328.png)] ] 5、局限性 1用户信息依赖文件方式 2操作管理机械效率低下 6、解决方法 1Nginx结合LUA实现高效验证 2Nginx和LDAP打通利用nginx-auth-ldap模块 3Nginx只做中间代理具体认证交给应用。 18、nginx 变量(了解) Nginx 同 Apache 和 Lighttpd 等其他 Web 服务器的配置方法不太相同Nginx的配置文件使用语法的就是一门微型的编程语言。可以类似写程序一般编写配置文件可操作性很大。既然是编程语言一般也就少不了“变量”这种东西。 1、nginx变量简介 所有的 Nginx变量在 Nginx 配置文件中引用时都须带上 $ 前缀 在 Nginx 配置中变量只能存放一种类型的值有且也只存在一种类型那就是字符串类型 nginx可以使用变量简化配置与提高配置的灵活性所有的变量值都可以通过这种方式引用 $变量名2、nginx 变量的定义和使用 nginx中的变量分为两种自定义变量与内置预定义变量 1、自定义变量 1、声明变量 可以在sever,http,location等标签中使用set命令非唯一声明变量语法如下 set $变量名 变量值注意: nginx 中的变量必须都以$开头nginx 的配置文件中所有使用的变量都必须是声明过的否则 nginx 会无法启动并打印相关异常日志 2、变量的可见性 nginx 变量的一个有趣的特性就是nginx中每一个变量都是全局可见的而他们又不是全局变量。如下例子 location a/ {return 200 $a }location b/ {set $a hello nginxreturn 200 $a }由于变量是全局可见的所以nginx启动不会报错而第一个location中并不知道$a的具体值因此返回的响应结果为一个空字符串。 在不同层级的标签中声明的变量性的可见性规则如下: location标签中声明的变量中对这个location块可见server标签中声明的变量对server块以及server块中的所有子块可见http标签中声明的变量对http块以及http块中的所有子块可见 3、配置 $foohello server {listen 8080;server_name localhost;location /test {set $foo hello;echo foo: $foo;} }输出 [rootlocalhost html]# nginx -s reload [rootlocalhost html]# curl localhost/test-dollar This is a dollar sign: \$这里用到了标准模块 ngx_geo 提供的配置指令 geo 来为变量 d o l l a r 赋 予 字 符 串 dollar 赋予字符串 dollar赋予字符串这样我们在下面需要使用美元符的地方就直接引用我们的 $dollar 变量就可以了。 4、 使用大括号插值 在“变量插值”的上下文中还有一种特殊情况即当引用的变量名之后紧跟着变量名的构成字符时比如后跟字母、数字以及下划线我们就需要使用特别的记法来消除歧义例如 server {...location /test-brace {set $first hello ;echo ${first}world;} }输出 [rootlocalhost html]# nginx -s reload [rootlocalhost html]# curl localhost/test-brace hello world这里我们在 echo 配置指令的参数值中引用变量 first 的时候后面紧跟着 world 这个单词所以如果直接写作 “firstworld” 则 Nginx “变量插值”计算引擎会将之识别为引用了变量 firstworld. 为了解决这个难题Nginx 的字符串记法支持使用花括号在 之后把变量名围起来比如这里的 ${first}。 5、变量作用域 set 指令以及前面提到的 geo 指令不仅有赋值的功能它还有创建 Nginx 变量的副作用即当作为赋值对象的变量尚不存在时它会自动创建该变量。比如在上面这个例子中如果 $a 这个变量尚未创建则 set 指令会自动创建 $a 这个用户变量。如果我们不创建就直接使用它的值则会报错。 例如 server {...location /bad {echo $foo;} }此时 Nginx 服务器会拒绝加载配置: [emerg] unknown foo variableNginx 变量的创建和赋值操作发生在全然不同的时间阶段Nginx 变量的创建只能发生在 Nginx 配置加载的时候或者说 Nginx 启动的时候而赋值操作则只会发生在请求实际处理的时候。 这意味着不创建而直接使用变量会导致启动失败同时也意味着我们无法在请求处理时动态地创建新的 Nginx 变量。 Nginx 变量一旦创建其变量名的可见范围就是整个 Nginx 配置甚至可以跨越不同虚拟主机的 server 配置块。我们来看一个例子 server {listen 8080;location /foo {echo foo [$foo];}location /bar {set $foo 32;echo foo [$foo];} }输出 [rootlocalhost html]# curl http://localhost/foo foo [][rootlocalhost html]# curl http://localhost/bar foo [32][rootlocalhost html]# curl http://localhost/foo foo []这里我们在 location /bar 中用 set 指令创建了变量 foo于是在整个配置文件中这个变量都是可见的因此我们可以在 location /foo 中直接引用这个变量而不用担心 Nginx 会报错。 从这个例子我们可以看到set 指令因为是在 location /bar 中使用的所以赋值操作只会在访问 /bar 的请求中执行。而请求 /foo 接口时我们总是得到空的 foo值因为用户变量未赋值就输出的话得到的便是空字符串。 从这个例子我们可以窥见的另一个重要特性是Nginx 变量名的可见范围虽然是整个配置但每个请求都有所有变量的独立副本或者说都有各变量用来存放值的容器的独立副本彼此互不干扰。比如前面我们请求了 /bar 接口后foo 变量被赋予了值 32但它丝毫不会影响后续对 /foo 接口的请求所对应的 foo 值它仍然是空的因为各个请求都有自己独立的 $foo 变量的副本。 对于 Nginx 新手来说最常见的错误之一就是将 Nginx 变量理解成某种在请求之间全局共享的东西或者说“全局变量”。而事实上Nginx 变量的生命期是不可能跨越请求边界的。 关于 Nginx 变量的另一个常见误区是认为变量容器的生命期是与 location 配置块绑定的。其实不然。我们来看一个涉及“内部跳转”的例子 server {listen 8080;location /foo {set $a hello;echo_exec /bar;}location /bar {echo a [$a];} }输出 [rootlocalhost html]# curl localhost/foo a [hello]这 里我们在 location /foo 中使用第三方模块 ngx_echo 提供的 echo_exec 配置指令发起到 location /bar 的“内部跳转”。所谓“内部跳转”就是在处理请求的过程中于服务器内部从一个 location 跳转到另一个 location 的过程。这不同于利用 HTTP 状态码 301 和 302 所进行的“外部跳转”因为后者是由 HTTP 客户端配合进行跳转的而且在客户端用户可以通过浏览器地址栏这样的界面看到请求的 URL 地址发生了变化。内部跳转和 Bourne Shell或 Bash中的 exec 命令很像都是“有去无回”。另一个相近的例子是 C 语言中的 goto 语句。 既然是内部跳转当前正在处理的请求就还是原来那个只是当前的 location 发生了变化所以还是原来的那一套 Nginx 变量的容器副本。对应到上例如果我们请求的是 /foo 这个接口那么整个工作流程是这样的先在 location /foo 中通过 set 指令将 a 变量的值赋为字符串 hello然后通过 echo_exec 指令发起内部跳转又进入到 location /bar 中再输出 a 变量的值。因为 a 还是原来的 a所以我们可以期望得到 hello 这行输出。测试证实了这一点 但如果我们从客户端直接访问 /bar 接口就会得到空的 a 变量的值因为它依赖于 location /foo 来对 a 进行初始化。 从上面这个例子我们看到一个请求在其处理过程中即使经历多个不同的 location 配置块它使用的还是同一套 Nginx 变量的副本。这里我们也首次涉及到了“内部跳转”这个概念。值得一提的是标准 ngx_rewrite 模块的 rewrite 配置指令其实也可以发起“内部跳转”例如上面那个例子用 rewrite 配置指令可以改写成下面这样的形式 server {listen 8080;location /foo {set $a hello;rewrite ^ /bar;}location /bar {echo a [$a];} }从上面这个例子我们看到Nginx 变量值容器的生命期是与当前正在处理的请求绑定的而与 location 无关。 2、内置预定义变量 内置预定义变量即无需声明就可以使用的变量通常包括一个http请求或响应中一部分内容的值以下为一些常用的内置预定义变量 变量名定义$arg_PARAMETERGET请求中变量名PARAMETER参数的值。$args这个变量等于GET请求中的参数。例如foo123barblahblah;这个变量只可以被修改$binary_remote_addr二进制码形式的客户端地址。$body_bytes_sent传送页面的字节数$content_length请求头中的Content-length字段。$content_type请求头中的Content-Type字段。$cookie_COOKIEcookie COOKIE的值。$document_root当前请求在root指令中指定的值。$document_uri与$uri相同。$host请求中的主机头(Host)字段如果请求中的主机头不可用或者空则为处理请求的server名称(处理请求的server的server_name指令的值)。值为小写不包含端口。$hostname机器名使用 gethostname系统调用的值$http_HEADERHTTP请求头中的内容HEADER为HTTP请求中的内容转为小写-变为_(破折号变为下划线)例如$http_user_agent(Uaer-Agent的值);$sent_http_HEADERHTTP响应头中的内容HEADER为HTTP响应中的内容转为小写-变为_(破折号变为下划线)例如 $sent_http_cache_control, $sent_http_content_type…;$is_args如果$args设置值为?否则为。$limit_rate这个变量可以限制连接速率。$nginx_version当前运行的nginx版本号。$query_string与$args相同。$remote_addr客户端的IP地址。$remote_port客户端的端口。$remote_user已经经过Auth Basic Module验证的用户名。$request_filename当前连接请求的文件路径由root或alias指令与URI请求生成。$request_body这个变量0.7.58包含请求的主要信息。在使用proxy_pass或fastcgi_pass指令的location中比较有意义。$request_body_file客户端请求主体信息的临时文件名。$request_completion如果请求成功设为OK如果请求未完成或者不是一系列请求中最后一部分则设为空。$request_method这个变量是客户端请求的动作通常为GET或POST。包括0.8.20及之前的版本中这个变量总为main request中的动作如果当前请求是一个子请求并不使用这个当前请求的动作。$request_uri这个变量等于包含一些客户端请求参数的原始URI它无法修改请查看$uri更改或重写URI。$scheme所用的协议比如http或者是https比如rewrite ^(.)$ $scheme://example.com$1 redirect;$server_addr服务器地址在完成一次系统调用后可以确定这个值如果要绕开系统调用则必须在listen中指定地址并且使用bind参数。$server_name服务器名称。$server_port请求到达服务器的端口号。$server_protocol请求使用的协议通常是HTTP/1.0或HTTP/1.1。$uri请求中的当前URI(不带请求参数参数位于args)不同于浏览器传递的args)不同于浏览器传递的args)不同于浏览器传递的request_uri的值它可以通过内部重定向或者使用index指令进行修改。不包括协议和主机名例如/foo/bar.html Nginx 内建变量最常见的用途就是获取关于请求或响应的各种信息。 1、uri vs request_uri 由 ngx_http_core 模块提供的内建变量 uri可以用来获取当前请求的 URI经过解码并且不含请求参数 而 request_uri 则用来获取请求最原始的 URI 未经解码并且包含请求参数。 location /test-uri {echo uri $uri;echo request_uri $request_uri; }输出 [rootlocalhost html]# nginx -s reload [rootlocalhost html]# curl localhost/test-uri uri /test-uri request_uri /test-uri[rootlocalhost html]# curl localhost/test-uri?a3b4 uri /test-uri request_uri /test-uri?a3b4[rootlocalhost html]# curl localhost/test-uri/hello%20world?a3b4 uri /test-uri/hello world request_uri /test-uri/hello%20world?a3b42、$arg_XXX 另一个特别常用的内建变量其实并不是单独一个变量而是有无限多变种的一群变量即名字以 arg_ 开头的所有变量我们估且称之为 arg_XXX 变量群。 一个例子是 arg_name这个变量的值是当前请求中名为 name 的参数的值而且还是未解码的原始形式的值。 location /test-arg {echo name: $arg_name;echo class: $arg_class; }输出 [rootlocalhost html]# nginx -s reload [rootlocalhost html]# curl localhost/test-arg name: class:[rootlocalhost html]# curl localhost/test-arg?nameTomclass3 name: Tom class: 3[rootlocalhost html]# curl localhost/test-arg?namehello%20worldclass9 name: hello%20world class: 93、$arg_XXX 不区分大小写 其实 $arg_name 不仅可以匹配 name 参数也可以匹配 NAME 参数抑或是 NameNginx 会在匹配参数名之前自动把原始请求中的参数名调整为全部小写的形式。 [rootlocalhost html]# curl localhost/test-arg?NAMEMarry name: Marry class:[rootlocalhost html]# curl localhost/test-arg?NameJimmy name: Jimmy class:4、对 uri 解码 如果你想对 URI 参数值中的 %XX 这样的编码序列进行解码可以使用第三方 ngx_set_misc 模块提供的 location /test-unescape-uri {set_unescape_uri $name $arg_name;set_unescape_uri $class $arg_class;echo name: $name;echo class: $class; }现在我们再看一下效果 [rootlocalhost html]# curl localhost/test-arg?namehello%20worldclass9 name: hello world class: 9从这个例子我们同时可以看到这个 set_unescape_uri 指令也像 set 指令那样拥有自动创建 Nginx 变量的功能。后面我们还会专门介绍到 ngx_set_misc 模块。 像 $arg_XXX 这种类型的变量拥有无穷无尽种可能的名字所以它们并不对应任何存放值的容器。而且这种变量在 Nginx 核心中是经过特别处理的第三方 Nginx 模块是不能提供这样充满魔法的内建变量的。 类 似 arg_XXX 的内建变量还有不少比如用来取 cookie 值的 cookie_XXX 变量群用来取请求头的 http_XXX 变量群以及用来取响应头的 sent_http_XXX 变量群。这里就不一一介绍了感兴趣的读者可以参考 ngx_http_core 模块的官方文档。 19、nginx 监控 1、nginx的基础监控 进程监控端口监控 注意 这两个是必须要加在zabbix监控加触发器有问题及时告警。 web 服务器 nginx 以其高性能与抗并发能力越来越多的被用户使用 作为一款服务器产品其运行状态是运维密切关注的因此对 nginx 的实时监控就必须要关注的了 nginx 提供了 ngx_http_stub_status_modulengx_http_reqstat_module模块这个模块提供了基本的监控功能 作为官方企业版的 nginx plus 通过 ngx_http_status_module 提供了更加完善的监控功能: http://demo.nginx.com/status.html 2、监控的主要指标 我们需要对以下主要的指标进行监控 1、基本活跃指标 Accepts接受、Handled已处理、Requests请求数是一直在增加的计数器。Active活跃、Waiting等待、Reading读、Writing写随着请求量而增减。 名称描述指标类型Accepts接受NGINX 所接受的客户端连接数资源: 功能Handled已处理成功的客户端连接数资源: 功能Dropped已丢弃计算得出丢弃的连接数接受 - 已处理工作错误*Requests请求数客户端请求数工作吞吐量 NGINX worker 进程接受 OS 的连接请求时 Accepts 计数器增加而Handled 是当实际的请求得到连接时通过建立一个新的连接或重新使用一个空闲的。这两个计数器的值通常都是相同的如果它们有差别则表明连接被Dropped往往这是由于资源限制比如已经达到 NGINX 的worker_connections的限制。 2、每秒请求数 – QPS 按照固定时间间隔采样请求数据计算出单位时间的请求量可以看到你的 web 服务器的请求情况 通过持续的 QPS 监控可以立刻发现是否被恶意攻击或对服务的可用性进行评估 虽然当问题发生时通过 QPS 不能定位到确切问题的位置但是他却可以在第一时间提醒你环境可能出问题了 3、服务器错误率 通过监控固定时间间隔内的错误代码4XX代码表示客户端错误5XX代码表示服务器端错误可以了解到客户端收到的结果是否是正确的错误率突然的飙升很可能是你的网站漏洞发出的信号 如果你希望通过 access log 分析错误率那么你需要配置 nginx 的日志模块让 nginx 将响应码写入访问日志 4、请求处理时间 请求处理时间也可以被记录在 access log 中通过分析 access log统计请求的平均响应时间通过持续观察可以发现上游服务器的问题 3、指标的收集 介绍了这么多的监控指标事实上上面介绍的仅仅是基本的监控指标针对实际的情况还有很多指标十分具有监控的必要 那么怎么去收集这些指标进行监控呢 通过在编译时加入 nginx 的 ngx_http_stub_status_module 模块我们可以实时监控以下基本的指标 1、nginx Stub Status 监控模块安装 先使用命令查看是否已经安装这个模块 # -V大写会显示版本号和模块等信息、v小写仅显示版本信息 [rootlocalhost ~]# 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;allow 10.0.105.207; #允许本地电脑访问deny all;} }此处默认只有本地访问如果远程查看需要加相关的IP或者干脆去掉Deny all即可。加密文件可以使用#htpasswd -c /usr/nginx/conf hxb 命令来创建。配置完成后需要重启Nginx服务。状态配置只能是针对某个Nginx服务。目前Nginx还无法做到针对单个站点进行监控。 2、nginx 状态查看 配置完成后在浏览器中输入http://10.0.105.207/nginx-status 查看或者用 curl localhost/nginx_status显示信息如下 Active connections: 2 server accepts handled requests26 26 48 Reading: 0 Writing: 1 Waiting: 1 Accepts接受、Handled已处理、Requests请求数是一直在增加的计数器。Active活跃、Waiting等待、Reading读、Writing写随着请求量而增减 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2YCsNzYB-1602213757552)(assets/1562035406107.png)] 3、Stub Status 参数说明 active connections – 活跃的连接数量 server accepts handled requests — 总共处理了1075个连接 , 成功创建1064次握手, 总共处理了6253个请求 每个连接有三种状态waiting、reading、writing reading —读取客户端的Header信息数.这个操作只是读取头部信息读取完后马上进入writing状态因此时间很短。 writing — 响应数据到客户端的Header信息数.这个操作不仅读取头部还要等待服务响应因此时间比较长。 waiting — 开启keep-alive后等候下一次请求指令的驻留连接. 正常情况下waiting数量是比较多的并不能说明性能差。反而如果readingwriting数量比较多说明服务并发有问题。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mfn2VHGd-1602213757553)(assets/1562035574221.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zr7ObEYM-1602213757554)(assets/1562035977477.png)] 当用户请求连接Nginx服务器时accepts计数器会加一。且当服务器处理该连接请求时handled计数器同样会加一。一般而言两者的值是相等的除非达到了某些资源极限如worker_connection的限制。 用户连接请求被处理就会进入 active 状态。如果该连接没有其他 request则进入 waiting 的子状态如果有 requestnginx 会读取 request 的 header计数器 request 加一进入 reading 的子状态。 reading 状态持续时间非常短header 被读取后就会进入 writing 状态。事实上直到服务器将响应结果返回给用户之前该连接会一直保持 writing 状态。所以说writing 状态一般会被长时间占用。 一旦 NGINX 成功处理一个连接时连接会移动到Active状态在这里对客户端请求进行处理 Active状态 Waiting: 活跃的连接也可以处于 Waiting 子状态如果有在此刻没有活跃请求的话。新连接可以绕过这个状态并直接变为到 Reading 状态最常见的是在使用“accept filter接受过滤器” 和 “deferred accept延迟接受”时在这种情况下NGINX 不会接收 worker 进程的通知直到它具有足够的数据才开始响应。如果连接设置为 keep-alive 那么它在发送响应后将处于等待状态。 Reading: 当接收到请求时连接离开 Waiting 状态并且该请求本身使 Reading 状态计数增加。在这种状态下 NGINX 会读取客户端请求首部。请求首部是比较小的因此这通常是一个快速的操作。 Writing: 请求被读取之后其使 Writing 状态计数增加并保持在该状态直到响应返回给客户端。这意味着该请求在 Writing 状态时 一方面 NGINX 等待来自上游系统的结果系统放在 NGINX “后面”另外一方面NGINX 也在同时响应。请求往往会在 Writing 状态花费大量的时间。 通常一个连接在同一时间只接受一个请求。在这种情况下Active 连接的数目 Waiting 的连接 Reading 请求 Writing 。 怎么利用这些参数 开源的 Nginx 提供的原始参数中实时性的会比较有用如 Active connections、Reading、Writing 以及 Waiting。这些数据能够反映当前 Nginx 的负载情况方便在服务器出现问题时及时发现问题。而另一些数据由于不是状态量Nginx 无法计算当前的量值而改做其统计数如 accepts、handled 和 requests。 对于维护网站人员accepts、handled 和 requests 的统计值用处是不大的值得参考的是短时间内这三者数值的增量。这个短时间可以是一秒如 accepts_per_second、handled_per_second 和 requests_per_second。一个简单的做法就是每秒都去读取这些参数返回一个和上一秒的差值就行。当然handled_per_second 替换成 dropped_per_secondaccepts_per_second-handled_per_second 就更完美了。 通过这七个参数就可以从连接到请求全方位的监控起 Nginx 的运行状态。为了方便检测对每次获取的参数保留下来然后按时间展现出来。下图展示了 Nginx 在运行时的参考数据。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N1dCsJMn-1602213757556)(assets/1562036059274.png)] 4、Reqstat 模块监控 描述 ngx_http_reqstat_module 模块这个模块计算定义的变量根据变量值分别统计 nginx 的运行状况。可以监视的运行状况有连接数、请求数、各种响应码范围的请求数、输入输出流量、rt、upstream访问等。可以指定获取所有监控结果或者一部分监控结果。利用变量添加自定义监控状态。总的监控状态最大个数为50个。回收过期的监控数据。设置输出格式跟踪请求不受内部跳转的影响不要使用与响应相关的变量作为条件比如$status 编译 默认编入Tengine可通过 --without-http_reqstat_module 编译此模块或通过–with-http_reqstat_moduleshared 编译为so模块。 使用so模块加载的话请确保其顺序在ngx_http_lua_module之后。可以借助nginx -m来确认。 Syntax: req_status zone_name1 [zone_name2 [zone_name3 […]]] Default: none Context: http、srv、loc 开启统计可以指定同时统计多个目标每一个zone_name对应一个目标。 Syntax: req_status_show [zone_name1 [zone_name2 […]]] Default: 所有建立的共享内存目标 Context: loc 按格式返回统计结果。可指定返回部分目标的统计结果。 Syntax: req_status_show_field field_name1 [field_name2 [field_name3 […]]] Default: all the fields, including user defined fields Context: loc 定义输出格式。可以使用的字段内置字段以上面的名字来表示自定义字段用变量表示。 kv’总是每行的第一个字段。 Syntax: req_status_zone_add_indecator zone_name v a r 1 [ var1 [ var1[var2 […]] Default: none Context: http 通过变量增加自定义字段新增加的字段目前会展现在每行的末尾。 Syntax: req_status_zone_key_length zone_name length Default: none Context: http 定义某个共享内存块中key的最大长度默认值104。key中超出的部分会被截断。 Syntax: req_status_zone_recycle zone_name times seconds Default: none Context: http 定义某个共享内存块过期数据的回收。回收在共享内存耗尽时自动开启。只会回收访问频率低于设置值的监控数据。 频率定义为 times / seconds默认值为10r/min即 req_status_zone_recycle demo_zone 10 60;安装模块: tengine官方说req-statu模块默认安装。但是并没有。而且tengine的req-status模块不能分upstream监控从github引入第三方模块解决该问题 yum与编译安装的nginx扩展模块安装: [rootnginx-server ~]# yum install -y unzip 1. 安装先查看一下当前编译安装nginx的版本 [rootlocalhost nginx-1.16.0]# nginx -V 下载或者上传一个和当前的nginx版本一样的nginx的tar包。 [rootnginx-server ~]# tar xzf nginx-1.16.0.tar.gz -C /usr/local/ 2.下载ngx_req_status_module 模块 这是第三方模块需要添加 [rootnginx-server ~]# wget https://github.com/zls0424/ngx_req_status/archive/master.zip -O ngx_req_status.zip [rootnginx-server ~]# unzip ngx_req_status.zip [rootnginx-server ~]# cp -r ngx_req_status-master/ /usr/local/ #与解压的nginx在同一级目录下 [rootnginx-server ~]# cd /usr/local/nginx-1.16.0/ [rootnginx-server nginx-1.16.0]# yum -y install pcre pcre-devel openssl openssl-devel gcc gcc-c zlib zlib-devel [rootnginx-server nginx-1.16.0]# yum -y install patch.x86_64 [rootnginx-server nginx-1.16.0]# patch -p1 ../ngx_req_status-master/write_filter-1.7.11.patch [rootlocalhost nginx-1.16.0]# ./configure 添加上原来的参数 --add-module/usr/local/ngx_req_status-master [rootlocalhost nginx-1.16.0]# make -j2 由于原先已有nginx所以不能执行make install,否则会覆盖掉以前的配置文件及内容 [rootlocalhost nginx-1.16.0]# mv /usr/sbin/nginx /usr/sbin/nginx_bak [rootlocalhost nginx-1.16.0]# cp objs/nginx /usr/sbin/ [rootlocalhost nginx-1.16.0]# systemctl restart nginx [rootlocalhost nginx-1.16.0]# nginx -V 如果发现编译的配置文件有变化就成功了 配置如下: 需要在http里面配置。 !!注意添加了此配置只有重启nginx才能生效。 [rootlocalhost ~]# vim /etc/nginx/nginx.confreq_status_zone server_name $server_name 256k;req_status_zone server_addr $server_addr 256k;req_status_zone server_url $server_name$uri 256k;req_status server_name server_addr server_url;server {server_name localhost;location /req-status {req_status_show on;}}指令介绍req_status_zone 语法: req_status_zone name string size 默认值: None 配置块: http 定义请求状态ZONE,请求按照string分组来排列例如 req_status_zone server_url $server_name$uri 256k; 域名uri将会形成一条数据可以看到所有url的带宽流量访问数req_status 语法: req_status zone1[ zone2] 默认值: None 配置块: http, server, location 在location中启用请求状态你可以指定更多zones。req_status_show 语法: req_status_show on 默认值: None 配置块: location 在当前位置启用请求状态处理程序[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ytRk6hnq-1602213757557)(assets/1562055908162.png)] 请求状态信息包括以下字段 zone_name - 利用req_status_zone定义的分组标准。例如按照服务器名称对请求进行分组后key - 请求按分组标准分组后的分组标识即组名。例如按服务器名称分组时组名可能是10.0.105.196max_active - 该组的最大并发连接数max_bw - 该组的最大带宽traffic - 该组的总流量requests - 该组的总请求数active - 该组当前的并发连接数bandwidth - 该组当前带宽。 5、补充 查看Nginx并发进程数ps -ef | grep nginx | wc -l 查看Web服务器TCP连接状态netstat -n | awk ‘/^tcp/ {S[$NF]} END {for(a in S) print a, S[a]}’ LISTEN侦听来自远方的TCPport的连接请求 SYN-SENT再发送连接请求后等待匹配的连接请求 SYN-RECEIVED再收到和发送一个连接请求后等待对方对连接请求的确认 ESTABLISHED代表一个打开的连接 FIN-WAIT-1等待远程TCP连接中断请求或先前的连接中断请求的确认 FIN-WAIT-2从远程TCP等待连接中断请求 CLOSE-WAIT等待从本地用户发来的连接中断请求 CLOSING等待远程TCP对连接中断的确认 LAST-ACK等待原来的发向远程TCP的连接中断请求的确认 TIME-WAIT等待足够的时间以确保远程TCP接收到连接中断请求的确认 CLOSED没有不论什么连接状态 商业版的 nginx plus 通过他的 ngx_http_status_module 提供了比 nginx 更多的监控指标可以参看 http://demo.nginx.com/status.html 4、nginx access log 分析 nginx 的 access log 中可以记录很多有价值的信息通过分析 access log可以收集到很多指标 python 编写的 linux 工具 ngxtop 就实现了对 access log 的分析功能 1.制作nginx的日志切割每天凌晨切割并压缩。 PVPV(访问量) 即Page View, 即页面浏览量或点击量用户每次刷新即被计算一次。 UVUV(独立访客)即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[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hF1P8h9t-1602213757559)(assets/1562230171957.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9DWoKa41-1602213757561)(assets/1562230190957.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U813dDvX-1602213757562)(assets/1562230212061.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yy28h7eD-1602213757564)(assets/1562230247706.png)] 三、HTTPS 基本原理 1、https 介绍 HTTPS全称HyperText Transfer Protocol over Secure Socket Layer其实 HTTPS 并不是一个新鲜协议Google 很早就开始启用了初衷是为了保证数据安全。 近些年Google、Baidu、Facebook 等这样的互联网巨头不谋而合地开始大力推行 HTTPS 国内外的大型互联网公司很多也都已经启用了全站 HTTPS这也是未来互联网发展的趋势。 为鼓励全球网站的 HTTPS 实现一些互联网公司都提出了自己的要求 Google 已调整搜索引擎算法让采用 HTTPS 的网站在搜索中排名更靠前从 2017 年开始Chrome 浏览器已把采用 HTTP 协议的网站标记为不安全网站苹果要求 2017 年App Store 中的所有应用都必须使用 HTTPS 加密连接当前国内炒的很火热的微信小程序也要求必须使用 HTTPS 协议新一代的 HTTP/2 协议的支持需以 HTTPS 为基础。 等等因此想必在不久的将来全网 HTTPS 势在必行。 1、HTTPS 协议介绍 HTTP 协议HyperText Transfer Protocol超文本传输协议是客户端浏览器或其他程序与Web服务器之间的应用层通信协议 。HTTPS 协议HyperText Transfer Protocol over Secure Socket Layer可以理解为HTTPSSL/TLS 即 HTTP 下加入 SSL 层HTTPS 的安全基础是 SSL因此加密的详细内容就需要 SSL用于安全的 HTTP 数据传输。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hUjjXEjU-1602213757568)(assets/1562050089966.png)] 如上图所示 HTTPS 相比 HTTP 多了一层 SSL/TLS SSLSecure Socket Layer安全套接字层1994年为 Netscape 所研发SSL 协议位于 TCP/IP 协议与各种应用层协议之间为数据通讯提供安全支持。TLSTransport Layer Security传输层安全其前身是 SSL它最初的几个版本SSL 1.0、SSL 2.0、SSL 3.0由网景公司开发1999年从 3.1 开始被 IETF 标准化并改名发展至今已经有 TLS 1.0、TLS 1.1、TLS 1.2 三个版本。SSL3.0和TLS1.0由于存在安全漏洞已经很少被使用到。TLS 1.3 改动会比较大目前还在草案阶段目前使用最广泛的是TLS 1.1、TLS 1.2。 2、加密算法 据记载公元前400年古希腊人就发明了置换密码在第二次世界大战期间德国军方启用了“恩尼格玛”密码机所以密码学在社会发展中有着广泛的用途。 对称加密 有流式、分组两种加密和解密都是使用的同一个密钥。 例如DES、AES-GCM、ChaCha20-Poly1305等 非对称加密 加密使用的密钥和解密使用的密钥是不相同的分别称为公钥、私钥公钥和算法都是公开的私钥是保密的。非对称加密算法性能较低但是安全性超强由于其加密特性非对称加密算法能加密的数据长度也是有限的。 例如RSA、DSA、ECDSA、 DH、ECDHE 哈希算法 将任意长度的信息转换为较短的固定长度的值通常其长度要比信息小得多且算法不可逆。 例如MD5、SHA-1、SHA-2、SHA-256 等 数字签名 签名就是在信息的后面再加上一段内容信息经过hash后的值可以证明信息没有被修改过。hash值一般都会加密后也就是签名再和信息一起发送以保证这个hash值不被修改。 3、HTTPS 原理 1、HTTP 访问过程 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UoYM2uwR-1602213757569)(assets/1562050123147.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U0ulkyhV-1602213757571)(assets/1562050201266.png)] 如上图所示HTTP请求过程中客户端与服务器之间没有任何身份确认的过程数据全部明文传输“裸奔”在互联网上所以很容易遭到黑客的攻击如下 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VJwzEWs2-1602213757572)(assets/1562050246969.png)] 可以看到客户端发出的请求很容易被黑客截获如果此时黑客冒充服务器则其可返回任意信息给客户端而不被客户端察觉所以我们经常会听到一词“劫持”现象如下 下面两图中浏览器中填入的是相同的URL左边是正确响应而右边则是被劫持后的响应从貌美如花变成如花。。。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IADreBrm-1602213757573)(assets/1562050281277.png)] 所以 HTTP 传输面临的风险有 窃听风险黑客可以获知通信内容。篡改风险黑客可以修改通信内容。冒充风险黑客可以冒充他人身份参与通信。 2、HTTP 向 HTTPS 演化的过程 第一步为了防止上述现象的发生人们想到一个办法对传输的信息加密即使黑客截获也无法破解 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2pbVCqs2-1602213757575)(assets/1562050310151.png)] 如上图所示此种方式属于对称加密双方拥有相同的密钥信息得到安全传输但此种方式的缺点是 1不同的客户端、服务器数量庞大所以双方都需要维护大量的密钥维护成本很高 2因每个客户端、服务器的安全级别不同密钥极易泄露 第二步既然使用对称加密时密钥维护这么繁琐那我们就用非对称加密试试 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1ei1Q5VN-1602213757576)(assets/1562050336264.png)] 如上图所示客户端用公钥对请求内容加密服务器使用私钥对内容解密反之亦然但上述过程也存在缺点 1公钥是公开的也就是黑客也会有公钥所以第 ④ 步私钥加密的信息如果被黑客截获其可以使用公钥进行解密获取其中的内容 第三步非对称加密既然也有缺陷那我们就将对称加密非对称加密两者结合起来取其精华、去其糟粕发挥两者的各自的优势 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HL9aodA9-1602213757577)(assets/1562050389994.png)] 如上图所示 1第 ③ 步时客户端说咱们后续回话采用对称加密吧这是对称加密的算法和对称密钥这段话用公钥进行加密然后传给服务器 2服务器收到信息后用私钥解密提取出对称加密算法和对称密钥后服务器说好的对称密钥加密 3后续两者之间信息的传输就可以使用对称加密的方式了 遇到的问题 1客户端如何获得公钥 2如何确认服务器是真实的而不是黑客 第四步获取公钥与确认服务器身份 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bmetnPyB-1602213757579)(assets/1562050412953.png)] 1、获取公钥 1提供一个下载公钥的地址回话前让客户端去下载。缺点下载地址有可能是假的客户端每次在回话前都先去下载公钥也很麻烦 2回话开始时服务器把公钥发给客户端缺点黑客冒充服务器发送给客户端假的公钥 2、那有木有一种方式既可以安全的获取公钥又能防止黑客冒充呢 那就需要用到终极武器了SSL 证书申购 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uXiPyZA3-1602213757580)(assets/1562050492512.png)] 如上图所示在第 ② 步时服务器发送了一个SSL证书给客户端SSL 证书中包含的具体内容有 1证书的发布机构CA 2证书的有效期 3公钥 4证书所有者 5签名 ……… 3、客户端在接受到服务端发来的SSL证书时会对证书的真伪进行校验以浏览器为例说明如下 1首先浏览器读取证书中的证书所有者、有效期等信息进行一一校验 2浏览器开始查找操作系统中已内置的受信任的证书发布机构CA与服务器发来的证书中的颁发者CA比对用于校验证书是否为合法机构颁发 3如果找不到浏览器就会报错说明服务器发来的证书是不可信任的。 4如果找到那么浏览器就会从操作系统中取出 颁发者CA 的公钥然后对服务器发来的证书里面的签名进行解密 5浏览器使用相同的hash算法计算出服务器发来的证书的hash值将这个计算的hash值与证书中签名做对比 6对比结果一致则证明服务器发来的证书合法没有被冒充 7此时浏览器就可以读取证书中的公钥用于后续加密了 4、所以通过发送SSL证书的形式既解决了公钥获取问题又解决了黑客冒充问题一箭双雕HTTPS加密过程也就此形成 所以相比HTTPHTTPS 传输更加安全 1 所有信息都是加密传播黑客无法窃听。 2 具有校验机制一旦被篡改通信双方会立刻发现。 3 配备身份证书防止身份被冒充。 3、HTTPS 总结 综上所述相比 HTTP 协议HTTPS 协议增加了很多握手、加密解密等流程虽然过程很复杂但其可以保证数据传输的安全。所以在这个互联网膨胀的时代其中隐藏着各种看不见的危机为了保证数据的安全维护网络稳定建议大家多多推广HTTPS。 HTTPS 缺点 SSL 证书费用很高以及其在服务器上的部署、更新维护非常繁琐HTTPS 降低用户访问速度多次握手网站改用HTTPS 以后由HTTP 跳转到 HTTPS 的方式增加了用户访问耗时多数网站采用302跳转HTTPS 涉及到的安全算法会消耗 CPU 资源需要增加大量机器https访问过程需要加解密 4、构建私有的 CA 机构了解 1、CA 介绍 CACertificate Authority证书颁发机构主要负责证书的颁发、管理以及归档和吊销。证书内包含了拥有证书者的姓名、地址、电子邮件帐号、公钥、证书有效期、发放证书的CA、CA的数字签名等信息。证书主要有三大功能加密、签名、身份验证。 2、构建私有 CA 1、检查安装 openssl [roothttps-ca ~]# rpm -qa openssl如果未安装 [roothttps-ca ~]# yum install openssl openssl-devel2、查看配置文件 openssl 配置/etc/pki/tls/openssl.cnf有关CA的配置。如果服务器为证书签署者的身份那么就会用到此配置文件此配置文件对于证书申请者是无作用的。 [roothttps-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 certname_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 orderingpolicy policy_match #policy_match策略生效# For the CA policy [ policy_match ] countryName match #国家match表示申请者的申请信息必须与此一致 stateOrProvinceName match #州、省 organizationName match #组织名、公司名 organizationalUnitName optional #部门名称optional表示申请者可以的信息与此可以不一致 commonName supplied emailAddress optional# For the anything policy # At this point in time, you must list all acceptable object # types. [ policy_anything ] #由于定义了policy_match策略生效所以此策略暂未生效 countryName optional stateOrProvinceName optional localityName optional organizationName optional organizationalUnitName optional commonName supplied emailAddress optional3、根证书服务器目录 根CA服务器因为只有 CA 服务器的角色所以用到的目录只有/etc/pki/CA 网站服务器只是证书申请者的角色所以用到的目录只有/etc/pki/tls 4、创建所需要的文件 [roothttps-ca ~]# cd /etc/pki/CA/ [roothttps-ca CA]# ls certs crl newcerts private [roothttps-ca CA]# touch index.txt #创建生成证书索引数据库文件 [roothttps-ca CA]# ls certs crl index.txt newcerts private [roothttps-ca CA]# echo 01 serial #指定第一个颁发证书的序列号 [roothttps-ca CA]# ls certs crl index.txt newcerts private serial [roothttps-ca CA]# 5、创建密钥 在根CA服务器上创建密钥密钥的位置必须为/etc/pki/CA/private/cakey.pem这个是openssl.cnf中中指定的路径只要与配置文件中指定的匹配即可。 [roothttps-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是最顶级的认证机构没有人能够认证他所以只能自己认证自己生成自签名证书。 [roothttps-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 servers hostname) []:ca.qf.com Email Address []: [roothttps-ca CA]# ls cacert.pem certs crl index.txt newcerts private serial-new: 生成新证书签署请求 -x509: 专用于CA生成自签证书 -key: 生成请求时用到的私钥文件 -days n 证书的有效期限 -out /PATH/TO/SOMECERTFILE: 证书的保存路径7、下载安装证书 /etc/pki/CA/cacert.pem就是生成的自签名证书文件使用 SZ/xftp工具将他导出到窗口机器中。然后双击安装此证书到受信任的根证书颁发机构 [roothttps-ca CA]# yum install -y lrzsz [roothttps-ca CA]# sz cacert.pem[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gNGfOzMW-1602213757582)(assets/1562117752276.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-maF3KJNj-1602213757583)(assets/1562117778176.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4aSl3e6f-1602213757584)(assets/1562118358230.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5EBOO0vO-1602213757586)(assets/1562118410144.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LTm1tUYS-1602213757587)(assets/1562118451555.png)] 3、客户端CA 证书申请及签名 1、检查安装 openssl [rootnginx-server ~]# rpm -qa openssl如果未安装安装 openssl [rootnginx-server ~]# yum install openssl openssl-devel2、客户端生成私钥文件 [rootnginx-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) [rootnginx-server ~]# cd /etc/pki/tls/private/ [rootnginx-server private]# ls www.qf.com.key [rootnginx-server private]#3、客户端用私钥加密生成证书请求 [rootnginx-server private]# ls ../ cert.pem certs misc openssl.cnf private [rootnginx-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 servers 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 []: [rootnginx-server private]# ls ../ cert.pem certs misc openssl.cnf private www.qf.com.csr [rootnginx-server private]#CSR(Certificate Signing Request)包含了公钥和名字信息。通常以.csr为后缀是网站向CA发起认证请求的文件是中间文件。 在这一命令执行的过程中系统会要求填写如下信息 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-faJ8gSrT-1602213757588)(assets/1562059278073.png)] 最后把生成的请求文件/etc/pki/tls/www.qf.com.csr传输给CA ,这里我使用scp命令通过ssh协议将该文件传输到CA下的/etc/pki/CA/private/目录 [rootnginx-server private]# cd ../ [rootnginx-server tls]# scp www.qf.com.csr 10.0.105.181:/etc/pki/CA/private root10.0.105.181s password: www.qf.com.csr 100% 997 331.9KB/s 00:00 4、CA 签署证书 [roothttps-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 Certificate Details:Serial Number: 1 (0x1)ValidityNot Before: Jul 3 10:12:23 2019 GMTNot After : Jul 2 10:12:23 2020 GMTSubject:countryName CNstateOrProvinceName BEIJINGorganizationName QForganizationalUnitName OPTcommonName www.qf.comX509v3 extensions:X509v3 Basic Constraints: CA:FALSENetscape Comment: OpenSSL Generated CertificateX509v3 Subject Key Identifier: E3:AC:1A:55:2B:28:B9:80:DC:9C:C2:13:70:53:27:AD:3D:44:8F:D3X509v3 Authority Key Identifier: keyid:5D:2A:81:B2:E7:8D:D8:88:E5:7B:94:CA:75:65:9C:82:2B:A9:B2:3CCertificate is to be certified until Jul 2 10:12:23 2020 GMT (365 days) Sign the certificate? [y/n]:y1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated证书通常以.crt为后缀表示证书文件 1、可能遇到的问题 [roothttps-ca private]# cd [roothttps-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里面要求其一致修改organizationNamesupplied 修改 /etc/pki/tls/openssl.cnf [roothttps-ca ~]# vim /etc/pki/tls/openssl.cnf policy policy_match82 83 # For the CA policy84 [ policy_match ]85 countryName match86 stateOrProvinceName match87 organizationName supplied88 organizationalUnitName optional89 commonName supplied90 emailAddress optional2、查看生成的证书的信息 [roothttps-ca ~]# openssl x509 -in /etc/pki/CA/certs/www.qf.com.ctr -noout -subject subject /CCN/STBEIJING/OQF/OUOPT/CNwww.qf.com3、将生成的证书发放给请求客户端 [roothttps-ca ~]# cd /etc/pki/CA/certs/ [roothttps-ca certs]# scp www.qf.com.ctr 10.0.105.199:/etc/pki/CA/certs/ root10.0.105.199s password: www.qf.com.ctr 100% 4422 998.3KB/s 00:00 测试: nginx-client(充当服务端) [rootlocalhost ~]# cd /etc/pki/ [rootlocalhost pki]# ls CA ca-trust java nssdb nss-legacy rpm-gpg rsyslog tls [rootlocalhost pki]# cd CA/ [rootlocalhost CA]# ls certs crl newcerts private [rootlocalhost CA]# cd certs/ [rootlocalhost certs]# ls www.qf.com.ctr [rootlocalhost certs]# pwd /etc/pki/CA/certs [rootlocalhost certs]# ls www.qf.com.ctr [rootlocalhost certs]# mv www.qf.com.ctr www.qf.com.crt [rootlocalhost certs]# ls www.qf.com.crt [rootlocalhost certs]# pwd /etc/pki/CA/certs [rootlocalhost certs]# find / -name *.key /etc/pki/tls/private/www.qf.com.key /usr/share/doc/openssh-7.4p1/PROTOCOL.key [rootlocalhost certs]# find / -name *.ctr还是在这台机器安装nginx并且配置证书: rootlocalhost conf.d]# pwd /etc/nginx/conf.d [rootlocalhost 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_protocols SSLv2 SSLv3 TLSv1;ssl_ciphers ALL:!ADH:!EXPORT56:RC4RSA:HIGH:MEDIUM:LOW:SSLv2:EXP;ssl_prefer_server_ciphers on;location / {root /usr/share/nginx/html;index index.html index.htm;} } 保存重启 [rootlocalhost conf.d]# nginx -t [rootlocalhost conf.d]# nginx -s reload浏览器测试访问: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PsN0hxiy-1602213757590)(assets/1563288178855.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2CJ6spm2-1602213757591)(assets/1563288198981.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yQskaLCC-1602213757592)(assets/1563288213916.png)] 自己生成的证书成功 4、CA吊销证书 1、知道客户端吊销的证书的serial [roothttps-ca ~]# openssl x509 -in /etc/pki/tls/cert.pem -noout -serial -subject serial5EC3B7A6437FA4E0 subject /CNACCVRAIZ1/OUPKIACCV/OACCV/CES2、吊销证书 先根据客户提交的serial与subject信息对比检验是否与index.txt文件中的信息一致然后 [roothttps-ca ~]# openssl ca -revoke /etc/pki/CA/newcerts/01.pem3、生成吊销证书的编号 第一次吊销一个证书时才需要执行 [roothttps-ca ~]# echo 01 /etc/pki/CA/crlnumber4、更新证书吊销列表 [roothttps-ca ~]# openssl ca -gencrl -out thisca.crl5、查看证书吊销列表 [roothttps-ca ~]# openssl crl -in /root/thisca.crl -noout -text5、nginx HTTPS 部署实战 申请证书与认证证书下载与配置问题分析与总结 1、申请证书与认证 要搭建https服务首先需有SSL证书证书通常是在第三方申请在阿里云的安全服务中有SSL证书这一项可以在里面申请免费的证书 也可以在自己电脑中生成虽然也能完成加密但是浏览器是不认可的因此最好还是去第三方申请 1、证书申请 阿里云提供免费的证书不需要人工审核用来做测试是非常不错的选择申请地址如下URL。 https://common-buy.aliyun.com/?spm5176.2020520163.cas.1.1aa12b7aWWn20OcommodityCodecas#/buy免费型的证书隐藏的比较深想要申请免费证书需要先选择 1个域名-Symantec-免费型 ,所以读者这里需要注意一下如下图参考。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zR34LBD8-1602213757594)(assets/1562123381388.png)] 选择之后一直点击下一步便可购买完成免费购买证书之后笔者需要回到证书控制台在控制台有一个补全信息的链接地址需要通过此地址补充申请人的联系信息参考下图填写 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WmyFuFpN-1602213757595)(assets/1562123418824.png)] 2、域名验证 补全个人信息之后还需要给阿里云验证当前域名是属于本人的验证方式有两种第一种是通过dns解析认证第二种是通过上传验证文件认证这里采用的是验证文件认证首先需要下载文件如下图 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VX3XJRwD-1602213757597)(assets/1562129262162.png)] 在下载验证文件完成之后笔者需要把文件放到服务器中去这里提供一条复制命令 [rootweb ~]#scp ~/Downloads/fileauth.txt root192.168.43.34:~/将验证文件复制到服务器之后还需要将验证文件放到站点对应目录参考命令如下 [rootnginx ~]# cd /usr/share/nginx/html/ [rootnginx html]#mkdir -p /website/.well-known/pki-validation cp fileauth.txt /website/.well-known/pki-validation/ [rootnginx html]# cd vim /etc/nginx/nginx.conf server {listen 80;server_name localhost;location / {root /usr/share/nginx/html/website;}1、手动验证 手动验证的目的是首先确保文件位置放置是否正确可以通过访问站点的url是否成功进行判断比如笔者可以访问如下URL如果返回如果页面能够正常打开并且可以看到某些值则代表配置成功。 http://www.qf.com/.well-known/pki-validation/fileauth.txt2、通过阿里云来验证 在确保文件放置正确之后关键的是能让阿里云能访问到阿里云这里提供了一个检查配置的功能在下载验证文件页面有一个检测配置的链接单击之后便可进行检查如下图。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hse3FTNR-1602213757598)(assets/1562133394941.png)] 当点击 检查配置 之后如果阿里云能够正常访问则会在左侧给出提示现在可以返回证书列表在列表中可以看到当前状态为审核中如下图 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kW9oUGEj-1602213757600)(assets/1562133415788.png)] 审核因为不需要人为干预所以很快就能下发证书下发证书的时间大约是2分钟左右。 2、证书下载与配置 1、证书下载 证书签发之后可以在列表中可以看到状态栏中为 已签发 同时操作栏可以下载以及查看详情等如下图所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LwEwSBDL-1602213757601)(assets/1562133543812.png)] 点击下载后会跳转到下载详情页面在下载详情页可以选择自己相对应的web服务比如使用nginx当选择nginx之后下方还会很贴心的提示如何配置下载nginx配置文件。 下载配置文件之后需要将其解压解压之后可以看见里面包含了两个证书文件 xxx.key xxx.pem 接着需要把这两个证书文件给复制到服务器当中去首先需要在服务器创建对应的文件夹参考命令如下 [rootnginx ~]# cd /etc/nginx/ mkdir cert在服务器创建完成对应文件夹之后将证书文件复制到服务器中 [rootnginx ~]# ls 2447549_www.testpm.cn_nginx.zip [rootnginx ~]# unzip 2447549_www.testpm.cn_nginx.zip Archive: 2447549_www.testpm.cn_nginx.zip Aliyun Certificate Downloadinflating: 2447549_www.testpm.cn.pem inflating: 2447549_www.testpm.cn.key [rootnginx ~]# ls 2447549_www.testpm.cn.key 2447549_www.testpm.cn_nginx.zip 2447549_www.testpm.cn.pem [rootnginx ~]# cp 2447549_www.testpm.cn* /etc/nginx/cert/ [rootnginx ~]# cd /etc/nginx/cert/ [rootnginx cert]# mv 2447549_www.testpm.cn.key www.testpm.cn.key [rootnginx cert]# mv 2447549_www.testpm.cn.pem www.testpm.cn.pem2、证书配置 证书复制完成之后可以对nginx配置文件进行更改使用vim命令编辑nginx配置文件参考命令如下 [rootnginx ~]# cd /etc/nginx/conf.d/ [rootnginx conf.d]# cp default.conf default.conf.bak [rootnginx conf.d]# mv default.conf nginx_ssl.conf [rootnginx conf.d]# vim nginx_ssl.conf [rootnginx 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:RC4RSA:HIGH:MEDIUM:LOW:SSLv2:EXP;ssl_prefer_server_ciphers on;location / {root /usr/share/nginx/html;index index.html index.htm;} }3、重启Nginx 修改配置文件之后需要测试nginx配置文件是否正确 [rootnginx cert]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [rootnginx cert]# nginx -s reload [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tlQ18T6u-1602213757603)(assets/1562135276893.png)] 如果看到浏览器展示安全并且显示绿色就说明大功告成了! 6、nginx 性能优化 当我需要进行性能优化时说明我们服务器无法满足日益增长的业务。性能优化是一个比较大的课题需要从以下几个方面进行探讨 当前系统结构瓶颈了解业务模式性能与安全 1、当前系统结构瓶颈 首先需要了解的是当前系统瓶颈用的是什么跑的是什么业务。里面的服务是什么样子每个服务最大支持多少并发。比如针对nginx而言我们处理静态资源效率最高的瓶颈是多大能支持多少qps访问请求怎么得出系统当前的结构瓶颈 可以通过查看当前cpu负荷内存使用率进程使用率来做简单判断。还可以通过操作系统的一些工具来判断当前系统性能瓶颈如分析对应的日志查看请求数量。也可以通过nginx http_stub_status_module模块来查看对应的连接数总握手次数总请求数。也可以对线上进行压力测试来了解当前的系统能性能并发数做好性能评估。 2、了解业务模式 虽然我们是在做性能优化但还是要熟悉业务最终目的都是为业务服务的。我们要了解每一个接口业务类型是什么样的业务比如电子商务抢购模式这种情况平时流量会很小但是到了抢购时间流量一下子就会猛涨。也要了解系统层级结构每一层在中间层做的是代理还是动静分离还是后台进行直接服务。需要我们对业务接入层和系统层次要有一个梳理 3、性能与安全 性能与安全也是一个需要考虑的因素往往大家注重性能忽略安全或注重安全又忽略性能。比如说我们在设计防火墙时如果规则过于全面肯定会对性能方面有影响。如果对性能过于注重在安全方面肯定会留下很大隐患。所以大家要评估好两者的关系把握好两者的孰重孰轻以及整体的相关性。权衡好对应的点。 4、系统与nginx性能优化 大家对相关的系统瓶颈及现状有了一定的了解之后就可以根据影响性能方面做一个全体的评估和优化。 网络网络流量、是否有丢包网络的稳定性都会影响用户请求系统系统负载、饱和、内存使用率、系统的稳定性、硬件磁盘是否有损坏服务连接优化、内核性能优化、http服务请求优化都可以在nginx中根据业务来进行设置程序接口性能、处理请求速度、每个程序的执行效率数据库、底层服务 上面列举出来每一级都会有关联也会影响整体性能这里主要关注的是nginx服务这一层。 1、文件句柄 在linux/unix操作系统中一切皆文件我们的设备是文件文件是文件文件夹也是文件。当我们用户每发起一次请求就会产生一个文件句柄。文件句柄可以简单的理解为文件句柄就是一个索引。文件句柄就会随着请求量的增多,进程调用频繁增加那么产生的文件句柄也就会越多。 系统默认对文件句柄是有限制的不可能会让一个进程无限制的调用句柄。因为系统资源是有限的所以我们需要限制每一个服务能够使用多大的文件句柄。操作系统默认使用的文件句柄是1024个句柄。 2、设置方式 系统全局性修改用户局部性修改进程局部性修改 3、系统全局性修该和用户局部性修改 [rootnginx-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可以看到root和*root代表是root用户*代表的是所有用户后面的数字就是文件句柄大小。大家可以根据个人业务来进行设置。 4、进程局部性修改 [rootnginx-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; }worker_rlimit_nofile 是在进程上面进行限制。 5、cpu的亲和配置 cpu的亲和能够使nginx对于不同的work工作进程绑定到不同的cpu上面去。就能够减少在work间不断切换cpu把进程通常不会在处理器之间频繁迁移进程迁移的频率小来减少性能损耗。nginx 亲和配置 查看物理cpu [rootnginx-server ~]# cat /proc/cpuinfo | grep physical id | sort|uniq | wc -l查看cpu核心数 [rootnginx-server ~]# cat /proc/cpuinfo|grep cpu cores|uniq查看cpu使用率 [rootnginx-server ~]#top 回车后按 16、配置worker_processes [rootnginx-server ~]# vim /etc/nginx/nginx.conf 将刚才查看到自己cpu * cpu核心就是worker_processes worker_processes 2; #根据自己cpu核心数配置/这里也可以设置为auto7、cpu亲和配置 假如配置是2cpu每个cpu是8核。配置如下 worker_processes 16;1010101010101010 0101010101010101;配置完成后可以通过下面命令查看nginx进程配置在哪个核上 [rootnginx-server ~]# ps -eo pid,args,psr |grep [n]ginx在nginx 1.9版本之后就帮我们自动绑定了cpu; worker_cpu_affinity auto;5、nginx通用配置优化 #将nginx进程设置为普通用户为了安全考虑 user nginx; #当前启动的worker进程官方建议是与系统核心数一致 worker_processes 2; #方式一 第一个work进程绑定第一个cpu核心第二个work进程绑定到第二个cpu核心依次内推 直到第16个 #wokrer_cpu_affinity 0000000000000000 0000000000000001 0000000000000010 0000000000000100 ... 1000000000000000#方式二当 worker_processes 2 时表明 第一work进程可以绑定第 2 4 6 8 10 12 14 16 核心那么第二work进程就绑定 奇数核心 #worker_cpu_affinity 1010101010101010 0101010101010101;#方式三就是自动分配绑定 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 * 1024worker_connections 10240; }http {include /etc/nginx/mime.types;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 modulegzip on; #文件压缩默认可以打开gzip_disable MSIE [1-6]\.; #对于有些浏览器不能识别压缩需要过滤如ie6gzip_http_version 1.1;include /etc/nginx/conf.d/*.conf; }6、ab接口压力测试工具 ab是Apache超文本传输协议(HTTP)的性能测试工具。其设计意图是描绘当前所安装的Apache的执行性能主要是显示你安装的Apache每秒可以处理多少个请求。 [rootnginx-server ~]# yum install httpd-tools [rootnginx-server ~]# ab -n 2000 -c 2 http://127.0.0.1/ -n 总的请求数 -c 并发数 -k 是否开启长连接1、参数选项 -n即requests用于指定压力测试总共的执行次数 -c即concurrency用于指定的并发数 -t即timelimit等待响应的最大时间(单位秒) -b即windowsizeTCP发送/接收的缓冲大小(单位字节) -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信息例如Apache1234(可以重复该参数选项以添加多个) -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 -help2、内容解释 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% 43180% 51690% 60095% 84698% 157199% 1593100% 1619 (longest request)3、示例演示 注意事项 ● 测试机与被测试机要分开 ● 不要对线上的服务器做压力测试 ● 观察测试工具ab所在机器以及被测试的前端机的CPU、内存、网络等都不超过最高限度的75% [rootnginx-server ~]# ab -n 50 -c 2 http://www.testpm.cn/ This is ApacheBench, Version 2.3 $Revision: 1430300 $ Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking www.testpm.cn (be patient).....doneServer Software: nginx/1.16.0 Server Hostname: www.testpm.cn Server Port: 80Document Path: / Document Length: 612 bytesConcurrency Level: 2 Time taken for tests: 2.724 seconds Complete requests: 50 Failed requests: 0 Write errors: 0 Total transferred: 42250 bytes HTML transferred: 30600 bytes Requests per second: 18.35 [#/sec] (mean) Time per request: 108.968 [ms] (mean) Time per request: 54.484 [ms] (mean, across all concurrent requests) Transfer rate: 15.15 [Kbytes/sec] receivedConnection Times (ms)min mean[/-sd] median max Connect: 42 52 17.3 46 137 Processing: 43 54 20.8 47 170 Waiting: 42 53 20.7 47 170 Total: 84 106 28.9 93 219Percentage of the requests served within a certain time (ms)50% 9366% 9675% 10180% 13090% 15395% 16198% 21999% 219100% 219 (longest request) 4、ab性能指标 1、吞吐率Requests per second 服务器并发处理能力的量化描述单位是reqs/s指的是在某个并发用户数下单位时间内处理的请求数。某个并发用户数下单位时间内能处理的最大请求数称之为最大吞吐率。记住吞吐率是基于并发用户数的。这句话代表了两个含义 ● 吞吐率和并发用户数相关● 不同的并发用户数下吞吐率一般是不同的计算公式总请求数/处理完成这些请求数所花费的时间即 Request per secondComplete requests/Time taken for tests必须要说明的是这个数值表示当前机器的整体性能值越大越好 2、并发连接数The number of concurrent connections 并发连接数指的是某个时刻服务器所接受的请求数目简单的讲就是一个会话。 3、并发用户数Concurrency Level 要注意区分这个概念和并发连接数之间的区别一个用户可能同时会产生多个会话也即连接数。在HTTP/1.1下IE7支持两个并发连接IE8支持6个并发连接FireFox3支持4个并发连接所以相应的我们的并发用户数就得除以这个基数。 4.用户平均请求等待时间Time per request 计算公式处理完成所有请求数所花费的时间/总请求数/并发用户数即 Time per requestTime taken for tests/Complete requests/Concurrency Level5.服务器平均请求等待时间Time per request:across all concurrent requests 计算公式处理完成所有请求数所花费的时间/总请求数即 Time taken for/testsComplete requests可以看到它是吞吐率的倒数。同时它也等于用户平均请求等待时间/并发用户数即 Time per request/Concurrency Level7、特例 https 为什么慢把nginx 跑到 qat 卡上 Intel QAT 助力 Nginx 压缩处理 1、什么是Intel® QAT Intel® QuickAssist Technology是Intel®公司提供的一种高性能数据安全和压缩的加速方案。该方案利用QAT芯片分担对称/非对称加密计算,DEFLATE无损压缩等大计算量的任务来降低CPU使用率并提高整体平台性能。该方案可以主板芯片独立的PCI-E加速卡或者SOC三种方式部署。 QAT支持硬件加速Deflate无损压缩算法在处理海量数据时QAT在不增加CPU开销的前提下通过压缩来减少需要传输和存盘的数据量从而减少了网络带宽和磁盘读写的开销最终提高了整体的系统性能。 例如在Web Serer上使用QAT硬件加速压缩处理可将CPU从繁重的压缩计算中解放出来以处理更多的连接请求。 2、什么是Nginx Web Server Nginx发音同engine x是一款使用异步框架的高性能Web服务器相较于Apache、lighttpd等其他Web ServerNginx具有占有内存少稳定性高等优势。根据Netcraft 2018年一月的Web Server市场调查报告 Nginx的装机率达25.39%位列Web Server市场第三并在持续增长中[1]。 Nginx中的GZIP模块实现了对HTTP压缩的支持该模块通过调用Zlib库实现对网页内容进行Deflate压缩。由于使用软件实现无损压缩需要消耗大量CPU运算时间进行压缩运算。 然而在大并发流量的网站接入层的Nginx需要处理相当多的业务包括https连接建立安防攻击流量镜像链路追踪等等。使得CPU进行HTTP压缩处理成为Web Server最主要的CPU开销进而限制了网站支持最大并发连接数。根据客户提供的接入层流量模型分析来看 GZIP 单个模块 CPU 消耗占比达到 15%-20% 左右且占比呈上升趋势。所以若能使用加速Nginx的网页压缩处理可以极大的提高网站性能 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gptSl1T1-1602213757606)(assets/1562145313085.png)] 3、Zlib-SHIM API Zlib作为广泛部署的软件压缩库提供Deflate压缩的软件实现被包括Nginx在内的广大应用程序所采用。Intel® QuickAssist Technology提供了与Zlib类似接口的Zlib-SHIM 软件库来适配上层应用减少了应用迁移的开发量。该库提供了与Zlib一致的Deflate API只需对源代码做少量修改并将原有应用与Zlib-SHIM编译链接就能使用QuickAssit提供的硬件加速功能。 Zlib-SHIM库实现了DeflateInitDeflateInit2DeflateDeflateEnd等常用API并支持Stateful和Stateless压缩可以替代Zlib的绝大部分功能。 Zlib-SHIM提供了Deflate API同步模式接口调用程序阻塞在Deflate API上直到压缩任务完成而其内部实现调用了异步模式API即在CPU上运行的QAT驱动程序向QAT协处理器提交了一个数据压缩请求后即返回期间使用Polling 接口定期检查压缩请求是否完成等到QAT硬件完成压缩处理后通过回调函数通知CPU端的应用程序进行下一步操作。这样的设计, 在不影响上层应用程序原有设计的前提下实现了高并发场景中CPU和QAT的协同工作CPU专注于网络链接处理而QAT处理复杂的压缩计算, 各司其职最终提高了系统整体性能。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iDptf3kT-1602213757607)(assets/1562145340420.png)] 4、Zlib-SHIM工作原理 采用这种异步模式API实现对外的同步接口在实现上有三种方法Direct PollingIndirect Polling Spinning和Indirect Polling Semaphore模式。 使用Direct Polling模式时Deflate调用者会在当前线程直接调用Polling接口若压缩结果还没有返回则休眠一段时间后再检查直到压缩成功后Deflate 调用才返回。Direct Polling模式下CPU开销小但是单个Request从发出到返回结果延迟较长只有在多进程多线程高并发模式下才能充分发挥QAT的压缩性能。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5WAhrJGz-1602213757608)(assets/1562145358390.png)] Direct polling 模式流程图 Indirect Polling模式是通过创建一个轮询线程定期调用Polling接口来检查压缩请求在QAT 协处理器中的执行状态轮询线程一旦发现有请求执行完毕就通过回调函数Callback Function通知CPU端程序进行后续处理。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-03WwbdSZ-1602213757610)(assets/1562145381885.png)] Indirect pooling模式时序图 根据回调通知方式的不同Indirect Polling模式又可细分为Spinning模式和Semaphore模式 Spinning模式中Deflate函数调用线程定期轮询与回调函数共享的任务完成标志若尚未完成则主动休眠若已完成则进行后续处理。 Semaphore模式中Deflate调用线程通过互斥锁来隔离与轮询线程共享的任务完成标志的访问操作若任务尚未完成则Deflate调用线程休眠一旦任务完成轮询线程中的回调函数会通过信号量唤醒调用线程进行后续处理。 采用Indirect Polling模式无论Deflate调用数目多少都需要启动轮询线程在压缩请求数不大的情况下增加了CPU的Polling开销但是当压缩任务作为CPU的主要任务时可以减少不必要的Polling调用提高CPU的使用率。 Nginx为了实现高性能的高并发处理能采用了单进程单线程异步工作模式如果使用Indirect Polling模式就需要在每个Nginx Worker进程中创建一个轮询线程 (Polling Thread), 从而增加了线程间切换的开销和共享数据的互斥的操作, 所以在Nginx和Zlib-SHIM集成中我们使用了Direct Polling Mode。 5、USDM优化 USDM是QAT为了优化内存使用效率而提供的用户态内存管理工具。由于QAT和CPU之前需要频繁高速的交换数据使用传统的Memory Copy方式不仅效率低而且消耗CPU资源所以QAT支持DMA方式进行数据传输CPU只需分配好拥有物理连续内存的输入地址和输出地址QAT会自动完成的从该地址的输入读取或输出写回的操作。QAT Driver中的USDM模块利用了Linux 内核提供的Huge-Page特性来获得物理地址连续内存并使用SLAB算法进行内存管理。 对于每一个新分配的Huge-PageUSDM会对应地在Devfs中新建一个临时文件并通过mmap将临时文件描述符与新申请到的Huge-Page关联上当USDM发现该Huge-Page上所有内存块均已释放并不需将其留作缓存时就关闭该临时文件以释放Huge-Page。当Zlib-SHIM运行过程中需要使用连续的内存时就使用USDM Alloc接口从内存池中申请连续物理地址的内存, 并在发送压缩请求时将申请到的连续内存地址作为参数传递给QAT。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8zU1jqZc-1602213757611)(assets/1562145408201.png)] 6、测试结果 基于以上设计的Zlib-SHIM可以很方便的替换原有Zlib库使得调用者可以方便的利用QAT进行压缩加速。 在实际应用中 客户就是将Zlib-SHIM与基于Nginx定制的Web Server进行集成在接入层的性能优化上取得了理想的效果。 客户的Web Server运行在Intel® Xeon® CPU上CPU型号Intel® Xeon® CPU E5-2650 v2 2.60GHz 32核 内核2.6.32 Zlib版本zlib-1.2.8 QAT驱动版本intel-qatOOT40052 在相同网络流量条件下未开启QAT加速的CPU平均使用率为48%左右而开启QAT加速后CPU平均使用率为41%左右。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9O45IUfF-1602213757613)(assets/1562145434782.png)] 综合以上数据Web Server在QPS 10K的压力下使用QAT加速后可以节省CPU 15%左右且Gzip基本上完全卸载、随着其占比变高优化效果将越好。 7、总结 拥有和Zlib相同API接口的Zlib-SHIM可以很方便的与上层应用集成利用QAT的硬件加速性能。此外为了最大限度的发挥QAT的新能Intel还提供了使用专有API的QATzip软件库相应的Nginx module也在开发中相信不久的将来集成QATzip的Web Server能够提供更好的性能。 性能测试中使用的软件和工作负荷可能仅在英特尔微处理器上进行了性能优化。诸如SYSmark和MobileMark等测试均系基于特定计算机系统、硬件、软件、操作系统及功能。上述任何要素的变动都有可能导致测试结果的变化。请参考其他信息及性能测试包括结合其他产品使用时的运行性能以对目标产品进行全面评估。
http://www.hkea.cn/news/14557158/

相关文章:

  • 怎样做网站检索数据分析重庆交通网站建设
  • 仿抖音网站开发片头网站
  • 学生网站做兼职冬镜seo
  • 黑群晖的做网站文件岳阳网站界面设计
  • 学会python做网站自己怎么设计装修房子
  • 度假村网站模板深圳博大建设集团网站
  • 网站被收录金湖网站制作
  • 深圳英文网站建设专业公司网站建设 发短信文案
  • 网站建设一般的流程做搜狗pc网站
  • 网站建设 软件烟台专业网站建设公司哪家好
  • 手机网站微信网站开发成都网站开发排名
  • 做网站驻马店平邑建设局网站首页
  • 成都网站建设 四川冠辰网站建设镇江网站建设企业
  • 云南网站优化哪家好一级域名二级域名哪个好
  • 宁波公司网站首页优化网站设计制作从哪
  • 官方网站重要性福州网站公司
  • 建站成本龙华网站建设哪家公司好
  • ps怎么做网站特效广州建设手机网站
  • 盱眙网站制作网站开发双语
  • 织梦做的网站图片路径在哪做装修网站
  • 专业电商网站pico笔克品牌介绍
  • 大型网站都怎么做推广个人网站建设图片素材
  • 电商网站开发设计文档小程序制作119
  • 建设个读书网站大约需要投入多少钱安康市相亲平台
  • 移动网站建设制作公司小型影视网站源码
  • 网站企业有哪些流感用什么药更好
  • 上海企业网站建设公司哪家好货物公司网站建设方案
  • 国内美食网站欣赏网站发稿平台
  • 烟台网站建设科技公司宿迁房产网58同城网
  • 泉州响应式网站建设招商网站平网站平台