1. 简介
1.1 认识Nginx
Nginx 是高性能的 HTTP 和反向代理 web 服务器,其特点是占有内存少,并发能力强,国内使用 nginx 网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
Nginx 主要做:反向代理、负载均衡、动静分离。
Nginx 和 Tomcat 的区别?
- Nginx 可以作为静态页面的 web 服务器,将外来请求转发给后面的应用服务(tomcat、django 等),同时还支持 CGI 协议的动态语言,比如 perl、php 等,但是不支持 java。
- Tomcat 更多用来做一个应用容器,我们编写的 Java 项目可以在 Tomcat 下的 webapps 目录下运行,对应同级别的有 jboss 等。
- 但是事无绝对,nginx 也可以通过模块开发来提供应用功能,tomcat 也可以直接提供 http 服务,通常用在内网和不需要流控等小型服务的场景。
1.2 安装Nginx
- 联网下载 pcre:
wget http://downloads.sourceforge.net/project/pcre/pcre/8.37/pcre-8.37.tar.gz
。 - 解压缩:
tar -zxvf pcre-8.37.tar.gz
。 ./configure
完成后,回到 pcre 目录下执行 make,最后执行make install
。- 检查版本:
pcre-config --version
。 - 安装 openssl、zlib、gcc 依赖:
yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel
。 - 安装 nginx:
./configure
,make && make install
,并进入目录 /usr/local/nginx/sbin,执行 ./nginx 启动服务。 -
1.3 反向代理
1、正向代理:用户或者浏览器想要访问谷歌,但是无法直接访问,这时需要一个代理服务器(www.xxx.com),在客户端(浏览器)配置代理服务器信息,通过代理服务器进行联网访问。
2、反向代理:比如说我们想要别人访问我们的网址,但是又不想暴露 ip 和 端口,这时可以使用反向代理服务器。客户端不需要任何配置(即客户端对代理是无感知的),只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后再返回给客户端,此时反向代理服务器和目标服务器对外相当于就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器IP地址。
1.4 动静分离
动静分离:简单来说,把静态资源和动态文件由不同的服务器来解析,加快解析速度。在我们的软件开发中,有些请求是需要后台处理的(比如 jsp、servlet 等)称为动态文件,有些请求是不需要后台处理的(比如 css、html、jpg 等),称为静态文件。动静分离是将网站静态资源与后台应用分开部署,提高用户静态代码的速度,降低对后台应用访问,我们一般是将静态资源放到 Nginx 中,动态资源转发到 Tomcat 服务器中。动静资源做好拆分了以后,我们可以根据静态资源的特点将其做缓存操作,提高网站的性能,这就是网站静态化处理的核心思路。
1.5 负载均衡
负载均衡:比如说客户端(浏览器)发送多个请求到服务器,服务器处理请求,有一些需要与数据库进行交互,服务器处理完毕后,再将结果返回给客户端。但是当请求过多(即并发量特别大)的时候,单个服务器容易崩溃。我们有两种解决办法,一种是更换服务器为更高内存的(代价太大),另一种是增加服务器的数据,然后将请求分发到各个服务器。也就是说,将原先请求集中到单个服务器上的情况改为将请求分发到多个服务器上,降低了单个服务器压力,将负载分发到不同的服务器,也即是我们所说的负载均衡。
2. Nginx配置实例
2.1 实例一
实现效果:打开浏览器,在浏览器地址栏输入:www.123.com,直接跳转到 linux 系统 tomcat 主页面。
步骤如下: 在 linux 系统安装 tomcat,使用默认端口 8080,在 bin 目录中
./startup.sh
启动 tomcat。- 对外开放访问的端口:
firewall-cmd --add-port=8080/tcp --permanent
。 - 在 windows 的 host 文件进行域名和 ip 对应关系的配置,添加内容:
192.168.153.100 www.123.com
。 - 在 nginx 进行请求转发的配置。
2.2 实例二
实现效果:使用 nginx 反向代理,根据访问的路径跳转到不同端口的服务中,nginx 监听端口为 9000。
- 访问 http://127.0.0.1:9000/edu/ 直接跳转到127.0.0.1:8080。
- 访问 http://127.0.0.1:9000/vod/ 直接跳转到127.0.0.1:8081。
实现步骤:
- 准备两个 tomcat 服务器,一个 8080 端口,一个 8081 端口,在其中一个 tomcat 下的 webapps 目录下创建文件夹 edu,另一个创建 vod,并添加 a.html 文件。
- 配置对外的端口号 8080、8081、9000。
- 配置 nginx 文件。
重启 nginx 和 tomcat。
location指令说明
= :用于不含正则表达式的uri 前,要求请求字符串与 uri 严格匹配,如果匹配成功,就停止继续向下搜索并立即处理该请求。
- ~:用于表示 uri 包含正则表达式,并且区分大小写。
- ~:用于表示 uri 包含正则表达式,并且*不区分大小写。
- ^~:用于不含正则表达式的 uri 前,要求 Nginx 服务器找到标识 uri 和请求字符串匹配度最高的 location 后,立即使用此 location 处理请求,而不再使用 location 块中的正则 uri 和请求字符串做匹配。
注意:如果uri 包含正则表达式,则必须要有 ~ 或者 ~* 标识。
3.3 负载均衡实现
实现效果:浏览器地址栏输入地址:http://192.168.153.100/edu/a.html,负载均衡效果,平均 8080 和 8081 端口上。
实现步骤:
- 准备两台 tomcat 服务器,一台 8080,一台 8081。在两台 tomcat 里面 webapps 目录中,创建 edu 文件夹,放入 a.html 页面,用于测试。
- 在 nginx 的配置文件中进行负载均衡配置(代码没问题)。
nginx分配服务器策略
- 轮询:每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。
weight:权重,默认为 1,根据权重分配到不同的服务器,权重越高被分配的客户端越多。
upstream myserver {
server 192.168.153.100:8080 weight=5;
server 192.168.153.100:8081 weight=10;
}
ip_hash:每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 共享的问题。
upstream server_pool{
ip_hash;
server 192.168.5.21:80;
server 192.168.5.22:80;
}
fair(第三方):按后端服务器的响应时间来分配请求,响应时间短的优先分配。
upstream server_pool{
server 192.168.5.21:80;
server 192.168.5.22:80;
fair;
}
3.4 动静分离实现
实现步骤:
在 linux 系统中准备静态资源,在根目录下创建 data 文件夹,data 文件夹下创建 image 和 www 文件夹。一个存放 image 文件,一个存放 html 页面。
- 配置 nginx。
测试结果如上:
- 输入地址:
192.168.153.100/image/01.jpg
- 输入地址:
192.168.153.100/image/
输入地址:
192.168.153.100/www/a.html
3.5 高可用实现
实现效果:
实现步骤:
1、准备两台服务器:192.168.153.100 和 192.168.153.101。
2、安装 nginx 和 keepalived,命令yum install keepalived -y
,安装完成之后,会在 etc 里面生成目录 keepalived,有文件 keepalived.conf。如果 yum 安装失败,请参考:https://www.cnblogs.com/xxoome/p/8621677.html。
3、完成高可用配置(主从配置)。- 修改 /etc/keepalived/keepalived.conf 配置文件。 ```java global_defs { notification_email { acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 192.168.153.100 smtp_connect_timeout 30 router_id LVS_DEVEL }
vrrp_script chk_http_port { script “/usr/local/src/nginx_check.sh” interval 2 #(检测脚本执行的间隔) weight 2 }
vrrp_instance VI_1 { state BACKUP # 备份服务器上将 MASTER 改为 BACKUP interface ens33 //网卡 virtual_router_id 51 # 主、备机的 virtual_router_id 必须相同 priority 90 # 主、备机取不同的优先级,主机值较大,备份机值较小 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.153.50 // 暴露在外的虚拟地址,必须和自己ip在同一网段 } }
- 在 /usr/local/src 添加检测脚本,并给与该脚本 744 权限,命令:`chmod 744 /usr/local/src/nginx_check.sh`
```shell
#!/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
- 关闭 selinux,使用命令
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/sysconfig/selinux
永久关闭。 - 启动两台服务器的 Nginx,进行测试,启动命令:
systemctl start keepalived.service
。
4、最终测试
- 在浏览器地址栏输入虚拟 IP 地址:192.168.153.50。
- 把主服务器(192.168.153.100)的 Nginx 和 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.153.100
smtp_connect_timeout 30
router_id LVS_DEVEL #访问到主机,绑定主机名,centos7下可在/etc/hosts中定义主机名
}
# 检测脚本配置
vrrp_script chk_http_port {
script "/usr/local/src/nginx_check.sh"
interval 2 #(检测脚本执行的间隔)
weight 2 #权重,设置当前服务器的权重
}
# 虚拟IP的配置
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.17.50 // VRRP H 虚拟地址
}
}
3. Nginx使用原理
3.1 争抢机制
Nginx 启动后产生两个进程,一个 Master,一个 Worker,Worker 可以有多个。
客户端/浏览器发送请求到 Nginx,其实相当于发送给 Master 进程,相当于一个管理员,管理员拿到任务之后分配给 worker 进程。worker 通过争抢机制抢到任务之后,进行反向代理,完成具体操作。
3.2 多个worker
一个 master 和多个 worker 的好处:
- 可以使用 nginx -s reload 热部署,利用 nginx 进行热部署操作。
- 每个 worker 是独立的进程,如果有其中的一个 worker 出现问题,其他 worker 都是独立的,可以继续争抢,实现请求过程,不会造成服务中断。
设置多少个 worker 比较合适?
Nginx 同 redis 类似都采用了 io 多路复用机制,每个 worker 都是一个独立的进程,但每个进程里只有一个主线程,通过异步非阻塞的方式来处理请求,即使是千上万个请求也不在话下。每个 worker 的线程可以把一个 cpu 的性能发挥到极致。所以 worker 数和服务器的 cpu 数相等是最为适宜的。设少了会浪费cpu,设多了会造成 cpu 频繁切换上下文带来的损耗。
3.3 连接数worker_connection
发送请求,占用了 worker 的几个连接数?
2 个或 4 个。比如说客户端发送请求到 Nginx,访问静态资源,Worker 将静态资源返回,即两个连接数。如果还要进行动态操作,需要访问 Tomcat,一来一回,即 4 个连接数。
Nginx 有一个 master,有 4 个 worker,每个 worker 支持的最大连接数为 1024,支持最大并发数是多少?
- 普通的静态访问最大并发数是:worker_connections * worker_processes /2。
- 而如果是 HTTP 作为反向代理来说,最大并发数量应该是worker_connections * worker_processes/4。