Nginx入门--从核心配置与动静分离开始
写在前面
优化我们项目,服务器部署,不仅仅可以是分布式,Nginx一样可以通过动静分离,负载均衡来减轻我们服务器的压力。Nginx的知识链,学习周期相对比较长,博主也是刚刚入门,这篇就先从实现基础的动静分离,再了解一下基础概念与核心配置开始吧!
常见服务器对比
IIS
全称(Internet Information Services)即互联网信息服务,是由微软公司提供的基于windows系统的互联网基本服务。windows作为服务器在稳定性与其他一些性能上都不如类UNIX操作系统,因此在需要高性能Web服务器的场合下,IIS可能就会被"冷落"。
Tomcat
Tomcat是一个运行Servlet和JSP的Web应用软件,Tomcat技术先进、性能稳定而且开放源代码,因此深受Java爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web应用服务器。但是Tomcat天生是一个重量级的Web服务器,对静态文件和高并发的处理比较弱。
Apache
Apache的发展时期很长,同时也有过一段辉煌的业绩。从上图可以看出大概在2014年以前都是市场份额第一的服务器。Apache有很多优点,如稳定、开源、跨平台等。但是它出现的时间太久了,在它兴起的年代,互联网的产业规模远远不如今天,所以它被设计成一个重量级的、不支持高并发的Web服务器。在Apache服务器上,如果有数以万计的并发HTTP请求同时访问,就会导致服务器上消耗大量能存,操作系统内核对成百上千的Apache进程做进程间切换也会消耗大量的CUP资源,并导致HTTP请求的平均响应速度降低,这些都决定了Apache不可能成为高性能的Web服务器。这也促使了Lighttpd和Nginx的出现。
Lighttpd
Lighttpd是德国的一个开源的Web服务器软件,它和Nginx一样,都是轻量级、高性能的Web服务器,欧美的业界开发者比较钟爱Lighttpd,而国内的公司更多的青睐Nginx,同时网上Nginx的资源要更丰富些。
其他的服务器
Google Servers,Weblogic, Webshpere(IBM)...
经过各个服务器的对比,种种迹象都表明,Nginx将以性能为王。这也是我们为什么选择Nginx的理由。
Nginx的优点
(1)速度更快、并发更高
单次请求或者高并发请求的环境下,Nginx都会比其他Web服务器响应的速度更快。一方面在正常情况下,单次请求会得到更快的响应,另一方面,在高峰期(如有数以万计的并发请求),Nginx比其他Web服务器更快的响应请求。Nginx之所以有这么高的并发处理能力和这么好的性能原因在于Nginx采用了多进程和I/O多路复用(epoll)的底层实现。
(2)配置简单,扩展性强
Nginx的设计极具扩展性,它本身就是由很多模块组成,这些模块的使用可以通过配置文件的配置来添加。这些模块有官方提供的也有第三方提供的模块,如果需要完全可以开发服务自己业务特性的定制模块。
(3)高可靠性
Nginx采用的是多进程模式运行,其中有一个master主进程和N多个worker进程,worker进程的数量我们可以手动设置,每个worker进程之间都是相互独立提供服务,并且master主进程可以在某一个worker进程出错时,快速去"拉起"新的worker进程提供服务。
(4)热部署
现在互联网项目都要求以7*24小时进行服务的提供,针对于这一要求,Nginx也提供了热部署功能,即可以在Nginx不停止的情况下,对Nginx进行文件升级、更新配置和更换日志文件等功能。
(5)成本低、BSD许可证
BSD是一个开源的许可证,世界上的开源许可证有很多,现在比较流行的有六种分别是GPL、BSD、MIT、Mozilla、Apache、LGPL。这六种的区别是什么,我们可以通过下面一张图来解释下:
Nginx本身是开源的,我们不仅可以免费的将Nginx应用在商业领域,而且还可以在项目中直接修改Nginx的源码来定制自己的特殊要求。这些点也都是Nginx为什么能吸引无数开发者继续为Nginx来贡献自己的智慧和青春。OpenRestry [Nginx+Lua] Tengine[淘宝]
Nginx安装与配置
直接通过一条命令来安装相关环境
yum install -y gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel
进行全部安装。
wget
从官网中获取下载地址,如 wget http://nginx.org/download/nginx-1.16.1.tar.gz
- 也可以自行下载然后上传到服务器
tar -zxvf
建议直接安装在/usr/local 中 , 文件夹命名为nginx (后续操作会方便很多无需更改直接复用我的配置)
解压你下载下来的压缩包
***进入资源文件中,发现configure,然后./configure
注意./configure的时候这样设置就可以开启SSL支持了
注意此处写死了路径为 /usr/local
所以可以安装完更改一下nginx的安装路径为/usr/local/nginx
./configure --prefix=/usr/local/nginx \
--sbin-path=/usr/local/nginx/sbin/nginx \
--modules-path=/usr/local/nginx/modules \
--conf-path=/usr/local/nginx/conf/nginx.conf \
--error-log-path=/usr/local/nginx/logs/error.log \
--http-log-path=/usr/local/nginx/logs/access.log \
--pid-path=/usr/local/nginx/logs/nginx.pid \
--lock-path=/usr/local/nginx/logs/nginx.lock \
--with-http_ssl_module
make && make install
将nginx配置为环境变量
vi /etc/profil
然后添加
PATH=$PATH:/usr/local/nginx/sbin #此处对应为你的sbin目录位置
export PATH
最后记得 source /etc/profile
重新加载环境
验证一下 nginx -v
显示如下就没有问题了
nginx version: nginx/1.20.1
**最终完整配置(关于配置详解见后文)
user root;
worker_processes auto;
error_log /usr/local/nginx/logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
pid /usr/local/nginx/logs/nginx.pid;
events {
use epoll;
worker_connections 1024;
multi_accept on;
accept_mutex on;
}
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;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 75;
#gzip on;
server {
#选择要监听的端口
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
再使用nginx -s reload重新读取配置文件
发现报
nginx: [error] open() /usr/local/nginx/logs/nginx.pid failed (2: No such file or directory)错误,而且进到logs文件发现没有nginx.pid文件
使用nginx -c的参数指定nginx.conf文件的位置即可解决
nginx -c /usr/local/nginx/conf/nginx.conf
最后进入sbin目录 , ./nginx即可开启啦
记得先开启80端口安全组,如果报错地址已在使用,可能nginx已经启动了
- 可以lsof -i :80看看是不是nginx在使用了
- 或者直接访问 http://ip地址 看看是不是跳转到nginx的首页
至此,nginx的配置终于告一段落!
正向代理和反向代理
正向代理
正向代理,意思是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。
- 拿VPN举个例子,我们大陆没法直接访问到美国的服务器,而香港可以
- 所以我们可以在客户端和美国服务器之间加个中间商--香港服务器
- 让我们的客户端去请求香港服务器,然后香港服务器再帮我们去转发到美国服务器
正向代理是为我们服务的,即为客户端服务的,客户端可以根据正向代理访问到它本身无法访问到的服务器资源。
正向代理对我们是透明的,对服务端是非透明的,即服务端并不知道自己收到的是来自代理的访问还是来自真实客户端的访问。
反向代理
反向代理是为服务端服务的,反向代理可以帮助服务器接收来自客户端的请求,帮助服务器做请求转发,负载均衡等。
反向代理对服务端是透明的,对我们是非透明的,即我们并不知道自己访问的是代理服务器,而服务器知道反向代理在为他服务。
反向代理的优势:
- 隐藏真实服务器;
- 负载均衡便于横向扩充后端动态服务;
- 动静分离,提升系统健壮性;
动静分离
一般来说,都需要将动态资源和静态资源分开,由于 Nginx 的高并发和静态资源缓存等特性,经常将静态资源部署在 Nginx 上。如果请求的是静态资源,直接到静态资源目录获取资源,如果是动态资源的请求,则利用反向代理的原理,把请求转发给对应后台应用去处理,从而实现动静分离。
通俗来讲什么是动静分离?
- 动:后台应用程序的业务处理
- 静:网站的静态资源(html,javaScript,css,images等文件)
- 分离:将两者进行分开部署访问,提供用户进行访问。举例说明就是以后所有和静态资源相关的内容都交给Nginx来部署访问,非静态内容则交个类似于Tomcat的服务器来部署访问。
为什么要动静分离?
- 前面我们介绍过Nginx在处理静态资源的时候,效率是非常高的,而且Nginx的并发访问量也是名列前茅,而Tomcat则相对比较弱一些,所以把静态资源交个Nginx后,可以减轻Tomcat服务器的访问压力并提高静态资源的访问速度。
- 动静分离以后,降低了动态资源和静态资源的耦合度。如动态资源宕机了也不影响静态资源的展示。
假如某个时间点,由于某个原因导致Tomcat后的服务器宕机了,我们再次访问Nginx,会得到如下效果,用户还是能看到页面,只是缺失了访问次数的统计,这就是前后端耦合度降低的效果,并且整个请求只和后的服务器交互了一次,js和images都直接从Nginx返回,提供了效率,降低了后的服务器的压力。
如何实现动静分离?
- 实现动静分离的方式很多,比如静态资源可以部署到CDN、Nginx等服务器上,动态资源可以部署到Tomcat,weblogic或者websphere上。我使用的是Nginx+Tomcat来实现动静分离。
将war项目中的静态资源删除掉,重新打包生成war包
自行新建一个目录存放静态资源
修改nginx.conf
修改后保存,然后nginx-s reload即可
server {
#监听8081端口
listen 8081;
#服务器ip
server_name localhost;
#动态资源
location /demo {
proxy_pass localhostL:8082;
}
#静态资源
location /demo-html {
root /usr/local/nginx/html/dist;
index index.html index.htm;
}
}
效果
当我们访问 localhost:8081/demo/xxx , 就会去访问Tomcat中端口号为8082项目的动态资源
这个一般是写在前端的接口地址中的
而我们真正要在网页访问,只需要访问 localhost:8081/demo-html/index.html 即可
就会去相应的静态资源目录中找
Nginx服务器启停命令
默认多线程
核心配置文件结构
全局块
user指令
(1)user:用于配置运行Nginx服务器的worker进程的用户和用户组。
语法 | USER USER [GROUP] |
---|---|
默认值 | nobody |
位置 | 全局块 |
该属性也可以在编译的时候指定,语法如下./configure --user=user --group=group,如果两个地方都进行了设置,最终生效的是配置文件中的配置。
该指令的使用步骤:
(1)设置一个用户信息"www"
user www;
(2) 创建一个用户
useradd www
(3)修改user属性
user www
(4)创建/root/html/index.html页面,添加如下内容
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
<p><em>I am WWW</em></p>
</body>
</html>
(5)修改nginx.conf
location / {
root /root/html;
index index.html index.htm;
}
(5)测试启动访问
页面会报403拒绝访问的错误
(6)分析原因
因为当前用户没有访问/root/html目录的权限
(7)将文件创建到 /home/www/html/index.html,修改配置
location / {
root /home/www/html;
index index.html index.htm;
}
(8)再次测试启动访问
能正常访问。
综上所述,使用user指令可以指定启动运行工作进程的用户及用户组,这样对于系统的权限访问控制的更加精细,也更加安全。
work process指令
master_process:用来指定是否开启工作进程。
worker_processes:用于配置Nginx生成工作进程的数量,这个是Nginx服务器实现并发处理服务的关键所在。理论上来说workder process的值越大,可以支持的并发处理量也越多,但事实上这个值的设定是需要受到来自服务器自身的限制,建议将该值和服务器CPU的内核数保存一致。
rdc的服务器好像是用auto
语法 | WORKER_PROCESSES NUM/AUTO; |
---|---|
默认值 | 1 |
位置 | 全局块 |
如果将worker_processes设置成2,则会看到如下内容:
其他指令
daemon:设定Nginx是否以守护进程的方式启动。
守护式进程是linux后台执行的一种服务进程,特点是独立于控制终端,不会随着终端关闭而停止。
pid:用来配置Nginx当前master进程的进程号ID存储的文件路径。
语法 | PID FILE; |
---|---|
默认值 | 默认为:/usr/local/nginx/logs/nginx.pid |
位置 | 全局块 |
该属性可以通过./configure --pid-path=PATH来指定
error_log:用来配置Nginx的错误日志存放路径
语法 | ERROR_LOG FILE [日志级别]; |
---|---|
默认值 | error_log logs/error.log error; |
位置 | 全局块、http、server、location |
该属性可以通过./configure --error-log-path=PATH来指定
其中日志级别的值有:debug|info|notice|warn|error|crit|alert|emerg,翻译过来为试|信息|通知|警告|错误|临界|警报|紧急,这块建议大家设置的时候不要设置成info以下的等级,因为会带来大量的磁盘I/O消耗,影响Nginx的性能。
include:用来引入其他配置文件,使Nginx的配置更加灵活
语法 | INCLUDE FILE; |
---|---|
默认值 | 无 |
位置 | any |
events块
(1)accept_mutex:用来设置Nginx网络连接序列化
这个配置主要可以用来解决常说的"惊群"问题。大致意思是在某一个时刻,客户端发来一个请求连接,Nginx后台是以多进程的工作模式,也就是说有多个worker进程会被同时唤醒,但是最终只会有一个进程可以获取到连接,如果每次唤醒的进程数目太多,就会影响Nginx的整体性能。如果将上述值设置为on(开启状态),将会对多个Nginx进程接收连接进行序列号,一个个来唤醒接收,就防止了多个进程对连接的争抢。
(2)multi_accept:用来设置是否允许同时接收多个网络连接
建议on,效率会高一点
如果multi_accept被禁止了,nginx一个工作进程只能同时接受一个新的连接。否则,一个工作进程可以同时接受所有的新连接
(3)worker_connections:用来配置单个worker进程最大的连接数
语法 | WORKER_CONNECTIONS NUMBER; |
---|---|
默认值 | worker_commections 512; |
位置 | events |
这里的连接数不仅仅包括和前端用户建立的连接数,而是包括所有可能的连接数。另外,number值不能大于操作系统支持打开的最大文件句柄数量。
***(4)use:用来设置Nginx服务器选择哪种事件驱动来处理网络消息。
建议epoll
use epoll
语法 | USE METHOD; |
---|---|
默认值 | 根据操作系统定 |
位置 | events |
注意:此处所选择事件处理模型是Nginx优化部分的一个重要内容,method的可选值有select/poll/epoll/kqueue等,之前在准备centos环境的时候,我们强调过要使用linux内核在2.6以上,就是为了能使用epoll函数来优化Nginx。
另外这些值的选择,我们也可以在编译的时候使用
--with-select_module、--without-select_module、
--with-poll_module、--without-poll_module来设置是否需要将对应的事件驱动模块编译到Nginx的内核。
**events指令配置实例
打开Nginx的配置文件 nginx.conf,添加如下配置
events{
accept_mutex on;
multi_accept on;
worker_commections 1024;
use epoll;
}
启动测试
./nginx -t (测试)
./nginx -s reload
其他配置指令
(1)sendfile:用来设置Nginx服务器是否使用sendfile()传输文件,该属性可以大大提高Nginx处理静态资源的性能
(2)keepalive_timeout:用来设置长连接的超时时间。
为什么要使用keepalive?
我们都知道HTTP是一种无状态协议,客户端向服务端发送一个TCP请求,服务端响应完毕后断开连接。
如何客户端向服务端发送多个请求,每个请求都需要重新创建一次连接,效率相对来说比较多,使用keepalive模式,可以告诉服务器端在处理完一个请求后保持这个TCP连接的打开状态,若接收到来自这个客户端的其他请求,服务端就会利用这个未被关闭的连接,而不需要重新创建一个新连接,提升效率,但是这个连接也不能一直保持,这样的话,连接如果过多,也会是服务端的性能下降,这个时候就需要我们进行设置其的超时时间。
语法 | KEEPALIVE_TIMEOUT TIME; |
---|---|
默认值 | keepalive_timeout 75s; |
位置 | http、server、location |
(3)keepalive_requests:用来设置一个keep-alive连接使用的次数。
语法 | KEEPALIVE_REQUESTS NUMBER; |
---|---|
默认值 | keepalive_requests 100; |
位置 | http、server、location |
静态资源部署(root和index的含义)
root/alias
设置请求资源的目录root / alias
root:设置请求的根目录
语法 | root path; |
---|---|
默认值 | root html; |
位置 | http、server、location |
path为Nginx服务器接收到请求以后查找资源的根目录路径。
alias:用来更改location的URI
语法 | alias path; |
---|---|
默认值 | — |
位置 | location |
path为修改后的根路径。
以上两个指令都可以来指定访问资源的路径,那么这两者之间的区别是什么?
举例说明:
(1)在/usr/local/nginx/html
目录下创建一个 images目录,并在目录下放入一张图片mv.png
图片
location /images {
root /usr/local/nginx/html;
}
访问图片的路径为:
http://192.168.200.133/images/mv.png
(2)如果把root改为alias
location /images {
alias /usr/local/nginx/html;
}
再次访问上述地址,页面会出现404的错误,查看错误日志会发现是因为地址不对,所以验证了:
*** root的处理结果是: root路径+location路径
/usr/local/nginx/html/images/mv.png
alias的处理结果是:使用alias路径替换location路径
/usr/local/nginx/html/mv.png
需要在alias后面路径改为
location /images {
alias /usr/local/nginx/html/images;
}
(3)如果location路径是以/结尾,则alias也必须是以/结尾,root没有要求
将上述配置修改为
location /images/ {
alias /usr/local/nginx/html/images;
}
访问就会出问题,查看错误日志还是路径不对,所以需要把alias后面加上 /
小结:
root的处理结果是: root路径+location路径
alias的处理结果是:使用alias路径替换location路径
alias是一个目录别名的定义,root则是最上层目录的含义。
如果location路径是以/结尾,则alias也必须是以/结尾,root没有要求
index指令
index:设置网站的默认首页
语法 | index file ...; |
---|---|
默认值 | index index.html; |
位置 | http、server、location |
index后面可以跟多个设置,如果访问的时候没有指定具体访问的资源,则会依次进行查找,找到第一个为止。
举例说明:
location / {
root /usr/local/nginx/html;
index index.html index.htm;
}
访问该location的时候,可以通过 http://ip:port/,地址后面如果不添加任何内容,则默认依次访问index.html和index.htm,找到第一个来进行返回
error_page指令
error_page:设置网站的错误页面
语法 | error_page code ... [=[response]] uri; |
---|---|
默认值 | — |
位置 | http、server、location...... |
当出现对应的响应code后,如何来处理。
举例说明:
**(1)可以指定具体跳转的地址
server {
error_page 404 http://www.itcast.cn;
}
(2)可以指定重定向地址
server{
error_page 404 /50x.html;
error_page 500 502 503 504 /50x.html;
location =/50x.html{
root html;
}
}
写在最后
- 关于nginx的更多深入知识,负载均衡,缓存,ReWrite等,本专栏会持续更进,在学到用到的时候第一时间跟大家分享分享。