一、nginx基本概念
1.1 什么是nginx
nginx 是一个高性能的HTTP和反向代理web服务器,同时也提供了电子邮件IMAP/POP3/SMTP服务),其特点是占有内存少、并发能力强、事实上nginx的并发能力确实在同类型的网页服务器中表现较好。中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
1.2 nginx
作为web服务器nginx可以作为静态页面的web服务器,同时还支持CGI协议的动态语言,比如perl、php等,但是不支持java,java程序只能通过与tomcat配合完成,nginx专为性能优化而开发,性能是其最重要的考量,实现上非常注重效率,能经受高负载的考研,有报告表明能支持高达50000个并发连接数。
https://lnmp.org/nginx.html
1.3 反向代理
1.3.1 正向代理
nginx 不仅可以作反向代理,实现负载均衡,还能用做正向代理来进行上网等功能。正向代理:如果把局域网外的internet想象成一个巨大的资源库,则局域网中的客户端要访问internet,则需要通过代理服务器来访问,这种代理服务器就称为正向代理。
在客户端(浏览器)配置代理服务器,通过代理服务器进行互联网访问。说白了,就是能翻墙,访问外网。
1.3.2 反向代理
反向代理,其实客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,在返回给客户端,此时反向代理服务器,和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器IP地址。
1.4 负载均衡
客户端发送多个请求到服务器,服务器处理请求,有一些可能要与数据库进行交互,服务器处理我完毕后,再将结果返回给客户端。
这种架构模式模式对于早期的系统相对单一,并发请求相对较少的情况下比较适合的,成本也低,但是随着信息数量不断增长,访问量和数据量的飞速增长,以及系统业务的复杂度增加,这种架构会造成服务器相应客户端的请求日益缓慢,并发量特别大的时候,还容易造成服务器直接崩溃,很明显这是由于服务器性能的瓶颈造成的问题,那么如何解决这种情况呢?
我们首先想到的可能是升级服务器的配置,比如提高CPU执行频率,加大内存提高机器的物理性能来解决此问题,但是我们知道摩尔定律的日益失败,硬件的性能提升已经不能满足日益提升的需求了,最明显的例子,天猫双十一当天,某个热销商品的瞬时访问量是及其庞大的,南无类似上面的系统架构,将机器都增加到现有的顶级 物理配置,都是不能够满足需求的,那么怎么办呢?
上面的分析我们去掉了增加服务器物理配置来解决问题的办法,也就是说纵向解决问题的办法是行不通的,我们增加服务器的数量,然后将请求分发到各个服务器上,将原先请求集中到单个服务器的情况,改为将请求分发到多个服务器上,将负载分发到不同的服务器,也就是我们所说的负载均衡
1.5 动静分离
为了加快网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度,降低原来单个服务器的压力。
二、nginx 安装、常用命令和配置文件
2.1 Linux 安装nginx
1.将下载好后的
nginx.tar.gz
文件拖到linux的/usr/local下
2.解压tar -zxvf nginxxxx.tar.gz
3. 删除压缩包rm -rf nginx.xxx.tar.gz
4. 安装c语言yum install gcc-c++
下载C语言的开发包3个:
指令:yum install -y pcre-devel
指令:yum install -y zlib zlib-devel
指令:yum install -y openssl openssl-devel
5. 进入解压后的nginx文件目录执行如下命令
./configure
–prefix=/usr/local/nginx
–pid-path=/var/run/nginx/nginx.pid
–lock-path=/var/lock/nginx.lock
–error-log-path=/var/log/nginx/error.log
–http-log-path=/var/log/nginx/access.log
–with-http_gzip_static_module
–http-client-body-temp-path=/var/temp/nginx/client
–http-proxy-temp-path=/var/temp/nginx/proxy
–http-fastcgi-temp-path=/var/temp/nginx/fastcgi
–http-uwsgi-temp-path=/var/temp/nginx/uwsgi
–http-scgi-temp-path=/var/temp/nginx/scgi
- 编译安装 执行命令:
make
7.执行:make install
- 回退local目录下,此时会多出一个nginx目录
- 执行
mkdir -p /var/temp/nginx
10.进入local/nginx/conf下。将server_- 启动 local/nginx/sbin 下 ./nginx -s reload
- 查看进程是否启动 ps -ef | grep nginx
- 如果需要外部网络访问nginx,需要关闭防火墙
centOS6及以前版本使用命令:systemctl stop iptables.service
centOS7关闭防火墙命令:systemctl stop firewalld.service
关闭防火墙会导致服务器有一定风险,所以建议是单独开放服务端口
开放80端口:
firewall-cmd --zone=public --add-port=80/tcp --permanent
如果遇上指令出现报错,可执行如下指令,开启之后,再次开放如上指令,开放80端口
systemctl start firewalld.service
#开启服务
systemctl enable firewalld.service
#设置开机启动
查询端口号80 是否开启:firewall-cmd --query-port=80/tcp
重启防火墙:firewall-cmd --reload
随后访问该ip:端口 即可看到nginx界面
2.2 nginx 操作的常用命令
-
使用nginx操作命令前提条件,必须进入nginx的目录
/usr/local/nginx/sbin
-
查看nginx的版本号
./nginx -v
-
启动nginx
./nginx
-
关闭nginx
./nginx -s stop
-
重新加载nginx,配置文件修改时,不用先停止,在启动,可以reload即可加载最新的配置文件
./nginx -s reload
2.3 nginx 的配置文件
- nginx 配置文件位置
/usr/local/nginx/conf/
- nginx 配置文件组成
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
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;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#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;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
nginx 配置文件由三部分组成
第一部分:全局块
从配置文件开始到events块之间的内容,主要会设置一些影响nginx服务器整体运行的配置指令,主要包括配置运行nginx服务器的用户(组)、运行生成的worker process 数,进程PID存放路径,日志存放路径和类型以及配置文件的引入等。
这是nginx服务器并发处理服务的关键配置。worker_processes值越大,可以支持的并发处理量也越多,但是会受到硬件、软件等设备的制约
第二部分: events块
events块涉及的指令主要影响nginx服务器与用户网络的连接,常用的设置包括是否开启对多work
process下的网络连接进行序列化,是否运行同时接受多个网络连接,选取哪种事件驱动模型来处理连接请求,每个word process
可以同时支持的最大连接数等。 上述例子就表示每个work process 支持的最大连接数是1024.
这部分的配置对nginx的性能影响较大,在实际中应该灵活配置。
第三部分:http块
这算是Nginx服务器配置中最频繁的部分,代理、缓存和日志定义等绝大多少功能和第三方模块的配置都在这里。
需要注意的是:http块也可以包括http全局块、server块。
- http全局块
http 全局块配置的指令包括文件引入,MIME-TYPE定义、日志自定义、连接超时事件、单链接请求数上限等。 - server块
这块和虚拟主机由密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全一样的,该技术的产生是为了节省互联网服务器硬件成本。
每个http块可已包括多个server块,而每个server块就相当于一个虚拟主机。
而每个server块也分为全局server块,以及可以同时包含多个location块
全局server块
最常见的配置是本虚拟机主机的监听配置和本虚拟主机的名称或IP配置。
localtion 块
一个server块可以配置多个localtion块、
这块的主要作用是基于nginx服务器接收的请求字符串(例如 前面的/uri-string)进行匹配,对特定的请求进行处理,地址定向、数据缓存和应答控制等功能,还有许多第三方模块的配置也在这里运行。
三、nginx 配置文件实例-反向代理
tomcat 下载地址:https://tomcat.apache.org/download-80.cgi
jdk 下载地址:
1、实现效果
打开浏览器,在浏览器地址栏输入地址www.123.com,跳转到linux系统tomcat主页面中。
**2、 准备工作 **
1)在linux系统中安装tomcat,默认使用端口8080
tomcat安装文件到liunx系统中,解压,
进入tomcat的bin ./startup.sh 启动tomcat服务器。
2) 对外开放访问的端口。
firewall-cmd --add-port=8080/tcp --permanent
firewall-cmd --reload ##重新载入配置,比如添加规则之后,需要执行此命令
查看已经开放的端口: firewall-cmd --list-all
3. 访问过程分析
4、具体配置
- 在windows系统的host文件进行域名IP对应关系的配置
- 在nginx 的conf/nginx.conf文件下
5、最终效果
四、nginx 配置文件实例-反向代理
1.实现效果
使用nginx 反向代理,根据访问的路径跳转不同端口的服务中,nginx监听端口为9001
访问 http://127.0.0.1:9001/edu/
直接跳转到127.0.0.1:8080
访问 http://127.0.0.1:9001/vod/
直接跳转到127.0.0.1:8081
2. 准备工作
- 准备两个tomcat服务器。一个8080端口,一个8081端口
- 创建文件夹和测试页面
3.具体配置
- 找到nginx的配置文件,进行反向代理配置,配置完后进入nginx的sbin目录重新加载nginx配置
./nginx -s reload
location指令正则说明:
正则符号 | 说明 |
---|---|
= | 用于不含正则表达式的url前,要求请求字符串与url严格匹配,如果匹配成功,就停止继续向下搜索并立即处理该请求。 |
~ | 用于表示url包含正则表达式,并且区分大小写 |
~* | 用于表示url包含正则表达式,并且不区分大小写 |
^~ | 用于不含正则表达式的url前,要求nginx服务器找到标识url和请求字符串匹配最高的location后,立即使用此location处理请求,而不再使用location块中的正则url和请求字符串做匹配 |
注意:如果url包含正则表达式,则必须要有~
或者~*
标识
- 开放对外访问的端口号:9001
3. 测试
五、nginx配置实例-负载均衡
1、实现效果
浏览器地址栏输入地址 http://xxx/edu/a.html,负载均衡效果,平均8080和8081端口中。
2、准备工作
- 准备两台tomcat服务器,一台8080,一台8081
- 在两台tomcat里面webapps目录中,创建名称是edu文件夹,在edu文件夹中创建页面用于测试
3. 在nginx的配置文件中增加负载均衡的配置
4. 查看成果
随着互联网信息的爆炸性增长,负载均衡(load
balance)已经不再是一个很陌生的话题,顾名思义,负载均衡即是将负载分摊到不同的服务器单元,即保证服务的可用性,又保证响应足够块,给用户很好的体验,快速增长的访问量和数据流量催生了各式各样的负载均衡产品,很多专业的负载均衡硬件提供了很好的功能,但却价格不菲,这使得负载均衡软件大受欢迎,nginx就是其中一个,在Linux下有nginx,LVS,Haproxy等等服务可以提供负载均衡服务,而且nginx提供了几种分配方式(策略)
1、轮询(默认)
每个请求按事件顺序逐一分配到不同的后端服务器,如果后端服务器down掉,就能剔除。
2. weight
weight代表权重,默认为1,权重越高,分配的客户端越多。
指定轮询纪律,weight和访问比率成正比,用于后端服务器性能不均的情况:例如: 分配tomcat 8080:1次请求,在分配8081:2次请求,接着分配8080:1次请求,以此类推。
3.ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session问题,例如:
4. fair (第三方)
按后端服务器响应事件来分配请求,响应时间短优先分配、
六、nginx 配置实例-动静分离
6.1 什么是动静分离
nginx 动静分离简单来说就是把动态跟静态请求分开,不能理解成只是单纯的把动态页面和静态页面物理分离,严格意义上说应该是动态请求和静态请求分开,可以理解成使用nginx处理静态页面,tomcat处理动态页面,动静分离从目前实现角度来讲大致分为两种。
一种是纯粹把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案;
另外一种方法就是静态跟动态文件混合在一起发布,通过nginx来分开
通过location指定不同的后缀名实现不同的请求转发,通过expires参数设置,可以使浏览器缓存过期时间,减少与服务器之前的请求和浏览,具体Expires定义,是给一个资源设定一个过期时间,也就是说无需服务端验证,直接通过浏览器自身确认是否过期即可,所以不会产生额外的流量,此种方法非常适合不经常变动的资源(如果经常更新的文件,不建议使用Expires来缓存),我这里设置3d,表示三天之内访问这个url,发送一个请求,比对服务器该文件最后更新时间没有变化,则不会从服务器抓取,返回状态码304,如果有修改,直接从服务器重新下载,返回状态码200。
6.2 准备工作
在linux系统中准备静态资源,用于访问
6.3 具体配置
在nginx配置文件中进行配置
6.4最终测试
-
在浏览器中输入地址 http://192.168.31.132/image/01.jpg
autoindex on;
能列出文件目录; -
在浏览器地址栏输入地址http://192.168.31.132/page/a.html
七、nginx配置高可用集群-主从模式
7.1 什么是高可用集群
- 需要两台nginx服务器
- 需要keepalived
- 需要虚拟ip
7.2 配置高可用的准备工作
- 需要两台服务器 192.168.31.132 ;192.168.31.141
- 在两台服务器安装nginx
- 在两台服务器安装keepalived
使用yum命令进行安装yum install keepalived -y
查看是否已经安装rpm -q -a keepalived
keepalived会安装后在cd /etc生成keepalived配置文件,做主从nginx配置都是在keepalived.conf下进行相应修改
7.3 完成高可用配置(主从配置)
7.4 keepalive.conf的配置
! Configuration File for keepalived
# 全局配置
global_defs {
notification_email {
[email protected]
[email protected]
[email protected]
}
notification_email_from [email protected]
smtp_server 192.168.31.132 # 主机ip
smtp_connect_timeout 30
router_id LVS_DEVEL # 服务器域名,可以在etc/host中查看
}
# 检测脚本
vrrp_script chk_http_port {
script "/usr/local/src/nginx_check.sh" # 脚本路径
interval 2 # (检测脚本执行间隔,每2秒检测一次)
weight 2 # 设置服务器权重
}
# 虚拟IP配置
vrrp_instance VI_1 {
state MASTER # 备份服务器上将MASTER 改为BACKUP
interface ens33 # 网卡,可用 ip addr查看网卡名
virtual_router_id 51 # 主、备机的virtual_router_id必须相同, 这样keepalived才能知道当前主的和哪个系统的keepalived是一组的。
priority 100 # 主、备机取不同的的优先级,主机值较大,备份机值较小
advert_int 1 # 每一秒发送一次心跳
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.17.50 # VRRP H虚拟地址, 虚拟ip地址,用户浏览器访问,暴露给用户的,多台keepalived绑定一个ip;必须同一网段。
}
}
5 在/usr/local/src下添加nginx_check.sh的检测脚本
#!bin/bash
A=`ps -C nginx ---no-header |wc -l` # 获取nginx的状态
if [ $A -eq 0 ]; then # 为0时说明已经nginx已经挂掉了,进一步处理,非0时什么也不做
/usr/local/nginx/sbin/nginx # 尝试重启nginx
sleep 2 # 等待两秒,这里可以随意设置为的是给上面nginx留够启动的时间,保证nginx能正常启动
if [ `ps -C nginx --no-header |wc -l` -eq 0];then # 再次判断nginx是否已经启动成功,为0时,说明nginx无法启动了,彻底宕机了。
killall keepalived # 将keeaplived进程 彻底杀死
fi
fi
6 在/usr/local/src下添加nginx_check.sh的检测脚本
keepalived 启动命令 systemctl start keepalived.service
查看进程ps -ef | grep keepalived
7 最终测试
1)在浏览器访问虚拟ip地址:192.168.31.50
2)停止主服务器的nginx和keepalive,浏览器在进行访问。
3)恢复主服务器的keepalived心跳,验证从服务器是否切换为主服务器
总结:
测试的时候这里要保证keepalived的进程彻底杀死,之前不理解,一直以为将nginx stop就行了,这样并不行,
会给你一个错误的判断,仔细看上面的check的脚本就知道,它先判断nginx是否活着,nginx死掉了,它会尝试重启nginx,
实在nginx启动不了,它才会去杀死keepalived进程,
所有nginx的主从的心跳监听,其实在监听主从的keepalived的进程。并非nginx的进程。说白了,keepalived其实它是独立的,并不是只能和nginx搭配使用,check脚本时自定义的,它相当于keepalived的一个扩展,假设将nginx换成tomcat,脚本也可以这样写,当tomcat挂掉后,尝试重启tomcat,实在启动不了,就杀死keepalived,这里只是比喻。测试发现,主服务器的nginx宕机后,它会尝试启动nginx,当彻底启动不了,便将自身的keepalived进程杀死,以便备份服务器时时检测到主服务器keepalived心跳停止了,备份服务器便代理了主服务器的共作,但从服务器并没有放弃检测主服务器的心跳,当主服务器恢复了心跳,备份服务器便将接收浏览器请求的权力给主服务器,备份服务器依然会监听主服务器的keepalived的心跳。
八、nginx原理
一个master 和多个woker有什么好处
1.可以使用nginx -s reload 热部署,利于nginx进行热部署操作
2.对于每个worker进程来说,都是独立的进程,不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查找时,也会方便很多,其次,采用独立的进程,可以让互相之间不会影响,一个进程退出后,其他进程还在工作,服务器不会终端,master进程则很快启动新的worker进程,当然worker进程的异常退出,肯定时程序有bug了,异常退出,会导出前worker上的所有请求失败,不过不会影响所有请求,所有降低了风险
需要设置多少个worker
nginx同redis类似,都采用了io多路复用机制,每个worker都是一个对立的进程,但每个进程里只有一个主线程,通过异步非阻塞的方式来处理请求,即使是上万个请求也不再话下,每个worker的线程可以把一个cpu的性能发挥到极致。所有worker数和服务器的cpu数相当是最为适宜的,设少了会浪费cpu,设多了会造成cpu频繁切换上下文带来的损耗。