nginx cm
Nginx服务
一、HTTP 属于应用层
- 80端口对应的服务是Nginx,Apache服务
- Nginx,Apache服务用的协议是http协议
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。
HTTP工作在 TCP/IP协议体系中的TCP协议上,是一个基于 TCP/IP 通信协议来传递数据(HTML 文件、图片文件、查 询结果等)。
1、HTTP 工作原理
HTTP协议工作于客户端-服务端架构上。浏览器作为HTTP客户端通过URL向HTTP服务端(web服务端)发送的请求报文,这个请求报文包含了请求方法、URL协议版本、请求头部和请求数据。服务器以一个状态行作为响应,响应的内容包括协议的版本、成功或错误代码、服务器信息、响应头部和响应数据。
Web服务器有:Nginx,Apache服务器,IIS服务器(Internet Information Services)等。
Web服务器根据接收到的请求后,向客户端发送响应信息。
HTTP默认端口号为80,但是你也可以改为其他端口。
CGI
通用网关接口(Common Gateway Interface/CGI)描述了客户端和服务器程序之间传输数据的一种标准,可以让一个客户端,从网页浏览器向执行在网络服务器上的程序请求数据。CGI 程序可以用任何脚本语言或者是完全独立编程语言实现,只要这个语言可以在这个系统上运行
2、HTTP 消息结构
HTTP是基于客户端/服务端(C/S)的架构模型,通过一个可靠的链接来交换信息,是一个无状态的请求/响应协议。HTTP是无状态协议,意味着服务器不会保留关于客户端或请求的任何信息,每个请求都是独立的,即使是在持久连接(如Keep-Alive)的情况下也是如此。
一个HTTP"客户端"是一个应用程序(Web浏览器或其他任何客户端),通过连接到服务器达到向服务器发送一个或多个HTTP的请求的目的。
一个HTTP"服务器"同样也是一个应用程序(通常是一个Web服务,如Apache Web服务器或IIS服务器等),通过接收客户端的请求并向客户端发送HTTP响应数据。
HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。
3、客户端请求消息
HTTP 报文可以分为两类:请求报文(request message)和响应报文(response message),两者的基本报文结构相同。
客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行(request line)、请求头部(header)、空行和请求数据四个部分组成,下图给出了请求报文的一般格式。

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

