nginx访问配置
1. 初识Nginx配置文件以及基本命令
配置文件名为 nginx.conf ,Linux放在目录: /usr/local/nginx/conf 、 /etc/nginx , 或 /usr/local/etc/nginx 中;Windows放在 安装目录conf 中。 依据实际安装情况决定
nginx由配置文件中指定的指令控制模块组成。 指令分为 简单指令 和 块指令 :
简单指令 由空格分隔的名称和参数组成,并以分号 ; 结尾;
块指令 具有与简单指令相同的结构,但是是以大括号 { 和 } 包围的一组附加指令。 如果块指令在大括号内部有其他指令,则称为上下文(例如: events , http , server 和 location );
配置文件中放置在任何上下文之外的伪指令都被认为是主上下文。 events 和 http 指令驻留在主上下文中, server 在 http 中的,而 location 在 server 块中。一个配置文件一个 http ,一个及以上个 server ,一个 server 运行一个工作进程并代表一个虚拟服务器;
# 号所在的一行被视为注释;
几个顶级指令将适用于不同流量类型的指令组合在一起:
对于大多数指令,在子上下文中定义的上下文将继承父级中包含的伪指令的值,要覆盖从父进程继承的值,子上下文中需要包含该指令(即子上下文要显式声明)。
打开配置文件(如 /usr/local/nginx/conf/nginx.conf ),默认的配置文件已经包含了服务器块的几个示例,大部分是注释掉的。 现在注释掉所有这样的块,并启动一个新的服务器块:
每个 server 上下文都可以指定要监听的端口、server_name,当nginx决定哪个服务器处理请求后,它会根据服务器块内部定义的location指令的参数测试请求头中指定的URI, 比如如下配置,系统中创建 /data 目录及其子目录 /www :
第一个 location 块指定与请求中的URI比较 / 前缀。 对于匹配请求,URI将被添加到 root 指令中指定的路径(即 /data/www ),形成本地文件系统中的请求文件路径。 如果有几个匹配的location块,nginx将选择具有最长前缀来匹配location块。 上面第一个 location 块提供最短的前缀长度为1,因此只有当所有其他location块不能提供匹配时,才会使用该块。第二个 location ,将是以 /images/ 的请求来匹配,位置 / 也匹配这样的请求,但具有较短前缀,也就是 /images/ 比 / 长。
这已经是一个在标准端口 80 上侦听并且可以在本地机器上访问的服务器 http://localhost/ 的工作配置, 端口 80 和 server_name localhost 可以省略,它们为默认值 。 响应以/images/开头的URI的请求,服务器将从 /data/images 目录发送文件。 例如,响应 http://localhost/images/logo.png 请求,nginx将发送服务上的 /data/images/logo.png 文件。 如果文件不存在,nginx将发送一个指示 404 错误的响应。 不以 /images/ 开头的URI的请求将映射到 /data/www 目录。 例如,响应 http://localhost/about/example.html 请求时,nginx将发送 /data/www/about/example.html 文件。
反向代理应该是Nginx做的最多的一件事了,反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。简单来说就是真实的服务器不能直接被外部网络访问,所以需要一台代理服务器,而代理服务器能被外部网络访问的同时又跟真实服务器在同一个网络环境,当然也可能是同一台服务器,端口不同而已。
通过向nginx配置文件添加一个server块来定义代理服务器,其中包含以下内容:
这将是一个监听端口 8080 的简单服务器,并将所有请求映射到本地文件系统上的 /data/up1 目录。 请注意,root指令位于server块上下文中,当选择用于服务请求的 location 块不包含自己的 root 指令时,将使用此root指令。创建 /data/up1 目录然后可以将一个静态网页比如 index.html 文件放入其中,然后访问 http://localhost:8080/ 即可访问该文件。
目前为止,还是配置的静态资源访问,并不是代理服务器,然后增加或修改现有 location 上下文,改为如下:
当用户访问 http://localhost:8080/ 时,会返回 http://localhost:8181 服务器的的资源。
location 上下文后面的参数,可以是正则表达式,如果是正则表达式,前面要加 ~ ,比如:
以上配置表示,nginx接收到所有以.gif,.jpg或.png结尾的URI,相应的请求将映射到/data/images目录。当nginx选择一个location块来提供请求时,它首先检查指定前缀的location指令,记住具有最长前缀的location,然后检查正则表达式。 如果与正则表达式匹配,nginx会选择此location,否则选择之前记住的那一个。
要找到最符合URI的位置,NGINX首先将URI与前缀字符串的位置进行比较。然后用正则表达式搜索位置。除非使用^~修饰符对正则表达式给予更高的优先级。在前缀字符串中,NGINX选择最具体的字符串(也就是最长和最完整的字符串)。 下面给出了选择处理请求的位置的确切逻辑:
测试所有URI的前缀字符串。 = (等号)修饰符定义了URI和前缀字符串完全匹配。如果找到完全匹配,则搜索停止。如果 ^~ (插入符号)修饰符预先添加最长匹配前缀字符串,则不会检查正则表达式。存储最长匹配的前缀字符串。根据正则表达式测试URI。断开第一个匹配的正则表达式并使用相应的位置。如果没有正则表达式匹配,则使用与存储的前缀字符串相对应的位置。
= 修饰符的典型用例是 / (正斜杠)的请求。 如果请求/是频繁的,则指定 = / 作为location指令的参数加速处理,因为搜索匹配在第一次比较之后停止。
要启动nginx,请运行可执行文件。 当nginx启动后,可以通过使用-s参数调用可执行文件来控制它。 使用以下语法:
信号(signal)的值可能是以下之一:
当主进程收到要重新加载配置的信号,它将检查新配置文件的语法有效性,并尝试应用其中提供的配置。 如果这是成功的,主进程将启动新的工作进程,并向旧的工作进程发送消息,请求它们关闭。 否则,主进程回滚更改,并继续使用旧配置。 老工作进程,接收关闭命令,停止接受新连接,并继续维护当前请求,直到所有这些请求得到维护。 之后,旧的工作进程退出。
两者在 location 中,指定一个路径,其中使用 alias 做如下配置:
若按照上述配置的话,则访问/img/目录里面的文件时,ningx会自动去/var/www/image/目录找文件
若按照这种配置的话,则访问/img/目录下的文件时,nginx会去/var/www/image/img/目录下找文件。alias是一个目录别名的定义,root则是最上层目录的定义,指的是 /var/www/image/img/ 。还有一个重要的区别是alias后面必须要 / 结束,否则会找不到文件,而root则可有可无。
另外对于index,含义如下
这样,当用户请求 / 地址时,Nginx 就会自动在 root 配置指令指定的文件系统目录下依次寻找 index.htm 和 index.html 这两个文件。如果 index.htm 文件存在,则直接发起“内部跳转”到 /index.htm 这个新的地址;而如果 index.htm 文件不存在,则继续检查 index.html 是否存在。如果存在,同样发起“内部跳转”到 /index.html ;如果 index.html 文件仍然不存在,则放弃处理权给 content 阶段的下一个模块。
参考地址1
参考地址2:B站
2. 基于 Docker 安装 Nginx,启动运行,外网访问,映射配置文件
基于 Docker 安装 Nginx
查找Nginx镜像
语法:docker search nginx
示例:
获取Nginx镜像
示例:
启动nginx容器实例
说明:--name nginx nginx 第一个nginx是通过--name指定的nginx容器实例的名称,另一个nginx表示nginx仓库的名称。
查看nginx容器实例的进程信息
通过ps -ef | grep nginx查看
进入nginx容器内
杀死nginx容器实例
停止nginx实例
启动nginx容器实例
重启nginx容器实例
移除nginx容器实例
案例
暴露外部端口
基于docker run -d --name nginx nginx方法启动nginx后,Docker 容器并没有对外暴露访问的端口,即无法通过当前主机外部浏览器器访问nginx。那么该怎么样呢?
语法:
-p 80:80:通过-p来指定Docker容器中nginx实例对外开放的端口。本例中,第一个80端口是对外开放的端口,第二个80端口指对外开放的端口映射到容器里的端口号。
示例:
通过当前主机外的浏览器访问nginx,如下图:
指定外部的配置文件
语法:
说明:
-v: 表示挂载一个本机目录或文件到容器里。
-v /develop/nginx/nginx.conf:/etc/nginx/nginx.conf:将/develop/nginx/nginx.conf配置文件挂载到容器中/etc/nginx/nginx.conf这个配置文件中。
-v /develop:/develop:将/develop这个目录挂载到容器里的/develop这个目录里。
示例:
注意事项:指定外部配置文件,同时需要指定nginx的首页面,否则会抛出404错误,原因就是因为nginx找不到配置文件中默认的index页面。
本例中,使用/develop/apps/static/index.html替代了容器里的nginx默认的index页面,同时,-v /develop:/develop挂载根目录即可访问子目录。
指定网络模式:--net=bridge 默认模式
其中8080是指主机的端口,而80是指容器的端口
我们先看一下端口的状态
docker是运行在Linux上的,在Windows中运行docker,实际上还是在Windows下先安装了一个Linux环境,然后在这个系统中运行的docker。也就是说,服务中使用的localhost指的是这个Linux环境的地址,而不是我们的宿主环境Windows。我们可以通过命令:
找到这个Linux的ip地址,一般情况下这个地址是192.168.99.100,然后在Windows的浏览器中,输入这个地址,加上服务的端口即可启用了。
3. Nginx运行原理和配置详解(个人总结笔记)
话不多说,撸起键盘就是干!正所谓知其然知其所以然,个人总结了下Nginx运行原理和配置详解,便于理解和后续复盘。
先来看这一张图。
nginx启动后会有 一个master进程和多个worker进程 。master进程用来管理worker进程, 一个worker进程处理一个请求 ,一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。 worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致 ,这里面的原因与nginx的进程模型以及事件处理模型是分不开的 ,过多的worker数,只会导致进程来竞争cpu资源,从而带来不必要的上下文切换。
php WEB服务器目前最佳方式之一就是: Nginx + FastCGI(解决CGI并发重复fork问题) + PHP-FPM(管理PHP-CGI进程) 。nginx是怎么做到把请求抛给PHP解释来处理的呢?这个过程又是怎么实现的呢?稍后我们来看一下参数配置。
代理,反向代理,负载均衡是Nginx常用功能。
Http代理,反向代理:作为web服务器最常用的功能之一,尤其是反向代理。如果你和小马之前一样还是分不清代理和反向代理的区别,下面这个图对理解会有所帮助。
它们的区别就是,前者知道我要找的人并知道地址在哪,代理服务器按这个地址代为请求一下然后把他说的话返回给我。后者就是,我知道我要找谁问话但不知道地址在哪,我也不想管,代理服务你自己去找,只要帮我返回他要说的话就可以了。
负载均衡:其实也是 反向代理 的一种。负载均衡,热备等等其实都属于高可用范畴,Nginx提供的负载均衡策略有2种:内置策略和扩展策略。内置策略为 轮询,加权轮询,Ip hash 等等。扩展策略,就天马行空,只有你想不到的没有他做不到的啦,你可以参照所有的负载均衡算法,给他做下实现。思考一个问题,IP hash真的能解决session共享的问题么?
我们来简单看下两个 配置示例 。
这个配置将请求转发转向mysvr 定义的服务器列表。 注意proxy_pass配置。其实这块也是负载均衡的配置 。如下:
在访问网站时,由于配置了proxy_pass地址,所有请求都会先通过nginx反向代理服务器,在服务器将请求转发给目的主机时,读取upstream为 tomcatsever1的地址,读取分发策略,配置tomcat1权重为3,所以nginx会将大部分请求发送给49服务器上的tomcat1,也就是8080端口;较少部分给tomcat2来实现有条件的负载均衡,当然这个条件就是服务器1、2的硬件指数处理请求能力。
负载均衡配置 还有其他的相关参数,这是只是打个样,不赘述。
可以认为fastcgi_pass这个配置非常关键,将Nginx + FastCGI + PHP-FPM串连 。这个配置将PHP请求都交给 fastcgi_pass配置的PHP-FPM处理。 location分别通过正则过滤和转发配置决定了各个请求URL将要转发交与的处理方式 ,location /表示默认请求,location ~\.php(.*)$ 表示PHP 脚本请求全部转发到 FastCGI处理。 使用FastCGI默认配置.。
以上配置指定了这些 静态文件要nginx自己处理 。
NGINX负载均衡可以用于很多服务负载均衡的实现,比如做Redis服务的负载均衡,配置upstream的IP列表再配置 proxy_pass 代理即可。那要实现负载均衡除了NGINX,还有哪些呢?
根据7层OSI模型可将负载均衡分为 :
1)二层负载均衡(一般是用虚拟mac地址方式,外部对虚拟MAC地址请求,负载均衡接收后分配后端实际的MAC地址响应);
2)三层负载均衡(一般采用虚拟IP地址方式,外部对虚拟的ip地址请求,负载均衡接收后分配后端实际的IP地址响应);
3)四层负载均衡(在三次负载均衡的基础上,用 ip+port 接收请求,再转发到对应的机器);
4)七层负载均衡(根据虚拟的url或是IP,主机名接收请求,再转向相应的处理服务器)。
这其中,最常见的是四层和七层负载均衡。思考一下,NGINX的负载均衡是属于哪一种?
关于负载均衡的架构
4. 不容错过的Nginx配置详解,一文带你搞懂Nginx
Nginx是一个高性能的HTTP和反向代理服务器,特点是占用内存少,并发能力强,事实上Nginx的并发能力确实在同类型的网页服务器中表现好。Nginx专为性能优化而开发,性能是其最重要的考量,实现上非常注重效率,能经受高负载的考验,有报告表明能支持高达50000个并发连接数。
需要客户自己在浏览器配置代理服务器地址。
例如:在大陆访问www.google.com,我们需要一个代理服务器,我们通过代理服务器去访问谷歌,这个过程就是正向代理。
反向代理,客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,在返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器IP地址。
单个服务器解决不了,我们增加服务器的数量,然后将请求分发到各个服务器上,将原先请求集中到单个服务器上的情况改为将请求分发到多个服务器上,将负载分发到不同的服务器,也就是我们说的负载均衡。
为了加快网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度。降低原来单个服务器的压力。
进入到下面的目录,然后使用命令
配置文件所在位置:/usr/local/nginx/conf/nginx.conf
由全局块+events块+http块组成
从配置文件开始到events之间的内容,主要会设置一些影响Nginx服务器整体运行的配置指令,主要包括配置运行Nginx服务器的用户(组)、允许生成的worker process数,进程pid存放路径、日志存放路径和类型以及配置文件的引入等。
events块设计的指令主要影响Nginx服务器与用户的网络连接,常用的设置包括是否开启对多work process下的网络连接进行序列化,是否允许同时接收多个网络连接,选取哪种事件驱动模型来处理连接请求,每个work process可以同时支持的最大连接数等。下面的例子表示每个work process支持的最大连接数为1024。这部分配置对Nginx的性能影响较大,在实际中应该灵活配置。
Nginx服务器配置中最频繁的部分,代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里,http块又包括http全局块和server块。
http全局块配置的指令包括文件引入、MIME-TYPE定义、日志自定义、连接超时时间、单链接请求数上限等。
这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全一样的,该技术的产生是为了节省互联网服务器硬件成本。
每个http块可以包括多个server块,而每个server块就相当于一个虚拟主机。
每个server块也可以分为全局server块,以及可以同时包含多个location块。
最常见的配置时本虚拟主机的监听配置和本虚拟主机的名称或IP配置。
一个server块可以配置多个location块。
这块的主要作用是基于Nginx服务器接收到的请求字符串(例如server_name/uri-string),对虚拟主机名称(也可以是IP别名)之外的字符串(例如前面的/uri-string)进行匹配,对特定的请求进行处理。地址定向、数据缓存和应答控制等功能,还有许多第三方模块的配置也在这里进行。
访问http://ip,访问到的是Tomcat的主页面http://ip:8080。
Nginx+JDK8+Tomcat
访问:http://192.168.71.167/,看到的是Tomcat的首页。
根据访问的路径跳转到不同的服务器中去。
访问http://ip:9001/e 直接跳到http://127.0.0.1:8080/e
访问http://ip:9001/vod 直接跳到http://127.0.0.1:9090/vod
Nginx+JDK8+配置两个Tomcat,Tomcat的配置不再讲述。
访问http://192.168.71.167:9001/e/a.html跳到了http://127.0.0.1:8080/e/a.html页面。
访问http://192.168.71.167:9001/vod/a.html跳到了http://127.0.0.1:9090/vod/a.html页面。
假如Nginx代理服务器Server的配置为:192.168.71.167:9001,跳到:127.0.0.1:8080,访问者的IP为:192.168.71.200:20604。
通过访问http://192.168.71.167/e/a.html,实现负载均衡的效果,平均分摊到8080和8081端口中。
Nginx+JDK8+2台Tomcat,一台8080,一台8081。
访问:http://192.168.71.167/e/a.html,8080和8081交替访问。
1 轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
2 weight
weight代表权重,默认为1,权重越高被分配的客户端越多。
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
3 ip_hash
每个请求按访问IP的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题,示例如下:
4 fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
访问图片:http://192.168.71.167/image/1.jpg
访问页面:http://192.168.71.167/www/a.html
访问目录:http://192.168.71.167/image/(因为设置了autoindex on;)
两台机器,每台机器都装有keepalived+Nginx+Tomcat。
主备keepalived服务器中只有master一台机器会出现VIP地址,否则会出现脑裂问题。
【提示】脚本要加+x的执行权限:chmod +x chk_nginx.sh
在Nginx里把虚拟IP配置进去即可。
一个Nginx是由一个master进程和多个worker进程组成的。
客户端发送请求到Master,然后给worker,再由这些work争抢处理这个请求。
1 可以使用nginx -s reload进行热部署方式;
2 每个worker是独立的进程,如果有其中的一个worker出现了问题,其他worker独立的继续进行争抢,实现请求的过程,不会造成服务的中断;
Nginx和Redis类似,都采用了io多路复用机制。每个worker进程都可以把CPU发挥到极致,一般来说worker数和服务器的CPU数相等是最为适宜的。
发送请求:访问静态资源占用2个连接,反向代理占用4个连接。
【温馨提示】
5. Nginx配置文件详解
说到该指令 ,首先得阐述一下什么是所谓的 “惊群问题”,可以参考 WIKI网络的解释。就Nginx的场景来解释的话大致的意思就是:当一个新网络连接来到时,多个worker进程会被同时唤醒,但仅仅只有一个进程可以真正获得连接并处理之。如果每次唤醒的进程数目过多的话,其实是会影响一部分性能的。
所以在这里,如果accept_mutex on,那么多个worker将是以串行方式来处理,其中有一个worker会被唤醒;反之若accept_mutex off,那么所有的worker都会被唤醒,不过只有一个worker能获取新连接,其它的worker会重新进入休眠状态。
用rewrite转发的话,url会发生变化的,那就用proxy_pass吧,于是添加了如下的配置:
在现有环境的nginx里添加这段配置之后,访问却始终转不过去,查看nginx日志也只能看到是404信息,并没有更多定位问题的信息。检查了许久也没找到原因,于是重新装了一台新nginx,里面只加上面这段配置,结果nginx是能够转发成功的,这说明单独来看这条location的配置是没有问题的,很有可能是现有环境nginx里的某些配置影响到了这个转发。
为了定位问题原因,我将aaa.example.com虚拟主机下的其他配置注意注释掉来调试,最后发现当注释掉proxy_set_header Host $http_host ;这条配置之后,就能成功转发了。这才注意到是反向代理配置的问题。现有环境中原有的配置也不能随便删掉,上网查了下原因,找到下面这种解决方案:
即,在location里面添加一条proxy_set_header Host http_host时,则不改变请求头的值,所以当要转发到bbb.example.com的时候,请求头还是aaa.example.com的Host信息,就会有问题;当Host设置为$proxy_host时,则会重新设置请求头为bbb.example.com的Host信息。
另外,关于proxy_pass转发url的参数,可以通过在location中用rewrite来做,所以完善后的配置如下:
在location用rewrite改变了URI之后,proxy_pass将使用改变后的URI。上面例子(.*)是将所有参数传给 1会拼接在 http://bbb.example.com 后面。
先来看下proxy_set_header的语法
允许重新定义或者添加发往后端服务器的请求头。value可以包含文本、变量或者它们的组合。 当且仅当当前配置级别中没有定义proxy_set_header指令时,会从上面的级别继承配置。 默认情况下,只有两个请求头会被重新定义:
当匹配到/customer/straightcustomer/download时,使用crmtest处理,到upstream就匹配到crmtest.aty.sohuno.com,这里直接转换成IP进行转发了。假如crmtest.aty.sohuno.com是在另一台nginx下配置的,ip为10.22.10.116,则$proxy_host则对应为10.22.10.116。此时相当于设置了Host为10.22.10.116。如果想让Host是crmtest.aty.sohuno.com,则进行如下设置:
如果不想改变请求头“Host”的值,可以这样来设置:
但是,如果客户端请求头中没有携带这个头部,那么传递到后端服务器的请求也不含这个头部。 这种情况下,更好的方式是使用$host变量——它的值在请求包含“Host”请求头时为“Host”字段的值,在请求未携带“Host”请求头时为虚拟主机的主域名:
此外,服务器名可以和后端服务器的端口一起传送:
如果某个请求头的值为空,那么这个请求头将不会传送给后端服务器:
nginx配置项,里面的配置项有代理https,http,代理静态文件,H5分发,代理TCP连接,能满足大多数搭建测试环境所要用的nginx的情况,大家碰到要使用nginx的时候可以参考下