学无止境 Java工程师的进阶之旅
目录
一、Nginx简介
1.1、什么是Nginx
Nginx 是高性能的 HTTP 和反向代理的web服务器,处理高并发能力是十分强大的,能经受高负载的考验,有报告表明能支持高达 50,000 个并发连接数。
其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
1.2、Nginx做web服务器
Nginx 可以作为静态页面的 web 服务器,同时还支持 CGI 协议的动态语言,比如 perl、php 等。但是不支持 java。Java 程序只能通过与 tomcat 配合完成。Nginx 专为性能优化而开发, 性能是其最重要的考量,实现上非常注重效率 ,能经受高负载的考验,有报告表明能支持高 达 50,000 个并发连接数。
https://lnmp.org/nginx.html
1.3、正向代理
假设某个地区的用户无法访问百度,有个代理服务器可以访问百度,这个时候只要该用户访问该代理服务器就能访问到百度
1.4、反向代理
假设对外暴露的域名是www.laptoy.com,用户可以直接访问该域名,该域名也就是代理服务器将请求转到对应隐藏服务器进行处理
- 将请求发送到反向代理服务器
- 由反向代理服务器去选中目标服务器获取数据
- 返回数据给客户端
此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器的IP地址
1.5、负载均衡
传统请求响应过程,适合并发请求较少,但是如果高并发,会导致服务器响应请求缓慢
可以通过升级服务器配置,但单个服务器的性能瓶颈有限
可以通过增加服务器数量解决,负载均衡请求到每个服务器
1.6、动静分离
动态和静态页面由不同服务器解析,加快网站解析速度,降低单个服务器压力
二、安装
该教程目录在/mydata
2.1、安装pcre
# 直接命令行执行
wget http://downloads.sourceforge.net/project/pcre/pcre/8.37/pcre-8.37.tar.gz
# 解压
tar -xvf pcre-8.37.tar.gz
进入pcre目录
./configure
make && make install
# 查看版本
pcre-config --version
2.2、安装其他插件
yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel
2.3、Nginx安装
下载Nginx.tar.gz放到/mydata
官网下载
解压缩
tar -xvf nginx-1.20.2.tar.gz
进入nginx目录安装启动器
./configure
make && make install
2.4、启动Nginx
默认生成了/usr/local/nginx/sbin
进入该目录
./nginx
关闭防火墙
systemctl stop firewalld
访问nginx
虚拟机地址:端口号
192.168.88.129:80
三、常用命令
进入/usr/local/nginx/sbin
目录
./nginx -v 查看版本号
./nginx 启动服务
./nginx -s stop 停止服务
./nginx -s reload 重新启动
四、配置文件
进入配置文件目录/usr/local/nginx/conf
4.1、全局块
从配置文件开始到 events 块之间的内容
主要会设置一些影响nginx 服务器整体运行的配置指令,主要包括
- 配置运行 Nginx 服务器的用户(组)
- 允许生成的 worker process 数
- 进程 PID 存放路径
- 日志存放路径和类型
- 配置文件的引入等
值越大,支持处理的并发量越多,但会收到硬件软件的制约
worker_processes 1;
4.2、event块
主要影响 Nginx 服务器与用户的网络连接,比如下面的支持最大连接数
events {
worker_connections 1024;
}
4.3、http块
http全局块
:配置的指令包括文件引入、MIME-TYPE 定义、日志自定义、连接超时时间、单链接请求数上限等
server块
:这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全一样的,该技术的产生是为了节省互联网服务器硬件成本。
每个 http 块可以包括多个 server 块,而每个 server 块就相当于一个虚拟主机。
每个 server块
也分为全局server块
,以及可以同时包含多个locaton块
。
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
location
:
~ /edu/
表示只要路径里有/edu则匹配成功
location [ = | ~ | ~* | ^~ ] uri {
}
=
:要求请求字符串与uri严格匹配~
:uri包含正则表达式,区分大小写~*
:uri包含正则表达式,不区分大小写^~
:要求nginx服务器找到标识uri和请求字符串匹配的最高的location后,立刻使用该location,而不再使用正则uri做匹配
五、实现反向代理
5.1、实例一
实现效果:访问www.123.com
,跳转到linux系统里的tomcat主页面
准备tomcat8080
这里为了快速创建tomcat用了Docker
docker pull tomcat:7.0.70
docker run -d -p 8080:8080 --name tomcat8080 tomcat:7.0.70
输入192.168.88.129:8080
访问tomcat
1、进入C:\Windows\System32\drivers\etc hosts文件
添加
这样就等同于访问www.123.com=192.168.88.129
192.168.88.129 www.123.com
此时www.123.com:8080
可以访问到tomcat
2、配置nginx.conf
进入/usr/local/nginx/sbin
执行./nginx -s reload
重启
3、访问www.123.com
成功访问到tomcat首页
5.2、实例二
实现效果:使用nginx反向代理,根据访问路径跳转到不同端口的服务中
访问http://192.168.88.129:9001/edu/a.html 跳转到127.0.0.1:8081
访问http://192.168.88.129:9001/vod/a.html 跳转到127.0.0.1:8082
1、准备两个tomcat8081 tomcat8082
docker run -d -p 8081:8080 --name tomcat8081 tomcat:7.0.70
docker run -d -p 8082:8080 --name tomcat8082 tomcat:7.0.70
1.1、配置8081
进入容器8081内部
docker exec -it tomcat8081 bash
进入webapps目录创建edu目录并添加文件a.html并用管道输入
touch a.html
echo >> a.html '<h1>8081</h1>'
1.2、配置8082
进入容器8082内部
docker exec -it tomcat8082 bash
进入webapps目录创建vod目录并添加文件a.html并用管道输入
touch a.html
echo >> a.html '<h1>8082</h1>'
2、nginx.conf
~
:正则表达式方式匹配路径
~ /edu/
表示只要路径里有/edu则匹配成功
3、测试
六、负载均衡
6.1、演示
实现效果:http://192.168.88.129/edu/a.html,负载均衡到8081和8082
1、准备tomcat8081 tomcat8082
2、在webapps创建文件夹laptoy,在laptoy文件夹创建页面test.html
3、Nginx.conf
http
块下配置upstream
server
块配置
4、重启nginx
默认为轮询配置
6.2、负载均衡策略
-
轮询(默认):按时间顺序逐一分配到不同的后端服务器,如果服务器宕机能自动删除
-
weight
:代表权重,越高被分配的请求越多
-
ip_hash
:按访问的ip的hash结果分配,这样每个访客固定访问一个服务器,可以解决session的问题
-
fair
(第三方):按服务器的响应时间来分配请求,响应时间短的优先分配
七、动静分离
7.1、概述
将动态和静态请求分开,Nginx处理静态页面,Tomcat处理动态页面
- 把静态文件独立成单独的域名,放在独立的服务器(主推)
- 动态和静态文件混合发布,通过·nginx分离
location
指定不同的后缀名实现不同的请求转发
expires
使浏览器缓存过期时间,减少与服务器之前的请求和流量。
具体 expires 定义:
给资源设定过期时间,直接通过浏览器确认是否过期, 不会产生额外的流量,适合不会经常更新的文件
发送一个请求,比对服务器该文件最后更新时间没有变化,则不会从服务器抓取,返回状态码 304。
如果有修改,则直接从服务器重新下载,返回状态码 200。
7.2、实例
准备工作:创建/mydata/data/www
/mydata/data/image
放入文件
1、nginx.conf
autoindex on
列出当前文件夹内容
八、高可用集群
8.1、图解
- 需要多台nginx服务器
- 需要keepalived
- 需要虚拟ip
8.2、实验
8.2.1、准备工作
- 两台centos
- 都安装nginx
- 都安装keepalived
安装yum install keepalived -y
查看版本rpm -q -a keepalived
8.2.2、在每台centos的/usr/etc/keepalived ---- keepalived.conf配置
在/etc hosts
文件中添加127.0.0.1 LVS_DEVEL
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 208.208.128.122
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 MASTER # 备份服务器上将 MASTER 改为 BACKUP
interface ens192 # 网卡
virtual_router_id 51 # 主、备机的 virtual_router_id 必须相同
priority 100 # 主、备机取不同的优先级,主机值较大,备份机值较小
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.110 # 对外暴露的虚拟ip地址
}
}
8.2.2、在两台centos的/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 # nginx启动器位置
sleep 2
if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
killall keepalived # 如果nginx下线了就杀掉keepalived
fi
fi
8.2.3、启动
- 重启Nginx
- 启动keepalived
systemctl start keepalived.service
8.2.4、测试
- 访问虚拟ip192.168.1.110可以访问
- 停用主服务器
nginx
和主服务器的keepalived
(或者直接关闭主服务器centos) - 访问虚拟ip192.168.1.110仍然可以访问
九、Nginx的原理
9.1、master&worker
9.2、worker争抢资源过程
9.3、一个master和多个worker的好处
- 每个 worker 进程是独立的进程,不需要加锁,省掉了锁带来的开销, 同时在编程以及问题查找时,也会方便很多。
- 可以使用 nginx –s reload 热部署,利用 nginx 进行热部署操作
- 采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master 进程则很快启动新的 worker 进程。当然,worker 进程的异常退出,肯定是程序有 bug 了,异常退出,会导致当前 worker上的所有请求失败,不过不会影响到所有请求,所以降低了风险。
9.4、设置多少个worker
Nginx 同 redis 类似都采用了 io 多路复用机制
每个 worker 都是一个独立的进程,但每个进程里只有一个主线程,通过异步非阻塞的方式来处理请求, 即使是千上万个请求也不在话下。每个 worker 的线程可以把一个 cpu 的性能发挥到极致
worker 数和服务器的 cpu 数相等是最为适宜的。设少了会浪费 cpu,设多了会造成 cpu 频繁切换上下文带来的损耗。
worker 数和服务器的 cpu 数相等是最为适宜
9.5、 连接数 worker_connection
1.发送请求,占用了 woker 的几个连接数?
2个:仅仅是访问worker
4个:worker还需进行反向代理、路径跳转、访问tomcat、查询数据库
2.nginx 有一个 master,有四个 woker,每个 woker 支持最大的连接数 1024,支持的 最大并发数是多少?
- 普通的静态访问最大并发数是: worker_connections * worker_processes /2
- HTTP 作为反向代理来说,最大并发数量应该是 worker_connections * worker_processes/4