nginx简介
Nginx是一款开源代码的高性能HTTP服务器和反向代理服务器,同时支持IMAP/POP3/SMTP代理服务,处理高并发能力十分强大,能够经受高负载的考验,有报告表名nginx支持高达50000个并发连接数。
Linux下的nginx安装
Centos阿里云源配置
笔者这里使用的是centos7,在安装nginx之前需要对Linux源进行配置,配置教程可以移步笔者之前写过的文章。
Centos阿里云源配置
nginx的安装
由于上方步骤配置好了源,所以配置步骤也很方便,具体可以参见下方nginx安装教程。
nginx上手教程
nginx常用命令
查看nginx版本号
# 进入nginx目录
cd /usr/local/nginx/sbin
# 查看nginx版本号
./nginx -v
启动nginx
# 启动nginx
./nginx
停止nginx
# 停止nginx
./nginx -s stop
重新加载nginx配置
# 重新加载nginx
./nginx -s reload
nginx配置文件简介
nginx文件配置在conf目录下,所以我们可以通过cat命令到达nginx的conf目录查看配置详情。
cat /usr/local/nginx/conf/nginx.conf
nginx.conf配置文件的格式以及配置对应的含义笔者都已注明,读者可自行查阅。
全局配置
#user nobody; #运行用户
Worker_processes 1 ; #工作进程数量
#error_log log/error.log #错误日志文件的位置
#pid log/nginx.pid #PID文件的位置
I/O事件配置
events{
use epoll; #使用epoll模型
worker_connections 4096 #每进程处理4096个连接
}
HTTP配置
http {
.................
include mine.types; #nginx支持的媒体类型库文件
#include benet/www.conf #配置多个虚拟机主机,把server{}内的内容复制到外面新建的www.conf后包含进去
default_type application/octet-stranm; #默认的媒体类型
access_log log/access.log main; #访问日志位置
sendfile on ; #开启高效传输模式(支持文件发送下载)
keepalive_timeout 65; #连接保持超时
server { #可配置对三个基于域名的虚拟主机
listen 80; #web服务的监听配置
server_name www.benet.com #网站名称(FQDN),别名就是在后面再添加网址
charset utf-8 #网页的默认字符集
location / {
root html; #网站根目录的位置
error_page 500 502 503 504 /50x.html; #出现对应的http状态码时,使50x.html回应客户
location = /50x.html {
root html; #指定对应的站点目录为html
}
index index.html index.php #默认首页
}
}
nginx反向代理
简介
网站建立后,用户希望只需通过一个url即可访问网站。如下图所示,用户通过www.test.com
交由dns解析到而访问到nginx,此时nginx就是一个反向代理的角色,nginx收到请求后就会将请求转发的对应tomcat服务器上。
配置演示
基于上述需求,我们给出这样一个案例,希望打开浏览器,在浏览器地址栏输入地址 www.test.com
,跳转到指定一台的tomcat服务器中。
因为案例涉及tomcat服务器,所以笔者也给出安装tomcat服务器的步骤,具体步骤可参考笔者之前写过的这篇文章
Linux下tomcat的部署
由于本次实验需要通过域名访问nginx然后通过nginx请求tomcat主页并返回,所以为避免dns无法解析我们模拟的域名地址,可以在本机Windows下配置域名解析,具体步骤如下:
进入如下目录编辑hosts文件
C:\Windows\System32\drivers\etc
编辑该配置文件,内容如下,这里的ip地址是和本机桥接的虚拟机ip地址。
接下来就是编辑/usr/local/nginx/conf/nginx.conf
将内容改为如下所示,告知nginx监听的服务器地址和server_name
,以及跳转的代理服务器地址(即我们服务器上8080的tomcat服务器)。
最后重启nginx使配置生效。
#进入sbin目录输入
./nginx -s reload
测试
我们在Windows
系统的浏览器上输入对应的域名,可以看到浏览器跳转到了nginx代理的tomcat界面。
多映射反向代理
需求
我们希望使用 nginx 做反向代理,根据访问的路径跳转到不同端口的服务中,nginx 监听端口为 9001。希望访问192.168.1.29:9001/test1/index.html
和192.168.1.29:9001/test2/index.html
访问结果是不同的
配置演示
首先增加一台tomcat,如之前所示,注意修改相关端口与之区分,修改的端口如下所示:
同样的连接端口号改为8081
同样的下面这个端口号也改为8019。
完成配置后启动tomcat,并为两个tomcat配置不同的页面,即在分别在两台tomcat服务器下webapp
下,第一台tomcat参见test1目录并添加index.html,内容为:
this is 8080 port
第二台tomcat服务器即添加一个index.html内容为:
this is 8081 port
重点步骤来了,我们需要进行反向代理配置,进入nginx.conf进行如下配置,可以看到nginx会监听9001端口,对应test1映射的请求,就转发到8080的tomcat服务器上,对于test2的请求会转发到8081的服务器上。
server {
listen 9001;
server_name 192.168.1.29;
location ~ /test1/ {
proxy_pass http://127.0.0.1:8080;
}
location ~ /test2/ {
proxy_pass http://127.0.0.1:8081;
}
}
因为笔者是在虚拟机上做演示,需要一下开放9001端口。
firewall-cmd --zone=public --add-port=9001/tcp --permanent
systemctl stop firewalld.service
systemctl start firewalld.service
测试
先来请求test1
再请求test2
负载均衡
需求
浏览器地址栏输入地址 http://192.168.1.29/study/index.html
请求web页面,nginx会将多个http请求分配到8080或者8081服务器中。
步骤
准备两台tomcat服务器,并在webapp目录下创建study文件夹,并在文件夹中都创建一个index.html内容随意。
然后开启tomcat测试是否可达,先来测试8080的地址。
再测试8081地址。
然后就可以配置nginx负载均衡了,如下所示,upstream
即负载服务器,下文将upstream
起名为myserver
,然后在server
中配置负载服务器名myserver
即可完成负载均衡配置。
upstream myserver{
server 192.168.1.29:8080;
server 192.168.1.29:8081;
}
server {
listen 80;
server_name 192.168.1.29;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
proxy_pass http://myserver;
index index.html index.htm;
}
}
测试
我们连续刷新浏览器,可以看到每次请求到的tomcat页面都是不一样的。
可以看到第二次请求到了8081的tomcat上。
nginx 分配服务器策略
- 轮询(默认):每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,则自动剔除。
- weight:weight 代表权重默认为 1, 权重越高被分配的客户端越多
- ip_hash:每个请求按访问 ip 的 的 hash 结果分配,这样每个访客固定访问一个后端服务器
- fair(第三方):按后端服务器的响应时间来分配请求,响应时间短的优先分配。
动静结合
我们都知道请求一个web页面过程中,需要加载动态数据或者静态数据。动态数据变化多端,而静态数据基本不变。动静分离以后我们可以对静态文件放到一台服务器、动态文件放到另一台服务器上,加快网站解析速度,提升请求访问效率。
为了模仿动态文件和静态文件的场景,笔者在/data目录下创建www
作为动态文件夹,img
为静态文件夹。通过同一个http请求+文件路径模仿动态文件和静态文件的访问过程。
配置步骤
首先创建一个data文件夹
mkdir data
然后在该目录下创建动态文件和静态文件目录并添加文件
cd data/
mkdir www
mkdir img
nginx添加如下所示,可以看到对于img映射,笔者设置了autoindex,所以如果不指明文件名的话,会列出当前文件夹的所有文件。
测试
可以看到请求img直接显示文件界面
输入www就显示网站内容(我们假设这是动态的)
高可用配置(重点)
介绍
如下图,若只有一台nginx时,常规情况下发起http请求由nginx代理是正常的。当这台nginx服务器出现故障宕机了怎么办呢?
面对这种情况,我们预想的最好解决方案就是增加一台nginx服务器作为备用代理服务器,从而做到高可用配置。
如下图所示,用户使用192.168.1.50发起请求,若master主服务器正常则会交由主服务器代理http请求,若主服务器出现故障则由备用服务器进行http代理请求
配置步骤
- 增加一台虚拟机安装nginx服务器
- 两台虚拟机都安装keepalived
yum install keepalived –y
- 配置keepalived
配置keepalived检查主机存货状态脚本
vim /usr/local/src/nginx_check.sh
# 粘贴下方内容
#!/bin/bash
A=`ps -C nginx –no-header |wc -l`
if [ $A -eq 0 ];then
/usr/local/nginx/sbin/nginx
sleep 2
if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
killall keepalived
fi
fi
vim cd /etc/keepalived/keepalived.conf #编辑keepalived的配置文件
# 直接将内容覆盖成如下配置 配置详情可见注释
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.1.150 #本机ip地址
smtp_connect_timeout 30
router_id LVS_DEVEL # 本机设备名称,可使用命令 vim /etc/hosts 添加一行 127.0.0.1 LVS_DEVEL 完成主机id配置
}
# 下方为vrrp协议具体内容可参见百度
vrrp_script chk_http_port {
script "/usr/local/src/nginx_check.sh" # 检查当前服务器是否存货的脚本路径
interval 2 #(检测脚本执行的间隔)
weight 2
}
vrrp_instance VI_1 {
state MASTER # 备份服务器上将 MASTER 改为 BACKUP
interface ens33 //网卡
virtual_router_id 51 # 主、备机的 virtual_router_id 必须相同
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.50 // VRRP H 虚拟地址
}
}
- 开启nginx
- 开启keepalive
systemctl start keepalived.service
测试
使用192.168.1.50访问,若可以访问将master主机keepalived以及nginx关闭,再进行访问,关闭命令如下
systemctl stop keepalived.service
/usr/local/nginx/sbin/nginx -s stop
nginx原理解析
我们可以使用以下命令可以看到nginx的进程数
ps -ef |grep nginx
可以看出nginx占用了两个进程,一个是master,一个是worker,在我们发起请求到nginx时,nginx的master会收到该请求,并将请求发送给每个worker,所有worker会参与争抢。某个worker得到该请求后,若该请求是个代理请求,worker则会转发该请求到目标服务器。如下图所示:
那么问题来了,一个master搭配多个worker的好处有哪些呢?
- 热部署时,刷新配置不影响正在工作的worker。比如,我们当前这台nginx正在工作。某个worker正在担任某个服务器代理。此时,我们在nginx配置中添加一个新的代理工作。使用
./nginx -s reload
完成nginx重新加载,这时候就会又新的worker争抢这份工作。而之前已有工作的worker却不会收到影响。 - 每个worker是独立的进程。当某个worker出现问题时,其他worker不会收到影响。
由此我们又会问,那么设置几个worker数为宜呢?
与cpu数相等即可。比如八核就设置八个。
杀死nginx所有进程
有些情况我们会有多个nginx进程,如果我们希望杀死所有nginx进程可以使用下面这条命令:
kill -9 $(ps aux | grep 'nginx' | grep -v grep | tr -s ' '| cut -d ' ' -f 2)
nginx其他问题
发送一个请求时,master会占用worker几个连接数。
当只是请求静态资源时,只有请求结果,返回结果
这样一趟也就是两个请求。若作为代理,则是master->worker->目标服务器
+目标服务器->worker->master
计算箭头数则是4个请求。
假设nginx有一个master,和四个worker ,每个worker支持最大连接数为1024,支持的最大并发数为多少?
普通静态访问为:4*1024/2
(除2原因是因为一个静态请求有一趟往返,有一半的连接数处理返回结果了)
反向代理则是 4*1024/4
(与上同理)
常见问题
nginx配置不生效
问题简述:笔者在这段时间进行nginx配置时,进行正确的配置却发现配置没有生效,不断查看配置和reload没有发现问题所在。
解决方案:经过大佬排查很可能是nginx配置没有生效,将nginx所有进程杀死并重启nginx后配置就生效了,所以面对这类这类问题,在一切配置和部署方式都是正确的情况下,我们排查方向要从是否正确运行的方向进行思考。
参考文献
Nginx配置——动静分离: