正向代理和反向代理
Nginx是一款轻量级的Web服务器、反向代理服务器,在学习Nginx之前,首先要知道啥子是反向代理,啥子是正向代理。优势就是内存少,启动快,高并发强。
正向代理
正向代理是位于一个客户端和服务器之间的代理服务器,可以理解为一个缓冲区,正向代理的情况下,客户端需要进行一定的设置才能进行使用。
正是由于firewal的原因,不能直接访问谷歌,科学上网的就属于正向代理。
正向代理特点
- 需要手动设置ip或域名进行访问,由设置的服务器ip或者域名去访问内容
- 正向代理是代理的客户端,为客户端收发请求,使真实客户端对服务器不可见
正向代理的用途
- 突破IP访问限制
- 提高访问速度,通常代理服务器都具有较大的缓冲区,会将部分请求保存在缓冲区中,当其他用户访问时,通过缓冲区发送给用户,用以提高访问速度。
- 隐藏客户端的真实IP
反向代理:
反向代理的是以代理服务器来接收客户端的请求,然后将请求发送到内部网络的服务器上去,将从服务器上得到的结果返回给客户端,这个时候就表现为对外反向代理服务器,客户端不需要进行任何设置,提高服务器集群的可替代性。
反向代理隐藏了真实的服务端,反向代理服务器会把请求转发到真实的服务器那里去
反向代理特点
- 不需要像正向代理那样进行设置
- 提高内部服务器的安全性
- 加快内部服务器的访问速度
- 节约有限的IP
- 代理的服务器,为服务器收发请求,使真实服务器对客户端不可见
反向代理用途
- 负载均衡:根据真实服务器的负载情况,将客户端请求发送到不同的真实服务器上。
- 可以对静态内容以及短时间内访问的大量访问请求的动态内容提供缓存服务,提高速度
- 代理服务器可以作为应用层的firewall,防止恶意攻击
正向代理和反向代理的比较
- 正向代理属于客户端的代理,服务器不知道真正的客户端;反向代理属于服务端的代理,客户端不知道真正的服务端
- 正向代理一般用于解决访问限制的问题,反向代理主要用来解决负载均衡,安全防护等,正向代理和反向代理都能提高访问速度。
Nginx
简介
nginx是一款高性能的HTTP和反向代理的WEB服务器,强大的处理高并发的能力,其特点就是占用的内存少,并发能力强,另外nginx支持热部署,启动简单,几个月都不需要重新启动。这里的热部署指的是正在运行的时候升级软件,却不需要重新启动应用,跟键盘的热插拔一个意思。(tomcat,springboot也都支持热部署。)
nginx正向代理
nginx不仅可以作为反向代理,也能够进行正向代理来进行科学上网等。
nginx反向代理
客户端不需要进行任何配置就可以进行访问,客户端访问的是代理服务器的ip,而隐藏了真实的服务器ip。
负载均衡
增加服务器的数量,将请求分发到各个服务器上,将请求从集中到单个服务器上到分发到多个服务器上,这就是负载均衡。
负载均衡的三种方式(内置策略)
-
轮询法(默认方法,RR):
将请求轮流发送给所有的服务器。如果服务器down掉的话,会自动选择另外一条服务器
upstream dalaoyang-server { server localhost:8000; server localhost:8010; }
nginx将请求发送到8000和8010端口,如果这次选择的是8000端口,那么下次选择的就是8010端口。一直循环
适用场景:适用于服务器性能相同的时候
-
加权轮询(WRR):
按照权重比例发送请求
upstream alias { server 127.0.0.1:8000 weight=3; server 127.0.0.1:8010 weight=2; }
这里的权重就是3:2,这就表示nginx在转发的时候以3:2的比例转发给两台服务器,nginx的权重机制属于轮询权重,就是说先给8000的发送3次请求,再给8010的发送2次请求。
适用场景:适用于性能不同的服务器,应多给配请求给性能较强的服务器,这样可以将服务器的性能充分发挥,更有效的利用资源,提高资源利用率。
-
ip_hash(ip绑定):
就是将请求方的ip和服务器进行绑定。有的时候我们需要某一个请求一直访问某一台子服务器,这个时候就需要使用ip_hash这种负载均衡的方法,例如:当用户使用某个ip访问服务器的时候,nginx将请求转发至8000,那么该请求的后续所有请求都将被转发至8000端口进行处理。
upstream dalaoyang-server { ip_hash; server localhost:10001 weight=1; server localhost:10002 weight=2; }
适用场景:多用于带会话请求的场景,比如用户的登录信息保存在session中 ,如果更换服务器的话,之前的session就拿不到了,这个时候就需要重新登录,使用ip_hash保证用户请求的是同一台服务器,获取的session是相同的。解决session不共享的问题。
拓展策略的话这个需要参照所有的负载均衡算法,一一找出来进行实现。
web缓存(这里的只是粗略的写一下,方便理解,之后再继续更新)
可以对不同的文件做不同的缓存处理,配置比较灵活。
定义
也叫做代理服务器,代表初始WEB服务器来满足HTTP请求的网络实体。位于服务端和客户端之间,当用户访问一个URL时,web缓存服务器会向后端web源服务器取回想要的内容,下一个请求到来的时候,如果访问的相同的URL,WEB缓存服务器直接输出内容给客户端,而不是向源服务器再次发送请求,web缓存降低了源WEB服务器数据库的负载,减少延迟,提高了用户的访问速度。
响应过程
- 浏览器建立一个WEB缓存器的TCP连接,并向WEB缓存器中的对象发送一个HTTP请求。
- WEB浏览器检查,查看是否本体存储了该对象的副本,如果有的话,WEB缓存器就向浏览器用HTTP响应报文返回该对象。
- 如果WEB缓存器中没有该对象,就打开一个该对象的初始服务器的TCP连接,WEB缓存器在这个缓存器到服务器的TCP连接上发送一个该对象的HTTP请求。在收到该请求后,初始服务器向该WEB缓存器发送具有该对象的HTTP响应。
- 当WEB缓存器接收到该对象后,在本地存储空间存储一份副本,并向客户端的的浏览器用HTTP响应报文发送该副本。
WEB缓存即时服务端又是客户端,当他接收浏览端的请求并发送响应的时候,他是服务端。当他向服务端发送请求并接收响应的时候,他是客户端。
web缓存的作用
- 减少客户端对服务端的响应时间
- 减少网络带宽消耗
- 降低服务器的压力
动静分离
nginx的静态处理能力很强,但是动态处理能力不是很好,在企业级中主要采用动静分离的代理方式,主要是为了加快网站的解析和访问速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析和访问速度,降低单个服务器的压力,优化用户体验。
最小连接(least_conn)
这个一般跟权重一起用,一般是由于转发的请求耗时过长,会造成某些子服务器连接的数量比较多,least_conn首先便利后端集群,选取server_conns/weight比值最小者为请求处理者,如果最小值的服务器有多台,就会采用加权轮询选择权重值大的服务器。
upstream leastconn {
least_conn;
server 127.0.0.1:8000 weight=3;
server 127.0.0.1:8010 weight=2;
server 127.0.0.1:8020 weight=1;
}
第三方调度算法
-
url_hash
根据请求的url的hash值将请求分发到不同的服务器,使每个url定向到同一个后端服务器,需要配合缓存命中(cache hit)来使用,文章的末尾有介绍缓存命中率的概念,当后台服务器为缓存时效率较高。
同一个资源被多次请求,可能达到不同的服务器上,这样就使得资源利用率降低,同一个资源被多次下载,使用url_hash可以使得同一个url(同一个资源请求),会到达同一台服务器,只要缓存中有响应的资源,那么再次接收请求的时候,就可以从缓存中进行读取。
需要注意的有:
- 在server语句中不能够使用权重(weight)
- 需要安装第三方 ngx_http_upstream_hash_module 模块
upstream backend{ hash & request_uri; server 127.0.0.1:8000; server 127.0.0.1:8010; server 127.0.0.1:8020; }
-
fair
根据后端响应时间来发送请求,响应时间短的分发的请求多。
upstream backend { fair; server 127.0.0.1:8000; server 127.0.0.1:8010; }
nginx配置文件
nginx配置文件是在安装目录下的conf目录下,基本都是修改nginx.conf配置文件,修改过配置文件后,需要重启nginx服务。配置文件在nginx.conf中,每次修改完nginx.conf之后需要重启nginx服务才能进行生效。nginx.conf配置文件主要分为三块。
在nginx配置文件中 ,以/开头的路径表示绝对路径,不以/开头的路径表示相对路径,相对路径的根目录是nginx的根目录。
全局模块
一般配置的是nginx服务器的用户组,nginx进程pid存放的路径,日志的存放路径等。
- 用户或用户组默认是nobody
- worker_processs 1是工作进程数,该值越大,可以支持的并发就会越多,但是会收到网络和硬件设备的影响。
- pid logs/nginx.pid:进程文件的路径
Events 模块
常用的设置有:对网络连接序列化,是否允许同时接收多个网络连接,事件驱动模型,最大连接数
- accept_mutex on:设置网络连接序列化,默认为on
- multi_accept on:一个进程是否同时接收多个网络连接,默认为off
- use epoll:事件驱动模型,select | poll | kqueue | epoll | resig | /dev/poll | eventport
HTTP模块
这是nginx中最频繁的配置模块,http模块也包含http全局模块,server模块等。
http全局模块
写在http{}中,但不写在http{}子模块中的所有内容就属于http的全局模块,会影响http{}以及其子模块中的内容。
http {
include mime.types; #文件拓展名与文件类型映射表
default_type application/octet-stream; #默认文件类型
access_log logs/access.log main; #设置日志的格式(myLogFormat)
sendfile on; #开启文件高效
tcp_nopush on;
#不需要按0.2s的时间来传输数据,当包达到一定大小时发送,需要和sendfile一块使用
keepalive_timeout 65; #长连接超时时间
send_timeout 300;
#客户端响应时间,超过这个时间没有向服务器发送请求,nginx就会自动关闭连接
client_max_body_size 100m; #允许客户端请求的最大字节数
keepalive_requests 8192; #每个连接的最大请求数
sendfile_max_chunk 100k; #每个进程每次最大传输值,默认为0,表示不设上限
client_header_buffer_size 32k; #客户端请求头的缓冲区大小
large_client_header_buffers 8 32k; #客户端请求头的最大缓冲区数量和大小
}
http_proxy模块
proxy可以起到firewall的作用,提高访问速度
location /prod-api/ {
proxy_pass http://localhost:30030/; #将url为/prod-api/的请求代理到localhost:30030
proxy_http_version 1.1;
proxy_connect_timeout 70;
proxy_read_timeout 600; #nginx与代理服务器之间最大的响应时间(报文从接收到确认)
proxy_send_timeout 600; #nginx传输到代理服务器之间的超时时间
proxy_buffer_size 64k; #存储从代理服务器上传输的header信息的缓冲区大小
proxy_buffers 4 32k; #针对单个连接
proxy_connect_timeout 10; #nginx跟代理服务器连接的超时时间
proxy_http_version 1.1; #支持http传输的最低版本
proxy_temp_file_write_size 64k;
}
#请求连接为:http://localhost/prod-api/param/get1
#实际请求链接为 http://localhost/param/get1
http_gzip模块
使用gzip进行处理压缩传输的话,可以优化网站的访问速度。
http{
gzip on; #开启压缩传输,可以减少网络传输
gzip_min_length 1k;
#允许压缩的最小字节(到达这个字节才能进行压缩),页面字节数从 header 头的 content-length 中进行获取。默认值是 20。建议设置成大于 1k 的字节数,小于 1k 可能会越压越大;
gzip_buffers 16 64k;
gzip_http_version 1.1;
#设置 http 协议的版本,早期的浏览器不支持 Gzip 压缩,用户就会看到乱码,所以为了支持前期版本加上了这个选项;该指令是指定使用Gzip的HTTP最低版本,采用默认值即可。如果你用了 Nginx 的反向代理并启用 Gzip 压缩的话就需要加上,而由于末端通信是 http/1.0,故请设置为 1.0;
gzip_comp_level 6;
#zip 压缩比,为 1 时,压缩比最小处理速度最快;为 9 时,压缩比最大但处理速度最慢
gzip_vary on; #往头信息中添加压缩标识,告诉它该请求进行gzip处理
gzip_types text/plain application/x-javascript text/css application/xml image/jpeg;
#所选择的值可以从mime.types文件中进行查找,也可以使用"*"代表所有。匹配mime类型进行压缩,无论是否指定,text/html 类型总是会被压缩的;
gzip_proxied off; #nginx作为反向代理压缩服务端返回数据的条件
}
server模块
server{
listen 8080; #监听8080端口
server_name 192.168.10.10; #监听服务器的地址
keepalive_requests 8192; #每个连接的最大请求数
charset utf-8; #字符集编码
error_page 404 /404.html; #404错误显示页面
error_page 500 502 /50x.html;#500 502错误显示页面
}
location模块
location /prod-api/ {
root E:\\wwwroot\\; #服务器的默认网站根目录
index index.php index.html index.htm default.php default.htm default.html;#默认访问的文件名
deny 192.168.10.10; #拒绝访问的IP
deny all; #拒绝所有IP访问该目录
allow 192.168.10.10; #允许访问的IP
allow all; #允许所有IP访问该目录
}
nginx在linux上的安装与配置
-
进入ngingx官网:点击进入
-
将下载好的安装包通过Xftp传到linux服务器上去。
-
之后进行安装包所在的位置,执行解压命令:tar -zxvf nginx-1.22.1.tar.gz 下面是解压后的目录结构
-
编译:进入解压后的目录,执行./configure
-
安装:编译完成后执行make && make install
-
查看是否安装完毕的命令:pcre-config --version
-
安装nginx需要的依赖环境:
- nginx依赖gcc的编译环境 :yum install gcc-c++
- nginx的http模块需要使用prce来解析正则:yum install -y pcre pcre-devel
- 安装依赖需要的安装包:yum install -y zlib zlib-devel
- ssl功需要openssl:yum install -y openssl openssl-devel、
- 一键安装以上四个依赖:yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel
-
nginx启动:进入目录:cd /usr/local/nginx/sbin/ 执行启动命令:./nginx
-
打开nginx配置文件:vi /usr/local/nginx/conf/nginx.conf
-
-
每次修改完conf文件后需要重启nginx服务:/usr/local/nginx/sbin/nginx -s reload
重启的时候如果遇到报错:
[error] open() “/usr/local/nginx/logs/nginx.pid” failed (2: No such file or directory)
这个时候需要使用nginx -c重新指定niginx.conf的位置
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
-
重新启动之后就可以通过IP进行访问了。
- 若访问失败,请检查firewall,开放相应的端口。
配置环境变量
- 首先执行:find / - name nginx找到nginx所在的位置
- 复制带有sbin的路径
- 执行:ln -s /usr/local/nginx/sbin/nginx /usr/bin
- 执行:nginx -v查看nginx的版本号,验证结果
nginx目录结构
首先先下载tree命令,以树结构的形式能够更好的认识nginx的结构
CentOS:yum -y install tree Ubuntun:apt-get install tree
我自己用的是CentOs的,我的是安装上就能使用了,具体安装教程可以转到:点击进入
安装完成后,执行tree /usr/local/nginx,后面跟的是nginx的安装位置,目录结构如下:
[root@VM-24-5-centos xichenlong]# tree /usr/local/nginx
/usr/local/nginx
|-- client_body_temp
|-- conf #nginx的多有配置文件所在目录
| |-- fastcgi.conf #fastcgi相关配置文件
| |-- fastcgi.conf.default #fastcgi.cong的备份文件
| |-- fastcgi_params #fastcgi的参数文件
| |-- fastcgi_params.default #fastcgi_params的备份文件
| |-- koi-utf
| |-- koi-win
| |-- mime.types #记录的是HTTP协议中的Content-Type的值和文件后缀名的对应关系
| |-- mime.types.default #mime.types的备份文件
| |-- nginx.conf #nginx核心配置文件
| |-- nginx.conf.default #nginx.conf的备份文件
| |-- scgi_params #scgi的参数文件
| |-- scgi_params.default #scgi_params的备份文件
| |-- uwsgi_params #uwsgi的参数文件
| |-- uwsgi_params.default #uwsgi_params的备份文件
| `-- win-utf #与编码转映射换相关的配置文件
|-- fastcgi_temp #fastcgi临时数据目录
|-- html #nginx默认站点目录
| |-- 50x.html #502页面
| `-- index.html #默认的nginx首页
|-- logs #日志目录
| |-- access.log #访问日志
| |-- error.log #错误日志
| `-- nginx.pid #nginx启动后会把所有进程的PID都写在这里
|-- proxy_temp #proxy临时文件
|-- sbin #nginx命令目录
| `-- nginx #nginx启动目录
|-- scgi_temp #scgi临时文件
`-- uwsgi_temp #uwsgi临时文件
提示:执行tree命令后如果出现报错:[error opening dir],可能需要重新进行安装,但是我执行了:tree -v之后就能正常使用了。
nginx常用命令
Linux:进入目录:cd /usr/local/nginx/sbin/
-
./nginx 启动
-
./nginx -s stop 停止(不保存相关信息)
-
./nginx -s quit 安全退出(处理完所有的请求再停止服务,保存相关信息)
-
./nginx -s reload 重新加载配置文件 如果我们修改了配置文件,就需要重新加载。
-
./nginx -s reopen 重启命令
-
ps aux|grep nginx 查看nginx进程
-
sudo nginx -t -c /usr/local/nginx/conf/nginx.conf 检查nginx的配置文件修改后是否有语法错误的地方
缓存命中率
概念
缓存命中(cache hit):当应用程序或者软件请求数据时,会首先发生缓存命中。首先,中央处理器(CPU)在最近的内存的位置(通常是主缓存)中查找数据。如果在缓存中找到请求的数据,则将其视为缓存命中。
命中:可以直接通过缓存获取数据
不命中:无法直接通过缓存获取数据,需要再次查询数据库或者其他的一些操作,主要是由于缓存不中不存在或者缓存过期。
缓存的命中率越高,应用的性能就越好,响应时间越短,吞吐量越高,并发能力越强。所以缓存命中率也是高并发性应用的重要的性能指标。
如何提高缓存命中率
- 由于缓存的容量有限,这样就容易引起缓存过期或被清除的情况,这个时候采用分布式缓存会更容易扩展,不同的缓存框架以及中间件,效率和有效性存在差异
- 当系统更新的时候直接移除缓存的值会比移除缓存的命中率更高,系统复杂度也会更高。
- 尽可能将缓存放在高频访问而且时效性不高的业务上,可以通过增加缓存的容量,调整缓存粒度,更新缓存等来提高缓存的命中率
- 程序的颗粒度越小,命中率就会越高。
缓存应用的场景
- ”读多写少“的场景,这样更能提高缓存的利用率
- 适合应用于并发性高的地方,并发性不高的地方引入缓存会导致资源的浪费,成本的增加
- 时效性越低的地方,越适合引入缓存,增加系统的访问速度和系如同吞吐量。