1、简介
1.1 正向代理与反向代理
正向代理示意图:
反向代理示意图:
不同点:
"正向代理"指的是代理服务器代理客户端去向目标服务器请求数据,得到响应后再将数据返回给客户端;
"反向代理"指的是代理服务器代理目标服务器接收来自客户端的请求,再将请求分发给目标服务器,待目标服务器处理完毕后,再由代理服务器将数据返回给客户端。
相同点:客户端并不直接与目标服务器进行数据交互,而是通过中间的代理服务器来间接地进行。
2、安装与启动
2.1 从镜像仓库拉取镜像
以 1.18.0 版本为例:
$ docker pull nginx:1.18.0
2.2 启动容器
2.2.1 创建容器数据卷目录
在宿主机的/usr/local/docker/nginx/
目录下新建html
、conf
和logs
三个目录,分别用来挂载 Nginx 的页面测试文件、配置文件和日志文件:
$ mkdir -p /usr/local/docker/nginx/html
$ mkdir -p /usr/local/docker/nginx/conf
$ mkdir -p /usr/local/docker/nginx/logs
2.2.2 预启动以复制配置文件等数据
$ docker run -d --name nginx-tmp -p 80:80 nginx:1.18.0
$ docker cp nginx-tmp:/usr/share/nginx/html/ /usr/local/docker/nginx/
$ docker cp nginx-tmp:/etc/nginx/nginx.conf /usr/local/docker/nginx/conf/
$ docker cp nginx-tmp:/etc/nginx/conf.d/default.conf /usr/local/docker/nginx/conf/
$ docker rm -f nginx-tmp
2.2.3 正式启动
$ docker run -d --name Nginx-1.18.0 \
-p 4444:80 -p 4445:81 \
-v /usr/local/docker/nginx/html:/usr/share/nginx/html \
-v /usr/local/docker/nginx/logs:/var/log/nginx \
-v /usr/local/docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
-v /usr/local/docker/nginx/conf/default.conf:/etc/nginx/conf.d/default.conf \
nginx:1.18.0
2.3 访问测试
注:服务器地址为 xxx.xxx.xxx.65.下同.
2.4 在本机直接安装 (不使用Docker)
2.4.1 安装前置应用
yum install gcc pcre-devel zlib-devel openssl-devel -y
2.4.2 上传并解压安装包
首先将从官方下载地址下载好的压缩包上传到服务器的 /opt/ 目录下
$ ls -l /opt/
-rw-r--r--. 1 root root 1039530 3月 19 15:49 nginx-1.18.0.tar.gz
然后解压:
$ tar -zxvf /opt/nginx-1.18.0.tar.gz
// 略...
$ ls -l /opt/
drwxr-xr-x. 9 root root 186 3月 19 23:52 nginx-1.18.0
-rw-r--r--. 1 root root 1039530 3月 19 15:49 nginx-1.18.0.tar.gz
2.4.3 配置安装路径
# 首先进入到解压后的目录中
$ cd /opt/nginx-1.18.0/
# 执行配置命令
./configure --prefix=/usr/local/nginx
这样 Nginx 会被安装到/usr/local/nginx/
目录下。
2.4.4 开始"安装"
$ cd /opt/nginx-1.18.0/
$ make & make install
3、反向代理功能示例
3.1 示例一
在服务器上启动一个 Tomcat (端口号为8081):
$ docker run --name tomcat-test-1 \
-p 8081:8080 \
-d tomcat:10.0.2-jdk8-corretto
直接访问如下:
现在使用 Nginx 来作为反向代理服务器,使得当客户端访问 Nginx 所在的服务器的 4445 端口时,间接访问到上述 Tomcat 主页。
修改 Nginx 的配置文件:
$ vim /usr/local/docker/nginx/conf/default.conf
# 新增
server {
# 监听的端口号
listen 81;
# 监听的地址
server_name localhost;
# 字符集编码
charset utf-8;
# 访问根路径走以下规则
location / {
# 要转发到的地址
proxy_pass http://172.17.0.1:8081;
}
}
注:这里的 Nginx 和 Tomcat 均是宿主机上由 Docker 镜像启动的容器,但 nginx 转发到 tomcat 并没有直接使用容器间的通信,而是通过访问宿主机的映射端口,因此这里的 172.17.0.1 指的是 nginx 容器内部访问宿主机时,宿主机的 IP 地址。
查看 nginx 容器的内部细节可以获得其网络信息:
$ docker inspect Nginx-1.18.0
接下来再次访问 Nginx 所在的服务器的 4445 端口:
3.2 示例二
在上述的 tomcat-test-1 中创建一个 alice 项目,新建 index.html 文件如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Alice's Page</title>
<style type="text/css">
body {
color: azure;
}
h1 {
color: burlywood;
}
</style>
</head>
<body>
<h1>Hello Alice! This is Tomcat 10.0.2, port 8081.</h1>
</body>
</html>
另启动一个 Tomcat 实例,端口号为8082:
$ docker run --name tomcat-test-2 \
-p 8082:8080 \
-d tomcat:10.0.2-jdk8-corretto
在 tomcat-test-2 中创建一个 bob 项目,新建 index.html 文件如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Bob's Page</title>
<style type="text/css">
body {
color: aqua;
}
h1 {
color: blue;
}
</style>
</head>
<body>
<h1>Hello Bob! This is Tomcat 10.0.2, port 8082.</h1>
</body>
</html>
直接访问 tomcat-test-1 中的 alice 项目如下:
直接访问 tomcat-test-2 中的 bob 项目如下:
现在引入 Nginx 作为反向代理服务器,使得当客户端访问 Nginx 所在的服务器的 4445 端口时:
如果路径中含有 /alice,则转发到 tomcat-test-1 中的 alice 项目;
如果路径中含有 /bob,则转发到 tomcat-test-2 中的 bob 项目。
即自始至终不需要修改主机名和端口号,只需要修改项目名即可访问到位于不同服务器上的不同项目。
修改 Nginx 的配置文件:
$ vim /usr/local/docker/nginx/conf/default.conf
server {
# 监听的端口号
listen 81;
# 监听的地址
server_name localhost;
# 字符集编码
charset utf-8;
# 访问根路径走以下规则
location / {
proxy_pass http://172.17.0.1:80;
}
# 访问路径中存在 /alice 时走以下规则,会转发到 http://172.17.0.1:8081/alice
location /alice {
proxy_pass http://172.17.0.1:8081;
}
# 访问路径中存在 /alice 时走以下规则,会转发到 http://172.17.0.1:8081/bob
location /bob {
proxy_pass http://172.17.0.1:8082;
}
}
配置完成后再次访问:
4、负载均衡的功能示例
在 tomcat-test-1 和 tomcat-test-2 中分别创建一个同名的项目 user ,新建 index.html 文件如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>User Project</title>
<style type="text/css">
body {
color: aqua;
}
h1 {
color: blue;
}
</style>
</head>
<body>
<!-- tomcat-test-2 中的项目这里相应地改为tomcat-test-2 -->
<h1>Hello! This is User project in tomcat-test-1.</h1>
</body>
</html>
直接访问如下:
现在引入 Nginx 作为反向代理服务器,使得当客户端访问 Nginx 所在的服务器的 4445 端口上的 user 项目时:
时而转发到 tomcat-test-1 中的 user 项目、时而转发到 tomcat-test-2 中的 user 项目。
即自始至终不需要修改主机名和端口号,也不需要修改项目名称,即可访问到位于不同服务器上的不同项目。
注:实际上这种情况是同一个项目部署在了不同的服务器上,它们提供的是相同的服务。为了演示差异这里使用了两个稍有区别的 index.html。
修改 Nginx 的配置文件:
# 这里的"mylbtest"是任意合规的命名
upstream mylbtest {
server 172.17.0.1:8081;
server 172.17.0.1:8082;
}
server {
listen 81;
server_name localhost;
charset utf-8;
location / {
# 这里不再写具体的 ip+port,而是引用上面配置的 upstream
proxy_pass http://mylbtest/;
}
}
再次访问:
刷新后:
可以看到已实现同一访问路径但请求到了位于不同服务器上的项目。
5、动静分离的功能演示
以若依项目的部署为例。
5.1 处理静态请求
将前端项目 ruoyi-ui 进行生产打包,打包后的 dist 目录重命名为ruoyi-ui
,上传到服务器的 /usr/local/docker/nginx/html/ 目录下,即 nginx 容器内部的 /usr/share/nginx/html/ 目录:
$ pwd
/usr/local/docker/nginx/html
$ ls -l|grep ruoyi-ui
drwxr-xr-x. 3 root root 75 3月 26 08:47 ruoyi-ui
$ ls ruoyi-ui/
favicon.ico index.html robots.txt static
修改 nginx 容器的配置文件:
$ vim /usr/local/docker/nginx/conf/default.conf
server {
listen 81;
server_name localhost;
charset utf-8;
location / {
root /usr/share/nginx/html/ruoyi-ui;
index index.html index.htm
autoindex on;
}
}
访问 nginx 容器的 81 端口下的根路径:
可以看到已经可以访问到若依后台管理系统的登录页面了。但是验证码还是空白。
检查网络后可以看到,验证码的获取是请求了一个地址为 /prod-api/captchaImage 的接口:
因此还需要使 Nginx 将该动态请求转发到对应的若依的后端项目上。
5.2 处理动态请求
为了方便,不再将后端项目构建为 Docker 镜像。
将若依的后端项目打包后,把ruoyi-admin.jar
包上传到服务器的 /workspace/ 目录下:
$ ls -l /workspace/ruoyi-admin.jar
-rw-r--r--. 1 root root 77919978 3月 21 10:56 /workspace/ruoyi-admin.jar
将这个 jar 包启动两次,分别指定不同的端口号(9990和9991):
$ java -jar /workspace/ruoyi-admin.jar --server.port=9990
$ java -jar /workspace/ruoyi-admin.jar --server.port=9991
在 nginx 配置文件中增加处理动态请求的配置:
$ vim /usr/local/docker/nginx/conf/default.conf
# 增加 upstream 配置负载均衡,命名为 ruoyi-api
upstream ruoyi-api {
server 172.17.0.1:9990;
server 172.17.0.1:9991;
}
server {
listen 81;
server_name localhost;
charset utf-8;
# 原有配置不变
location / {
root /usr/share/nginx/html/ruoyi-ui;
index index.html index.htm
autoindex on;
}
# 新增对动态请求路径的处理
location /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://ruoyi-api/;
}
}
再次访问若依登录页面:
可以看到验证码已经请求成功。输入正确的验证码后可成功登录到管理页面:
6、负载均衡策略
6.1 轮询
默认方式,如第4节中配置的:
upstream mylbtest {
server 172.17.0.1:8081;
server 172.17.0.1:8082;
}
这样请求会被均匀地转发到 172.17.0.1:8081 和 172.17.0.1:8082 这两个服务器上。
6.2 weight 权重方式
可以在服务器后指定权重,如:
upstream mylbtest {
server 172.17.0.1:8081 weight=1;
server 172.17.0.1:8082 weight=2;
}
这样一来,第二台服务器被分配到的几率将会增到到第一台服务器的2倍。
6.3 最小连接数
将请求尽可能地分发给连接负载最少的服务器:
upstream mylbtest {
least_conn;
server 172.17.0.1:8081;
server 172.17.0.1:8082;
}
6.4 IP Hash
确保来自同一 IP 的客户端的请求始终分发给同一台服务器:
upstream mylbtest {
ip_hash;
server 172.17.0.1:8081;
server 172.17.0.1:8082;
}
7、配置文件的基本说明
7.1 基础配置
# 配置 worker 进程的运行用户. nobody也是Linux的一个用户,如果出现权限问题可以尝试改为 root
user nobody;
# 配置工作进程的数目. 通常为CPU数量的一倍或两倍
worker_processes 1;
# 配置全局的错误日志位置及类型. 类型可选值有[debug|info|notice|warn|error|crit],默认为 error
error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
# 配置进程的 pid 文件
pid logs/nginx.pid;
7.2 events 配置
# 配置工作模式和最大连接数
events {
# 配置每个 worker 进程的最大连接数(16位)
# Nginx 支持的总连接数为 events.worker_connections*worker_processes
worker_connections 1024;
}
7.3 http 配置
http {
# 配置 Nginx 支持的MIME类型. 可以在 conf/mime.types 文件中查看
include mime.types;
# 默认的类型: application/octet-stream
default_type application/octet-stream;
# 自定义日志格式,命名为"main"
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# 配置访问日志的位置及类型(格式),引用上面自定义的"main"
access_log logs/access.log main;
# 开启高效文件传输模式
sendfile on;
# 方式网络阻塞
tcp_nopush on;
# 长连接的超时时间. 以秒为单位
#keepalive_timeout 0;
keepalive_timeout 65;
# 是否开启 gzip 压缩输出
gzip on;
# 配置一个虚拟主机(可以有多个,由"listen"和"server_name"共同标识)
server {
# 监听的端口号
listen 80;
# 虚拟主机的主机名(域名)
server_name localhost;
# 配置字符集,如 utf-8
#charset koi8-r;
# 配置本虚拟主机的访问日志位置及格式
#access_log logs/host.access.log main;
# 当请求的 uri 为根路径时,走此规则
location / {
# 静态资源的根目录,默认为 Nginx 安装目录下的 html 目录. 也可以改为其他绝对路径
root html;
# 访问首页时指定默认文件
index index.html index.htm;
}
# 配置 404 页面
#error_page 404 /404.html;
# 配置 50x 错误页面. 重定向服务器错误页面到一个静态的 50x.htmk 页面
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
# 精确匹配. 如果请求的 uri 恰好就为"/50x.html",则响应 html 目录下的 50x.html 文件
location = /50x.html {
root html;
}
# 让所有 PHP 脚本请求全部转发到位于 127.0.0.1:80 的 Apache 服务器
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# 让所有 PHP 脚本请求全部转发到位于 127.0.0.1:9000 的 FastCGI 服务器
# 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;
#}
# 禁止访问 .htaccess 文件
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# 配置另一个虚拟主机. 注意 listen 和 server_name 与上一个虚拟主机不完全相同
# 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;
# }
#}
}
7.4 关于 location 的说明
# 这里的"/"就等于root所示的"/opt/workspace/test-app"
# 即会访问 /opt/workspace/test-app/alice 这个目录下的资源
location /alice {
# 静态资源的根目录,默认为 Nginx 安装目录下的 html 目录. 也可以改为其他绝对路径,如
root /opt/workspace/test-app;
# 访问首页时指定默认文件
index index.html index.htm;
}
本文暂时没有评论,来添加一个吧(●'◡'●)