虚拟主机介绍
虚拟主机 就是把一台物理服务器划分成多个“虚拟”的服务器,每一个虚拟主机都可以有独立的域名和独立的目录,可以独立发布一个网站。
实验案例: 同时发布两个网站:
DocumentRoot /usr/local/nginx/html/web1
DocumentRoot /usr/local/nginx/html/web2
基于IP的虚拟主机
应用场景:IP充足的环境,每个网站需要一个IP地址
server { listen 192.168.11.251:80; location / { root html/web1; index index.html index.htm; } } server { listen 192.168.11.252:80; location / { root html/web2; index index.html index.htm; } }
基于IP的虚拟主机特点
不同IP对应不同网站
访问方便,用户直接使用默认端口即可访问
服务器需要有多个IP地址(一个公网IP大概一年的费用是600左右)
维护方便,基于独立IP的站点,便于监控、维护。
基于端口的虚拟主机
应用场景:IP不足的环境
优点: 多个网站发布使用该配置方法只需要一个IP,节省IP地址
缺点 端口你是无法告诉公网用户,无法适用于公网客户,适合内部用户
基于端口 server { listen 80; #server_name www.jackson.com; location / { root html/web1; index index.html index.htm; } } server { listen 8080; #server_name www.jackson.com; location / { root html/web2; index index.html index.htm; } }
基于端口的虚拟主机特点
不同端口对应不同网站
访问需要加端口
节省IP地址
适合私网运行
基于域名的虚拟主机
应用场景:一个网站需要有一个域名,目前公网发布网站的首选
基于域名 server { listen 80; server_name web1.jackson.com; location / { root html/web1; index index.html index.htm; } } server { listen 80; server_name web2.jackson.com; location / { root html/web2; index index.html index.htm; } }
基于域名的虚拟主机特点
不同域名对应不同网站
需要多个域名 可以是二级或三级域名
每个站点使用默认端口,方便用户访问
只需要一个IP地址,节约成本
适合公网环境
代理介绍
代理在网络中使用是比较常见的,比如我们说的最多的就是翻墙软件,比如ss、蓝灯等这些大家常用的软件,他们就是能改代理大家访问国内无法访问的一些国外网站,比如facebook、YouTube等网站。其原理也比较简单:
1)用户将请求发给代理服务器
2)代理服务器代用户去访问数据
3)代理服务器将数据给用户
正常没有代理情况上网
代理服务器场景
代理服务器扮演的就是一个中间人的角色。
代理分为正向代理和反向代理两种类型:
正向代理(forward proxy):是一个位于客户端和目标服务器之间的服务器(代理服务器),为了从目标服务器取得内容,客户端向代理服务器发送一个请求并指定目标,然后代理服务器向目标服务器转交请求并将获得的内容返回给客户端。
比如国内访问谷歌,直接访问是不行的,我们可以通过一个能够访问谷歌的正向代理服务器,请求发到代理服务器,由代理去谷歌获取数据并返回,这样就变相的实现了访问谷歌的需求。
一句话总结:正向代理,就是代理服务器代理了客户端
,去和目标服务器进行交互。
反向代理(Reverse Proxy):与正向代理正好相反,反向代理中的代理服务器,代理的是服务器那端。代理服务器接收客户端请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给客户端,此时代理服务器对外表现为一个反向代理服务器的角色。
反向代理服务器位于用户与目标服务器之间,但是对于用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源。同时,用户不需要知道目标服务器的地址,也无须在用户端作任何设定。
一句话总结:反向代理,就是代理服务器代理了目标服务器
,去和客户端进行交互。
反向代理的用途:
隐藏服务器真实 IP
负载均衡
通过缓存加速访问资源
提供安全保障
应用场景
1)堡垒机:堡垒机承担所有的外部访问,保护后端服务器的安全
2)业务发布服务器:将多个服务器通过虚拟主机的方式发布到公网
3)缓存服务器:CDN加速
反向代理原理
客户端通过浏览器 发起请求 代理服务器
2)代理服务器 接受请求
代理服务器 发起请求 业务服务器
4)业务服务器 接受请求
5)业务服务器 处理请求
业务服务器 响应请求 代理服务器
7)代理服务器 响应请求 客户端
8)客户端通过浏览器渲染请求并展示给用户
反向代理实现
proxy_pass: nginx反向代理指令
反向代理实现
location / { #请求转向mysvr 定义的服务器列表 proxy_pass http://mysvr; }
反向代理优化
proxy_set_header Host $host; #修改请求头,添加Host字段 proxy_set_header X-Real-IP $remote_addr; #修改请求头,添加X-Real-IP字段 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #修改请求头,添加X-Forwarded-For字段 client_max_body_size 10m; #允许客户端请求的最大单文件字节数 client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数, proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间\(代理连接超时\) proxy_send_timeout 90; #后端服务器数据回传时间\(代理发送超时\) proxy_read_timeout 90; #连接成功后,后端服务器响应时间\(代理接收超时\) proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小 proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置 proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2) proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传
负载均衡
实际生产环境中,反向代理服务器代理的目标服务器可能不止一个。
比如开发好的某个应用部署在一台 Tomcat 服务器上,而 Tomcat 的并发上限不优化情况下,默认只有两百左右,这时候为了解决高并发的问题,就只能选择更替服务器或者搭建多台服务器通过反向代理与负载均衡的技术解决并发问题。
负载均衡(Load Balance)是由多台服务器以对称的方式组成一个服务器集群,每台服务器都具有等价的地位,都可以单独对外提供服务而无须其他服务器的辅助。经过某种负载分管技术,将外部发送来的中央请求均匀分配到对称结构中的某一台服务器上。
部署多台tomcat服务器
修改 Tomcat 自带 ROOT 项目中的 index.jsp 页面。
# 编辑 index.jsp vim /opt/t2/webapps/ROOT/index.jsp
在 body 标签中随便添加点内容用于区分不同的服务器。
<h1 style="color:red">T2----</h1>
vim /usr/local/nginx/conf/nginx.conf
编辑配置文件。
在 http
节点下,添加 upstream
节点。使用 upstream name{}
语法定义一组服务器。
然后在 server
节点的 80 端口下添加下图中的内容。默认情况下,Nginx 是按加权轮询的方式将请求分发到各个服务器,当权重 weight
不指定时,各服务器 weight
相同。关于 Nginx 启动用户的问题请根据自身实际环境进行配置。
通过上面的流程,我们已经完成基于 Nginx 实现反向代理 Tomcat 服务器集群与负载均衡的需求。重启 Nginx 以后,此时再访问 Nginx 则会被路由到被代理的 Tomcat 服务器上,并且采用了轮询方式(默认)的负载均衡算法。客户端请求到 Nginx 的中央请求会每台一次的平均分配至 Tomcat 每个机器上。
限速介绍
在生产环境中,为了保护WEB服务器的安全,我们都会对用户的访问做出一些限制,保证服务器的安全及资源的合理分配。
限流(rate limiting)是NGINX众多特性中最有用的,也是经常容易被误解和错误配置的,特性之一访问请求限速。
该特性可以限制某个用户在一个给定时间段内能够产生的HTTP请求数。请求可以简单到就是一个对于主页的GET请求或者一个登陆表格的POST请求。用于安全目的上,比如减慢暴力密码破解攻击。
通过限制进来的请求速率,并且(结合日志)标记出目标URLs来帮助防范DDoS攻击。一般地说,限流是用在保护上游应用服务器不被在同一时刻的大量用户请求湮没。
限速说的很笼统,其实限速分为很多种限速方法:
1)下载速度限速
2)单位时间内请求数限制
3)基于客户端的并发连接限速
nginx限速模块
Nginx官方版本限制IP的连接和并发分别有两个模块:
limit_req_zone 用来限制单位时间内的请求数,即速率限制,采用的漏桶算法 “leaky bucket”。
limit_req_conn 用来限制同一时间连接数,即并发限制。
应用场景
下载限速:限制现在速度及并发连接数,应用在下载服务器中,保护带宽及服务器的IO资源。
请求限速:限制单位时间内用户访问请求,防止恶意攻击,保护服务器及资源安全。
限速原理
漏桶原理
算法思想是: 水(请求)从上方倒入水桶,从水桶下方流出(被处理); 来不及流出的水存在水桶中(缓冲),以固定速率流出; 水桶满后水溢出(丢弃)。 这个算法的核心是:缓存请求、匀速处理、多余的请求直接丢弃。 相比漏桶算法,令牌桶算法不同之处在于它不但有一只“桶”,还有个队列,这个桶是用来存放令牌的,队列才是用来存放请求的。
限速实现
1)单位时间内请求数限制
#基于IP对下载速率做限制 限制每秒处理1次请求,对突发超过5个以后的请求放入缓存区 http { limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; server { location /abc { limit_req zone=one burst=5 nodelay; } } limit_req_zone $binary_remote_addr zone=baism:10m rate=1r/s; 第一个参数:$binary_remote_addr 表示通过remote_addr这个标识来做限制,“binary_”的目的是缩写内存占用量,是限制同一客户端ip地址。 第二个参数:zone=baism:10m表示生成一个大小为10M,名字为one的内存区域,用来存储访问的频次信息。 第三个参数:rate=1r/s表示允许相同标识的客户端的访问频次,这里限制的是每秒1次,还可以有比如30r/m的。 limit_req zone=one burst=5 nodelay; 第一个参数:zone=one 设置使用哪个配置区域来做限制,与上面limit_req_zone 里的name对应。 第二个参数:burst=5,重点说明一下这个配置,burst爆发的意思,这个配置的意思是设置一个大小为5的缓冲区当有大量请求(爆发)过来时,超过了访问频次限制的请求可以先放到这个缓冲区内。 第三个参数:nodelay,如果设置,超过访问频次而且缓冲区也满了的时候就会直接返回503,如果没有设置,则所有请求会等待排队。
dd if=/dev/zero of=output_file bs=1G count=1
for i in `seq 1 10`;do( wget http://192.168.66.146/a/xx -P /tmp ) & done;
2)限制并发连接数
#基于IP做连接限制 限制同一IP并发为1 limit_conn_zone $binary_remote_addr zone=addr:10m; server { listen 80; server_name localhost; location / { root html; index index.html index.htm; } location /abc { limit_conn addr 1; } } }
3)限制下载速度
下载速度为100k server { listen 80; server_name localhost; location / { root html; index index.html index.htm; } location /abc { limit_rate 100k; } } }
4)综合案例
限制web服务器请求处理为1秒一个,触发值为5;
限制并发连接数为4;
限制下载速度为100.
http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; #基于IP做连接限制 限制同一IP并发为1 下载速度为100K limit_conn_zone $binary_remote_addr zone=addr:10m; #基于IP对下载速率做限制 限制每秒处理1次请求,对突发超过5个以后的请求放入缓存区 limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; server { listen 80; server_name localhost; location / { root html; index index.html index.htm; } location /abc { limit_req zone=one burst=5 nodelay; limit_conn addr 4; limit_rate 100k; } } }
URL重写介绍
和apache等web服务软件一样,rewrite的主要功能是实现URL地址的重定向。Nginx的rewrite功能需要PCRE软件的支持,即通过perl兼容正则表达式语句进行规则匹配的。默认参数编译nginx就会支持rewrite的模块,但是也必须要PCRE的支持。
Rewrite功功能是Nginx服务器提供的一个重要功能。几乎是所有的web产品必备技能,用于实现URL重写。URL重写是非常有用的功能,比如它可以在我们在改变网站结构后,不需要客户端修改原来的书签,也不需要其他网站修改对我们网站的友情链接,还可以在一定程度上提高网站的安全性,能够让我们的网站显得更专业。
应用场景
域名变更 (京东)
用户跳转 (从某个连接跳到另一个连接)
伪静态场景 (便于CDN缓存动态页面数据)
URL重写原理
URL重写
URL 模块语法
set 设置变量
if 负责语句中的判断
return 返回返回值或URL
break 终止后续的rewrite规则
rewrite 重定向URL
set指令 自定义变量
将http://www.jackson.com 重写为 http://www.jackson.com/baism location / { set $name baism; rewrite ^(.*)$ http://www.jackson.com/$name; }
if 指令 负责判断
条件匹配
#模糊匹配 ~匹配 !~不匹配 ~* 不区分大小写的匹配
#精确匹配 = !=
location / { root html; index index.html index.htm; if ($remote_addr ~* '192.168.66.146') { break; # return 403; return http://www.jd.com; } }
return 指令 定义返回数据
location / { root html; index index.html index.htm; if ($http_user_agent ~* 'Chrome') { return 403; #return http://www.jd.com; } }
break 指令 停止执行当前虚拟主机的后续rewrite指令集
location / { root html; index index.html index.htm; if ($http_user_agent ~* 'Chrome') { break; return 403; } }
rewrite指令 实现重写url
rewrite <regex> <replacement> [flag];
关键字 正则 替代内容 flag标记
flag:
last #本条规则匹配完成后,继续向下匹配新的location URI规则
break #本条规则匹配完成即终止,不再匹配后面的任何规则
redirect #返回302临时重定向,浏览器地址会显示跳转后的URL地址
permanent #返回301永久重定向,浏览器地址栏会显示跳转后的URL地址
重定向就是将网页自动转向重定向,permanent和redirect从定向的区别
301永久性重定向:新网址完全继承旧网址,旧网址的排名等完全清零
301重定向是网页更改地址后对搜索引擎友好的最好方法,只要不是暂时搬移的情况,都建议使用301来做转址。
302临时性重定向:对旧网址没有影响,但新网址不会有排名
搜索引擎会抓取新的内容而保留旧的网址
permanent标志:永久重定向
域名跳转 www.jackson.com 重写为 www.jd.com server { listen 80; server_name www.jackson.com; location / { rewrite ^/$ http://www.jd.com permanent; } }
redirect标志:临时重定向
域名跳转 www.jackson.com 重写为 www.jd.com server { listen 80; server_name www.jackson.com; location / { rewrite ^/$ http://www.jd.com redirect; } }
break标志: 类似临时重定向
域名跳转 www.jackson.com 重写为 www.jd.com server { listen 80; server_name www.jackson.com; location / { rewrite ^/$ http://www.jd.com break; } }
last标志:
url重写后,马上发起一个新的请求,再次进入server块,重试location匹配,超过10次匹配不到报500错误,地址栏url不变
last 一般出现在server或if中
根据用户浏览器重写访问目录
如果是chrome浏览器 就将 http://192.168.10.42/$URI 重写为 http://http://192.168.10.42/chrome/$URI 实现 步骤 1)URL重写 2)请求转给本机location location / { ..... if ($http_user_agent ~* 'chrome'){ #^ 以什么开头 ^a #$ 以什么结尾 c$ #. 除了回车以外的任意一个字符 #* 前面的字符可以出现多次或者不出现 #更多内容看正则表达式 re rewrite ^(.*)$ /chrome/$1 last; } location /chrome { root html ; index index.html; } }
调优的必要性
在聊调优之前,我们先要知道为何调优,业务运行和调优的关系。
业务运行:线上业务正常运行,承载了公司业务。 监控业务:通过监控业务对线上业务进行监控,及时发现问题。 优化业务:通过监控分析,发现业务问题或者瓶颈,及时对业务或者软件就行调整、优化。 测试优化:优化完成后,需要对现有的优化进行测试,保证业务在当前优化模式中稳定、高效,能够解决当前问题。 这就是业务运行的一个流程,也是我们保证业务稳定、高效、高可用的运维之道。
Nginx调优
并发优化
nginx工作模式:主进程+工作进程
启动工作进程数量 worker_processes 4; #指定运行的核的编号,采用掩码的方式设置编号 worker_cpu_affinity 0001 0010 0100 1000; events { 单个工作进程维护的请求队列长度 worker_connections 1024; }
长连接
减少服务器维护因为与客户端建立http连接产生的大量tcp三次握手四次断开的开销
keepalive_timeout 0; 0代表关闭 #keepalive_timeout 100; #keepalive_requests 8192;
压缩
降低传输时间,增加用户体验度;降低公司带宽费用。
gzip on; gzip_proxied any; gzip_min_length 1k; gzip_buffers 4 8k; gzip_comp_level 6; gzip_types text/plain text/css application/x-javascript application/javascript application/xml; # 开启gzip gzip off; #Nginx做为反向代理的时候启用: off – 关闭所有的代理结果数据压缩 expired – 如果header中包含”Expires”头信息,启用压缩 no-cache – 如果header中包含”Cache-Control:no-cache”头信息,启用压缩 no-store – 如果header中包含”Cache-Control:no-store”头信息,启用压缩 private – 如果header中包含”Cache-Control:private”头信息,启用压缩 no_last_modified – 启用压缩,如果header中包含”Last_Modified”头信息,启用压缩 no_etag – 启用压缩,如果header中包含“ETag”头信息,启用压缩 auth – 启用压缩,如果header中包含“Authorization”头信息,启用压缩 any – 无条件压缩所有结果数据 gzip_proxied any; # 启用gzip压缩的最小文件,小于设置值的文件将不会压缩 gzip_min_length 1k; # gzip 压缩级别,1-9,数字越大压缩的越好,也越占用CPU时间,后面会有详细说明 gzip_comp_level 1; # 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。 gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png application/vnd.ms-fontobject font/ttf font/opentype font/x-woff image/svg+xml; # 增加响应头”Vary: Accept-Encoding” # 是否在http header中添加Vary: Accept-Encoding,建议开启 gzip_vary on; # 禁用IE 6 gzip gzip_disable "MSIE [1-6]\."; # 设置压缩所需要的缓冲区大小 gzip_buffers 32 4k; # 设置gzip压缩针对的HTTP协议版本 gzip_http_version 1.0;
静态缓存
将部分数据缓存在用户本地磁盘,用户加载时,如果本地和服务器的数据一致,则从本地加载。提升用户访问速度,提升体验度。节省公司带宽成本。
expires指令:开启缓存并指定静态缓存时间 location ~* \.(png|gif)$ { expires 1h; }