1.Nginx基础
1.1基础概念:
作为一名初学者,需要知道Nginx(“engine x”)是一个名叫伊戈尔·赛索耶夫的俄罗斯人搞出来的,是一个高性能的HTTP和反向代理服务器,特点是占用内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好。
Nginx是专为性能优化而开发的,因此性能是其最重要的考量标准,在实现上非常注重效率,能经受高负载的考验,有报告表明能支持高达50,000个并发连接数,要是你搞的网站活跃用户是这个数量级,那么用Nginx绝对是很香的。
1.2nginx作用
1.2.1 基本的web服务器
web(World wide Web)即全球广域网,也称为万维网,它是一种基于超文本和HTTP的、全球性的、动态交与的、跨平台的分布式图形信息系统。 Nginx 可以作为静态页面的 web 服务器,同时还支持 CGI 协议的动态语言,比如 per、php 等。但是不支持ava。Java 程序只能通过tomcat 配合完成。Nginx 专为性能优化而开发,性能是其最重要的考量,实现上非常注重效率,能经受高负载的考验,有报告表明能支持高达 50,000 个并发连接数。.
1.2.2正向代理
是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理。
这里客户端需要要进行一些正向代理的设置的。
正向代理中被代理的是客户端的请求
总结:
1、正向代理,我们的角色是 被代理者2、正向代理,我们不对外提供服务,反而是对外消费服务,属于消费者
1.2.3反向代理
反向代理,客户端对代理是无感知的,客户端不需要任何配置就可以访问,客户端将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,在返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器IP地址。
说明:客户端必须设置正向代理服务器,当然前提是要知道正向代理服务器的IP地址,还有代理程序的端口。
反向代理正好与正向代理相反,对于客户端而言代理服务器就像是原始服务器,并且客户端不需要进行任何特别的设置。客户端向反向代理的命名空间(name-space)中的内容发送普通请求,接着反向代理将判断向何处(原始服务器)转交请求,并将获得的内容返回给客户端。
总结:
1、反向代理,我们的角色是 局域网 web服务2、反向代理,我们对外提供服务,属于服务提供者
1.2.4负载均衡
负载均衡(Load Balance),它在网络现有结构之上可以提供一种廉价、有效、透明的方法来扩展网络设备和服务器的带宽,并可以在一定程度上增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性等。用官网的话说,它充当着网络流中“交通指挥官”的角色,“站在”服务器前处理所有服务器端和客户端之间的请求,从而最大程度地提高响应速率和容量利用率,同时确保任何服务器都没有超负荷工作。
如果单个服务器出现故障,负载均衡的方法会将流量重定向到其余的集群服务器,以保证服务的稳定性。当新的服务器添加到服务器组后,也可通过负载均衡的方法使其开始自动处理客户端发来的请求。
简言之,负载均衡实际上就是将大量请求进行分布式处理的策略。
1.2.5动静分离
动静分离是指在web服务器架构中,将静态页面与动态页面或者静态内容接口和动态内容接口分开不同系统访问的架构设计方法,进而提升整个服务访问性能和可维护性。
一般来说,都需要将动态资源和静态资源分开,将静态资源部署在Nginx上,当一个请求来的时候,如果是静态资源的请求,就直接到nginx配置的静态资源目录下面获取资源,如果是动态资源的请求,nginx利用反向代理的原理,把请求转发给后台应用去处理,从而实现动静分离。
在使用前后端分离之后,可以很大程度的提升静态资源的访问速度,同时在开过程中也可以让前后端开发并行可以有效的提高开发时间,也可以有些的减少联调时间 。
2.nginx安装
window下直接解压到一个非中文目录下
linux下安装nginx
2.2.1 准备工作
执行: yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel 安装nginx前需要确保linux上安装了gcc、PCRE 、zlib、OpenSSL 1.安装 nginx 需要先将官网下载的源码进行编译,编译依赖 gcc 环境。 2.PCRE(Per Compatible Regular Expressions)是一个Per库,包括 perl 兼容的正则表达式库nginx 的 htp 模块使用 pcre 来解析则表达式,所以需要在 linux 上安装 pcre 库,pcre-devel 是使用 pcre 开发的一个二次开发库。nginx也需要此库。命令:3.zlib 库提供了很多种压缩和解压的方式,nginx 使用 lib 对 http 包的内容进行 gzip ,所以需要在 Centos 上安装 zlib 库。4,OpenSSL是一个强大的安全套接字层索码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及 SSL 协议,并提供丰富的应用程序供测试或其它目的使用。nginx 不仅支持 htp 协议,还支持 https (即在ss协议上传输http),所以需要在 Centos 安装OpenssL 库。 执行后等待安装完毕!
2.2.2安装
将nginx安装包上传到usr/src目录下 解压到当前文件夹,命令为: tar -zxvf nginx-1.22.0.tar.gz
进入到解压后的nginx文件夹中cd nginx-1.22.0 配置当前nginx,命令为: ./configure 这里其实也是执行nginx下的configure 文件 执行命令: make && make install
开启防火墙 : systemctl start firewalld 设置防火墙白名单 : firewall-cmd --zone=public --add-port=80/tcp
2.2.3运行
- 查看 nginx 的版本号 ./nginx -v - 启动 nginx ./nginx - 关闭nginx ./nginx -s stop - 重新加载 nginx ./nginx -s reloa
2.3防火墙命令
防火墙的开启、关闭、禁用命令
(1) 设置开机启用防火墙: systemctl enable firewalld.service (2) 设置开机禁用防火墙: systemctl disable firewalld.service (3)启动防火墙: systemctl start firewalld (4)关闭防火墙: systemctl stop firewalld (5) 检查防火墙状态: systemctl status firewalld
使用firewall-cmd配置端口
(1) 查看防火墙状态: firewall -cmd --state (2) 重新加载配置: firewall -cmd --reload (3) 查看开放的端口: firewall -cmd --list-ports (4) 开启防火墙端口: firewall -cmd --zone=public --add -port=9200/tcp --add -port=8080/tcp --permanentd
(5)关闭端口命令: firewall -cmd --zone= public --remove -port= 80/tcp --permanent
(6) 查看端口是否打开: firewall -cmd --zone = public --query -port=80/tcp
*开放防护墙端口(设置白名单)
# 查询端口是否开放 firewall-cmd --query-port=8080/tcp #开放80端口2 firewall-cmd --permanent --add-port=80/tcp # 移除端口 firewall-cmd --permanent --remove-port=8080/tcp #重启防火墙(修改配置后要重启防火墙) firewall-cmd --reload
3.进程管理
#window netstat -nao# ctr1+f找到pid
taskki11 /pid ***# /f 强制停止进程 #linux ps -aux grep nginx
ps -ef grep nginx
kill 进程号 -9# -9 强制停止进程
4.配置文件
4.1全局块配置
#定义Nginx运行的用户和用户组
#user nobody; 默认nobody
#nginx进程数,建议设置为等于CPU总核心数。
worker_processes 8;
#全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#进程文件
#pid logs/nginx.pid;
4.2events块
#工作模式与连接数上限
events {
$remote_addr - $remote_user [$time_local] "$request" '
#单个进程最大连接数(最大连接数=连接数*进程数)
#
worker_connections 1024;
}
4.3http全局配置
#设定http服务器
http {
include mime.types;#文件扩展名与文件类型映射表
default_type application/octet-stream;#默认文件类型
#log_format main ' '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"'; #日志格式设定
#access_log logs/access.log main; #定义本虚拟主机的访问日志
sendfile on;#开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,
可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成off。
#tcp_nopush on;#防止网络阻塞
#keepalive_timeout 0;#长连接超时时间,单位是秒
keepalive_timeout 65;
#gzip on;#开启gzip压缩输出
4.4service全局配置
#虚拟主机的配置
server {
listen 80; #监听端口
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;#默认请求的文件
index index.html index.htm;#访问的缺省网页
}
#404访问地址
#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;
}
listen 表示监听的端口号,这个端口就是访问nginx时候使用的,80是默认端口,访问时候可以省略。也可以配置其他端口 server_name Nginx中的server_name指令主要用于配置基于名称的虚拟主机,如果没有多配置的情况下,名称可以随意指定一个就行 location 这里主要配置需要访问的资源地址,root表示哪个文件夹。index表示访问的缺省网页是哪一个。如果走代理,则配置修改为proxy_pass方式 error_page 配置异常信息访问地址
5. 正向代理实现
server {
listen 80;
location / {
proxy_pass http://www.baidu.com;
} }
nginx可以作为http的正向代理服务器,但是不能用做https的正向代理服务器。因为http正向代理使用的是 get请求,但是https使用的确实connect请求,而nginx不支持connect请求。所以需要第三方模块 ngx_http_proxy_connect_module 来支持https的正向代理
6. 反向代理实现
1.安装jdk
2.安装tomcat 开启tomcat,在bin目录下,使用 命令:./startup.sh
6.1反向代理单台服务器
1. 直接修改nginx配置文件,并重启nginx
server {
listen 80;
server_name 192.168.31.100; #默认80端口
location / {
proxy_pass http://192.168.200.100:8080; #代理的地址
}
}
开启端口防火墙firewall -cmd --zone=public --add -port=8080/tcp
然后重启防火墙firewall-cmd --reload
然后windows下访问192.168.200.100如果成功访问tomcat就成了
6.2反向代理多台服务器
1.复制一个tomcat cp -r apache-tomcat-9.0.73 ./apache-tomcat9090
2.进入tomcat的server.xml修改端口号为9090
3. 修改两个tomcat的/webapp/ROOT/index.jsp 区别两个tomcat 创建文件夹v1/v2 把两个文件移动到文 件夹中,修改后重启两个tomcat
4.修改nginx配置文件,并重启nginx
server {
listen 80;
server_name 192.168.200.100; #默认80端口
location ~/v1/ {
proxy_pass http://192.168.200.100:8080; #代理的地址
}
location ~/v2/ {
proxy_pass http://192.168.200.100:9090; #代理的地址
}
}
5.windows下输入192.168.200.100查验结果
= :用于不含正则表达式的 uri 前,要求请求字符串与 uri 严格匹配,如果匹配 成功,就停止继续向下搜索 并立即处理该请求。
~:用于表示 uri 包含正则表达式,并且区分大小写。
~*:用于表示 uri 包含正则表达式,并且不区分大小写。
^~:用于不含正则表达式的 uri 前,要求 Nginx 服务器找到标识 uri 和请求字 符串匹配度最高的 location 后,立即使用此 location 处理请求,而不再使用 location 块中的正则 uri 和请求字符串做匹配。
注意:如果 uri 包含正则表达式,则必须要有 ~ 或者 ~*标识。
7. 负载均衡配置
7.1负载均衡实现
负载均衡是将一个项目形成一个集群,可以通过nginx进行负载。通过访问一个代理实现能访问同一个项目但是可能不是同一个服务器运行的。
我们可以将多台tomcat下的项目看做为一个集群,当我访问一个路径的时候为了分担服务区压力,我们让其 通过定义nginx的负载策略实现nginx负载均衡处理
修改nginx配置如下
upstream cluster {
server 192.168.200.100:8080;
server 192.168.200.100:9090;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://cluster;
}
}
直接访问1912.168.200.100进行测试
springboot项目负载均衡
springboot项目给上不同的端口号
打包部署在linux下面
给端口号防火墙开启白名单放行
nginx修改配置文件
upstream cluster {
server 192.168.200.100:8082;
server 192.168.200.100:8083;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://cluster;
}
}
再开两台虚拟机启动不同端口号的相同项目
在window下输入192.168.200.100测试
7.2 负载均衡策略
7.2.1 轮询策略(默认)
轮询策略其实是一个特殊的加权策略,不同的是,服务器组中的各个服务器的权重都是1
upstream backend {
server 192.168.200.100:8080 weight=1;
server 192.168.200.100:9090 weight=1;
}
7.2.2 加权轮询策略
weight 通过加入 weight的值进行加权处理,权重值越大,服务器越容易被访问,因此,性能好的服务器应适当加大 权重值
upstream backend {
server 192.168.200.100:8080 weight=1;
server 192.168.200.100:9090 weight=2; }
7.2.3 ip 哈希策略
ip_hash 策略能够将某个客户端IP的请求固定到同一台服务器上,例如A用户访问服务器,通过固定算法后, 被固定到 192.168.136.136 的web服务器上,那么,用户A下次访问时,依旧会到访问 192.168.136.136 服 务器。因此,该策略解决了多台服务器Session不共享的问题【因为不同的客户端会被分到不同的服务器,且 之后这种对应关系是不变的】
upstream backend {
ip_hash; server 192.168.200.100:8080;
server 192.168.200.100:9090; }
该算法不能保证服务器的负载均衡,可能存在个别服务器访问量很大,很小的情况.
7.2.4 least_conn 策略
最少连接,把请求转发给连接数最少的服务器。 轮询算法/轮询加权算法会把请求按照一定比例分发请求到各服务器上,但是,有些请求占用时间长,如果把 这些响应占用时间长的请求大比例发送到了某一台服务器,那么这台服务器随着时间的增加会负载比较高 【因为响应较长的请求还没处理完,新的请求又来了,在这种情况下,采用 least_conn 的方式是最适合的, 它能达到更好的负载均衡
upstream backend {
least_conn; server 192.168.200.100:8080;
server 192.168.200.100:9090; }
此负载策略适合用于,请求处理时间长短不一造成服务器过载的情况
7.2.5 url_hash 策略
url_hash 和 ip_hash 类似,不同的是,客户端ip可能变,但客户端发送的请求URL不同功能模块虽说不同, 但同一个功能点的URL是固定不变的,该算法主要是解决 缓存命中率的问题【例如下载文件】
upstream backend {
hash $request_uri;
server 192.168.200.100:8080;
server 192.168.200.100:9090; }
7.2.6 智能的fair
策略 fair nginx默认不支持,需下载第三方模块采用的不是固定的轮询算法进行负载均衡,而是智能的根据页面大 小、加载时间长短进行负载计算.
upstream backend {
fair; server 192.168.200.100:8080;
server 192.168.200.100:9090; }
8. 动静分离配置
Nginx 动静分离简单来说就是把动态跟静态请求分开,不能理解成只是单纯的把动态页面和 静态页面物理分 离。严格意义上说应该是动态请求跟静态请求分开,可以理解成使用 Nginx 处理静态页面,Tomcat 处理动 态页面。动静分离从目前实现角度来讲大致分为两种:
一种是纯粹把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案; 前后端 分离。
另外一种方法就是动态跟静态文件混合在一起发布,通过 nginx 来分开
9. nginx高可用集群
为了防止当Nginx代理服务器挂掉了后面的服务就都没有办法访问了。所有就引出了高可用集群。下面的实 例将配置一主一从的高可用集群
1.在虚拟机中克隆一个os系统,并配置对应的ip VM系统->右键->管理->克隆->完全克隆 原始OS ip地址为192.168.200.100 克隆新配置ip为192.168.200.101
2.在2台服务器安装keepalived yum install keepalived -y
# 查看版本: rpm -q -a keepalived
3.配置keepalived
改/etc/keepalived/keepalivec.conf配置文件,主从模式主要在这个文件里配置。
如果有两个nginx,一个作为主机,一个作为备机,如果备机故障,主机可以提供服务,如果主机故障,备 机一样可以提供服务。
3.1主备机配置
vrrp_script chk_nginx_up_down {
script "/etc/keepalived/nginx_check.sh" #运行脚本,脚本内容下面有,就是起到一个nginx宕
机以后,自动开启服务
interval 2 #检测时间间隔
weight 2 #如果条件成立的话,则权重 +2
}
# 定义虚拟路由,VI_1 为虚拟路由的标示符,自己定义名称
vrrp_instance VI_1 {
state MASTER #来决定主从BACKUP
interface ens33 # 绑定虚拟 IP 的网络接口,根据自己的机器填写
virtual_router_id 51 # 虚拟路由的 ID 号, 两个节点设置必须一样
mcast_src_ip 192.168.200.100 #填写本机ip
priority 100 # 节点优先级,主要比从节点优先级高
#nopreempt # 优先级高的设置 nopreempt 解决异常恢复后再次抢占的问题
advert_int 1 # 心跳监测间隔,两个节点设置必须一样,默认 1s
authentication {
auth_type PASS
auth_pass 1111
}
# 将 track_script 块加入 instance 配置块
track_script {
chk_nginx_up_down #执行 Nginx 监控的服务
}
virtual_ipaddress {
192.168.200.50 # 虚拟ip,也就是解决写死程序的ip怎么能切换的ip,也可扩展,用途广泛。可配置
多个。
}
}
在两个系统/etc/keepalived/ 添加检测脚本nginx_check.sh
#!/bin/bash
A=`ps -C nginx --no-header |wc -l`
#判断nginx是否宕机,如果宕机了,尝试重启
if [ $A -eq 0 ];then
# nginx的启动目录
/usr/local/nginx/sbin/nginx
# 等待3秒再次检查nginx,如果没有重启成功,则停止keepalived,使其启动备用机
sleep 3
if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
kill keepalived
fi
fi
4.分别给两台nginx_check.sh 这个脚本指定权限
chmod +x /etc/keepalived/nginx_check.sh
5.如果linux开启了防火墙, 请配置两个系统的防火墙放行vrrp协议
firewall-cmd --add-rich-rule='rule protocol value="vrrp" accept' --permanent
firewall-cmd --reload
6.临时关闭安全 setenforce 0
sed -i 's/SELINUX=enforcing/\SELINUX=disabled/' /etc/selinux/config #永久关闭,重启生效。
7.启动观测
#启动主机的keepalived systemctl start keepalived.service
#启动成功之后ip addr 查看主机是否有50的虚拟ip
#启动主机nginx /usr/local/nginx/sbin/nginx #使用192.168.200.50访问项目查看是否成功!
#启动备机keepalived
#启动成功之后ip addr 如果配置成功备机是没有50的虚拟ip,主有主机故障才有
#启动备机nginx
#测试发现访问50的ip数据一直是走主机的这是正确的。
#其他命令 systemctl stop keepalived.service
8.nginx宕机的话keepalived会自动重启nginx,如果关闭keepalived那个服务器就会不可访问(相当于这个服务器崩了)会访问另外一台服务器。
10. nginx 执行原理
Nginx 启动后会有一个 Master 进程和多个Worker 进程,Master 进程主要用来管理 Worker 进程,对网络事件进程进行收集和分发,调度哪个模块可以占用 CPU 资源,从而处理请求。
一般配置Worker进程的个数与机器cpu个数一致,从而达到cpu资源的最大化利用,也避免由于进程资源分配带来的额外开销。
master 和 worke机制 Nginx结合了多进程机制和异步机制对外提供服务,Nginx服务启动后,会产生一个主进程和多个工作进程。
master进程主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控 worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程.
master来管理worker进程,所以我们只需要与master进程通信就行了。master进程会接收来自外界发来的 信号,再根据信号做不同的事情,比如我们前面常用的 ./sbin/nginx -c conf/nginx.conf -s reload 执行这个命令时,master收到这个信号以后先启动一个新的Nginx进程,而新的Nginx进程在解析到reload 参数后,就知道是要控制Nginx来重新加载配置文件,它会向master进程发送信号,然后master会重新加载 配置文件,在启动新的worker进程,并向所有老的worker进程发送信号,告诉他们可以退休了,新的 worker启动之后就可以以新的配置文件接收新的请求了 – 热部署的原理
worker进程是如何处理请求? 我们基本上知道了在操作nginx时,nginx内部所做的事情,那么worker进程是如何处理请求的呢? 在Nginx 中,所有的worker进程都是平等的,每个进程处理每个请求的机会是一样的。当我们提供80端口的http服务 时,一个连接请求过来,每个进程都可能处理这个连接。 worker进程是从master进程fork(派生、分支)过来的,而在master进程中,会先建立好需要listen的 socket,然后fork出多个worker进程,当有新连接请求过来时work进程可以去处理,为了避免惊群效应, worker进程在处理请求之前先要去抢占accept_mutex,也就是互斥锁,当获得锁成功以后,就可以去解析 处理这个请求。请求处理完以后再返回给客户端。
Master进程工作原理
master进程主要用来管理worker进程,如:
接收来自外界的信号,向各worker进程发送信号; 监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。
Worker进程工作原理
基本的网络事件,则是放在worker进程中来处理了。
worker进程之间是平等的,每个进程,处理请求的机会也是一样的。
当一个worker进程在accept这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,这样一个完整的请求就是这样的了。我们可以看到,一个请求,完全由worker进程来处理,而且只在一个worker进程中处理。
(nginx提供了一个accept_mutex(互斥锁),有了这把锁之后,同一时刻,就只会有一个进程在accpet连接,worker进程内部不需要锁)
好处:
对于每个worker进程来说,独立的进程,不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查找时,也会方便很多。 互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master进程则很快启动新的worker进程。
好文推荐
发表评论