手把手教你在Docker中安装Nginx(图文超具体)

玛卡巴卡的卡巴卡玛  金牌会员 | 2024-6-20 14:44:51 | 来自手机 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 797|帖子 797|积分 2391

本文介绍如安在 Windows Docker Desktop 平台安装 Nginx 容器(Linux 平台同样实用),并具体讲解怎样配置 Nginx ,实现 HTTP 请求在后端服务器集群间的负载平衡。
Nginx安装

拉取镜像

访问 dockerhub 查找所需的镜像版本:


这里我选择 1.24.0 版,执行如下下令:
  1. docker pull nginx:1.24.0
复制代码
下令执行结果:

拷贝配置文件

随后,我们第一次运行镜像,用于拷贝配置文件和 html 目录到宿主机。
我表明下将 Docker 容器的目录挂载到宿主机的目的:


  • 数据长期化:默认环境下,当容器被删除时,它内部的所有数据也会丢失。通过将数据目录挂载到宿主机,可以确保重要数据得到长期化保存;随后如果运行雷同的镜像,新的容器仍旧可以利用保存在宿主机上的数据和配置。
  • 方便数据管理和调试:我选择 Docker 主要是看重它便捷的分布式应用摆设能力,可以在开发和调试阶段在本地开发机上摆设多个应用。通过卷挂载,我可以直接在宿主机上编辑配置文件,调整应用参数,从而加快开发和调试过程。
第一次运行 nginx 镜像的下令:容器名nginx
  1. docker run -p 80:80 -d --name nginx nginx:1.24.0
复制代码

拷贝 Nginx 主配置文件/etc/nginx/nginx.conf:
  1. # nginx容器名、/etc/nginx/nginx.conf 配置文件容器内的地址
  2. # D:\Programing\Docker\volumns\nginx\conf 宿主机上拷贝的目标地址
  3. docker cp nginx:/etc/nginx/nginx.conf D:\Programing\Docker\volumns\nginx\conf
复制代码
Nginx 主配置文件包含了影响 Nginx 全局行为的下令,包罗事故处置惩罚、HTTP 服务器的根本配置(如监听端口、文件路径等)、日志文件位置以及其他重要配置。

拷贝 Nginx 额外配置文件目录:/etc/nginx/conf.d
  1. docker cp nginx:/etc/nginx/conf.d D:\Programing\Docker\volumns\nginx\conf
复制代码
conf.d目任命于存放 Nginx 的额外配置文件。默认环境下,nginx.conf主配置文件中包含了一个 include 指令,指向此目录下的所有 .conf 文件。

拷贝 html 目录:/usr/share/nginx/html
  1. docker cp nginx:/usr/share/nginx/html D:\Programing\Docker\volumns\nginx
复制代码
这是 Nginx 的默认文档根目录。当您利用 Nginx 来提供静态网页服务时,放置在此目录下的文件和目录将可以通过 web 访问。(注:可以在配置文件 server 块中,利用 root 指令指定根目录)
正式运行镜像

拷贝文件完成后,删除第一次试运行的 nginx 容器:
  1. docker rm nginx
复制代码

正式运行 nginx,将宿主机上的配置文件和文档根目录挂载到容器上:
  1. # 多行便于展示()
  2. docker run -p 81:80 \
  3.     --network api-my_net \
  4.     -d --name nginx \
  5.     -v D:\Programing\Docker\volumns\nginx\conf\nginx.conf:/etc/nginx/nginx.conf \
  6.     -v D:\Programing\Docker\volumns\nginx\conf\conf.d:/etc/nginx/conf.d \
  7.     -v D:\Programing\Docker\volumns\nginx\html:nginx:/usr/share/nginx/html \
  8.     nginx:1.24.0
  9. # 可直接复制该行命令运行
  10. docker run -p 81:80 --network my_net -d --name nginx -v D:\Programing\Docker\volumns\nginx\conf\nginx.conf:/etc/nginx/nginx.conf  -v D:\Programing\Docker\volumns\nginx\conf\conf.d:/etc/nginx/conf.d -v D:\Programing\Docker\volumns\nginx\html:/usr/share/nginx/html nginx:1.24.0