实例
下面实例是一点典型的使用GET来传递数据的实例:
客户端请求:
# curl -v http://www.testpm.cn
Connected to www.testpm.cn (47.244.247.240) port 80 (#0)
> GET /hello.txt HTTP/1.1 # 请求方式与版本协议。
> User-Agent: curl/7.29.0 #用什么客户端访问
> Host: www.testpm.cn #主机名,域名。主机和端口号,
> Accept: */* #匹配什么文件类型,“*” 是通用匹配。匹配所有类型
服务端响应:
< HTTP/1.1 200 OK #请求返回的状态码
< Server: nginx/1.16.0 #请求的服务和版本号
< Date: Thu, 04 Jul 2019 08:19:40 GMT #当前时间,北京时间为GMT+8小时
< Content-Type: text/plain #mime类型,test/plain:普通文本,比如image/png...、video
< Content-Length: 12 #内容的长度
< Last-Modified: Thu, 04 Jul 2019 08:13:25 GMT #最后修改时间
< Connection: keep-alive #是否支持长连接
< ETag: "5d1db525-c" #标识,每次访问如果与最开始的值一样返回304否则校验不一致返回200
< Accept-Ranges: bytes #接受的范围单位
输出结果:
hello world
经典面试题(重点)
在浏览器地址栏键入 URL,按下回车之后会经历什么?
浏览器向 DNS 服务器请求解析该 URL 中域名对应的 IP 地址;
解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立 TCP 连接;
服务器发出读取文件的HTTP请求(URL 中域名后面部分对应的文件),(该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器);
服务器对浏览器请求作出响应,并把对应的HTML文本发送给浏览器;
释放TCP连接;
浏览器将HTML文档渲染并显示内容;
5、HTTP 请求方法
-
检查 Web 访问情况
-
curl -I ip地址 向指定的 IP 地址发送 HTTP 请求,仅获取响应的头部信息
-
**curl -v ip地址 **可以看网站的响应主体,展示与服务器之间的详细交互信息
根据HTTP标准,HTTP请求可以使用多种请求方法。
HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
以下是常见的 HTTP 请求方法(HTTP Request Methods) 及其核心作用、应用场景和特性总结:
1. GET
- 用途:获取资源(只读操作)。
- 特点:
- 安全(Safe):不会修改服务器资源。
- 示例:
- 访问网页:
GET /index.html - 查询用户信息:
GET /users/123
- 访问网页:
- 注意:
- 参数通过 URL 传递(如
/users?id=123)。 - 不应用于提交敏感数据(URL 可能被日志记录)。
- 参数通过 URL 传递(如
2. POST
- 用途:提交数据(通常用于创建资源或触发操作)。
- 示例:
- 提交表单:
POST /login(提交用户名密码)。 - 创建订单:
POST /orders(提交订单数据)。
- 提交表单:
3. PUT
- 用途:替换或更新整个资源(需提供完整数据)。
- 特点:
- 不安全(Non-Safe):修改资源。
- 示例:
- 更新用户信息:
PUT /users/123(提供完整的用户数据)。
- 更新用户信息:
4. DELETE
- 用途:删除指定资源。
- 特点:
- 不安全(Non-Safe):删除资源。
- 示例:
- 删除文章:
DELETE /posts/456
- 删除文章:
5. PATCH
- 用途:部分更新资源(仅提交需修改的字段)。
- 特点:
- 不安全(Non-Safe):修改资源。
6. HEAD
- 用途:获取资源的元数据(如响应头,不返回响应体)。
- 特点:
- 安全(Safe):不修改资源。
- 示例:
- 检查资源是否存在:
HEAD /files/report.pdf - 验证缓存有效性(通过
Last-Modified或ETag头)。
- 检查资源是否存在:
7. OPTIONS
- 用途:查询服务器支持的请求方法。
- 示例:
- 获取
/users支持的 HTTP 方法:OPTIONS /users - 响应头包含:
Allow: GET, POST, HEAD
- 获取
8. TRACE
- 用途:回显客户端请求(用于调试)。
9. CONNECT
- 用途:建立隧道连接(通常用于 HTTPS 代理)。
- 示例:
- 代理服务器中转 HTTPS 请求:
CONNECT example.com:443 HTTP/1.1
- 代理服务器中转 HTTPS 请求:
总结对比表
| 方法 | 用途 | 安全 | 幂等 | 请求体支持 |
|---|---|---|---|---|
| GET | 获取资源 | ✔️ | ✔️ | ❌ |
| POST | 提交数据 | ❌ | ❌ | ✔️ |
| PUT | 替换或创建资源 | ❌ | ✔️ | ✔️ |
| DELETE | 删除资源 | ❌ | ✔️ | ❌ |
| PATCH | 部分更新资源 | ❌ | △ | ✔️ |
| HEAD | 获取元数据 | ✔️ | ✔️ | ❌ |
| OPTIONS | 查询支持的方法 | ✔️ | ✔️ | ❌ |
| TRACE | 回显请求(调试) | ✔️ | ✔️ | ❌ |
| CONNECT | 建立隧道(如 HTTPS) | ❌ | ❌ | ✔️ |
核心概念
1. 安全性(Safe Methods)
- 定义:请求不会修改服务器资源(如 GET、HEAD、OPTIONS)。
- 意义:允许浏览器预加载或爬虫安全访问。
2. 幂等性(Idempotent Methods)
- 定义:多次请求效果相同(如 GET、PUT、DELETE)。
- 意义:网络超时后可安全重试。
掌握 HTTP 请求方法是构建高效、可靠 Web 应用和 API 的基础。正确使用方法可提升安全性、可维护性,并与 RESTful 设计原则保持一致。
6、HTTP 响应头信息
HTTP 响应字段(HTTP Response Headers)是服务器在返回 HTTP 响应时附加的元数据,用于向客户端(如浏览器)传递关于响应的附加信息。以下是常见的 HTTP 响应字段及其作用:
通用字段(General Headers)
- Cache-Control
- 用途:控制缓存行为(如
public,private,max-age,no-cache)。 - 示例:
Cache-Control: max-age=3600(缓存 1 小时)。
- 用途:控制缓存行为(如
- Connection
- 用途:管理网络连接(如
keep-alive或close)。 - 示例:
Connection: keep-alive(保持长连接)。
- 用途:管理网络连接(如
- Date
- 用途:响应生成的日期和时间(GMT 格式)。
- 示例:
Date: Tue, 15 Aug 2023 12:00:00 GMT。
响应字段(Response Headers)
- Status
- 用途:显示 HTTP 状态码和状态短语(实际由协议行传递,非显式头字段)。
- 示例:
HTTP/1.1 200 OK。
- Server
- 用途:标识服务器软件(如 Apache、Nginx)。
- 示例:
Server: nginx/1.18.0。
- Location
- 用途:重定向目标 URL(常用于
3xx状态码)。 - 示例:
Location: https://example.com/new-page。
- 用途:重定向目标 URL(常用于
- Set-Cookie
- 用途:向客户端设置 Cookie。
- 示例:
Set-Cookie: sessionId=abc123; Path=/; Secure。
- Retry-After
- 用途:客户端应等待多久后重试请求(用于
503服务不可用)。 - 示例:
Retry-After: 3600(1 小时后重试)。
- 用途:客户端应等待多久后重试请求(用于
实体字段(Entity Headers)
- Content-Type
- 用途:响应体的媒体类型(如
text/html,application/json)。 - 示例:
Content-Type: application/json; charset=utf-8。
- 用途:响应体的媒体类型(如
- Content-Length
- 用途:响应体的字节长度。
- 示例:
Content-Length: 1024。
- Content-Encoding
- 用途:响应体的压缩方式(如
gzip,br)。 - 示例:
Content-Encoding: gzip。
- 用途:响应体的压缩方式(如
- Content-Disposition
- 用途:指示客户端如何处理内容(如下载文件)。
- 示例:
Content-Disposition: attachment; filename="file.txt"。
- Last-Modified
- 用途:资源最后修改时间(用于缓存验证)。
- 示例:
Last-Modified: Tue, 15 Aug 2023 10:00:00 GMT。
- ETag
- 用途:资源版本的唯一标识符(用于缓存验证)。
- 示例:
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"。
安全相关字段(Security Headers)
- Strict-Transport-Security (HSTS)
- 用途:强制使用 HTTPS(防止降级攻击)。
- 示例:
Strict-Transport-Security: max-age=31536000; includeSubDomains。
- Content-Security-Policy (CSP)
- 用途:限制页面加载资源的来源(防止 XSS)。
- 示例:
Content-Security-Policy: default-src 'self'。
- X-Content-Type-Options
- 用途:禁止浏览器猜测 MIME 类型(防止 MIME 类型嗅探)。
- 示例:
X-Content-Type-Options: nosniff。
- X-Frame-Options
- 用途:阻止页面在
中加载(防止点击劫持)。 - 示例:
X-Frame-Options: DENY。
- 用途:阻止页面在
- Permissions-Policy
- 用途:控制浏览器功能(如摄像头、地理位置)的访问权限。
- 示例:
Permissions-Policy: geolocation=()(禁用地理位置)。
CORS 相关字段(跨域资源共享)
- Access-Control-Allow-Origin
- 用途:允许跨域请求的源(如
*或特定域名)。 - 示例:
Access-Control-Allow-Origin: https://example.com。
- 用途:允许跨域请求的源(如
- Access-Control-Allow-Methods
- 用途:允许的 HTTP 方法(如
GET,POST)。 - 示例:
Access-Control-Allow-Methods: GET, POST, OPTIONS。
- 用途:允许的 HTTP 方法(如
其他常用字段
- WWW-Authenticate
- 用途:定义身份验证方式(用于
401 Unauthorized)。 - 示例:
WWW-Authenticate: Basic realm="Access to site"。
- 用途:定义身份验证方式(用于
- Link
- 用途:定义资源之间的关系(如预加载)。
- 示例:
Link: ; rel=preload; as=style。
7、HTTP 状态码
当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应浏览器的请求。
HTTP状态码的英文为HTTP Status Code。
下面是常见的HTTP状态码:
- 200 - 请求成功
- 301 - 资源(网页等)被永久转移到其它URL
- 302 - 资源临时移动到新 URL(浏览器不会缓存)
- 304 - 资源未修改(客户端可使用缓存版本)
- 403 - 服务器拒绝请求(权限不足),做了访问控制
- 404 - 请求的资源(网页等)不存在
- 500及以上 - 内部服务器错误
- 502,504 - 代理出现了问题,nginx反向代理
- 503 - 服务器暂时不可用(如维护或过载)
HTTP状态码分类
HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。HTTP状态码共分为5种类型:

1xx(信息响应)
- 100 Continue
- 用途:客户端应继续发送请求的剩余部分(常用于大文件上传前的确认)。
- 示例:客户端发送
Expect: 100-continue,服务器确认可继续。
- 101 Switching Protocols
- 用途:服务器同意切换协议(如从 HTTP 升级到 WebSocket)。
- 示例:WebSocket 握手时返回此状态码。
2xx(成功响应)
- 200 OK
- 用途:请求成功,响应中包含请求的数据(如网页、JSON)。
- 示例:访问页面或 API 返回数据时常见。
- 201 Created
- 用途:资源已成功创建(常见于 POST 请求)。
- 示例:提交表单后返回新资源的 URL(如
Location: /users/123)。
- 202 Accepted
- 用途:请求已接受,但处理尚未完成(异步任务)。
- 示例:长时间任务(如视频转码)的初始响应。
- 204 No Content
- 用途:请求成功,但无返回内容(常见于 DELETE 或 PUT 请求)。
- 示例:删除资源后返回空响应。
- 206 Partial Content
- 用途:部分内容响应(用于分块下载或断点续传)。
- 示例:视频播放器请求指定字节范围时返回。
3xx(重定向响应)
- 301 Moved Permanently
- 用途:资源已永久移动到新 URL(浏览器会缓存重定向)。
- 示例:网站更换域名时使用
Location: https://new-domain.com。
- 302 Found
- 用途:资源临时移动到新 URL(浏览器不会缓存)。
- 示例:临时维护页面跳转。
- 304 Not Modified
- 用途:资源未修改(客户端可使用缓存版本)。
- 触发条件:客户端发送
If-Modified-Since或If-None-Match头,服务器验证后返回。
- 307 Temporary Redirect
- 用途:临时重定向(强制保持原请求方法,如 POST)。
- 示例:表单提交时临时跳转。
- 308 Permanent Redirect
- 用途:永久重定向(强制保持原请求方法)。
- 示例:API 路径永久迁移。
4xx(客户端错误)
- 400 Bad Request
- 用途:请求格式错误(如参数缺失、JSON 语法错误)。
- 示例:客户端发送了无效的请求体。
- 401 Unauthorized
- 用途:未提供有效身份验证凭证。
- 示例:访问需要登录的页面时未携带 Token。
- 403 Forbidden
- 用途:服务器拒绝请求(权限不足)。
- 示例:普通用户尝试访问管理员页面。
- 404 Not Found
- 用途:请求的资源不存在。
- 示例:访问的 URL 路径错误或资源已被删除。
- 405 Method Not Allowed
- 用途:请求方法不被允许(如对只支持 GET 的接口发送 POST)。
- 示例:
Allow: GET, HEAD标明支持的 HTTP 方法。
- 408 Request Timeout
- 用途:服务器等待请求超时。
- 示例:客户端上传大文件时网络中断。
- 409 Conflict
- 用途:请求与服务器当前状态冲突(如重复提交)。
- 示例:修改资源时版本号冲突。
- 413 Payload Too Large
- 用途:请求体超过服务器限制。
- 示例:上传文件超过
nginx的client_max_body_size。
- 429 Too Many Requests
- 用途:客户端请求频率过高。
- 示例:API 限流时返回
Retry-After: 60。
5xx(服务器错误)
- 500 Internal Server Error
- 用途:服务器内部错误(未具体说明的通用错误)。
- 示例:后端代码抛出未捕获的异常。
- 501 Not Implemented
- 用途:服务器不支持请求的功能。
- 示例:客户端请求了服务器未实现的 HTTP 方法。
- 502 Bad Gateway
- 用途:网关或代理服务器从上游服务器收到无效响应。
- 示例:Nginx 作为反向代理时,后端服务崩溃。
- 503 Service Unavailable
- 用途:服务器暂时不可用(如维护或过载)。
- 示例:高流量时返回
Retry-After: 3600。
- 504 Gateway Timeout
- 用途:网关或代理服务器等待上游响应超时。
- 示例:后端服务处理时间过长,导致 Nginx 超时。
- 505 HTTP Version Not Supported
- 用途:服务器不支持请求的 HTTP 版本。
- 示例:客户端使用 HTTP/3,但服务器仅支持 HTTP/1.1。
其他特殊状态码
- 418 I’m a teapot
- 用途:玩笑状态码(来自 1998 年愚人节 RFC 文档)。
- 示例:用于测试或幽默场景。
- 451 Unavailable For Legal Reasons
- 用途:因法律原因不可访问(如政府审查)。
- 示例:某些国家/地区限制访问特定内容。
常见应用场景
- 调试 API
- 通过状态码快速定位问题:
400:检查请求参数格式。401:验证 Token 或 Cookie。403:检查用户权限。500:查看服务器日志。
- 通过状态码快速定位问题:
- SEO 优化
- 使用
301而非302重定向以传递页面权重。 - 避免链式重定向(如多次跳转)影响爬虫效率。
- 使用
- 缓存控制
304可减少重复传输,提升性能。- 结合
Cache-Control和ETag实现高效缓存策略。
二、nginx 进阶基础
1、nginx 介绍
- 高性能、高并发、高扩展,地址重写,负载均衡,是一个web服务器和反向代理服务器,消耗系统资源低

**Nginx (engine x) 是一个轻量级,高性能的 HTTP 和 反向代理 服务,也是一个IMAP/POP3/SMTP服务。因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。其特点是占有内存少,并发能力强,**事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
在高连接并发的情况下,Nginx是Apache服务器不错的替代品。
创始人伊戈尔·赛索耶夫

2、为什么选择 nginx(优势)
1.高并发,高性能---采用epoll模型监控所有连接,采用异步,非阻塞的的方式实现的请求处理
2.高可靠---可以7*24小时不间断运行
3.可扩展性强--模块化设计,使得添加模块非常的平稳。
4.热部署--可以在不停止服务器的情况下升级nginx
5.BSD许可证--nginx不止开源免费的我们还可以更具实际需求进行定制修改源代码
Nginx 是一个高性能的 Web 和反向代理服务器, 它具有有很多非常优越的特性:
单机环境下参考服务器配置。 并发连接数在7000+ -8000左右。 集群模式20000+
作为 Web 服务器:相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效率,这点使 Nginx 尤其受到虚拟主机提供商的欢迎。能够支持高达 50,000 个并发连接数的响应。
作为负载均衡服务器:可以进行自定义配置,支持虚拟主机,支持URL重定向。Nginx 既可以在内部直接支持 Rails 和 PHP,也可以支持作为 HTTP代理服务器 对外进行服务。Nginx 用 C 编写, 不论是系统资源开销还是 CPU 使用效率都比 Perlbal 要好的多。
Nginx 安装非常的简单,配置文件 非常简洁(还能够支持perl语法),Bugs非常少的服务器: Nginx 启动特别容易,并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动。还能够在不间断服务的情况下进行软件版本的升级。yum安装与编译安装
1、IO多路复用
- 采用epoll模型监控所有连接,通过IO多路复用的方式,采用异步,非阻塞的的方式实现的请求处理,从而实现高性能、高并发
1、I/O multiplexing【多并发】
第一种方法就是最传统的多进程并发模型 (每进来一个新的I/O流会分配一个新的线程管理。)

第二种方法就是I/O多路复用 (单个线程,通过记录跟踪每个I/O流(sock)的状态,来同时管理多个I/O流 。)
I/O multiplexing 这里面的 multiplexing 指的其实是在单个线程通过记录跟踪每一个Sock(I/O流)的状态来同时管理多个I/O流。发明它的原因,是尽量多的提高服务器的吞吐能力。在同一个线程里面, 通过拨开关的方式,来同时传输多个I/O流

2、nginx基于事件驱动模型实现I/O多路复用
一个请求到来了,nginx使用epoll接收请求的过程是怎样的?
- epoll.
• epoll 现在是线程安全的。
• epoll 现在不仅告诉你sock组里面数据,还会告诉你具体哪个sock有数据,你不用自己去找了。
#ngnix会有很多连接进来, 默认采用epoll会把他们都监视起来,然后像拨开关一样,谁有数据就拨向谁,然后调用相应的代码处理。
3、异步,非阻塞
$ pstree |grep nginx
|-+= 81666 root nginx: master process nginx
| |— 82500 nobody nginx: worker process
| — 82501 nobody nginx: worker process
1个master进程,n个work进程
每进来一个request,会有一个worker进程去处理。但不是全程的处理,处理到什么程度呢?处理到可能发生阻塞的地方,比如向上游(后端)服务器转发request,并等待请求返回。那么,这个处理的worker不会这么一直等着,他会在发送完请求后,注册一个事件:“如果upstream返回了,告诉我一声,我再接着干”。于是他就休息去了。这就是异步。此时,如果再有request 进来,他就可以很快再按这种方式处理。这就是非阻塞和IO多路复用。而一旦上游服务器返回了,就会触发这个事件,worker才会来接手,这个request才会接着往下走。这就是异步回调。
我们为什么更喜欢用Nginx 呢,Nginx 相对Apache 有那些有点呢?
- 轻量级,同样是web服务比Apache占用更少的内存及资源
- 静态处理,Nginx 静态处理性能比 Apache 高 3倍以上
- 抗并发,Nginx 处理请求是异步非阻塞的,而Apache则是阻塞型的。在高并发下Nginx 能保持低资源低消耗高性能。
- 高度模块化的设计,编写模块相对简单
3.nginx安装部署和配置管理
1、nginx部署-Yum安装
访问nginx的官方网站:http://www.nginx.org/
Nginx版本类型
Mainline version: 主线版,即开发版
Stable version: 最新稳定版,生产环境上建议使用的版本
Legacy versions: 遗留的老版本的稳定版

Yum安装nginx
配置Yum源的官网:http://nginx.org/en/linux_packages.html
1、配置nginx的Yum源
Installation instructions
Before you install nginx for the first time on a new machine, you need to set up the nginx packages repository. Afterward, you can install and update nginx from the repository.
安装说明
在新计算机上首次安装nginx之前,需要设置nginx软件包存储库。 之后,您可以从存储库安装和更新nginx。
RHEL/CENTOS
Install the prerequisites:
sudo yum install yum-utils -y
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
sudo yum install nginx -y
这里我们用稳定版本
[root@nginx-server yum.repos.d]# yum install -y nginx
[root@nginx-server yum.repos.d]# nginx -V //格式化打印
nginx version: nginx/1.16.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'
[root@nginx-server yum.repos.d]# nginx -v #查看版本号
nginx version: nginx/1.16.0
关闭防火墙和selinux
[root@nginx-server ~]# getenforce
Enforcing
[root@nginx-server ~]# sed -i '/SELINUX/s/enforcing/disabled/' /etc/selinux/config
[root@nginx-server ~]# systemctl stop firewalld
[root@nginx-server ~]# systemctl disable firewalld
启动并设置开机启动
[root@nginx-server ~]# systemctl start nginx
[root@nginx-server ~]# systemctl enable nginx
浏览器输入ip访问:

2、nginx 编译安装与配置使用
1、安装编译环境
yum -y install gcc gcc-c++
2、安装pcre软件包(使nginx支持http rewrite模块)
yum install -y pcre pcre-devel gd-devel
3、安装openssl-devel(使nginx支持ssl)
yum install -y openssl openssl-devel
4、安装zlib
yum install -y zlib zlib-devel
5、创建用户nginx
useradd nginx
passwd nginx
6、安装nginx
[root@localhost ~]# wget http://nginx.org/download/nginx-1.16.0.tar.gz
[root@localhost ~]# tar xzf nginx-1.16.0.tar.gz -C /usr/local/
[root@localhost ~]# cd /usr/local/nginx-1.16.0/
[root@localhost nginx-1.16.0]# ./configure --prefix=/usr/local/nginx --group=nginx --user=nginx --sbin-path=/usr/local/nginx/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/tmp/nginx/client_body --http-proxy-temp-path=/tmp/nginx/proxy --http-fastcgi-temp-path=/tmp/nginx/fastcgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-pcre --with-http_realip_module --with-stream
[root@localhost nginx-1.16.0]# make && make install
7、Nginx 编译参数
# 查看 nginx 安装的模块
[root@localhost ~]#/usr/local/nginx/sbin/nginx -V
--prefix=/usr/local/nginx //指向安装目录
--conf-path=/etc/nginx/nginx.conf //指定配置文件
--http-log-path=/var/log/nginx/access.log //指定访问日志
--error-log-path=/var/log/nginx/error.log //指定错误日志
--lock-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-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_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支持启用外部模块支持
#--with 表示在编译过程中需要给nginx添加的模块
#--without 表示编译nginx时默认该模块是添加进去的当使用这个参数时表示将默认编译的模块移除
8、修改配置文件/etc/nginx/nginx.conf
# 全局参数设置
user nginx; #设置nginx使用的用户
worker_processes 4; #设置nginx启动进程的数量,一般设置成与逻辑cpu数量相同
error_log logs/error.log; #指定错误日志
pid /var/run/nginx.pid;
events {
worker_connections 1024; #设置一个进程的最大并发连接数
}
# http 服务相关设置
http {
include mime.types; #关联mime类型,关联资源的媒体类型
default_type application/octet-stream; #根据文件的后缀来匹配相应的MIME类型
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; #用于开启文件高效传输模式,一般设置为on,若nginx是用来进行磁盘IO负载应用时,可以设置为off,降低系统负载
tcp_nopush on; # 减少网络报文段数量,当有数据时,先别着急发送, 确保数据包已经装满数据, 避免了网络拥塞
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
}
}
}
#1.nginx.conf的组成:nginx.conf一共由三部分组成,分别为:全局块、events块、http块。在http块中又包含http全局块、多个server块。每个server块中又包含server全局块以及多个location块。在统一配置块中嵌套的配置快,各个之间不存在次序关系。
2.Nginx的组成:
nginx的二进制可执行文件----启动关闭,有各个模块编译出来的
nginx.conf配置文件----控制nginx
access.log访问日志--记录每条http请求
error.log 错误日志--定位问题
9、检测nginx配置文件是否正确
[root@localhost ~]# /usr/local/nginx/sbin/nginx -t
[root@localhost ~]# mkdir -p /tmp/nginx
10、启动nginx服务
[root@localhost ~]# /usr/local/nginx/sbin/nginx
11、通过 nginx 命令控制 nginx 服务
# /usr/local/nginx/sbin/nginx -s stop 停服务
# /usr/local/nginx/sbin/nginx -s reload 刷新配置文件
设置软连接
# ln -s /usr/local/nginx/sbin/nginx /bin/nginx
重新加载nginx配置文件
# nginx -s reload
nginx -c /path/nginx.conf # 以特定目录下的配置文件启动nginx:
nginx -s reload # 修改配置后重新加载生效
nginx -s stop # 快速停止nginx
nginx -s quit # 正常停止nginx
nginx -t # 测试当前配置文件是否正确
nginx -t -c /path/to/nginx.conf # 测试特定的nginx配置文件是否正确
#注意:
nginx -s reload 命令加载修改后的配置文件,命令下达后发生如下事件
1. Nginx的master进程检查配置文件的正确性,若是错误则返回错误信息,nginx继续采用原配置文件进行工作(因为worker未受到影响)
2. Nginx启动新的worker进程,采用新的配置文件
3. Nginx将新的请求分配新的worker进程
4. Nginx等待以前的worker进程的全部请求已经都返回后,关闭相关worker进程
5. 重复上面过程,知道全部旧的worker进程都被关闭掉
12、nginx 日志文件详解
nginx 日志文件分为 log_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"';


4、使用 limit_rate 限制客户端传输数据的速度
1、编辑/etc/nginx/nginx.conf
location / {
root /var/www/nginx/;
index index.html index.htm;
limit_rate 2k; #对每个连接的限速为2k/s
}
重启服务
注意要点:
配置文件中的每个语句要以 ; 结尾
5、nginx 虚拟机配置
什么是虚拟主机?
虚拟主机是一种特殊的软硬件技术,它可以将网络上的每一台计算机分成多个虚拟主机,每个虚拟主机可以独立对外提供www服务,这样就可以实现一台主机对外提供多个web服务,每个虚拟主机之间是独立的,互不影响。

nginx可以实现虚拟主机的配置,nginx支持三种类型的虚拟主机配置。
1、基于域名的虚拟主机 (server_name来区分虚拟主机——应用:外部网站)
2、基于ip的虚拟主机, (一块主机绑定多个ip地址)
3、基于端口的虚拟主机 (端口来区分虚拟主机——应用:公司内部网站,外部网站的管理后台)
1、 基于域名的虚拟主机
1、配置通过域名区分的虚拟机
[root@localhost ~]# cat /etc/nginx/nginx.conf
worker_processes 4;
#error_log logs/error.log;
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 www.testpm.com;
location / {
root /1000phone/html;
index index.html index.htm;
}
}
}
2、 为 域名为 web.1000phone.com 的虚拟机,创建 index 文件
[root@localhost ~]# mkdir -p /1000phone/html
[root@localhost ~]# vim /1000phone/html/index.html
<html>
<p>
this is my 1000phone
</p>
</html>
3、重新加载配置文件
# 如果编译安装的执行
[root@nginx]# /usr/local/nginx/sbin/nginx -s reload
# 如果 yum 安装的执行
[root@nginx]# nginx -s reload
4、客户端配置路由映射
在 C:WindowsSystem32driversetchosts 文件中添加两行(linux:/etc/hosts)
10.0.105.199 web.testpm.com
10.0.105.199 web.1000phone.com
5、 测试访问
浏览器输入:http://web.testpm.com/
浏览器输入:http://web.1000phone.com/
2、 基于ip的虚拟主机
[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:17:f1:af brd ff:ff:ff:ff:ff:ff
inet 10.0.105.199/24 brd 10.0.105.255 scope global dynamic ens33
valid_lft 81438sec preferred_lft 81438sec
inet6 fe80::9d26:f3f0:db9c:c9be/64 scope link
valid_lft forever preferred_lft forever
两种方式添加网卡
[root@localhost ~]# ifconfig ens33:1 10.0.105.201/24
[root@localhost ~]# ip a a 10.0.105.201/24 dev ens33
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.105.199 netmask 255.255.255.0 broadcast 10.0.105.255
inet6 fe80::9d26:f3f0:db9c:c9be prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:17:f1:af txqueuelen 1000 (Ethernet)
RX packets 9844 bytes 1052722 (1.0 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 5567 bytes 886269 (865.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.105.201 netmask 255.255.255.0 broadcast 10.0.105.255
ether 00:0c:29:17:f1:af txqueuelen 1000 (Ethernet)
2、配置通过ip区分的虚拟机
[root@localhost ~]# cat /etc/nginx/nginx.conf
user root;
worker_processes 4;
#error_log logs/error.log;
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 www.testpm.com;
location / {
root /1000phone/html/;
index index.html index.htm;
}
}
}
3、重新加载配置文件
[root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload
4、 测试访问
浏览器输入:http://10.0.105.199
浏览器输入:http://10.0.105.201
5、补充
-- 两种方式删除绑定的vip
[root@localhost ~]# ifconfig ens33:1 10.0.105.201/24 down
[root@localhost ~]# ip a d 10.0.105.201/24 dev ens33
重启一下nginx
[root@localhost ~]# systemctl restart nginx
3、 基于端口的虚拟主机
[root@localhost ~]# cat /etc/nginx/nginx.conf
user root;
worker_processes 4;
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 www.testpm.com;
location / {
root /1000phone/html/;
index index.html index.htm;
}
}
}
重新加载配置文件:
[root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload
测试访问:
浏览器输入:http://web.testpm.com/
浏览器输入:http://web.1000phone.com:8080
Nginx进阶-常见配置
一、nginx Proxy 反向代理
1、代理原理
反向代理产生的背景:
在计算机世界里,由于单个服务器的处理客户端(用户)请求能力有一个极限,当用户的接入请求蜂拥而入时,会造成服务器忙不过来的局面,可以使用多个服务器来共同分担成千上万的用户请求,这些服务器提供相同的服务,对于用户来说,根本感觉不到任何差别。
反向代理服务的实现:
需要有一个负载均衡设备(即反向代理服务器)来分发用户请求,将用户请求分发到后端正真提供服务的服务器上。服务器返回自己的服务到负载均衡设备。负载均衡设备将服务器的服务返回用户。

2、正/反向代理的区别
正向代理
**正向代理的过程隐藏了真实的请求客户端,服务器不知道真实的客户端是谁,客户端请求的服务都被代理服务器代替请求。**我们常说的代理也就是正向代理,正向代理代理的是请求方,也就是客户端;比如我们要访问youtube,可是不能访问,只能先安装个FQ软件代你去访问,通过FQ软件才能访问,FQ软件就叫作正向代理。


两者的区别在于代理的对象不一样:
正向代理中代理的对象是客户端,服务器不知道访问的对象是谁
反向代理中代理的对象是服务端,客户端不知道真正提供服务的是谁
3、nginx Proxy 配置
- # curl -I http://192.168.139.146 看是否正常访问
1、代理模块
ngx_http_proxy_module
2、启用 nginx proxy 代理
环境两台nginx真实服务器
a、nginx-1 启动网站(内容)(作为应用服务器)
nginx-1的ip:10.0.105.199
已经编译安装好,检查nginx是否启动是否可以访问
b、nginx-2 作为代理服务器
nginx-2的ip:10.0.105.202
配置nginx的yum源直接yum安装
启动
编辑nginx的配置文件:
[root@nginx-server ~]# vim /etc/nginx/conf.d/default.conf
server {
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://10.0.105.199:80;
proxy_redirect default;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
}
}
重新加载nginx配置文件
设置软连接
# ln -s /usr/local/nginx/sbin/nginx /bin/nginx
[root@nginx-server ~]# nginx -s reload
yum安装页面位置:/usr/share/nginx/html/index.html
c、nginx proxy 具体配置详解
proxy_pass :真实后端服务器的地址,可以是ip也可以是域名和url地址
proxy_redirect :如果真实服务器使用的是的真实IP:非默认端口。则改成IP:默认端口。
proxy_set_header:重新定义或者添加发往后端服务器的请求头
proxy_set_header X-Real-IP $remote_addr;#只记录连接服务器的上一个ip地址信息。
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #通过这个选项可以记录真正客户端机器的ip地址
proxy_connect_timeout::后端服务器连接的超时时间发起三次握手等候响应超时时间
proxy_send_timeout:后端服务器数据回传时间,就是在规定时间之内后端服务器必须传完所有的数据
proxy_read_timeout :nginx接收upstream(上游/真实) server数据超时, 默认60s, 如果连续的60s内没有收到1个字节, 连接关闭。像长连接
注意:proxy_pass http:// 填写nginx-1服务器的地址。
使用PC客户端访问nginx-2服务器地址
浏览器中输入http://10.0.105.202 (也可以是nginx-2服务器的域名)
成功访问nginx-1服务器页面
观察nginx-1服务器的日志
10.0.105.202 - - [27/Jun/2019:15:54:17 +0800] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" "10.0.105.207"
10.0.105.202 代理服务器地址
10.0.105.207 客户机地址。
访问成功。 记录了客户机的IP和代理服务器的IP
二、Nginx负载均衡
- 负载均衡–通过算法将用户的请求平均分配给每一台机器,从而降低单台机器的访问压力,网站响应速度提高了,避免了单节点故障
- 模块:upstream–七层的负载均衡
1、upstream配置
首先给大家说下 upstream 这个配置的,这个配置是写一组被代理的服务器地址,然后配置负载均衡的算法.
upstream testapp {
server 10.0.105.199:8081;
server 10.0.105.202:8081;
}
server {
....
location / {
proxy_pass http://testapp; #请求转向 testapp 定义的服务器列表
}
2、负载均衡算法
upstream 支持6种负载均衡调度算法
1、轮询(默认):每个请求按时间顺序逐一分配到不同的后端服务器;
2、加权轮询:根据权重值来分配,默认服务器权重1,修改了权重值就给权重值大的多分配
3、ip_hash:每个请求按访问IP的hash结果分配,同一个IP客户端固定访问一个后端服务器。可以保证来自同一ip的请求被打到固定的机器上,可以解决session问题。
4、url_hash:按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器。
5、fair:这是比上面两个更加智能的负载均衡算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx本身是不支持 fair的,如果需要使用这种调度算法,必须下载Nginx的 upstream_fair模块。
6、least_conn:最少连接:优先将请求分发给当前连接数最少的后端服务器。
3、配置实例
1、热备:如果你有2台服务器,当一台服务器发生事故时,才启用第二台服务器给提供服务。服务器处理请求的顺序:AAAAAA突然A挂啦,BBBBBBBBBBBBBB…
upstream myweb {
server 172.17.14.2:8080;
server 172.17.14.3:8080 backup; #热备
}
2、轮询:nginx默认就是轮询其权重都默认为1,服务器处理请求的顺序:ABABABABAB…
upstream myweb {
server 172.17.14.2:8080;
server 172.17.14.3:8080;
}
3、加权轮询:跟据配置的权重的大小而分发给不同服务器不同数量的请求。如果不设置,则默认为1。下面服务器的请求顺序为:ABBABBABBABBABB…
upstream myweb {
server 172.17.14.2:8080 weight=1;
server 172.17.14.3:8080 weight=2;
}
4、ip_hash:nginx会让相同的客户端ip请求相同的服务器。
upstream myweb {
server 172.17.14.2:8080;
server 172.17.14.3:8080;
ip_hash;
}
5、nginx负载均衡配置状态参数
- down,表示当前的server暂时不参与负载均衡。
- backup,预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻。
- max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。
- fail_timeout,在经历了max_fails次失败后,暂停服务的时间单位秒。max_fails可以和fail_timeout一起使用。
upstream myweb {
server 172.17.14.2:8080 weight=2 max_fails=2 fail_timeout=2;
server 172.17.14.3:8080 weight=1 max_fails=2 fail_timeout=1;
}
如果你想跟多更深入的了解 nginx 的负载均衡算法,nginx官方提供一些插件大家可以了解下。
4、nginx配置7层协议
- 用http,upstream模块
举例讲解下什么是7层协议,什么是4层协议。
(1)7层协议
OSI(Open System Interconnection)是一个开放性的通行系统互连参考模型,他是一个定义的非常好的协议规范,共包含七层协议。直接上图,这样更直观些:

好,详情不进行仔细讲解,可以自行百度!
(2)协议配置
这里我们举例,在nginx做负载均衡,负载多个服务,部分服务是需要7层的,部分服务是需要4层的,也就是说7层和4层配置在同一个配置文件中。
准备三台机器:
代理服务IP:10.0.105. --配置本地host解析域名;
后端服务器IP:nginx-a :10.0.105.199/nginx-b:10.0.105.202(yum安装)后端服务器将nginx服务启动
配置代理服务器的nginx配置文件:/etc/nginx/nginx.conf
worker_processes 4;
worker_rlimit_nofile 102400;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
keepalive_timeout 65;
gzip on;
upstream testweb {
#ip_hash;
server 10.0.105.199:80 weight=2 max_fails=2 fail_timeout=2s;
server 10.0.105.202:80 weight=2 max_fails=2 fail_timeout=2s;
}
server {
listen 80;
server_name www.test.com;
charset utf-8;
#access_log logs/host.access.log main;
location / {
proxy_pass http://testweb;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
202服务器yum安装的创建新的配置文件:
[root@nginx-server ~]# cd /etc/nginx/conf.d/
[root@nginx-server conf.d]# cp default.conf test.conf
[root@nginx-server conf.d]# cat test.conf
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
定义yum安装的页面位置为:/usr/share/nginx/html
[root@nginx-server ~]# nginx -s reload
浏览器测试访问:
http://www.test.com/
nginx 配置后端健康检查模块
nginx自带的针对后端节点健康检查的功能比较简单,通过默认自带的ngx_http_proxy_module 模块和ngx_http_upstream_module模块中的参数来完成,当后端节点出现故障时,自动切换到健康节点来提供访问。但是nginx不能事先知道后端节点状态是否健康,后端即使有不健康节点,负载均衡器依然会先把请求转发给该不健康节点,然后再转发给别的节点,这样就会浪费一次转发,而且自带模块无法做到预警。所以我们可以使用第三方模块 nginx_upstream_check_module模块
nginx_upstream_check_module模块由淘宝团队开发 淘宝自己的 tengine 上是自带了该模块的。我们使用原生Nginx,采用添加模块的方式
获取nginx_upstream_check_module模块
从github上面获取就可以了。
[root@nginx-server ~]# yum install -y unzip
下载模块
[root@nginx-server ~]# wget https://github.com/yaoweibin/nginx_upstream_check_module/archive/refs/heads/master.zip
[root@nginx-server ~]# unzip -d /usr/local/ master.zip
安装补丁:
注意 check版本和Nginx版本要求有限制 1.12以上版本的nginx,补丁为check_1.11.5+.patch 具体参考github
# ls nginx_upstream_check_module-master 可以看版本
# -p0,是“当前路径” -p1,是“上一级路径”
[root@nginx-server ~]# cd /usr/local/nginx-1.22.1/ #进入nginx的解压目录中
[root@nginx-server nginx-1.22.1]# yum install -y patch
[root@nginx-server nginx-1.22.1]# patch -p1 < ../nginx_upstream_check_module-master/check_1.20.1+.patch
[root@nginx-server nginx-1.22.1]# ./configure --prefix=/usr/local/nginx --group=nginx --user=nginx --sbin-path=/usr/local/nginx/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/tmp/nginx/client_body --http-proxy-temp-path=/tmp/nginx/proxy --http-fastcgi-temp-path=/tmp/nginx/fastcgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-pcre --with-http_realip_module --with-stream --add-module=../nginx_upstream_check_module-master/
[root@nginx-server nginx-1.22.1]# make #重新编译文件, 如果是添加模块只需要make 第一次安装需要make install
[root@nginx-server nginx-1.22.1]# mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak #将原来的nginx二进制命令备份
[root@nginx-server nginx-1.22.1]# cp objs/nginx /usr/local/nginx/sbin/ #将新生成的命令cp到nginx的命令目录中。
配置健康检查
编译安装:/etc/nginx/nginx.conf
yum安装: /etc/nginx/conf.d/default.conf
http {
upstream app {
server 192.168.209.128 weight=1;
server 192.168.209.130 weight=1;
check interval=5000 rise=2 fall=3 timeout=4000 type=http port=80;
check_http_send "HEAD / HTTP/1.0
";
check_http_expect_alive http_2xx http_3xx;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://app;
proxy_redirect default;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /status { #开启监控状态页面
check_status;
access_log off;
}
}
}
参数解释:
interval:表示每隔多少毫秒向后端发送健康检查包;
rise:表示如果连续成功次数达到2 服务器就被认为是up;
fail:表示如果连续失败次数达到3 服务器就被认为是down;
timeout:表示后端健康请求的超时时间是多少毫秒;
type:表示发送的健康检查包是什么类型的请求;
port: 表示发送检查到后端的服务的端口;
check_http_send:表示http健康检查包发送的请求内容。为了减少传输数据量,推荐采用“head”方法;
check_http_expect_alive:指定HTTP回复的成功状态,默认认为2XX和3XX的状态是健康的;
浏览器查看访问状态

5、4层协议方法(扩展)
- 用tcp,使用stream模块
(2)4层协议
TCP/IP协议
之所以说TCP/IP是一个协议族,是因为TCP/IP协议包括TCP、IP、UDP、ICMP、RIP、SMTP、ARP、TFTP等许多协议,这些协议一起称为TCP/IP协议。
从协议分层模型方面来讲,TCP/IP由四个层次组成:网络接口层、网络层、传输层、应用层。

nginx在1.9.0的时候,增加了一个 stream 模块,用来实现四层协议(网络层和传输层)的转发、代理、负载均衡等。stream模块的用法跟http的用法类似,允许我们配置一组TCP或者UDP等协议的监听.
配置案例:
#4层tcp负载
stream {
upstream ssh_01 {
server 192.168.209.129:22;
}
server {
listen 6666;
proxy_pass ssh_01;
proxy_timeout 60s;
proxy_connect_timeout 30s;
}
}
#注意:stream块是与http块同一级别
#ssh 本机ip -p6666
6.经典面试题
nginx中有两个server 一个是a.com 一个是b.com 现在访问c.com 返回的是哪个页面,(定义友好返回页面)
1. 匹配 server_name:Nginx 优先检查请求的Host头(此处为c.com),并尝试匹配配置中的 server_name。由于配置中只有a.com和b.com的server块,没有匹配项。
2. 默认server块:若未匹配到任何server_name,Nginx会选择监听相同端口且标记为`default_server`的 server块。若未显式指定default_server,则默认选择第一个定义的server块。
3.设置了地址重写,根据规定进行相应的返回
配置案例
server {
listen 80 default_server;
server_name _;
return 444; # 关闭连接或返回自定义错误页
}
三、nginx 会话保持
nginx会话保持主要有以下几种实现方式。
1、ip_hash
ip_hash使用源地址哈希算法,将同一客户端的请求总是发往同一个后端服务器,除非该服务器不可用。
ip_hash语法:
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com down;
}
ip_hash简单易用,但有如下问题:
当后端服务器宕机后,session会丢失;
来自同一局域网的客户端会被转发到同一个后端服务器,可能导致负载失衡;
2、sticky_cookie_insert—而是基于cookie实现
- 使用sticky_cookie_insert模块
使用sticky_cookie_insert,这会让来自同一客户端的请求被传递到一组服务器的同一台服务器。与ip_hash不同之处在于,它不是基于IP来判断客户端的,而是基于cookie来判断。(需要引入第三方模块才能实现)---sticky模块。因此可以避免上述ip_hash中来自同一局域网的客户端和前段代理导致负载失衡的情况。
语法:
编译安装sticky模块,#给yum安装的nginx添加模块
[root@nginx-server ~]# yum install -y pcre* openssl* gcc gcc-c++ make 安装编译环境
[root@nginx-server ~]# wget https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/08a395c66e42.zip #下载sticky模块
[root@nginx-server ~]# nginx -v
nginx version: nginx/1.18.0
# systemctl stop nginx
[root@nginx-server ~]# wget http://nginx.org/download/nginx-1.18.0.tar.gz #下载yum安装nginx对应版本的源码包
[root@nginx-server ~]# yum install -y unzip #安装解压工具
[root@nginx-server ~]# unzip 08a395c66e42.zip #解压模块包
[root@nginx-server ~]# mv nginx-goodies-nginx-sticky-module-ng-08a395c66e42/ nginx-sticky-module-ng/
[root@nginx-server ~]# tar xzvf nginx-1.18.0.tar.gz -C /usr/local/ #解压nginx的源码包
[root@nginx-server ~]# cd /usr/local/nginx-1.18.0/
[root@nginx-server nginx-1.18.0]# nginx -V #查看yum安装nginx所有模块
[root@nginx-server nginx-1.18.0]# ./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' --add-module=/root/nginx-sticky-module-ng
[root@nginx-server nginx-1.18.0]# make && make install
配置基于cookie会话保持
[root@nginx-server nginx-1.18.0]#cd /etc/nginx
#vim nginx.conf
[root@nginx-server conf.d]# vim upstream.conf
upstream qfedu {
server 192.168.198.143;
server 192.168.198.145;
sticky;
}
[root@nginx-server conf.d]# vim proxy.conf
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
# root html; 默认参数
# index index.html index.htm;
proxy_pass http://qfedu;
proxy_redirect default;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
[root@nginx-server conf.d]# nginx -t
[root@nginx-server conf.d]# nginx -s reload
或者:
upstream qfedu {
server 192.168.198.143;
server 192.168.198.145;
sticky expires=1h domain=testpm.com path=/;
}
说明:
expires:设置浏览器中保持cookie的时间
domain:定义cookie的域
path:为cookie定义路径
浏览器测试访问
注意:使用后端服务器自身通过相关机制保持session同步,如:使用数据库、redis、memcached 等做session复制
四、nginx 实现动静分离
- 动态分离好处:动态页面和静态页面由不同的服务器来解析,加快解析速度,降低单个服务器的压力,提升整个网站的响应速度
为了加快网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度。降低原来单个服务器的压力。 简单来说,就是使用正则表达式匹配过滤,然后交个不同的服务器。
1、准备环境
准备一个nginx代理 两个http 分别处理动态和静态。
expires功能说明---(为客户端配置缓存时间),主要用于图片类
nginx缓存的设置可以提高网站性能,对于网站的图片,尤其是新闻网站,图片一旦发布,改动的可能是非常小的,为了减小对服务器请求的压力,提高用户浏览速度,我们可以通过设置nginx中的expires,让用户访问一次后,将图片缓存在用户的浏览器中,且时间比较长的缓存。
原理:当nginx设置了expires后,例如设置为:expires 10d; 那么用户在10天内请求的时候,都只会访问浏览器中的缓存,而不会去请求nginx。
注:需要注意的是,这种缓存方式只能在用户不对浏览器强制刷新的情况下生效,如果用户通过url来进行访问,是可以访问到缓存的。
1.静态资源配置
编译安装:/etc/nginx/nginx.conf
yum安装: /etc/nginx/conf.d/default.conf
server {
listen 80;
server_name localhost;
location ~ .(html|jpg|png|js|css) {
root /home/www/nginx;
expires 1d; #为客户端设置静态资源缓存时间
}
}
# mkdir -p /home/www/nginx
# cd /home/www/nginx
上传照片并给权限
测试:
[root@nginx-yum2 conf.d]# curl -I http://10.0.105.200/test.jpg
HTTP/1.1 200 OK
Server: nginx/1.16.0
Date: Mon, 07 Sep 2019 11:35:08 GMT
Content-Type: image/jpeg
Content-Length: 27961
Last-Modified: Mon, 07 Sep 2019 11:31:17 GMT
Connection: keep-alive
ETag: "5f561a05-6d39"
Expires: Tue, 08 Sep 2019 11:35:08 GMT #缓存到期时间
Cache-Control: max-age=86400 #缓存持续时间秒
Accept-Ranges: bytes
2.动态资源配置:
yum 安装php7.1
[root@nginx-server ~]# yum install -y epel-release
[root@nginx-server ~]# rpm -ivh http://rpms.remirepo.net/enterprise/remi-release-7.rpm
[root@nginx-server ~]# cd /etc/yum.repos.d/
[root@nginx-server yum.repos.d]# ls
remi-php73.repo remi-php74.repo
remi-php80.repo nginx.repo
remi-php81.repo remi-modular.repo
remi-php82.repo remi-php54.repo
remi-php83.repo remi-php70.repo
remi.repo remi-php71.repo
remi-safe.repo epel.repo
remi-php72.repo
[root@nginx-server ~]# yum install -y yum-utils
[root@nginx-server ~]# yum-config-manager --enable remi-php71
[root@nginx-server ~]# yum -y install php-xsl php php-ldap php-cli php-common php-devel php-gd php-pdo php-mysql php-mbstring php-bcmath php-mcrypt php-fpm
[root@nginx-server ~]# systemctl start php-fpm
[root@nginx-server ~]# systemctl enable php-fpm
#动态服务器编辑nginx连接php
编辑nginx的配置文件:
编译安装:/etc/nginx/nginx.conf
yum安装: /etc/nginx/conf.d/default.conf
server {
listen 80;
server_name localhost;
location ~ .php$ {
root /home/nginx/html; #指定网站目录
fastcgi_pass 127.0.0.1:9000; #开启fastcgi连接php地址
fastcgi_index index.php; #指定默认文件
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; #站点根目录,取决于root配置项
include fastcgi_params; #包含fastcgi使用的常量
}
}
创建目录:mkdir -p /home/nginx/html
测试代码:
#vim /home/nginx/html/index.php
<?php
echo "hello world"
?>
3.配置nginx反向代理upstream,并实现客户端缓存时间
配置upstream:
upstream static {
server 10.0.105.196:80 weight=1 max_fails=1 fail_timeout=60s;
}
upstream php {
server 10.0.105.200:80 weight=1 max_fails=1 fail_timeout=60s;
}
配置反向代理:
server {
listen 80;
server_name localhost
#动态资源加载
location ~ .(php|jsp)$ {
proxy_pass http://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|jpg|png|css|js)$ {
proxy_pass http://static;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
当访问静态页面的时候location 匹配到 (html|jpg|png|js|css) 通过转发到静态服务器,静态服务通过location的正则匹配来处理请求。
当访问动态页面时location匹配到 .php 结尾的文件转发到后端php服务处理请求。
五、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 [=|^~|~|~*|!~|!~*|/|@] pa4ttern{……}
2、location 前缀含义
常用:
~ 表示区分大小写的正则匹配
~* 表示不区分大小写的正则匹配
^~ 表示uri以某个常规字符串开头,理解为匹配url路径即可
= 表示精确匹配,优先级也是最高的
!~ 表示区分大小写不匹配的正则
!~* 表示不区分大小写不匹配的正则
/ 通用匹配,任何请求都会匹配到
查找顺序和优先级
= 大于 ^~ 大于 ~|~*|!~|!~* 大于 /
多个location配置的情况下匹配顺序为:首先匹配 =,其次匹配^~, 其次是按正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。
3、location 配置示例
1、没有修饰符 表示:必须以指定模式开始
server {
listen 80;
server_name localhost;
location /abc {
root /home/www/nginx;
index 2.html;
}
那么,如下是对的:
http://192.168.1.9/abc
注意:此时 /home/www/nginx为根目录
在此目录下
创建mkdir /home/www/nginx/abc目录
创建文件 touch /abc/2.html
2、=表示:必须与指定的模式精确匹配
server {
listen 80;
server_name localhost;
access_log /var/log/nginx/http_access.log main;
location / {
return https://www.baidu.com;
}
location = / {
return https://www.jd.com;
}
}
测试:
3、~ 表示:指定的正则表达式要区分大小写
server {
server_name localhost;
location ~ /abc {
root /home/www/nginx;
index 2.html index.html;
}
}
测试访问:
http://192.168.1.9/abc
不正确的
http://192.168.1.9/ABC
========================================
如果将配置文件修改为
location ~ /ABC {
root /home/www/nginx;
index 2.html index.html;
}
在创建目录和文件:
[root@ansible-server html]# cd /home/www/nginx/
[root@ansible-server nginx]# mkdir ABC
[root@ansible-server nginx]# vim ABC/2.html
访问:
http://192.168.1.9/ABC/
结论:~ 需要区分大小写。而且目录需要根据大小写定义。
4、^和*匹配案例
~*:表示不区分大小写的正则匹配
[root@localhost conf.d]# cat default.conf
server {
listen 80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location ~* /a/b/ {
return 888;
}
}
测试:
[root@localhost ~]# curl -I http://192.168.209.200/a/b/
HTTP/1.1 888
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:14:09 GMT
Content-Length: 0
Connection: keep-alive
[root@localhost ~]# curl -I http://192.168.209.200/A/B/
HTTP/1.1 888
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:16:52 GMT
Content-Length: 0
Connection: keep-alive
^~:表示uri以某个常规字符串开头,理解为匹配url路径即可
例如:下面配置文件有两条规则,分别匹配url以字母a开头,但是长度不同,首先将长的规则先注释掉,如下:
[root@localhost conf.d]# cat default.conf
server {
listen 80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location ^~ /a/ {
return 123;
}
#location ^~ /a/b/ {
#return 12345;
#}
}
测试:
[root@localhost ~]# curl -I http://192.168.209.200/a/
HTTP/1.1 678
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:28:03 GMT
Content-Length: 0
Connection: keep-alive
[root@localhost ~]# curl -I http://192.168.209.200/a/b/
HTTP/1.1 678
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:28:07 GMT
Content-Length: 0
Connection: keep-alive
[root@localhost ~]# curl -I http://192.168.209.200/a/b/dsdfsdf
HTTP/1.1 678
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:28:10 GMT
Content-Length: 0
Connection: keep-alive
结论:
当前只有一个规则开启,因此当匹配url以/a/开头的任何url时,都会返回状态码678
现在打开注释:
[root@localhost conf.d]# cat default.conf
server {
listen 80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location ^~ /a/ {
return 678;
}
location ^~ /a/b/ {
return 876;
}
}
测试:
[root@localhost ~]# curl -I http://192.168.209.200/a/
HTTP/1.1 678
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:44:52 GMT
Content-Length: 0
Connection: keep-alive
[root@localhost ~]# curl -I http://192.168.209.200/a/b/
HTTP/1.1 876
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:44:56 GMT
Content-Length: 0
Connection: keep-alive
[root@localhost ~]# curl -I http://192.168.209.200/a/b/sdgsdgdg
HTTP/1.1 876
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:44:58 GMT
Content-Length: 0
Connection: keep-alive
结论:
两条规则同时被匹配成功,但是第二条规则比较长,因此第二条规则优先被匹配。
六、nginx 地址重写 rewrite
1、什么是Rewrite
Rewrite对称URL Rewrite,即URL重写,就是把传入Web的请求重定向到其他URL的过程
- 从安全角度上讲,如果在URL中暴露太多的参数,无疑会造成一定量的信息泄漏,可能会被一些黑客利用,对你的系统造成一定的破坏,所以静态化的URL地址可以给我们带来更高的安全性。
- 实现网站地址跳转,例如用户访问360buy.com,将其跳转到jd.com。例如当用户访问tianyun.com的
80端口时,将其跳转到443端口。
2、Rewrite 相关指令
- Nginx Rewrite 相关指令有 if、rewrite、set、return
2.1、if 语句
-
应用环境
server,location语法:
if (condition) { … } if 可以支持如下条件判断匹配符号 ~ 正则匹配 (区分大小写) ~* 正则匹配 (不区分大小写) !~ 正则不匹配 (区分大小写) !~* 正则不匹配 (不区分大小写) -f 和!-f 用来判断是否存在文件 -d 和!-d 用来判断是否存在目录 -e 和!-e 用来判断是否存在文件或目录 -x 和!-x 用来判断文件是否可执行 在匹配过程中可以引用一些Nginx的全局变量 $args 请求中的参数; $document_root 针对当前请求的根路径设置值; $host 请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名; $limit_rate 对连接速率的限制; $request_method 请求的方法,比如"GET"、"POST"等; $remote_addr 客户端地址; $remote_port 客户端端口号; $remote_user 客户端用户名,认证用; $request_filename 当前请求的文件路径名(带网站的主目录/usr/local/nginx/html/images/a.jpg) $request_uri 当前请求的文件路径名(不带网站的主目录/images/a.jpg) $query_string 与$args相同; $scheme 用的协议,比如http或者是https $server_protocol 请求的协议版本,"HTTP/1.0"或"HTTP/1.1"; $server_addr 服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费); $server_name 请求到达的服务器名; $document_uri 与$uri一样,URI地址; $server_port 请求到达的服务器端口号;2.2、Rewrite flag 地址重写的四个标记
rewrite 指令根据表达式来重定向URI,或者修改字符串。可以应用于server,location, if环境下每行rewrite指令最后跟一个flag标记,支持的flag标记有:
last 表示完成rewrite。默认为last。 break 本条规则匹配完成后,终止匹配,不再匹配后面的规则 redirect 返回302临时重定向,浏览器地址会显示跳转后的URL地址 permanent 返回301永久重定向,浏览器地址会显示跳转后URL地址redirect 和 permanent区别则是返回的不同方式的重定向:
对于客户端来说一般状态下是没有区别的。而对于搜索引擎,相对来说301的重定向更加友好,如果我们把一个地址采用301跳转方式跳转的话,搜索引擎会把老地址的相关信息带到新地址,同时在搜索引擎索引库中彻底废弃掉原先的老地址。
使用302重定向时,搜索引擎(特别是google)有时会查看跳转前后哪个网址更直观,然后决定显示哪个,如果它觉的跳转前的URL更好的话,也许地址栏不会更改。
1、Rewrite匹配参考示例
本地解析host文件--wind
# http://www.testpm.com/a/1.html ==> http://www.testpm.com/b/2.html
location /a {
root /html;
index 1.html index.htm;
rewrite .* /b/2.html permanent;
}
location /b {
root /html;
index 2.html index.htm;
}
例2:
# http://www.testpm.com/2019/a/1.html ==> http://www.testpm.com/2018/a/1.html
location /2019/a {
root /var/www/html;
index 1.html index.hml;
rewrite ^/2019/(.*)$ /2018/$1 permanent;
}
location /2018/a {
root /var/www/html;
index 1.html index.htl;
}
例3:
# http://www.qf.com/a/1.html ==> http://jd.com
location /a {
root /html;
if ($host ~* www.qf.com ) {
rewrite .* http://jd.com permanent;
}
}
例4:
# http://www.qf.com/a/1.html ==> http://jd.com/a/1.html
location /a {
root /html;
if ( $host ~* qf.com ){
rewrite .* http://jd.com$request_uri permanent;
}
}
例5:
# http://www.tianyun.com/login/tianyun.html ==> http://www.tianyun.com/reg/login.html?user=tianyun
location /login {
root /usr/share/nginx/html;
rewrite ^/login/(.*).html$ http://$host/reg/login.html?user=$1;
}
location /reg {
root /usr/share/nginx/html;
index login.html;
}
例6:
#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、set 指令
set 指令是用于定义一个变量,并且赋值
应用环境:
server,location,if
应用示例
例8:
#http://alice.testpm.com ==> http://www.testpm.com/alice
#http://jack.testpm.com ==> http://www.testpm.com/jack
[root@nginx-server conf.d]# cd /usr/share/nginx/html/
[root@nginx-server html]# mkdir jack alice
[root@nginx-server html]# echo "jack.." >> jack/index.html
[root@nginx-server html]# echo "alice.." >> alice/index.html
本地解析域名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;
}
}
3、return 指令
return 指令用于返回状态码给客户端
server,location,if
应用示例:
例9:如果访问的.sh结尾的文件则返回403操作拒绝错误
server {
listen 80;
server_name www.testpm.cn;
#access_log /var/log/nginx/http_access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location ~* .sh$ {
return 403;
}
}
例10:80 ======> 443 :80转443端口
server {
listen 80;
server_name www.testpm.cn;
access_log /var/log/nginx/http_access.log main;
return 301 https://www.testpm.cn$request_uri;
}
server {
listen 443 ssl;
server_name www.testpm.cn;
access_log /var/log/nginx/https_access.log main;
#ssl on;
ssl_certificate /etc/nginx/cert/2447549_www.testpm.cn.pem;
ssl_certificate_key /etc/nginx/cert/2447549_www.testpm.cn.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
[root@nginx-server ~]# curl -I http://www.testpm.cn
HTTP/1.1 301 Moved Permanently
Server: nginx/1.16.0
Date: Wed, 03 Jul 2019 13:52:30 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://www.testpm.cn/
4、last,break详解

[root@localhost test]# cat /etc/nginx/conf.d/last_break.conf
server {
listen 80;
server_name localhost;
access_log /var/log/nginx/last.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /break/ {
root /usr/share/nginx/html;
rewrite .* /test/break.html break;
}
location /last/ {
root /usr/share/nginx/html;
rewrite .* /test/last.html last;
}
location /test/ {
root /usr/share/nginx/html;
rewrite .* /test/test.html break;
}
}
[root@localhost conf.d]# cd /usr/share/nginx/html/
[root@localhost html]# mkdir test
[root@localhost html]# echo "last" > test/last.html
[root@localhost html]# echo "break" > test/break.html
[root@localhost html]# echo "test" > test/test.html
http://10.0.105.196/break/break.html
http://10.0.105.196/last/last.html
注意:
- last 标记在本条 rewrite 规则执行完后,会对其所在的 server { … } 标签重新发起请求;
- break 标记则在本条规则匹配完成后,停止匹配,不再做后续的匹配;
- 使用 proxy_pass 指令时,则必须使用break。
nginx 日志配置
1、nginx 日志介绍
nginx 有一个非常灵活的日志记录模式,每个级别的配置可以有各自独立的访问日志, 所需日志模块 ngx_http_log_module 的支持,日志格式通过 log_format 命令来定义,日志对于统计和排错是非常有利的,下面总结了 nginx 日志相关的配置 包括 access_log、log_format、rewrite_log、error_log。
# 设置访问日志
access_log path;
# 关闭访问日志
access_log off;
- path 指定日志的存放位置。
作用域:
可以应用access_log指令的作用域分别有http,server,location,也就是说,在这几个作用域外使用该指令,Nginx会报错。
access_log /var/logs/nginx-access.log
该例子指定日志的写入路径为/var/logs/nginx-access.log,日志格式使用默认的combined。
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 [escape=default|json] string ...;
- name 格式名称。在 access_log 指令中引用。
- escape 设置变量中的字符编码方式是`json`还是`default`,默认是`default`。
- string 要定义的日志格式内容。该参数可以有多个。参数中可以使用Nginx变量。
log_format 指令中常用的一些变量:
$remote_addr, $http_x_forwarded_for #记录客户端IP地址
$remote_user #记录客户端用户名称
$request #记录请求的URL和HTTP协议
$status #记录请求状态
$body_bytes_sent #发送给客户端的字节数,不包括响应头的大小
$bytes_sent #发送给客户端的总字节数
$connection #连接的序列号
$connection_requests #当前通过一个连接获得的请求数量。
$msec #日志写入时间。单位为秒,精度是毫秒。
$http_referer #记录从哪个页面链接访问过来的,可以根据该参数进行防盗链设置
$http_user_agent #记录客户端浏览器相关信息
$request_length #请求的长度(包括请求行,请求头和请求正文)。
$request_time #请求处理时间,单位为秒,精度毫秒; 从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。
$time_iso8601 #ISO8601标准格式下的本地时间。
$time_local #通用日志格式下的本地时间。
自定义日志格式的使用:
access_log /var/logs/nginx-access.log main
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
注意:
注:如果Nginx位于负载均衡器,nginx反向代理之后,web服务器无法直接获取到客户端真实的IP地址。
$remote_addr获取的是反向代理的IP地址。反向代理服务器在转发请求的http头信息中,可以增加X-Forwarded-For信息,用来记录客户端IP地址。
使用log_format指令定义了一个main的格式,并在access_log指令中引用了它。客户端发起请求访问:http://192.168.246.154/,看一下请求的日志记录:
10.0.105.207 - - [01/Jul/2019:10:44:36 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" "-"
我们看到最终的日志记录中$remote_user、$http_referer、$http_x_forwarded_for都对应了一个-,这是因为这几个变量为空。
面试时:注意日志里面的ip地址一定要在第一列。
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。
扩展日志级别:
debug级别:低级别,包含的信息非常详细
info级别:稍微的高一点了。用的多一些。
notice 和warning
notice:相当于提示
warning:警告 和warn 一样
err和error 一样,记录错误日志
crit:比较严重了
alert:告警,很严重
emerg: 恐慌级别, 级别最高的
基本用法
error_log /var/logs/nginx/nginx-error.log
配置段: http, server, location作用域。
例子中指定了错误日志的路径为:/var/logs/nginx/nginx-error.log,日志级别使用默认的 error。
4、nginx 日志配置总结
Nginx中通过access_log和error_log指令配置访问日志和错误日志,通过log_format我们可以自定义日志格式。
详细的日志配置信息可以参考Nginx官方文档
单独开启server的访问日志
[root@nginx-client ~]# cd /etc/nginx/conf.d/
[root@nginx-client conf.d]# vim nginx.conf
server {
listen 80;
server_name localhost;
charset koi8-r;
access_log /var/log/nginx/test.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /admin {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
[root@nginx-client conf.d]# nginx -s reload
访问
[root@nginx-client conf.d]# curl -I http://192.168.1.10

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

作业:编写nginx日志切割脚本
[root@nginx-web script]# cat nginx_log.sh
#!/bin/bash
date=`date +%F -d -1day`
log_dir=/var/log/nginx/
log_name=access.log
[ -d $log_dir ] && cd $log_dir || exit 1
[ -f $log_name ] || exit 1
/bin/mv $log_name $log_name.${date}
/usr/sbin/nginx -s reload
tar czf $log_name.${date}.tar.gz $log_name.${date} && rm -rf $log_name_${date}
#delete
cd $log_dir || exit 1
find ./ -mtime +7 -type f -name *.tar.gz | xargs rm -rf
nginx 的平滑升级
1、为什么要对 nginx 平滑升级
随着 nginx 越来越流行,并且 nginx 的优势也越来越明显,nginx 的版本迭代也来时加速模式,1.9.0版本的nginx更新了许多新功能,例如 stream 四层代理功能,伴随着 nginx 的广泛应用,版本升级必然越来越快,线上业务不能停,此时 nginx 的升级就是运维的工作了
nginx 方便地帮助我们实现了平滑升级。其原理简单概括,就是:
(1)在不停掉老进程的情况下,启动新进程。
(2)老进程负责处理仍然没有处理完的请求,但不再接受处理请求。
(3)新进程接受新请求。
(4)老进程处理完所有请求,关闭所有连接后,停止。
这样就很方便地实现了平滑升级。一般有两种情况下需要升级 nginx,一种是确实要升级 nginx 的版本,另一种是要为 nginx 添加新的模块
2、Nginx信号简介
主进程支持的信号
- TERM, INT: 立刻退出
- QUIT: 等待工作进程结束后再退出
- KILL: 强制终止进程
- HUP: 重新加载配置文件,使用新的配置启动工作进程,并逐步关闭旧进程。
- USR1: 重新打开日志文件
- USR2: 启动新的主进程,实现热升级
- WINCH: 逐步关闭工作进程
工作进程支持的信号
- TERM, INT: 立刻退出
- QUIT: 等待请求处理结束后再退出
- USR1: 重新打开日志文件
3、nginx 平滑升级实战
1、查看现有的 nginx 编译参数
[root@nginx-server ~]# /usr/local/nginx/sbin/nginx -V
按照原来的编译参数安装 nginx 的方法进行安装,只需要到 make,千万不要 make install 。如果make install 会将原来的配置文件覆盖
[root@nginx-server ~]# cd /usr/local/nginx-1.16.0/
[root@nginx-server nginx-1.16.0]# ./configure --prefix=/usr/local/nginx --group=nginx --user=nginx --sbin-path=/usr/local/nginx/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/tmp/nginx/client_body --http-proxy-temp-path=/tmp/nginx/proxy --http-fastcgi-temp-path=/tmp/nginx/fastcgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-pcre --with-http_realip_module --with-stream --with-http_image_filter_module
[root@nginx-server nginx-1.16.0]# make
3、备份原 nginx 二进制文件
备份二进制文件和 nginx 的配置文件(期间nginx不会停止服务)
[root@nginx-server nginx-1.16.0]# mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx_$(date +%F)
4、复制新的nginx二进制文件,进入新的nginx源码包
[root@nginx-server nginx-1.16.0]# cp /usr/local/nginx-1.16.0/objs/nginx /usr/local/nginx/sbin/
5、测试新版本的nginx是否正常
[root@nginx-server nginx-1.16.0]# /usr/local/nginx/sbin/nginx -t
6、给nginx发送平滑迁移信号(若不清楚pid路径,请查看nginx配置文件)
[root@nginx-server ~]# kill -USR2 `cat /var/run/nginx.pid`
7、查看nginx pid,会出现一个nginx.pid.oldbin
[root@nginx-server ~]# ll /var/run/nginx.pid*
-rw-r--r-- 1 root root 5 Jul 1 11:29 /var/run/nginx.pid
-rw-r--r-- 1 root root 5 Jul 1 09:54 /var/run/nginx.pid.oldbin
8、从容关闭旧的Nginx进程
[root@nginx-server ~]# kill -WINCH `cat /var/run/nginx.pid.oldbin`
9、结束工作进程,完成此次升级
[root@nginx-server ~]# kill -QUIT `cat /var/run/nginx.pid.oldbin`
10、验证Nginx是否升级成功
[root@nginx-server ~]# /usr/local/nginx/sbin/nginx -V
4、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编码嵌入;如下:
base64 图片—转码
[root@localhost html]# vim 404.html
404
哎呀,找不到该页面啦!
请检查您的网络连接是否正常或者输入的网址是否正确
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//Z" class=“layout-img”>
哎呀,找不到该页面啦!
请检查您的网络连接是否正常或者输入的网址是否正确

