文章目录
一、Nginx基本运行原理
Nginx的进程是使用经典的「Master-Worker」模型,Nginx在启动后,会有一个master进程和多个worker进程。master进程主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。worker进程主要处理基本的网络事件,多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。worker进程的个数是可以设置的,一般会设置与机器cpu核数一致,这里面的原因与nginx的进程模型以及事件处理模型是分不开的。
二、Nginx的基本配置文件
Nginx的默认配置文件
刚安装好的nginx.conf如下:
#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;
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
#
error_page 500 502 503 504 /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
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
去掉注释的简单版如下:
worker_processes 1; #允许开启的进程数量,建议设置为cpu核心数或者auto自动检测,注意Windows服务器上虽然可以启动多个processes,但是实际只会用其中一个
events {
#单个进程最大连接数(最大连接数=连接数*进程数)
#根据硬件调整,和前面工作进程配合起来用,尽量大,但是别把cpu跑到100%就行。
worker_connections 1024;
}
http {
#文件扩展名与文件类型映射表(是conf目录下的一个文件)
include mime.types;
#默认文件类型,如果mime.types预先定义的类型没匹配上,默认使用二进制流的方式传输
default_type application/octet-stream;
#sendfile指令指定nginx是否调用sendfile 函数(zero copy 方式)来输出文件,对于普通应用,必须设为on。如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络IO处理速度。
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;
#/50x.html文件所在位置 用户出错时访问/50x.html,就会根据location去root 的html去找
location = /50x.html {
root html;
}
}
}
http://localhost:8080/hello
url是这一整段网址
uri是域名也就是8080后面的/hello
没开启sendFile,需要一次拷贝
开启后,无需拷贝
三、Nginx虚拟主机和域名解析
3.1 虚拟主机与域名解析
虚拟主机使用特殊的软硬件技术,把一台运行在因特网上的服务器主机分成一台台“虚拟”的主机,每一台虚拟主机都具有独立的域名,具有完整的Internet服务器(WWW、FTP、Email等)功能,虚拟主机之间完全独立,并可由用户自行管理,在外界看来,每一台虚拟主机和一台独立的主机完全一样。
域名解析就是域名到IP地址的转换过程,IP地址是网路上标识站点的数字地址,为了简单好记,采用域名来代替ip地址标识站点地址,。域名的解析工作由DNS服务器完成。
3.2 域名、dns、ip地址的关系
域名是相对网站来说的,IP是相对网络来说的。当输入一个域名的时候,网页是如何做出反应的?
输入域名---->域名解析服务器(dns)解析成ip地址—>访问IP地址—>完成访问的内容—返回信息。
Internet上的计算机IP是唯一的,一个IP地址对应一个计算机。
一台计算机上面可以有很多个服务,也就是一个ip地址对应了很多个域名,即一个计算机上有很多网站。
3.3 IP地址和DNS地址的区别
IP地址是指单个主机的唯一IP地址,而DNS服务器地址是用于域名解析的地址。
一个是私网地址,一个是公网地址;
一个作为主机的逻辑标志,一个作为域名解析服务器的访问地址。
IP地址:IP地址就是因特网上的某个设备的一个编号。
IP地址一般由网络号,主机号,掩码来组成。IP网络上有很多路由器,路由器之间转发、通信都是只认这个IP地址,类似什么哪?就好像你寄包裹,你的写上发件人地址,你的姓名,收件人地址,收件人姓名。这个发件人地址就是你电脑的IP的网络号,你的姓名就是你的主机号。
3.4 虚拟主机原理
虚拟主机是为了在同一台物理机器上运行多个不同的网站,提高资源利用率引入的技术。
一般的web服务器一个ip地址的80端口只能正确对应一个网站。web服务器在不使用多个ip地址和端口的情况下,如果需要支持多个相对独立的网站就需要一种机制来分辨同一个ip地址上的不同网站的请求,这就出现了主机头绑定的方法。简单的说就是,将不同的网站空间对应不同的域名,以连接请求中的域名字段来分发和应答正确的对应空间的文件执行结果。举个例子来说,一台服务器ip地址为192.168.8.101,有两个域名和对应的空间在这台服务器上,使用的都是192.168.8.101的80端口来提供服务。如果只是简单的将两个域名A和B的域名记录解析到这个ip地址,那么web服务器在收到任何请求时反馈的都会是同一个网站的信息,这显然达不到要求。接下来我们使用主机头绑定域名A和B到他们对应的空间文件夹C和D。当含有域名A的web请求信息到达192.168.8.101时,web服务器将执行它对应的空间C中的首页文件,并返回给客户端,含有域名B的web请求信息同理,web服务器将执行它对应的空间D中的首页文件,并返回给客户端,所以在使用主机头绑定功能后就不能使用ip地址访问其上的任何网站了,因为请求信息中不存在域名信息,所以会出错。
在host文件上配置nginx启动的ip地址去对应指定的域名
例如:192.168.144.131 myh.com
此时访问myh.com也是去访问nginx即192.168.144.131
3.5 泛域名
所谓“泛域名解析”是指:利用通配符* (星号)来做次级域名以实现所有的次级域名均指向同一IP地址。
好处:
1.可以让域名支持无限的子域名(这也是泛域名解析最大的用途)。
2.防止用户错误输入导致的网站不能访问的问题
3.可以让直接输入网址登陆网站的用户输入简洁的网址即可访问网站
泛域名在实际使用中作用是非常广泛的,比如实现无限二级域名功能,提供免费的url转发,在IDC部门实现自动分配免费网址,在大型企业中实现网址分类管理等等,都发挥了巨大的作用。
在阿里云aliyun.com的域名配置如下:
访问abc.myh.com 或者def.myh.com …都是访问192.168.144.131
3.6 虚拟主机配置
原本一台服务器只能对应一个站点,通过虚拟主机技术可以虚拟化成多个站点同时对外提供服务
- 在根目录下创建www文件夹
- 在www文件夹下分别创建www文件夹和vod文件夹
- 在www文件夹下创建index.html,内容为 this is www html
- 在vod文件夹下创建index.html,内容为this is vod html
- 修改nginx.conf
server {
//这个虚拟主机就是访问www.myh.com,就去访问/www/www下的index.html
listen 80;
server_name www.myh.com;
location / {
root /www/www;
index index.html index.htm;
}
#error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server {
//这个虚拟主机访问vod.myh.com就是访问/www/vod下的index.html
listen 80;
server_name vod.myh.com;
location / {
root /www/vod;
index index.html index.htm;
}
#error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
//前提是都得先去阿里云那里配置了域名*.myh.com,否则www.myh.com和vod.myh.com是访问不了的
修改配置文件后要 systemctl reload nginx
3.7 servername匹配规则
需要注意的是servername匹配分先后顺序,写在前面的匹配上就不会继续往下匹配了。
-
完整匹配 可以在同一servername中匹配多个域名
server_name vod.mmban.com www1.mmban.com; -
通配符匹配
server_name *.mmban.com; -
通配符结束匹配
server_name vod.*; -
正则匹配
server_name ~^[0-9]+\.mmban\.com$;
四. 反向代理
反向代理是指nginx以代理服务器来接收互联网上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给互联网上请求连接的客户端
nginx和内部服务器是在同一个网络,所以是反向代理
这是正向代理,客户端和代理服务器在同一个网络
nginx的反向代理配置如下:
访问192.168.144.131就访问到了bilibili.com这个网站
五、负载均衡
早期的网站流量和业务功能都比较简单,单台服务器足以满足基本的需求,但是随着互联网的发展,业务流量越来越大并且业务逻辑也跟着越来越复杂,单台服务器的性能及单点故障问题就凸显出来了,因此需要多台服务器进行性能的水平扩展及避免单点故障出现,那么如何将不同用户的请求流量分发到不同的服务器上呢?
举个例子:用轮询算法访问服务器,一段时间访问服务器1,一段时间访问服务器2…
基于反向代理的负载均衡
克隆2个虚拟机,将两台虚拟机的ip修改为192.168.144.132和192.168.144.133
分别修改132和133的index.html文件的内容
用轮询方式访问132和133
这样多次访问192.168.144.131,132和133会交替出现
负载均衡的权重(weight)
权重大的出现的概率比较大。这样就可以根据每台服务器的性能差异来分配不同的权重,性能好的服务器分配大权重。
其他负载均衡策略(不常用)
-
ip_hash
根据客户端的ip地址转发同一台服务器,可以保持会话,但是很少用这种方式去保持会话,例如我们当前正在使用wifi访问,当切换成手机信号访问时,会话就不保持了。 -
least_conn
最少连接访问,优先访问连接最少的那一台服务器,这种方式也很少使用,因为连接少,可能是由于该服务器配置较低,刚开始赋予的权重较低。 -
url_hash(需要第三方插件)
根据用户访问的url定向转发请求,不同的url转发到不同的服务器进行处理(定向流量转发)。 -
fair(需要第三方插件)
根据后端服务器响应时间转发请求,这种方式也很少使用,因为容易造成流量倾斜,给某一台服务器压垮。
六、动静分离
6.1 基本介绍
为了提高网站的响应速度,减轻程序服务器(Tomcat,Jboss等)的负载,对于静态资源,如图片、js、css等文件,可以在反向代理服务器中进行缓存,这样浏览器在请求一个静态资源时,代理服务器就可以直接处理,而不用将请求转发给后端服务器。对于用户请求的动态文件,如servlet、jsp,则转发给Tomcat,Jboss服务器处理,这就是动静分离。即动态文件与静态文件的分离。
6.2 基本使用
有两台虚拟机131和132
131作为nginx进行反向代理,132作为后端服务器
在131的nginx.conf文件进行配置location / 的proxy_pass http://131:8080
这样访问131就能访问到132下的页面,而131其实并没有这些页面,借助131访问到了132下的资源
现在将132的静态资源css、img等放到131,再访问132的资源发现没有静态资源
加了这个配置后,先将css的资源传输到131的html目录下,再次访问131,就能发现css的静态资源生效了
同理,要想js静态资源生效,就再要配个location /js
按照上面这样写的话,如果有非常多的静态文件的话,就需要很多location,这样太冗余了
所以用正则配置动静分离
注意:
- 精确匹配: = , 后面的表达式中写的是纯字符串
- 字符串匹配: ^~ 和 无符号匹配 , 后面的表达式中写的是纯字符串
- 正则匹配: ~ 和 ~* 和 !~ 和 !~* , 后面的表达式中写的是正则表达式
(1)location = / {}
=为精确匹配 / ,主机名后面不能带任何字符串,比如访问 / 和 /data,则 / 匹配,/data 不匹配
再比如 location = /abc,则只匹配/abc ,/abc/或 /abcd不匹配。若 location /abc,则即匹配/abc 、/abcd/ 同时也匹配 /abc/。
(2)location / {}
因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求 比如访问 / 和 /data, 则 / 匹配, /data 也匹配,
但若后面是正则表达式会和最长字符串优先匹配(最长匹配)
(3)location /documents/ {}
匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索其它 location
只有其它 location后面的正则表达式没有匹配到时,才会采用这一条
(4)location /documents/abc {}
匹配任何以 /documents/abc 开头的地址,匹配符合以后,还要继续往下搜索其它 location
只有其它 location后面的正则表达式没有匹配到时,才会采用这一条
(5)location ^~ /images/ {}
匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条
(6)location ~* \.(gif|jpg|jpeg)$ {}
匹配所有以 gif、jpg或jpeg 结尾的请求
然而,所有请求 /images/ 下的图片会被 location ^~ /images/ 处理,因为 ^~ 的优先级更高,所以到达不了这一条正则
(7)location /images/abc {}
最长字符匹配到 /images/abc,优先级最低,继续往下搜索其它 location,会发现 ^~ 和 ~ 存在
(8)location ~ /images/abc {}
匹配以/images/abc 开头的,优先级次之,只有去掉 location ^~ /images/ 才会采用这一条
(9)location /images/abc/1.html {}
匹配/images/abc/1.html 文件,如果和正则 ~ /images/abc/1.html 相比,正则优先级更高
优先级总结:
(location =) > (location 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (location /)
七、URLRewrite
rewrite是实现URL重写的关键指令,根据regex(正则表达式)部分内容,重定向到repacement,结尾是flag标记。
URLRewrite的优缺点
优点:掩藏真实的url以及url中可能暴露的参数,以及隐藏web使用的编程语言,提高安全性便于搜索引擎收录
缺点:降低效率,影响性能。如果项目是内网使用,比如公司内部软件,则没有必要配置。
访问131/6666.html就能转到131/index.jsp?pageNum=6666
7.1 负载均衡+URLRewrite实战
开启两台虚拟机101和102,102做为反向代理
首先开启101的防火墙
systemctl start firewalld
重载规则
firewall-cmd --reload
查看已配置规则
firewall-cmd --list-all
添加指定端口和ip访问(添加之后记得重新启动防火墙)
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.8.102" port protocol="tcp" port="8080" accept"
在这里101的防火墙配置上,101只能由102访问,其他ip地址访问不了,这样就完成了外网访问不了101,只能由指定的ip地址去访问
移除规则
firewall-cmd --permanent --remove-rich-rule="rule family="ipv4" source address="192.168.8.102" port protocol="tcp" port="8080" accept"
重启防火墙
firewall-cmd --reload
直接访问:http://192.168.8.101:8080/,发现页面加载不出来,也就是访问不了
访问:http://192.168.8.102:8888/test.html能访问
使用负载均衡的方式访问:
防盗链与http的referer
访问一个页面,我认为它发送一个访问1333.html页面的请求,但它内部还有许多访问静态资源的请求,这些请求内部就有referer,表示当前静态资源是从哪里来的
防盗链配置
101有这些静态资源,102没有,现在配置102的nginx.conf作为代理服务器,使102能访问到101的静态资源
修改102的nginx.conf
valid_referers 101的意思是只有referer里带有101的就能访问,否则就返回403,也就是不能访问
valid_referers none的意思是没有referer就能访问
使用curl测试防盗链
安装curl:yum install -y curl
盗链资源返回错误图片或错误页面
先写个错误页面401.html
配置location
这时候去访问那个访问不到的资源就会显示这个401.html
也可以在这里将return 401改成rewrite,重定向到错误图片
八、高可用场景
8.1 基本介绍及解决方案
现在是一台nginx对应多个后台服务器,现在的问题是如果这台nginx宕机了,那么整个服务就不能用了
解决方案:用2台nginx,这两台nginx都有keepalived插件,如果有一台宕机了,就可以通过keepalived传递信息去切换到另一台nginx。这两台nginx的ip地址肯定是不一样的,但是用户肯定只会去访问一个特定的ip地址,而且也不能简单的将另一台nginx的ip地址换成宕机的nginx的ip地址,因为这两台的nginx内部分区不一样,所以想到一个方法,用一个虚拟ip(vip),这个虚拟ip可以在两台nginx中切换,当一台nginx宕机了,就切换到另一台nginx,这样就实现用户访问一个特定的ip地址,但是内部且能访问两台nginx。
复制虚拟机的时候,记得将虚拟机的ip地址改一下
改完重启一下:systemctl restart network
安装keepalived:yum install -y keepalived
keepalived的配置文件所在位置
修改主nginx的keepalived.conf
注意priority不一样,主比较大,备用比较小
九、不安全的http协议
不安全的http协议就是说:客户端向服务端发送数据,这些数据会被一些人拦截到,从而知道你发的数据内容是什么
这时候使用安全协议,就是对发送的数据加密,到服务端再解密,这样那些人即使拦截到也不知道密码。但是有一个问题是这些算法大多都是在互联网上,人们都知道这些算法的原理。所以还要再加一层保险就是自己设的密码。
上面图片就是对称算法
非对称算法
非对称算法也不安全,比如说访问一个网站,有一个假冒该网站的服务器,你访问到他那里去了,然后他帮你去传输这个请求给真正的网站,在这过程中它是能知道你要干嘛
十、线上实战
10.1 购买域名流程
进入aliyun.com