代理(proxy_pass)
nginx定义
Nginx是轻量级的Web 服务器 、反向代理服务器及电子邮件(IMAP/POP3)代理服务器。
Nginx最初仅仅主要被用于做反向代理,后来随着HTTP核心的成熟和各种HTTP扩展模块的丰富,Nginx越来越多被用来取代Apache而单独承担HTTP Server的责任,例如目前淘宝内各个部门正越来越多使用Nginx取代Apache.
nginx安装
安装nginx需要先安装其依赖组件以及c++环境,最后安装nginx;
组件包含:
• pcre-8.3.7.tar.gz :nginx的http模块使用pcre来解析正则表达式,需要在linux上安装pcre库
• openssl-1.0.1t.tar.gz :安装openssl库,让 nginx 支持 https(即在ssl协议上传输http)
• zlib-1.2.8.tar.gz : nginx使用zlib对http包的内容进行gzip,需要在linux上安装安装zlib库
-
组件下载
wget http://nginx.org/download/nginx-1.10.2.tar.gz
wget http://www.openssl.org/source/openssl-fips-2.0.10.tar.gz
wget http://zlib.net/zlib-1.2.11.tar.gz
wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.40.tar.gz -
c++环境安装
yum install gcc-c++
-
组件安装
openssl安装
tar zxvf openssl-fips-2.0.10.tar.gz
cd openssl-fips-2.0.10
./config && make && make installpcre安装
tar zxvf pcre-8.40.tar.gz
cd pcre-8.40
./configure && make && make installzlib安装
tar zxvf zlib-1.2.11.tar.gz
cd zlib-1.2.11
./configure && make && make install -
nginx安装
tar zxvf nginx-1.10.2.tar.gz
cd nginx-1.10.2
./configure && make && make install
nginx目录
-
linux目录
目录 内容 conf 存放配置文件 html 类似于tomcat的webapps目录,存放网络访问的资源 logs 存放日志 sbin 存放nginx的启动文件 -
windows目录
核心配置文件位置:
程序相关命令
-
linux系统
安装完成后的路径为:/usr/local/nginx。nginx位于/usr/local/nginx/sbin,以下命令都是基于这个目录的
(也可以将/usr/local/nginx/sbin添加到环境变量中)-
启动服务
• 普通启动服务:./nginx
• 配置文件启动服务:./nginx -c /usr/local/nginx/conf/nginx.conf -
停止服务
• 暴力停止服务:./nginx -s stop
• 优雅停止服务:./nginx -s quit -
检查与重启服务
• 检查配置文件:./nginx -t
• 重新加载配置:./nginx -s reload -
查看相关进程
• 查看相关进程:ps -ef | grep nginx
-
服务相关命令
-
linux系统
bash#开机自动启动systemctl systemctl enable nginx #启动Nginx(x成功后可以直接访问主机IP,会展示Nginx默认页面) systemctl start nginx #停止Nginx systemctl stop nginx #重启Nginx systemctl restart nginx #重新加载Nginx systemctl reload nginx #查看Nginx运行状态 systemctl status nginx
虚拟主机(server)
(服务器级别)nginx使用server容器定义一个虚拟主机。server容器没有严格区分基于IP和基于名称的虚拟主机,它们通过listen指令和server_name指令结合起来形成不同的虚拟主机。
typescript
# 基于IP地址的虚拟主机
server {
listen 80;
server_name 192.168.100.25;
location / {
root /www/longshuai/;
index index.html index.htm;
}
}
server {
listen 80;
server_name 192.168.100.26;
location / {
root /www/xiaofang/;
index index.html index.htm;
}
}
# 基于名称的虚拟主机
server {
listen 80;
server_name www.longshuai.com;
location / {
root /www/longshuai/;
index index.html index.htm;
}
}
server {
listen 80;
server_name www.xiaofang.com;
location / {
root /www/xiaofang/;
index index.html index.htm;
}
}
# 基于端口的虚拟主机
server {
listen 80;
server_name 192.168.100.25;
location / {
root /www/longshuai/;
index index.html index.htm;
}
}
server {
listen 8080;
server_name 192.168.100.25;
location / {
root /www/xiaofang/;
index index.html index.htm;
}
}
路由匹配(location)
(请求级别)nginx根据用户请求的URI对应至server模块,然后依靠location块的匹配规则,选择进入对应location块进行处理。
修饰符匹配规则如下:
它们之间匹配优先级:精确匹配>左侧通配符匹配>右侧通配符匹配>正则表达式匹配
进入对应的location块后再通过root指令和index指令结合起来配置被访问的首页即可
指令 | 内容 |
---|---|
root | 配置服务器的默认网站根目录位置,默认为nginx安装主目录下的html目录 |
index | 配置首页文件的名称 |
写法如下:
bash
location / {
root html;
index index.html index.htm;
}
正向代理
正向代理对我们是透明的,对服务端是非透明的,即服务端并不知道自己收到的是来自代理的访问还是来自真实客户端的访问。
反向代理
以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端
举个栗子,我想在本地使用 www.mickey.com 的域名去访问 www.taobao.com。那么这个时候我们就可以通过nginx去实现。
nginx负载均衡
-
负载均衡
我们项目部署在不同的服务器上,但是通过统一的域名进入,nginx则对请求进行分发,减轻了各服务器的压力。
负载均衡在实际项目操作过程中,有硬件负载均衡和软件负载均衡两种:
负载种类 成本 内容 硬件负载 造价昂贵成本较高 数据的稳定性安全性等等有非常好的保障 软件负载均衡 低 利用现有的技术结合主机硬件实现的一种消息队列分发机制 -
负载均衡策略
请求数量按照负载均衡策略进行分发到不同的服务器
负载均衡策略
-
轮询策略(默认)
每个请求按时间顺序,逐一分配到不同的后端服务器,这是默认的负载均衡策略。如果后端服务器down掉,能自动剔除。
typescript#动态服务器组 upstream bobo{ server 192.168.64.1:9001; #tomcat 1 server 192.168.64.1:9002; #tomcat 2 server 192.168.64.1:9003; #tomcat 3 server 192.168.64.1:9004; #tomcat 4 } location ~ .jps$ { proxy_pass http://bobo }
轮询策略可以给不同的后端服务器设置一个权重值(weight),所谓权重就是按照比例来进行分配,如果有三次请求,2次在第一个机器上,1次在另外一个机器上。
权重大小和访问比率成正比,该策略常用于后端服务器性能不均衡的情况下。typescript#动态服务器组 upstream dynamicserver { server 192.168.64.1:9001 weight=2; #tomcat 1 server 192.168.64.1:9002; #tomcat 2 server 192.168.64.1:9003; #tomcat 3 server 192.168.64.1:9004; #tomcat 4 }
-
ip_hash策略
(nginx版本1.3.1之前不能在ip_hash中使用权重)
对每个请求访问的ip进行hash运算,再根据结果进行分配,这样每个访客固定访问一个后端服务器。
这也在一定程度上解决了集群部署环境下session共享的问题。
当有服务器需要剔除,必须手动down掉。typescriptupstream dynamicserver { ip_hash; #保证每个访客固定访问一个后端服务器 server 192.168.64.1:9001 weight=2; #tomcat 1 server 192.168.64.1:9002; #tomcat 2 server 192.168.64.1:9003; #tomcat 3 server 192.168.64.1:9004; #tomcat 4 }
-
fair
智能调整调度算法,动态的根据后端服务器的请求处理到响应的时间进行均衡分配,响应时间短处理效率高的服务器分配到请求的概率高,响应时间长处理效率低的服务器分配到的请求少;结合了前两者的优点的一种调度算法。但是需要注意的是nginx默认不支持fair算法,如果要使用这种调度算法,请安装upstream_fair模块
-
url_hash
按照访问的url的hash结果分配请求,每个请求的url会指向后端固定的某个服务器,可以在nginx作为静态服务器的情况下提高缓存效率。同样要注意nginx默认不支持这种调度算法,要使用的话需要安装nginx的hash软件包
通常情况下,我们在实际项目操作时,正向代理和反向代理很有可能会存在在一个应用场景中,正向代理代理客户端的请求去访问目标服务器,目标服务器是一个反向代理服务器,反向代理了多台真实的业务处理服务器。
动静分离
在说动静分离前,我们要知道为何要做动静分离以及他能解决啥问题,首先,我们常见的web系统中会有大量的静态资源文件比如掘金主页面刷新后的f12如下:
可以看到有很多静态资源,如果将这些资源都搞到后端服务的话,将会提高后端服务的压力且占用带宽增加了系统负载(要知道,静态资源的访问频率其实蛮高的)所以为了避免该类问题我们可以把不常修改的静态资源文件放到nginx的静态资源目录中去,这样在访问静态资源时直接读取nginx服务器本地文件目录之后返回,这样就大大减少了后端服务的压力同时也加快了静态资源的访问速度,何为静,何为动呢?
• 静: 将不常修改且访问频繁的静态文件,放到nginx本地静态目录(当然也可以搞个静态资源服务器专门存放所有静态文件)
• 动: 将变动频繁/实时性较高的比如后端接口,实时转发到对应的后台服务
接下来我们将构造一个html页面,然后点击按钮后发送get请求到后端接口,流程如下:
typescript
server {
listen 9000;
server_name localhost;
location ~*.(jps|js|css|html|png|gif|map)$ {
root /usr/local/web;
expires 1d;
}
location ~.action$ {
proxy_pass http:1.117.75.21:8080;
}
}
跨域
-
同源策略
由于同源策略的原因产生了跨域问题,同源策略目的是为了保护用户信息安全,防止恶意网站窃取数据,目前所有浏览器都实现同源策略。
同源策略主要是指三点相同即:协议 、域名、端口,这三点相同的两个请求则可以看作是同源的,如果其中任意一点不同,则代表两个不同源的请求,此时同源策略会限制不同源之间的资源交互。
-
场景
web 领域开发中,经常采用前后端分离模式。这种模式下,前端和后端分别是独立的 web 应用程序,例如:后端是 Java 程序,前端是 React 或 Vue 应用。各自独立的 web app 在互相访问时,势必存在跨域问题。
-
解决跨域
避免不同源可以解决跨域,将后端的代理放在前端的server(即统一使用一个端口),因为server支持多个location配置
https配置
-
前置条件
• 服务器已经安装nginx并且通过http可以正常访问
• 拥有ssl证书,没有的可以去阿里购买或者免费申请一年 -
ssl模块安装
一般情况下自己安装的nginx都是不存在ssl模块的
-
检查是否存在ssl模块
进行Nginx安装目录的sbin目录下,输入:./nginx -V
如果出现 (configure arguments: --with-http_ssl_module), 则已安装
-
-
配置ssl证书
解压缩下载好的证书(证书一般是pem文件和key文件,这里名字可以随便改)
将下载好的证书上上传到服务器,我将证书放在了root目录下的card文件夹
-
配置nginx.conf
bashhttp { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { #监听443端口 listen 443; #你的域名 server_name huiblog.top; ssl on; #ssl证书的pem文件路径 ssl_certificate /root/card/huiblog.top.pem; #ssl证书的key文件路径 ssl_certificate_key /root/card/huiblog.top.key; location / { proxy_pass http://公网地址:项目端口号; } } server { listen 80; server_name huiblog.top; #将请求转成https rewrite ^(.*)$ https://$host$1 permanent; } }
nginx优化
-
安全优化(提升网站安全性配置)
-
性能优化(提升用户访问网站效率)
nginx实例
一些对安全性要求比较高的站点,可能会使用 HTTPS(一种使用ssl通信标准的安全HTTP协议),使用 nginx 配置 https 需要知道几点:
• HTTPS 的固定端口号是 443,不同于 HTTP 的 80 端口
• SSL 标准需要引入安全证书,所以在 nginx.conf 中你需要指定证书和它对应的 key
-
模仿多个主机
• (Linux服务器)修改nginx配置文件如下,并重启
• (客户机)修改hosts文件typescript192.168.64.150 www.abc.com 192.168.64.150 www.bbs.com
-
location匹配
-
前缀匹配
• 没有修饰符,修改配置文件如下,并重启nginx
typescriptserver { listen 80; server_name www.tangbb.com; location /abc { default_type text/html; echo "abc..."; } }
• 可匹配示例:
www.tangbb.com/abc
www.tangbb.com/abc/other
www.tangbb.com/abc?.... -
通用匹配
• 一般nginx配置文件最后都会有一个通用匹配规则,当其他匹配规则均失效时,请求会被路由给通用匹配规则处理;如果没有配置通用匹配,并且其他所有匹配规则均失效时,nginx会返回 404 错误
typescriptserver { listen 80; server_name www.tangbb.com; location /{ default_type text/html; echo "abc..."; } }
-
精确匹配
• 精确匹配使用 = 表示,nginx进行路由匹配的时候,精确匹配具有最高的优先级,请求一旦精确匹配成功nginx会停止搜索其他到匹配项
typescriptserver { listen 80; server_name www.tangbb.com; location = /abc { default_type text/html; echo "abc..."; } }
• 可匹配示例:
www.tangbb.com/abc
www.tangbb.com/abc?....• 无法匹配示例:
-
-
反向代理
-
打开浏览器,在浏览器地址栏输入地址 www.123.com,跳转到 liunx 系统 tomcat 主页 面中
• (Linux服务器-208.208.128.122)安装并启动tomcat,并对外开放8080端口
• (客户机)浏览器验证访问208.208.128.122:8080
• (客户机)更改host文件,添加一条DNS记录(208.208.128.122 www.123.com)
• (Linux服务器-208.208.128.122)Nginx配置请求转发typescriptserver { listen 80; server_name 208.208.128.122; location / { root html; proxy_pass http://127.0.0.1:8080 index index.html index.htm; } }
测试:访问域名为 www.123.com,故访问该域名时会先到linux服务器,再转到本机127.0.0.1:8080路径
-
简单示例
• (后端服务器-172.30.128.64)tomcat启动Java项目,指定端口为8081
• (Nginx服务器-172.30.128.65)修改nginx.conf配置文件
通过upstream指令块定义我们的上游服务器(即被代理的服务器)
通过location指令块中的proxy_pass指令,指定该location要路由到哪个upstream来了请求后会通过url路由到对应的location,然后nginx会将请求打到upstream定义的服地址中去
• (Nginx服务器-172.30.128.65)重新加载nginx配置(nginx -s reload)
• (Nginx服务器-172.30.128.65)关闭seLinux的限制(setenforce 0)
• (客户机)更改host文件,添加一条DNS记录(www.proxytest.com),postman测试
• 流程分析
-
根据访问路径跳转到不同端口的服务中
要求:
nginx监听端口8001
访问http://127.0.0.1:8001/edu/ 直接跳转到 127.0.0.1:8081
访问 http://127.0.0.1:8001/vod/ 直接跳转到 127.0.0.1:8082• 准备两个tomcat,一个8081端口,一个8082端口,具体如下:
-->新建tomcat8081和tomcat8082两个文件夹
-->将tomcat安装包分别存入并解压(需改对应配置文件),分别启动
-->
-
-
负载均衡
-
轮询策略
• (后端服务器)启动三个不同端口的服务,别分是8081、8082、8083
• (Nginx服务器)定义我们的上游服务器(即被代理的服务器),将三个ip + 端口放入upstream
轮询是默认的,所以upstream不需要额外加参数• (Nginx服务器)重新加载nginx配置(nginx -s reload)
• (客户机)请求三次,可以看到是按upstream中的先后顺序来进行轮询的 -
权重策略
• (Nginx服务器)修改我们的上游服务器(即被代理的服务器)
• (客户机)发送四次请求,可以看到在一轮轮询中,8081命中1次,8082由于配置了 weight=2所以命中了2次,8083命中了1次。即配置了weight=2的8082服务,命中几率是8081或者8083的两倍
-
ip_hash策略
• (Nginx服务器)修改我们的上游服务器(即被代理的服务器)
• (客户机)发送多次请求,可以看到,由于我的访问ip总是固定的宿主机的172.30.128.64 根据hash算法我的ip被匹配给了8083端口的服务,所以只要我不换ip 不管我请求多少次,请求都是被 转发到了8083的服务上了。
-
least_conn策略
• (Nginx服务器)修改我们的上游服务器(即被代理的服务器)
最小连接数看不出啥效果,所以就不演示截图了,知道怎么配置最小连接数即可。
-
-
动静分离
• 编写一个Html页面(index_page.html)并上传到虚拟机
• (Nginx服务器)配置俩location规则,一个( /frontend )是读取静态文件,一个(/backend)是转发到 我们配置的upstream服务中去。如下:
• (客户机)浏览器输入www.proxytest.com/frontend/ ,可以看到请求返回了一个html页面,其实就是我们刚才的 /usr/local/nginx/test/static/index_page.html文件
• (客户机)调用get请求
-
跨域
• nginx.conf 文件配置两个server,分别代表前后端,并且监听的端口以及域名名称都不一致,造成非"同源"场景(重启nginx)
• 修改index_page.html中的后端地址
• (客户机)更改host文件,添加一条DNS记录
typescript172.30.128.65 www.front.com 172.30.128.65:90 www.backend.com
• 浏览器复现
可以看到浏览器提示我们受同源规则影响我们不能跨域访问资源。造成的原因是我的两个域名解析出来的端口不一致 一个是80一个是90。不符合同源策略,所以必然会有跨域报错。
• 修改配置文件,让一个server配置多个location(重启Nginx)
• 测试页面 www.xxxadminsystem.com/page/ (成功返回页面)• 调用get请求(请求成功)