Nginx
公司产品出现瓶颈?
我们公司项目刚刚上线的时候,并发量小,用户使用的少,所以在低并发的情况下,一个 jar 包启动应用就够了,然后内部
tomcat 返回内容给用户。
但是慢慢的,使用我们平台的用户越来越多了,并发量慢慢增大了,这时候一台服务器满足不了我们的需求了。
于是我们横向扩展,又增加了服务器。这个时候几个项目启动在不同的服务器上,用户要访问,就需要增加一个代理服务器
了,通过代理服务器来帮我们转发和处理请求。——> 相当于是需要一个中间件 ——> ==Nginx 反向代理==
还可以给服务器加权重,因为每个服务器的访问量可能不一样,所以他们的能力也应当不一样 ——> ==Nginx 负载均衡==
所以说:没有什么是加一层解决不了的!
我们希望这个代理服务器可以帮助我们接收用户的请求,然后将用户的请求按照规则帮我们转发到不同的服务器节点之上。这
个过程用户是无感知的,用户并不知道是哪个服务器返回的结果,我们还希望他可以按照服务器的性能提供不同的权重选择。
保证最佳体验!所以我们使用了 Nginx。
1.什么是 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 个并发连接数的响应。
2.Nginx 作用
Http 代理,反向代理:作为 web 服务器最常用的功能之一,尤其是反向代理。
正向代理:代理客户端
反向代理:代理服务器端
3.Nginx 特性
3.1 负载均衡
Nginx:Nginx 提供的负载均衡策略有 2 种:内置策略和扩展策略。
1.轮询:先把请求给第一台,第一台接收不了了再给第二台,以此类推
2.加权轮询:每个服务器接收的请求数量不同,并且是按照权重比例来分配访问数(且每次访问随机分配)
3.iphash
对客户端请求的 ip 进行 hash 操作,然后根据 hash 结果将同一个客户端 ip 的请求分发给同一台服务器进行处理(这样 session
只在这个指定的服务器里面),可以解决 session 不共享的问题。
缺点:服务器挂了信息就没有了,也不是很好
更好的方案:用 redis 存储 session,性能好,并且安全性高!同样可以解决 session 不共享的问题!
上述三种负载均衡策略,后台的服务器连接都是同一个数据库,所以数据是一致的,所有的文件也应该放在文件服务器上。
3.2 动静分离
动静分离: 在我们的软件开发中,有些请求是需要后台处理的,有些请求是不需要经过后台处理的(如:css、html、jpg、js 等等文件),这些不需要经过后台处理的文件称为静态文件。让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来,动静资源做好了拆分以后,我们就可以根据静态资源的特点将其做缓存操作。提高资源响应的速度。
单独开一台服务器用 nginx 存储静态资源(bootstrap.js,jquery.js,style.css 等)
提升访问速度!
目前,通过使用 Nginx 大大提高了我们网站的响应速度,优化了用户体验,让网站的健壮性更上一层楼!
3.windows 下安装
1、下载 nginx
http://nginx.org/en/download.html 下载稳定版本。 以 nginx/Windows-1.16.1 为例,直接下载 nginx-1.16.1.zip。
下载后解压,解压后如下:
配置文件:
默认端口为 80 端口,和 http 相同
2、启动 nginx
有很多种方法启动 nginx
(1)直接双击 nginx.exe,双击后一个黑色的弹窗一闪而过(不推荐)
(2)打开 cmd 命令窗口,切换到 nginx 解压目录下,输入命令 nginx.exe ,回车即可
启动成功之后,什么都不输出,只是光标在闪
(3)打开 cmd 命令窗口,切换到 nginx 解压目录下,输入命令 start nginx,关闭窗口可以结束 nginx 服务
3、检查 nginx 是否启动成功
直接在浏览器地址栏输入网址 localhost:80 回车,出现以下页面说明启动成功!
4、配置监听
nginx 的配置文件是 conf 目录下的 nginx.conf,默认配置的 nginx 监听的端口为 80,如果 80 端口被占用可以修改为未被占用的端口即可。
这是配置的监听就是我们要访问的地址!当我们监听后,我们访问这个网址时,请求会被转向定义的的服务器列表
当我们修改了 nginx 的配置文件 nginx.conf 时,不需要关闭 nginx 后重新启动 nginx,只需要执行命令 nginx -s reload
即可让改动生效
5、关闭 nginx
如果使用 cmd 命令窗口启动 nginx, 关闭 cmd 窗口是不能结束 nginx 进程的,可使用两种方法关闭 nginx
(1)输入 nginx 命令:nginx -s stop(快速停止 nginx) 或 nginx -s quit(完整有序的停止 nginx)
(2)使用 taskkill 命令: taskkill /f /t /im nginx.exe
taskkill是win上面用来终止进程的,
/f是强制终止
/t终止指定的进程和任何由此启动的子进程
/im是指定进程名称
4.linux 下安装
4.1 yum 安装
1、安装 gcc
安装 nginx 需要先将官网下载的源码进行编译,编译依赖 gcc 环境,如果没有 gcc 环境,则需要安装:
yum install gcc-c++
2、PCRE pcre-devel 安装
PCRE(Perl Compatible Regular Expressions) 是一个 Perl 库,包括 perl 兼容的正则表达式库。nginx 的 http 模块使用 pcre 来解析正则表达式,所以需要在 linux 上安装 pcre 库,pcre-devel 是使用 pcre 开发的一个二次开发库。nginx 也需要此库。命令:
yum install -y pcre pcre-devel
3、zlib 安装
zlib 库提供了很多种压缩和解压缩的方式, nginx 使用 zlib 对 http 包的内容进行 gzip ,所以需要在 Centos 上安装 zlib 库。
yum install -y zlib zlib-devel
4、OpenSSL 安装 OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及 SSL 协议,并提供丰富的应用程序供测试或其它目的使用。 nginx 不仅支持 http 协议,还支持 https(即在 ssl 协议上传输 http),所以需要在 Centos 安装 OpenSSL 库。
yum install -y openssl openssl-devel
4.2 安装包安装
手动下载.tar.gz 安装包,地址: https://nginx.org/en/download.html
下载完毕上传到服务器上 /root
注意.tar.gz 文件不能用 rz 命令上传,需要用 xftp 上传!
解压
tar -zxvf nginx-1.22.0.tar.gz
cd nginx-1.22.0
配置
使用默认配置,在 nginx 根目录下执行命令:
./configure #自动配置
make #配置
make install #配置
==查找安装路径:whereis nginx ——> 这个查出来的才是 nginx 真正位于的位置,因为自动配置之后会产生一个新的 nginx,而不是我们之前解压的那个包!==
==我们所有的配置更改都要在这个/usr/local/nginx 中进行,而不是/opt/module/nginx 中!==
进入:
启动 nginx:
在 sbin 目录输入./nginx 即可
发现端口被占用了!
我们去修改为 81 端口吧(80 留给 docker)
查看 81 端口号是否被占用:
netstat -nap | grep 81
修改/usr/local/nginx/nginx/conf/nginx.conf 文件!
5.Nginx 常用命令
==报错解决:需要指定一下配置文件位置,注意是指定为/usr/local/nginx/conf 目录下的,因为这个 config 文件是那个原来的拷贝,是一样的!但是/usr/local/nginx 这个 nginx 才是真正的 nginx==
命令:
cd /usr/local/nginx/sbin/
./nginx 启动
./nginx -s stop 停止(强制停止)
./nginx -s quit 安全退出
./nginx -s reload 重新加载配置文件并启动!(用的非常多)
ps aux|grep nginx 查看nginx进程信息
启动:只要没报错就是启动成功了!
成功访问 服务器 ip:81
注意:如何连接不上,检查阿里云安全组是否开放端口,或者服务器防火墙是否开放端口! 防火墙相关命令:
# 开启
service firewalld start
# 重启
service firewalld restart
# 关闭
service firewalld stop
# 查看防火墙规则
firewall-cmd --list-all
# 查询端口是否开放
firewall-cmd --query-port=8080/tcp
# 开放80端口
firewall-cmd --permanent --add-port=80/tcp
# 移除端口
firewall-cmd --permanent --remove-port=8080/tcp
#重启防火墙(修改配置后要重启防火墙)
firewall-cmd --reload
# 参数解释
1、firwall-cmd:是Linux提供的操作firewall的一个工具;
2、--permanent:表示设置为持久;
3、--add-port:标识添加的端口;
6.Nginx 实战演练及配置文件详解
6.1 模拟多台服务器
**第一步:**本地启动狂神自己的项目,启动同一个项目 2 次,并设置使用不同端口,模拟使用多台服务器。
8080:
8081:
**第二步:**我们不能让用户不停的去访问不同的端口号或者服务器,那么我们需要一个代理服务器。
**Nginx:**Nginx 提供的负载均衡策略有 2 种:内置策略和扩展策略。
内置策略:轮询,加权轮询,Ip hash。
扩展策略:天马行空,只有你想不到的没有他做不到的。
我们希望的是这样的:用户只能访问一个端口,但是访问到的却是不同的服务器上面的项目!
**第三步:**进入安装 nginx 的服务器中,然后修改并配置 nginx.conf 文件:
upstream kuangstudy{
server 127.0.0.1:8080 weight=3; #weight就是权重,默认都是1 ——>负载均衡
server 127.0.0.1:8081 weight=1;
}
location / {
proxy_pass http://kuangstudy; #我们通过代理kuangstudy,找到我们真正要请求的服务器。——>反向代理
}
配置成功后,我们重新启动 nginx,重新加载配置文件:
我们访问:localhost/(即:监听的网址,http 默认是 80 接口),则请求会根据 proxy_pass 反向代理配置
值找到 upstream 配置的服务器,然后请求这些服务器,实现反向代理,加上 weight 配置实现负载均衡。
如果是微服务架构的话,我理解我们反向代理的真正的服务器,应该是网关 gateway 的服务器,让 gateway 再去处理分配请求。详见 gateway 博客
6.2 配置文件结构
#全局配置(百度可以搜到)
events {
worker_connections 1024;
}
#网络配置
http {
upstream haojiahuo {
#负载均衡配置:服务器资源
server 124.220.15.95 weight=2;
server 124.221.15.95 weight=1;
}
upstream haha {
#负载均衡配置:服务器资源
server 124.222.15.95 weight=1;
server 124.223.15.95 weight=1;
}
#http
server {
listen 80;
server_name localhost;
#项目根目录/访问配置(即直接访问80):可以分配给a,b服务器
location /{
#反向代理:与上面upstream负载均衡关联
proxy_pass http://haojiahuo;
}
#/login访问配置:可以分配给c,d服务器
location /login{
#反向代理:与上面upstream负载均衡关联
proxy_pass http://haha;
}
}
#https
server {
listen 443;
server_name localhost;
#代理
}
}
6.3 实战结果
8080 的和 8081 的两台服务器收到的请求是 8080 三次,8081 一次:
因为权重都是 8080 权重是 3,8081 权重是 1,四次会有三次在 8080(但是至于是哪三次是随机的)!
图解:(8080 是 tomcat 的默认端口,有三台服务器不同的权重)
6.4 总结
具体配置文件详解可以看专门博客: Nginx 配置详解 | 菜鸟教程
配置文件解释含义:一个例子
########### 每个指令必须有分号结束。#################
#user administrator administrators; #配置用户或者组,默认为nobody nobody。
#worker_processes 2; #允许生成的进程数,默认为1
#pid /nginx/pid/nginx.pid; #指定nginx进程运行文件存放地址
error_log log/error.log debug; #制定日志路径,级别。这个设置可以放入全局块,http块,server块,级别以此为:debug|info|notice|warn|error|crit|alert|emerg
events {
accept_mutex on; #设置网路连接序列化,防止惊群现
象发生,默认为on
multi_accept on; #设置一个进程是否同时接受多个网络连接,默认为off
#use epoll; #事件驱动模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport
worker_connections 1024; #最大连接数,默认为512
}
http {
include mime.types; #文件扩展名与文件类型映射表
default_type application/octet-stream; #默认文件类型,默认为text/plain
#access_log off; #取消服务日志
log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定义格式
access_log log/access.log myFormat; #combined为日志格式的默认值
sendfile on; #允许sendfile方式传输文件,默认为off,可以在http块,server块,location块。
sendfile_max_chunk 100k; #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。
keepalive_timeout 65; #连接超时时间,默认为75s,可以在http,server,location块。
upstream mysvr {
server 127.0.0.1:7878;
server 192.168.10.121:3333 backup; #热备
}
error_page 404 https://www.baidu.com; #错误页
server {
keepalive_requests 120; #单连接请求上限次数。
listen 4545; #监听端口
server_name 127.0.0.1; #监听地址
location ~*^.+$ { #请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小写。
#root path; #根目录
#index vv.txt; #设置默认页
proxy_pass http://mysvr; #请求转向mysvr 定义的服务器列表
deny 127.0.0.1; #拒绝的ip
allow 172.18.5.54; #允许的ip
}
}
}
Nginx 可以配置请求转发的服务器的路径:实现 http 请求获取服务器上的文件。
nginx 中 location 和 root,你确定真的明白他们关系?_果汁华的博客-CSDN 博客_nginx 中的 root
nginx 指定文件路径有两种方式 root 和 alias,这两者的用法区别,使用方法总结了下,方便大家在应用过程中,快速响应!
root 与 alias 主要区别在于 nginx 如何解释 location 后面的 uri,这会使两者分别以不同的方式将请求映射到服务器文件上。
root 和 alias 的语法格式:
[root] 语法:root path 默认值:root html 配置段:http、server、location、if
[alias] 语法:alias path 配置段:location
root 实例:
location ^~ /t/ {
root /www/root/html/; } 如果一个请求的URI是/t/a.html时,web服务器将会返回服务器上的/www/root/html/t/a.html的文件。alias 实例:
location ^~ /t/ {
alias /www/root/html/new_t/; } 如果一个请求的URI是/t/a.html时,web服务器将会返回服务器上的/www/root/html/new_t/a.html的文件。注意这里是new_t,因为**alias会把location后面配置的路径丢弃掉,把当前匹配到的目录指向到指定的目录**。注意:
- 使用 alias 时,目录名后面一定要加"/"。
- alias 在使用正则匹配时,必须捕捉要匹配的内容并在指定的内容处使用。
- alias 只能位于 location 块中。(root 可以不放在 location 中,也可以放在 location 中)
实际项目配置:
nginx.conf
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
stream {
upstream pg-server{
server 47.99.104.62:5432;
}
server {
listen 5433;
proxy_pass pg-server;
}
}
http {
include mime.types;
default_type application/octet-stream;
client_max_body_size 100m;
access_log off;
sendfile on;
keepalive_timeout 100;
fastcgi_connect_timeout 75;
fastcgi_read_timeout 600;
fastcgi_send_timeout 600;
gzip on;
gzip_min_length 1k;
gzip_comp_level 4;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
gzip_disable "MSIE [1-6]\.";
gzip_vary on;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream msc {
server 47.99.104.62:18010;
}
upstream nacos-server {
server 47.99.104.62:8848;
}
upstream graphs {
server 47.99.104.62:8000;
}
upstream websocket-server {
server 47.99.104.62:2014;
}
server {
listen 18001;
location / {
proxy_pass http://nacos-server;
}
}
server {
listen 80 default;
server_name localhost;
#ssl on;
#root ../webapps;
#location / {
# rewrite ^/$ /fusionsite-are-basic-web last;
# add_header 'Cache-Control' 'no-cache';
#}
root ../../Oceansite/webapps/oceansite-basic-web;
location = / {
#root ../../Oceansite/webapps/oceansite-basic-web;
#index index.html index.htm;
rewrite ^/$ /index last;
}
location /index {
alias ../../Oceansite/webapps/oceansite-basic-web;
}
location /login {
alias ../../Oceansite/webapps/oceansite-basic-web;
}
location /system/menu {
alias ../../Oceansite/webapps/oceansite-basic-web/;
}
location /RTData/navigation {
alias ../../Oceansite/webapps/oceansite-basic-web/;
}
location /RTData/flowChart {
alias ../../Oceansite/webapps/oceansite-basic-web/;
}
location /RTData/47.99.104.62/oceansite-conduction-web {
alias ../../Oceansite/webapps/oceansite-basic-web/;
}
location /RTData/47.99.104.62/oceansite-video-monitor-web {
alias ../../Oceansite/webapps/oceansite-basic-web/;
}
location /47.99.104.62/oceansite-ship-record-web {
alias ../../Oceansite/webapps/oceansite-basic-web/;
}
#记录簿网页资源
location /oceansite-ship-record-web {
root ../../Oceansite/webapps;
index index.html index.htm;
}
#通导系统网页资源
location /oceansite-conduction-web {
root ../../Oceansite/webapps;
index index.html index.htm;
}
#视频监控网页资源
location /oceansite-video-monitor-web {
root ../../Oceansite/webapps;
index index.html index.htm;
}
#视频监控报警照片和视频
location /alarmimgdata {
root ../../;
}
#流程图网页资源
location /flowchart {
root ../webapps;
index index.html index.htm;
}
location /fusionsite-are-basic-web {
root ../webapps;
index index.html index.htm;
}
location /common {
root ../webapps;
index index.html index.htm;
}
#OceanSite 数据接口跳转
location /prod-api/ {
proxy_read_timeout 86400;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Origin' *;
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE';
add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
proxy_pass http://47.99.104.62:8080/;
}
location /msc {
proxy_pass http://msc;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /fusionsite-are-h5-flowchart-web/graph {
root ../webapps;
}
location ~* /fusionsite-are-h5-flowchart-web/graph/.*/Resource/.*\.(jpg|png|jpeg|gif)$ {
rewrite ^/fusionsite-are-h5-flowchart-web/graph/(.*)$ /mare-graph/$1 last;
}
location ~* /mare-graph {
root ../App_Server/fusionsite-are-minio-server/data;
}
location /zrender/src/core/util.js {
root ../webapps/fusionsite-are-h5-flowchart-web/graph;
}
location /graphs/ {
proxy_pass http://graphs;
proxy_set_header Host 47.99.104.62:8000;
}
location /msc/fusionsite-are-basic/minIO/fileUpload {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'POST';
add_header 'Access-Control-Allow-Headers' 'lastoperatime,token,DNT,web-token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
proxy_pass http://47.99.104.62:18110/minIO/fileUpload;
}
location /msc/fusionsite-are-basic/minIO/file/fileUpload {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'POST';
add_header 'Access-Control-Allow-Headers' 'lastoperatime,token,DNT,web-token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
proxy_pass http://47.99.104.62:18110/minIO/file/fileUpload;
}
location /msc/fusionsite-are-basic/minIO/fileDownload {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'POST';
add_header 'Access-Control-Allow-Headers' 'lastoperatime,token,DNT,web-token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
proxy_pass http://47.99.104.62:18110/minIO/fileDownload;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
server {
listen 8000;
server_name localhost;
client_max_body_size 100m;
location /
{
root ../webapps/fusionsite-are-h5-flowchart-web/graph;
index index.html index.htm;
}
location ~* .*/Resource/.*\.(jpg|png|jpeg|gif)$ {
rewrite ^.*/Resource/(.*)$ /resources/$1 last;
}
location ~* .*/Flows/.*\.(jpg|png|jpeg|gif)$ {
rewrite ^.*/Flows/(.*)$ /resources/$1 last;
}
location /resources {
alias ../webapps/fusionsite-are-h5-flowchart-web/resources;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html
{
root html;
}
location /flowchart
{
proxy_read_timeout 86400;
proxy_pass http://websocket-server;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
location /graphs/rest {
rewrite ^/graphs/(.*)$ /$1 last;
}
location /rest
{
proxy_pass http://47.99.104.62:8689/rest;
#proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
expires off;
}
}
}