一个web服务器软件默认状况下只能发布一个web,由于一个web分享出去须要三个条件(IP、Port、Domain name)
Nginx虚拟主机实现一个web服务器软件发布多个web。
虚拟主机就是将一台物理服务器划分红多个“虚拟”的服务器,每一个虚拟主机均可以有独立的域名和独立的目录。
如今不少公司出售的产品——“网站空间”,就是基于虚拟主机来卖的。价格和使用成本远远低于购买云服务器。php
案例:同时发布两个网站html
DocumentRoot /usr/local/nginx/html/web1 DocumentRoot /usr/local/nginx/html/web2
要测试基于IP的虚拟主机,必需要有两个IP的虚拟机、DocumentRoot存在、索引页index.html配置。
场景是:每一个网站都须要一个IP。
缺点是:须要多个IP,若是是公网IP,每一个IP都须要付费。前端
在这里须要知道nginx.conf文件是有一个默认备份文件的:nginx.conf.default,使用它能够迅速完成配置重置。node
$ pwd /usr/local/nginx/conf $ cp nginx.conf nginx.conf.bak $ cp nginx.conf.default nginx.conf # 仅保留有用的配置 sed -i "/#/d" nginx.conf # 有#的都删除 sed -i "/^$/d" nginx.conf # 有空行的都删除
worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 192.168.31.42:80; server_name localhost; location / { root html/web1; index index.html index.htm; } } server { listen 192.168.31.52:80; server_name localhost; location / { root html/web2; index index.html index.htm; } } }
两个IP、DocumentRoot存在、索引页index.html配置nginx
# 两个ip除了建立虚机等方式外,还能够配置虚拟ip $ ifconfig eno16777736:1 192.168.31.52/24 up # 建立DR目录 $ mkdir /usr/local/nginx/html/web1 $ mkdir /usr/local/nginx/html/web2 # 索引页配置 $ echo web01 > /usr/local/nginx/html/web1/index.html $ echo web02 > /usr/local/nginx/html/web2/index.html # 启动nginx并查看端口 $ /usr/local/nginx/sbin/nginx $ netstat -ntpl Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1317/master tcp 0 0 192.168.31.52:80 0.0.0.0:* LISTEN 12422/nginx: master tcp 0 0 192.168.31.42:80 0.0.0.0:* LISTEN 12422/nginx: master tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1095/sshd tcp6 0 0 ::1:25 :::* LISTEN 1317/master tcp6 0 0 :::22 :::* LISTEN 1095/sshd # 访问验证 $ elinks http://192.168.31.42 --dump web01 $ elinks http://192.168.31.52 --dump web02 # 关闭子网卡方法 $ ifconfig eno16777736:1 down
基于端口的虚拟主机只须要一个IP,但只适合内部用户,端口变化内部通知便可。(各类不良网站会须要改变IP和端口来逃避封锁)
缺点:端口没法告诉公网用户,没法适用于公网用户。web
worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; #server_name localhost; location / { root html/web1; index index.html index.htm; } } server { listen 8080; #server_name localhost; location / { root html/web2; index index.html index.htm; } } }
$ /usr/local/nginx/sbin/nginx -g nginx.conf # 验证前面修改的nginx配置 nginx: [emerg] unexpected end of parameter, expecting ";" in command line $ killall nginx $ /usr/local/nginx/sbin/nginx # 启动服务 $ netstat -ntpl Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1317/master tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 12543/nginx: master tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 12543/nginx: master tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1095/sshd tcp6 0 0 ::1:25 :::* LISTEN 1317/master tcp6 0 0 :::22 :::* LISTEN 1095/sshd $ elinks http://192.168.31.42 --dump # 未加端口默认是80端口 web01 $ elinks http://192.168.31.42:8080 --dump web02
一个网站必然有一个域名,能够ip和端口相同,但域名不一样。基于域名的虚拟主机主要用来处理线上问题。
基于域名的虚拟主机,完美解决了基于IP和基于端口虚拟主机的问题。正则表达式
# /etc/hosts ...... 原始的保留 192.168.31.42 www.abc.com 192.168.31.42 www.cbd.com # nginx.conf worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name www.abc.com; location / { root html/web1; index index.html index.htm; } } server { listen 80; server_name www.cbd.com; location / { root html/web2; index index.html index.htm; } } }
$ /usr/local/nginx/sbin/nginx -g nginx.conf $ killall nginx $ /usr/local/nginx/sbin/nginx $ netstat -ntpl Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1317/master tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 12676/nginx: master tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1095/sshd tcp6 0 0 ::1:25 :::* LISTEN 1317/master tcp6 0 0 :::22 :::* LISTEN 1095/sshd $ elinks http://www.abc.com -dump web01 $ elinks http://www.cbd.com -dump web02
反向代理图示以下:算法
业务服务器安全配置只接受来自源IP为堡垒机的连接访问,其余的都拒绝。黑客攻击的只是一台暴露在外网的反向代理服务器,服务器上其实什么都没有,不用担忧数据丢失。chrome
适用于公网IP地址不足的场景。
在业务服务器前面作一个反向代理服务器,以虚拟主机的方式配置三个虚拟机主机,并配置三个代理。访问不一样的虚拟主机找不一样的业务服务器获取数据,再将数据提供给用户。后端
常见缓存场景应用:CDN。
网站具备动态、静态两种数据。自行配置缓存服务器时,在缓存服务器上保存静态数据。客户访问时,缓存服务器将静态数据发给客户端。动态数据则是由缓存服务器向业务服务器发送请求获取后发给客户端。每每静态页面还在渲染,动态数据已经获取并逐渐加载。
好处是:加载速度较快,用户体验提高;下降业务服务器压力。
1)客户端经过浏览器发起请求,请求发送给代理服务器;
2)代理服务器接收请求;
3)代理服务器发送请求给业务服务器;
4)业务服务器接受请求、处理请求;
5)业务服务器发送响应请求把数据交给代理服务器;
6)代理服务器再发送响应请求将数据交给客户端;
7)客户端经过浏览器将数据渲染出来并展现给用户。
client用mac电脑代替,反向代理用以前的Nginx,业务机器用book.ayitula.com(http://118.190.209.153:4000)。指望实如今mac上访问http://192.168.31.42访问到该服务页面。
(1)备份重启操做
$ cp nginx.conf nginx.conf.bak_2 $ cp nginx.conf.default nginx.conf $ killall nginx $ /usr/local/nginx/sbin/nginx
(2)nginx.conf配置修改内容
server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { # root html; # 这个机器再也不是web服务器,而是反向代理,所以没用了 proxy_pass http://118.190.209.153:4000; # 请求转向指定地址 index index.html index.htm; }
(3)反向代理效果
location / { index index.php index.html index.htm; #定义首页索引文件的名称 proxy_pass http://mysvr ; #请求转向mysvr 定义的服务器列表 # 设置请求头——给请求头加字段 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # 告诉业务服务器是代替哪一个客户来拿数据 proxy_set_header X-Forwarded-For $proxy_add_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服务器传 }
限流(rate limiting)是NGINX众多特性中最有用的,也是常常容易被误解和错误配置的特性之一。
限速该特性能够限制某个用户在一个给定时间段内可以产生的HTTP请求数。请求能够简单到就是一个对于主页的GET请求或者一个登录表格的POST请求。
限流也能够用于安全目的上,好比减慢暴力密码破解攻击。经过限制进来的请求速率,而且(结合日志)标记出目标URLs来帮助防范DDoS攻击。通常地说,限流是用在保护上游应用服务器不被在同一时刻的大量用户请求湮没。另外还能够保护磁盘IO。
算法思想是:
水(请求)从上方倒入水桶,从水桶下方流出(被处理);
来不及流出的水存在水桶中(缓冲),以固定速率流出;
水桶满后水溢出(丢弃)。
这个算法的核心是:缓存请求、匀速处理、多余的请求直接丢弃。
相比漏桶算法,令牌桶算法不一样之处在于它不但有一只“桶”,还有个队列,这个桶是用来存放令牌的,队列才是用来存放请求的。
Nginx官方版本限制IP的链接和并发分别有两个模块:
Syntax: limit_req zone=name [burst=number] [nodelay]; Default: —
Context: http, server, location
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
基于IP对下载速率作限制,限制每秒处理1次请求,对突发超过5个之后的请求放 入缓存区
http { limit_req_zone $binary_remote_addr zone=baism:10m rate=1r/s; server { location /abc { limit_req zone=baism burst=5 nodelay; } } }
1)limit_req_zone $binary_remote_addr zone=baism:10m rate=1r/s; 设置缓存区(设置一个漏桶)
2)limit_req zone=baism burst=5 nodelay; 应用缓存区
http { #基于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 1; # 并发限制,同一时间能下几个资源 limit_rate 100k; # 下载最高速率限制 #limit_rate_after 250m; # 下载到250M限速(不太经常使用) } } }
# 案例一:请求数限速 $ elinks http://192.168.31.42 -dump # 连续发起5次,第五次将获得404页面,返回页面也能够自行定义 # 案例二:下载限速 #在服务器端生成一个300M的文件 $ dd if=/dev/zero of=../html/abc/bigfile bs=1M count=300 #从mac上访问下载 $ wget http://192.168.31.42/abc/bigfile #启动下载限速最高100kB/s limit_rate 100k; #启动同时链接数限制,最多一个 limit_conn addr 1;
URL重写是基于ngx_http_rewrite_module这个rewrite模块。
Rewrite功能是Nginx服务器提供的一个重要功能,也几乎是全部web产品必备技能,用于实现URL重写。
URL重写是很是有用的功能,好比它能够在咱们改变网站结构后,不须要客户端修改原来的书签,也不须要其余网站修改对咱们网站的友情连接,还能够在必定程度上提升网站的安全性,可以让咱们的网站显得更加专业。
Nginx服务器Rewrite功能的实现是依赖于PCRE(Perl Compatible Regular Expression,Perl兼容的正则表达式)的支持,因此在编译安装Nginx以前,须要安装PCRE库。
上述图片过程:用户经过浏览器向nginx发起请求,nginx接收请求后,url重写将新的url告诉用户浏览器,用户浏览器再用新的url去访问业务服务器,业务服务器将数据发给用户浏览器。
(1) set:设置变量
(2) if:负责语句中的判断
(3) return:返回返回值或URL
(4) break:终止后续的rewrite规则
(5) rewrite:重定向URL
模糊匹配:~匹配 !~不匹配 ~* 不区分大小写的匹配
精确匹配:=匹配 !=不匹配
rewrite <regex> <replacement> [flag]; 关键字 正则 替代内容 flag标记 经常使用flag: last —— 本条规则匹配完成后,继续向下匹配新的location URL规则 break —— 本条规则匹配完成即终止,再也不匹配后面的任何规则 redirect —— 返回302临时重定向,浏览器地址会显示跳转后的URL地址 permanent —— 返回301永久重定向,浏览器地址栏会显示跳转后的URL地址
示例:将http://www.ayitula.com重写为http://www.ayitula.com/baism
语法:set $variable value;
做用域:server,location,if
location / { #root html; #index index.html index.htm; set $name baism; rewrite ^(.*)$ http://www.ayitula.com/$name; # 调用了变量$name }
语法:if (condition) {......}
做用域:server和location。
location / { root html; index index.html index.htm; if ($http_user_agent ~* 'Chrome') { # 不区分大小写匹配chrome return 403; # 若是浏览器是chrome,直接返回403 #return http://www.jd.com; } }
须要注意:$http_user_agent是Nginx内部变量。
语法:
return code [text]; # 返回代码和文本 return code URL; return URL; # 返回url
做用域:server,location,if
语法:break;
做用域:server,location,if
location / { root html; index index.html index.htm; if ($http_user_agent ~* 'Chrome') { break; return 403; } }
break表明本条规则匹配完成即终止,再也不匹配后面的任何规则。
server { listen 80; server_name www.ayitula.com; location / { rewrite ^/$ http://www.jd.com break; # rewrite ^/$ http://www.jd.com redirect; # redirect:临时重定向 } }
直接将重写的域名发给客户端后结束。相似临时重定向效果,返回客户端302。
域名跳转:www.ayitula.com 重写为 www.jd.com
server { listen 80; server_name www.ayitula.com; location / { rewrite ^/$ http://www.jd.com permanent; # ^/$ 指定根目录 permanent:永久重定向 # rewrite ^/$ http://www.jd.com redirect; # redirect:临时重定向 } }
Nginx配置完后,还须要配置/etc/hosts,将域名解析到本地nginx服务器地址:
192.168.31.42 www.ayitula.com
注意:
last指令在url重写后,并不会结束而是立刻发起一个新的请求,再次进入server块,重试location匹配,超过十次匹配不到报500错误,地址栏url不变。
示例:根据用户浏览器重写访问目录
若是是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'){ rewrite ^(.*)$ /chrome/$1 last; # 第一步重写url } location /chrome { # 第二步用新的url(http://192.168.31.42/chorm/$uri)来匹配规则 root html ; index index.html; } }
注意正则使用: