带你了解Nginx
基本概念
Nginx是一款轻量级的Web服务器、反向代理服务器,由于它的内存占用少,启动极快,高并发能力强,在互联网项目中广泛应用。
正向代理
在客户端(浏览器)配置代理服务器,通过代理服务器进行互联网访问。
反向代理
由反向代理服务器取选择目标服务器获取数据后,在返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器IP地址。
具体配置步骤:
(1)实现效果:打开浏览器,在浏览器地址栏输入地址www.123.com ,跳转到linux 系统tomcat 主页面中
(2)准备环境
(3)访问过程分析:
(4)配置步骤:
第一步在windows 系统的host 文件中进行域名和ip对应关系的配置。
写以下内容:
192.168.0.101 www.123.com
第二步在nginx进行请求转发的配置(反向代理)
打开nginx 下的conf/nginx.conf 文件,修改server_name 和 proxy_pass
访问成功
(5) 访问两个tomcat 不同端口上的页面
location 指令说明
负载均衡
单个服务器解决不了,我们增加服务器的数量,然后将请求分发到各个服务器上,将原先请求集中到单个服务上的情况改为将请求分发到多个服务器上,将负载分发到不同的服务器,也就是我们所说的负载均衡。
主要是在nginx.conf中进行配置
具体实例:
nginx 分配服务的策略
第一种轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down 掉,能自动剔除。
第二种 weight
weight 代表权重默认为1,权重越高被分配的客户端越多。指定轮询几率,weigth 和 访问比率成正比,用于后端服务器性能不均的情况。
upstream server_pool{
server 192.168.5.21 weight=10
server 192.168.5.22 weight=10
}
第三种 ip_hash
每个请求按访问ip 的hash 结果分配,这样每个访问固定访问一个后端服务器,就可以解决session 的问题。例如:
upstream server_pool{
ip_hash
server 192.168.5.21 weight=10
server 192.168.5.22 weight=10
}
第四种 fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
upstream server_pool{
fair
server 192.168.5.21 weight=10
server 192.168.5.22 weight=10
}
动静分离
为了加速网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度,降低原来单个服务器的压力。
通过location 指定不同的后缀名实现不同的请求转发。通过expires 参数设置,可以使浏览器缓冲过期时间,减少与服务器之前的请求和流量。Expires 定义:是给一个资源设定一个过期时间,也就是说无需去服务端验证。直接通过浏览器自身确认是否过期即可,所有不会产生额外的流量,此种方法非常适合不经常变动的资源。(如果经常更新的文件,不建议适应Expires 来缓冲),我这里设置的3d ,,表示在这三天之内访问这个URL,发送一个请求,比对服务器该文件最后更新时间没有变化,则不会从服务抓取,返回状态码304,如果有修改,则直接从服务重新下载,返回状态码200。
主要是ngnix 配置
高可用
安装keepalived 的命令
yum install keepalived -y
修改 keepalived.conf 文件
第一部分
第二部分
第三部分
脚本:
安装步骤
1.用 SecureCRT 8.1 连接Linux 操作系统
2.安装编译工具及库文件
yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel
3.先安装PRCE
PCRE 作用是让 Nginx 支持 Rewrite 功能
(1)下载PRCE 安装包
cd /usr/local/src/
wget http://downloads.sourceforge.net/project/pcre/pcre/8.35/pcre-8.35.tar.gz
(2) 解压安装包
tar zxvf pcre-8.35.tar.gz
(3)进入安装目录
cd pcre-8.35
(4) 编译安装
./configure
make && make install
(5) 查看pcre版本
pcre-config --version
4.安装Ngnix
(1)下载Nginx
cd /usr/local/src/
wget http://nginx.org/download/nginx-1.6.2.tar.gz
(2) 解压安装包
tar zxvf nginx-1.6.2.tar.gz
(3) 进入安装包目录
cd nginx-1.6.2
(4)编译安装
./configure --prefix=/usr/local/webserver/nginx --with-http_stub_status_module --with-http_ssl_module --with-pcre=/usr/local/src/pcre-8.35
make && make install
(5) 查看nginx 版本
/usr/local/webserver/nginx/sbin/nginx -v
检验是否安装成功
(1)切换到nginx 下的sbin 下才可以启动nginx
(2)启动,并查看进程中是否存在
./nginx
ps -ef | grep nginx
(3)打开 nginx/conf/nginx.conf
vi nginx.conf
默认是80端口
(4) 访问前台
发现无法访问,检查防火墙的端口是否打开
firewall-cmd --list-all
设置开放的端口号
sudo firewall-cmd --add-port=80/tcp --permanent
重启防火墙
firewall-cmd --reload
再次访问
nginx 操作的常用命令
使用命令的前提是必须进入到nginx/sbin
(1) 查看版本
./nginx -v
(2) 启动nginx
./nginx
(3)关闭nginx
./nginx -s stop
(4)重新加载nginx
./nginx -s reload
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;
er 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"';
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
# 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
nginx 的原理
一个master 和多个worker 的好处
(1)可以使用nginx -s reload 热部署,利用nginx 进行热部署操作
(2)每个worker 是独立的进程,如果有其中一个woker 出现问题,其他woker 独立的,继续进行争抢,实现请求过程,不会造成服务中断。
(3) 需要设置多少个worker?
nginx 同 redis 类似都采用io 多路复用机制,每个worker 都是一个独立的进程,但每个进程里只有一个主线程,通过异步非阻塞的方式来处理请求,每个worker 的线程可以把一个cpu 的性能发挥到极致。所以worker 数和服务器的cpu 数相等是最为适宜的,设少了浪费cpu,,设多了,会造成cpu 频繁切换上下文带来的损耗。
(4) 连接数 worker_connection
连接静态资源2个,访问数据库的时候4个
支持最大并发数:
Nginx的Master-Worker模式
启动Nginx后,其实就是在80端口启动了Socket服务进行监听,如图所示,Nginx涉及Master进程和Worker进程。
思考:Nginx如何做到热部署?
所谓热部署,就是配置文件nginx.conf修改后,不需要stop Nginx,不需要中断请求,就能让配置文件生效!(nginx -s reload 重新加载/nginx -t检查配置/nginx -s stop)
通过上文我们已经知道worker进程负责处理具体的请求,那么如果想达到热部署的效果,可以想象:
方案一:
修改配置文件nginx.conf后,主进程master负责推送给woker进程更新配置信息,woker进程收到信息后,更新进程内部的线程信息。(有点valatile的味道)
方案二:
修改配置文件nginx.conf后,重新生成新的worker进程,当然会以新的配置进行处理请求,而且新的请求必须都交给新的worker进程,至于老的worker进程,等把那些以前的请求处理完毕后,kill掉即可。
Nginx采用的就是方案二来达到热部署的!
思考:Nginx如何做到高并发下的高效处理?
上文已经提及Nginx的worker进程个数与CPU绑定、worker进程内部包含一个线程高效回环处理请求,这的确有助于效率,但这是不够的。
作为专业的程序员,我们可以开一下脑洞:BIO/NIO/AIO、异步/同步、阻塞/非阻塞...
要同时处理那么多的请求,要知道,有的请求需要发生IO,可能需要很长时间,如果等着它,就会拖慢worker的处理速度。
Nginx采用了Linux的epoll模型,epoll模型基于事件驱动机制,它可以监控多个事件是否准备完毕,如果OK,那么放入epoll队列中,这个过程是异步的。worker只需要从epoll队列循环处理即可。
思考:Nginx挂了怎么办?
Nginx既然作为入口网关,很重要,如果出现单点问题,显然是不可接受的。
答案是:Keepalived+Nginx实现高可用。
Keepalived是一个高可用解决方案,主要是用来防止服务器单点发生故障,可以通过和Nginx配合来实现Web服务的高可用。(其实,Keepalived不仅仅可以和Nginx配合,还可以和很多其他服务配合)
Keepalived+Nginx实现高可用的思路:
第一:请求不要直接打到Nginx上,应该先通过Keepalived(这就是所谓虚拟IP,VIP)
第二:Keepalived应该能监控Nginx的生命状态(提供一个用户自定义的脚本,定期检查Nginx进程状态,进行权重变化,,从而实现Nginx故障切换)