Nginx
Nginx是一个高性能的HTTP和反向代理服务器,同时可以提供一些邮件服务。
反向代理、反向代理、反向代理
Nginx方向代理
先说说什么是正向代理,举个生活中的例子:你打游戏,或者是科学上网使用的vpn就是正向代理。
你—>代理服务器—>其他资源
这种安装在客户端的代理(vpn)就是正向代理
与此同时,还有一种是代理服务端的,就是所有用户都访问一个代理服务器,然后这个代理服务器去访问真正的服务器,这就叫反向代理。
Nginx的负载均衡
-
轮询
依次访问,按照顺序访问服务器
-
加权轮询
给每个服务器设置权重,根据权重值来分配访问次数,跟dubbo的负载均衡策略相似。例如两个服务器,权重比是2:3,来50个请求就会按照权重来轮询分配
-
iphash策略
根据ip来进行计算,通过hash运算之后,一个ip只能达到同一个服务器,每个ip的服务器hash值是不一样的,也可以达到负载均衡的策略
-
fair策略
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
Nginx动静分离
假如你的项目里面有非常多的静态资源,比如说静态资源:bootstrap、很多js文件,如果这些静态资源每次都要从java的jar包里面去加载就非常麻烦,所以nginx可以作为一个单独的静态资源服务器。
就是页面请求的静态资源直接从nginx服务器返回了,能够提升一定的访问速度
Windows安装Nginx
官方下载地址:
nginx: download
windows版本就直接点击这里,然后得到一个安装包,这个安装包在任何位置解压就能使用了。
打开文件夹是这个样子的:
我们打开config文件夹,打开nginx.conf文件,这个文件是Nginx的配置文件,我们可以看到现在Nginx监听的是80端口。
所以我们启动Nginx.exe,访问我们电脑的80端口,出现Nginx欢迎页就代表下载成功了
Linux安装Nginx
下载好tar包之后,上传到Linux系统,进入到tar包所在目录,然后使用命令进行解压。
命令:tar -zxvf nginx-1.22.1.tar.gz
然后我们进入 nginx-1.22.1 文件夹,查看目录发现跟window上面是一样的。
然后执行
./configure
,让系统执行一下这个文件,执行完毕,再执行
make
命令,执行结束之后,再执行
make install
命令。
输入
whereis nginx
验证是否安装成功
进入nginx目录,然后执行./nginx,启动成功
Nginx的常见命令
在运行命令的时候,要进入nginx的文件夹位置
/usr/local/nginx/sbin/
-
cd /usr/local/nginx/sbin/ 进入到nginx的文件所在位置
-
./nginx 启动
-
./nginx -s stop 停止
-
./nginx -s quit 安全退出
-
./nginx -s reload 重新加载配置文件
-
ps aux|grep nginx 查看nginx进程
Nginx的配置文件
区域划分
-
头部区域
全局变量等声明的地方
-
工作模式:events
跟nginx自身工作相关的一些配置,模式
-
http模块
后面的所有都是http设置,包括转发路径啊什么的
-
http.server
主要工作的模块,就是我们配置的模块
配置文件概览:
# 全局快
------------------------------------------------------------------------------
#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块
events {
worker_connections 1024;
}
# http块
http {
------------------------------------------------------------------------------# http全局块
include mime.types;
default_type application/octet-stream;
#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;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
------------------------------------------------------------------------------
# server块
server {
# server全局块
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
# location块
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root 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;
#}
}
# 可以配置多个server块
}
全局块
配置文件从头开始到events块之间的内容,
主要设置的是影响nginx服务器整体运行的配置指令
比如worker_process, 值越大,可以支持的并发处理量也越多,但是还是和服务器的硬件相关
worker_process一般可以设置为核心数的2倍
events块
events 块涉及的指令主要影响 Nginx 服务器与用户的网络连接,常用的设置包括是否开启对多 work process下的网络连接进行序列化,是否允许同时接收多个网络连接,选取哪种事件驱动模型来处理连接请求,每个 word process 可以同时支持的最大连接数等。
例如:worker_connections 1024,代表最大连接数为1024个。 这部分的配置对 Nginx 的性能影响较大,在实际中应该灵活配置。
http块
http块包括全局块和多个server块。
http全局块的配置包括文件引入、MIME—TYPE定义,日志自定义、链接超时时间、单链接最多请求数等。
server块
一个server块可以当作是一个服务,对这个服务进行配置,server块有一个listen变量,这个是用来监听端口的,只要访问了该端口,就会使用对应的server块。
例如:
listen 80;监听80端口,只要是nginx服务器被访问80端口,就会使用配置这个的server块。
server_name test 给这台主机起名字为test。
location块
一个 server 块可以配置多个 location 块。主要作用是根据请求地址路径的匹配,匹配成功进行特定的处理。location块可以使用正则表达式。
简单来说,就是匹配uri,匹配到了就使用对应的location块;
例如:表示只要有user的请求,就去对应的服务器的某个端口
location ~/user/ {
proxy_pass
http://127.0.0.1:8080
;}
location的语法详解
语法:
location [=|~|~*|^~] /uri/ { … }
-
= 严格匹配。如果请求匹配这个location,那么将停止搜索并立即处理此请求
-
~ 区分大小写匹配(可用正则表达式)
-
~* 不区分大小写匹配(可用正则表达式)
-
!~ 区分大小写不匹配
-
!~* 不区分大小写不匹配
-
^~ 如果把这个前缀用于一个常规字符串,那么告诉nginx 如果路径匹配那么不测试正则表达式
location / { } #代表匹配任何请求
location ~* .(gif|jpg|jpeg)$ { # ~*不区分大小写,然后以gif、jpg、jpeg结尾的请求 rewrite .(gif|jpg|jpeg)$ /logo.png;#重定向到/logo.png }
root和alias的区别:
-
root 实际访问文件路径会拼接URL中的路径
-
alias 实际访问文件路径不会凭借URL中的路径
例如:如果请求路径是
http://test.com/sta/sta1.html
location ^~ /sta/ { root /usr/local/nginx/html/; alias /usr/local/nginx/html/static/; }
location匹配到的url是:/sta/sta1.html
如果使用root,实际访问:/usr/local/nginx/html/sta/sta1.html 文件
如果使用alias,实际访问:/usr/local/nginx/html/static/sta1.html 文件
可以看到两者的区别就是有没有拼接/sta这个字符串,alias就是将匹配到的字符串,不再拼接了,root就是会拼接。
last和break关键字的区别
(1)last 和 break 当出现在location 之外时,两者的作用是一致的没有任何差异
(2)last 和 break 当出现在location 内部时:
-
last 使用了last 指令,rewrite 后会跳出location 作用域,重新开始再走一次刚才的行为
-
break 使用了break 指令,rewrite后不会跳出location 作用域,它的生命也在这个location中终结
permanent 和 redirect关键字的区别
-
rewrite … permanent 永久性重定向,请求日志中的状态码为301
-
rewrite … redirect 临时重定向,请求日志中的状态码为302
转发案例(反向代理)
监听本机的80端口,然后将访问80端口的请求转发到tomcat服务器所在的页面。
server { # 监听端口80 即当访问服务器的端口是80时,进入这个server块处理 listen 80; # server_name当配置了listen时不起作用 server_name localhost; # location后面代表访问路径 当是/ 请求时 代理到tomcat的地址 location / { # 使用 proxy_pass(固定写法)后面跟要代理服务器地址 proxy_pass http://192.168.80.102:8080; } }
Springboot结合操作
现有一个需求:我们希望对外隐藏我们项目的真实接口,希望用户访问一个不真实的url进入我们的接口,达到保护我们程序的目的。我们可以利用Nginx实现这一点。
首先创建一个项目,启动端口为9090,然后定义一个UserController,模拟查询用户的接口
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/get")
public User get(){
return new User(new Random().nextInt(200),"da","tom","浙江省杭州市");
}
}
我们在网页上直接访问
http://localhost:9090/user/get
得到返回值
但是这个并不是我们所期望的效果,所以我们通过改变nginx的配置文件的方式,利用nginx达到转发的目的。
http { include mime.types; default_type application/octet-stream; sendfile on; server { listen 80; server_name hehe; location /test { proxy_pass http://localhost:9090/user/get ; } } }
这个文件的意思就是:监听我们的电脑的80端口,然后如果收到/test请求之后,转发到9090端口的/user/get接口上面去,我们来看看效果。
负载均衡案例
首先,在http的模块中定义好 upstream,可以理解为同一个服务的不同实现,例如:user服务,可能在不同的服务器上实现。
然后,在upstream模块里面设置好负载均衡的策略,不写默认是轮询。
最后,在location模块中就写upstream服务的名字,不配置某个具体的地址了。
# 在http块中的全局块中配置 # upstream固定写法 后面的myserver可以自定义 upstream myserver{ server 192.168.80.102:8081; server 192.168.80.102:8082; } # server配置 server { # 监听80端口 listen 80; #location块 location / { # 反向代理到上面的两台服务器 写上自定义的名称 proxy_pass http://myserver; } }
设置负载均衡规则
-
上诉例子什么都不添加:轮询
-
添加权重:根据权重轮询
upstream myserver { server 192.168.80.102:8081 weight=1 ; server 192.168.80.102:8082 weight=2 ; }
-
添加ip_hash规则
upstream myserver { server 192.168.80.102:8081; server 192.168.80.102:8082; ip_hash; }
-
添加fair规则
upstream myserver { server 192.168.80.102:8081; server 192.168.80.102:8082; fair; }
动静分离(静态资源)案例
我们可以将静态资源直接部署在专门的服务器上,也可以直接放在反向代理服务器上(Nginx)所在在的服务器上 然后动态资源还是部署在服务器上,如tomcat。
然后请求来的时候,静态资源从专门的静态资源服务器获取,动态资源还是转发到后端服务器上。
实现步骤:
1)我们先在电脑的任意位置创建文件夹,然后将静态资源(图片,html文件)放进去:我是放在D:\dev-tool\nginx-1.22.1\static目录下的
2)在nginx的配置下,进行配置,使用root关键字
server { listen 80; server_name localhost; location / { root D:/dev-tool/nginx-1.22.1/static; index index.html index.htm; } }
然后进行测试:我们访问:
http://localhost/123.jpg
可以看到正常访问到了图片