复制代码
参数表明


  • --network:将容器加入到名为 my_net 的网络。注:如果该网络不存在,docker 会报错。若网络不存在,需要执行docker network create my_net创建。
  • -p:端口映射,冒号前为宿主机端口,冒号后为容器内的端口,即宿主机上访问 81 端口的 HTTP 请求会被交给 nginx 容器的 80 端口。
  • -d:背景运行容器;
  • --name:指定容器名称,本例中名称为 nginx。
  • -v:挂载配置文件、html 目录到宿主机;冒号前为宿主机文件路径,冒号后为挂载到容器中的路径。可以看到宿主机被挂载的三个目录/文件是第一次运行时从容器内拷贝出来的,
测试

浏览器访问宿主机映射的 81 端口:
  1. http://localhost:81
复制代码

页面展示如下,那么恭喜你 Nginx 已经成功安装并运行啦!

Nginx 配置

我安装并摆设 Nginx 的目的是为了让请求在多个 API 网关实例间负载平衡,这些 API 网关实例的主要作用是将 HTTP 协议的请求,映射为对某个服务的 RPC 协议调用。
在本节,我将讲解怎样配置 Nginx 请求转发给后端服务器集群。
负载平衡配置

首先给出完整的 nginx.conf 主配置文件:
  1. user  nginx;
  2. worker_processes  auto;
  3. error_log  /var/log/nginx/error.log notice;
  4. pid        /var/run/nginx.pid;
  5. events {
  6.     worker_connections  1024;
  7. }
  8. http {
  9.     include       /etc/nginx/mime.types;
  10.     default_type  application/octet-stream;
  11.     log_format main '[$time_local] request="$request" remoteAddr="$remote_addr" upstreamAddr="$upstream_addr" status=$status bodyBytesSent=$body_bytes_sent userAgent="$http_user_agent" forwardedFor="$http_x_forwarded_for" realIP="$http_x_real_ip" ';
  12.     access_log  /var/log/nginx/access.log  main;
  13.     sendfile        on;
  14.     #tcp_nopush     on;
  15.     keepalive_timeout  65;
  16.     #gzip  on;
  17.     include /etc/nginx/conf.d/*.conf;
  18.     # map $source_variable #new_variable, source变量的值将被检查, 从而确定映射的结果
  19.     map $http_x_real_ip $real_ip {
  20.         default $http_x_real_ip;  # 如果 X-Real-IP 存在,则使用其值
  21.         ''      $remote_addr;     # 如果 X-Real-IP 不存在(为空),则使用 $remote_addr
  22.     }
  23.     upstream gateway { # (1)
  24.         server api-gateway-engine-01:7396;
  25.         server api-gateway-engine-02:7396;
  26.     }
  27.     # HTTP服务器
  28.     server {
  29.         # 监听80端口
  30.         listen 80; # (2)
  31.         # 定义使用IP/域名访问
  32.         server_name 127.0.0.1; # (3)
  33.         index index.html;
  34.         # 使用 $real_ip 设置 X-Real-IP,它会根据 map 指令的逻辑来决定值
  35.         proxy_set_header X-Real-IP $real_ip;
  36.         # 添加或更新 X-Forwarded-For 头,将 $proxy_add_x_forwarded_for 保留原有的 X-Forwarded-For 信息,并添加当前客户端的 IP
  37.         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  38.         location / {
  39.             root   /usr/share/nginx/html;
  40.             index  index.html index.htm;
  41.         }
  42.                 # 反向代理路径(upstream绑定)
  43.         location /gateway/ {  # (4)
  44.             proxy_pass http://gateway;
  45.         }
  46.     }
  47. }
复制代码
标记(1): upstream gateway界说了名为 gateway 的上游服务器组。
server api-gateway-engine-01:7396; 以及 server api-gateway-engine-02:7396; 指定了组成 gateway 服务器组的两个后端服务器的主机名(或 IP 地址)和端口号。这意味着通过/gateway路径的请求,Nginx 将会在这两个服务器之间进行负载平衡。
默认所有服务器的权重为 1,我们也可以根据服务器实例的硬件配置进行加权轮询,例如:
  1.     upstream gateway {
  2.         server api-gateway-engine-01:7396 weight=2;
  3.         server api-gateway-engine-02:7396; # 默认 weight=1
  4.     }
复制代码
最少连接策略
  1.     upstream gateway {
  2.             least_conn;
  3.         server api-gateway-engine-01:7396;
  4.         server api-gateway-engine-02:7396;
  5.     }
复制代码

更多的负载平衡策略,参考Nginx 负载平衡。
标记(2):指定 Nginx 的监听端口,80 端口为标准的 HTTP 服务器端口。
标记(3):server_name 指定了 Nginx 服务器块 (server block) 应该处置惩罚哪些域名或 IP 地址的请求。本例中利用127.0.0.1,意味着当 Host 头部字段匹配到127.0.0.1时,Nginx 将会利用这个服务器块来处置惩罚该请求。
标记(4):在 proxy_pass 指令中引用 gateway 服务器组,指定 uri 以/gateway为前缀的请求应该被转发给该服务器组。

通过查看 Nginx 访问日志,可以看出 4 次 HTTP 请求中,路由给 engine-01 和 engine-02 实例的请求数均为两次,这反映了默认的负载平衡策略为等权重轮询


API网关案例分享

在计划 API 网关时,我将网关 算力节点 划分进多个网关 算力组 ,算力组按找业务部分划分(例如:交易、计费、结算、运营等),每个算力组拥有本身的算力资源。
请求 URI 前缀标识所属的算力组,然后经过 Nginx 路由给该部分的算力节点,由算力节点完成 鉴权、Http 请求参数解析、RPC 泛化调用、调用结果返回 这一整套流程。
举个例子
交易组的编号 123,请求 uri 样式为:/123/purchase/coupon/79347,这个 uri 用于团购券的下单请求。我希望将该请求转发给交易组申请的算力节点上,但是请求的 uri 经过 Nginx 处置惩罚后去除前缀部分/123。
那么在 Nginx 的配置文件中可以这样做:
  1.     upstream 123 {
  2.         least_conn;
  3.         server 172.19.0.7:7396;
  4.         server 172.19.0.8:7396;
  5.     }
  6.     server {
  7.         listen 80;
  8.         location ~ ^/123/(.*)$ {
  9.             proxy_pass http://123/$1;
  10.         }
  11.     }
复制代码
在这个配置中,location指令利用正则表达式来匹配请求URI。^/123/(.*)$正则表达式匹配以/123/开头的请求URI,并将匹配的部分之后的URI(由(.*)捕获)通报给 proxy_pass 指令。
这样,当一个请求 URI 为/123/purchase/coupon/79347时,它会被转发到http://123/purchase/coupon/79347,123终极会被名称为 123 的 upstream 服务器组中的某一个地址替换,例如替换为http://172.19.0.7:7396/purchase/coupon/79347。

在 Nginx 中,~ 符号用于指示接下来的位置匹配将利用正则表达式;$符号在正则表达式中用来表现字符串的结束。所以,~ ^/123/(.*)$表达式的含义为:


  • ^ 表现字符串的开始,确保匹配的URI从头部开始。
  • /123/ 表现确切的字符序列,匹配所有以这个序列开始的 URI。
  • (.*)是一个捕获组,匹配/123/之后的任何字符序列,直到 URI 的结束。在 proxy_pass 中,利用了 $1 访问这个匹配组,即剪切了前缀的 URI。
  • $ 确保匹配到的是整个请求 URI 的结尾,避免部分匹配的环境发生。

下面是 Nginx 和应用服务器的请求日志图,可以看到请求 URI 发生了变化:
Nginx 日志



Spring Boot 后端服务器日志


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

玛卡巴卡的卡巴卡玛

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表