前言
公司项目刚刚上线的时候,并发量小,用户使用的少,所以在低并发的情况下,一个jar包启动应用就够了,然后内部 tomcat 返回内容给用户。
但是慢慢的,使用我们平台的用户越来越多了,并发量慢慢增大了,这时候一台服务器满足不了我们的需求了。
于是我们横向扩展,又增加了服务器。这个时候几个项目启动在不同的服务器上,总不能是每次请求的地址都去改变,所以用户要访问,就需要增加一个代理服务器了,通过代理服务器来帮我们转发和处理请求。
我们希望这个代理服务器可以帮助我们接收用户的请求,然后将用户的请求按照规则帮我们转发到不同的服务器节点之上。这个过程用户是无感知的,用户并不知道是哪个服务器返回的结果,我们还希望他可以按照服务器的性能提供不同的权重选择。保证最佳体验!所以我们使用了Nginx。
一、什么是 Nginx
Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。2011年6月1日,nginx 1.0.4发布。
其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。在全球活跃的网站中有12.18%的使用比率,大约为2220万个网站。
Nginx 是一个安装非常的简单、配置文件非常简洁(还能够支持perl语法)、Bug非常少的服务。Nginx 启动特别容易,并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动。你还能够不间断服务的情况下进行软件版本的升级。
Nginx代码完全用C语言从头写成。官方数据测试表明能够支持高达 50,000 个并发连接数的响应。
二、Nginx 作用
- Http 代理,反向代理:作为web服务器最常用的功能之一,尤其是反向代理。
正向代理
举例:经常玩国外的游戏因为延迟的问题都会用 VPN ,因为现在中国目前不能访问外网,就像是访问谷歌官网之类的,但是为什么连接 VPN 之后就能够访问了呢,这是一种什么原理,其实这个就是正向代理,电脑请求代理的时候也就是请求 VPN 的时候,这个代理会帮助你去请求外部的资源,比如说这个代理服务器可能在香港,香港是可以访问外网的,这个时候你去请求这个代理服务器,代理服务器会去请求国外的服务器,然后国外服务器返回数据到代理服务器,代理服务器返回给你,这种正向代理都是代理客户端的,还有一种是代理服务端的也就是反向代理。
反向代理
举例:比如访问百度首页,访问百度永远是一个域名,难道百度只有一个服务器吗,那是不可能的,可能是有北京的服务器,上海的服务器,还有深圳的服务器等等,但是访问永远用的是一个域名 www.baidu.com ,但是对你来说你不感知,因为对你来说访问这一个地址就够了,这其实是服务端有一个代理,这个叫反向代理,后面无论动态扩容多少台服务器,你访问的永远是 www.baidu.com ,反向代理可以让你无感知的浏览资源并且可以更好的调整服务器上限。
- Nginx提供的负载均衡策略有2种:内置策略和扩展策略。内置策略为轮询,加权轮询,Ip hash。扩展策略,就天马行空,只有你想不到的没有他做不到的。
轮询
轮询是比较简单的,比如说下面这三个服务器的权重都是 1,那么每次请求在三个服务器轮询执行,第一次请求打到服务器1,第二次打到服务器2,第三次打到服务器3,第四次打到服务器4,…以此类推。
加权轮询
加重轮询也比较简单就是在轮询的基础上加了权重,因为三个服务器可能处理请求的能力不同,要做到能者多劳,有能力的服务器如果权重是3的话,另外两台如果是1和1,那么发送十次请求会有6次打到服务器3,两次打到服务器2,两次打到服务器1,是有比例的3:1:1。
iphash对客户端请求的ip进行hash操作,然后根据hash结果将同一个客户端ip的请求分发给同一台服务器进行处理,可以解决session不共享的问题。
每个请求按访问 IP 的哈希结果分配,使来自同一个 IP 的访客固定访问一台后端服务器,并且可以有效解决动态网页存在的 session 共享问题。
就是我们在写项目的时候都会有一个session的问题,会话都是保存在tomcat里面的,如果启动了很多台服务器那么就有很多台服务器,那么tomcat有n个,session就有n个,这个时候是可能做session共享的,nginx做都是通过hash计算将客户端的请求固定打到服务器。现在更多方案是加Redis。
- 动静分离,在我们的软件开发中,有些请求是需要后台处理的,有些请求是不需要经过后台处理的(如:css、html、jpg、js等等文件),这些不需要经过后台处理的文件称为静态文件。让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来,动静资源做好了拆分以后,我们就可以根据静态资源的特点将其做缓存操作。提高资源响应的速度。
三、Nginx 安装
windows下安装
- 下载 nginx
http://nginx.org/en/download.html 下载稳定版本。以nginx/Windows-1.16.1为例,直接下载 nginx-1.16.1.zip。
下载后解压,解压后如下:
- 启动 nginx
有很多种方法启动nginx
① 直接双击nginx.exe,双击后一个黑色的弹窗一闪而过
② 打开cmd命令窗口,切换到nginx解压目录下,输入命令 nginx.exe ,回车即可
- 检查nginx是否启动成功
直接在浏览器地址栏输入网址 http://localhost:80 回车,出现以下页面说明启动成功!
- 配置监听
nginx的配置文件是conf目录下的nginx.conf,默认配置的nginx监听的端口为80,如果80端口被占用可以修改为未被占用的端口即可。
当我们修改了nginx的配置文件nginx.conf 时,不需要关闭nginx后重新启动nginx,只需要执行命令 nginx -s reload
即可让改动生效。
- 关闭 nginx
如果使用cmd命令窗口启动nginx, 关闭cmd窗口是不能结束nginx进程的,可使用两种方法关闭nginx
① 输入nginx命令 nginx -s stop
(快速停止nginx) 或 nginx -s quit
(完整有序的停止nginx)
② 使用taskkill taskkill /f /t /im nginx.exe
taskkill是用来终止进程的,
/f是强制终止 .
/t终止指定的进程和任何由此启动的子进程。
/im示指定的进程名称 .
四、Linux 上 Nginx 常用命令
cd /usr/local/nginx/sbin/
./nginx 启动
./nginx -s stop 停止
./nginx -s quit 安全退出
./nginx -s reload 重新加载配置文件
ps aux|grep nginx 查看nginx进程
五、nginx.conf 详解
------------------------------------------------------------------------------------------------------------------------------
// 全局配置 //
#user nobody;// 配置worker进程运行用户,安全问题,建议用nobody,不要用root
worker_processes 1;// #配置工作进程数目,根据硬件调整、通常等于CPU数量或者2倍于CPU数量 比如四核电脑(可以配置4或者8)
#error_log logs/error.log;// 配置日志类型、默认为error级别
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;// 配置进程pid文件 【进程编号】
// 负载均衡
upstream yang {
# 服务器资源
server 127.0.0.1:8080 weight=1; // 权重 1
server 127.0.0.1:8081 weight=1; // 权重 1
}
------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------
// 事件配置 //
events {
worker_connections 1024;// 每一个 worker 所能支持的最大并发连接数
}
------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------
// 配置http服务器,利用他的反向代理功能提供负载均衡支持 //
// http基本配置
http {
include mime.types;// 配置nginx支持哪些多媒体类型,当web服务器收到静态的资源文件请求时,依据请求文件的后缀名在服务器的MIME配置文件中找到对应的MIME Type,再根据MIME Type设置HTTP Response的Content-Type,然后浏览器根据Content-Type的值处理文件。
default_type application/octet-stream;// 如果不能从mime.types找到映射的话,用以下作为默认值
#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;// 配置access.log日志及存放路径、并使用上面定义的main日志格式
sendfile on;// 开启高效文件传输模式,开启从磁盘直接到网络的文件传输,适用于有大文件上传下载的情况,提高IO效率
#tcp_nopush on;// 防止网络阻塞
#keepalive_timeout 0;// 一个请求完成之后还要保持连接多久, 默认为0,表示完成请求后直接关闭连接
keepalive_timeout 65;// 长连接超时时间
#gzip on;// 开启gzip压缩输出
#gzip_min_lenth 1k;// 设置允许压缩的页面最小字节数,页面字节数从header头中的Content-Length中进行获取
#gzip_comp_level 4;// gzip压缩比,1 压缩比最小处理速度最快,9 压缩比最大但处理最慢(传输快但比较消耗cpu)
#gzip_types types text/plain text/css application/json application/x-javascript text/xml// 匹配MIME类型进行压缩,(无论是否指定)"text/html"类型总是会被压缩的。
// 动静分离
open_file_cache max=655350 inactive=20s;// 服务器端静态资源缓存,最大缓存到内存中的文件,不活跃期限
open_file_cache_min_uses 2;// 活跃期限内最少使用的次数,否则视为不活跃。
open_file_cache_valid 30s;// 验证缓存是否活跃的时间间隔
upstream yang{
# 1、轮询(默认)
# 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
# 2、指定权重
# 指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
#3、IP绑定 ip_hash
# 每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
#4、备机方式 backup
# 正常情况不访问设定为backup的备机,只有当所有非备机全都宕机的情况下,服务才会进备机。
#5、fair(第三方)
#按后端服务器的响应时间来分配请求,响应时间短的优先分配。
#6、url_hash(第三方)
#按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
# ip_hash;
server 192.168.161.132:8080 weight=1;
server 192.168.161.132:8081 weight=1 backup;
#fair
#hash $request_uri
#hash_method crc32
------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------
// 多个server配置 //
server {
listen 80;// 监听端口号
server_name localhost;// 服务名
#charset koi8-r;// 字符集
#access_log logs/host.access.log main;
#location [=|~|~*|^~] /uri/ { … }
# = 精确匹配
# ~ 正则匹配,区分大小写
# ~* 正则匹配,不区分大小写
# ^~ 关闭正则匹配
#匹配原则:
# 1、所有匹配分两个阶段,第一个叫普通匹配,第二个叫正则匹配。
# 2、普通匹配,首先通过“=”来匹配完全精确的location
# 2.1、 如果没有精确匹配到, 那么按照最大前缀匹配的原则,来匹配location
# 2.2、 如果匹配到的location有^~,则以此location为匹配最终结果,如果没有那么会把匹配的结果暂存,继续进行正则匹配。
# 3、正则匹配,依次从上到下匹配前缀是~或~*的location, 一旦匹配成功一次,则立刻以此location为准,不再向下继续进行正则匹配。
# 4、如果正则匹配都不成功,则继续使用之前暂存的普通匹配成功的location.
location / {// 匹配任何查询,因为所有请求都已 / 开头。但是正则表达式规则和长的块规则将被优先和查询匹配
root html;// 定义服务器的默认网站根目录位置
index index.html index.htm;// 默认访问首页索引文件的名称
proxy_pass http://yang// 反向代理路径
// 高可用
proxy_connect_timeout 60;// 与上游服务器(真实访问的服务器)超时时间 后端服务器连接的超时时间_发起握手等候响应超时时
proxy_send_timeout 90s;// 发送给上游服务器(真实访问的服务器)超时时间
proxy_read_timeout 120s;// 接受上游服务器(真实访问的服务器)超时时间
proxy_redirect default;
}
location ~*.(gif|jpg|jpeg)$ {
root pic ;// 所有静态文件直接读取硬盘
expires 3d;// expires定义用户浏览器缓存的时间为3天,如果静态页面不常更新,可以设置更长,这样可以节省带宽和缓解服务器的压力
}
#error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;// 出现对应的http状态码时,使用50x.html回应客户
location = /50x.html {
root html;// 指定对应的站点目录为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;
# }
#}
}