nginx 负载均衡
什么是负载均衡,nginx 如何实现负载均衡
负载均衡是一种技术,它允许将工作量分散到多个操作单元上,如计算机、网络链接、中央处理器或磁盘驱动器等,以优化资源使用、最大化吞吐量、最小化响应时间,并防止任何单个资源的过载。在互联网领域,负载均衡通常指的是将进入的网络流量分配到多个服务器上,以确保网络服务的可用性和性能。
Nginx 是一款轻量级的 Web 服务器/反向代理服务器以及电子邮件(IMAP/POP3)代理服务器,并在一个 BSD-like 协议下发行。由于其高性能、稳定性、丰富的功能集、简单的配置以及低资源消耗而被广泛使用。
Nginx 实现负载均衡的常用方式是通过内置的 ngx_http_upstream_module
模块。该模块允许 Nginx 定义一组服务器作为上游服务器,用于处理客户端的请求。当 Nginx 作为反向代理服务器时,它会接收客户端的请求,并将这些请求转发到上游服务器。Nginx 支持多种负载均衡策略,如轮询、加权轮询、IP 哈希、最少连接等。
以下是一个简单的 Nginx 负载均衡配置示例:
http {
upstream myapp1 {
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
server {
listen 80;
location / {
proxy_pass http://myapp1;
}
}
}
在这个配置中,myapp1
是一个上游服务器组,包含了三个服务器。Nginx 将根据配置的负载均衡策略将客户端请求分发到这三个服务器之一。默认情况下,如果没有指定策略,Nginx 将使用轮询策略。
有负载均衡和没有负载均衡
没有负载均衡
有负载均衡
官方文档 ngx_http_upstream_module
https://nginx.org/en/docs/http/ngx_http_upstream_module.html
Details
The ngx_http_upstream_module module is used to define groups of servers that can be referenced by the proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, memcached_pass, and grpc_pass directives.
Example Configuration
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com:8080;
server unix:/tmp/backend3;
server backup1.example.com:8080 backup;
server backup2.example.com:8080 backup;
}
server {
location / {
proxy_pass http://backend;
}
}
Dynamically configurable group with periodic health checks is available as part of our commercial subscription:
resolver 10.0.0.1;
upstream dynamic {
zone upstream_dynamic 64k;
server backend1.example.com weight=5;
server backend2.example.com:8080 fail_timeout=5s slow_start=30s;
server 192.0.2.1 max_fails=3;
server backend3.example.com resolve;
server backend4.example.com service=http resolve;
server backup1.example.com:8080 backup;
server backup2.example.com:8080 backup;
}
server {
location / {
proxy_pass http://dynamic;
health_check;
}
}
ngx_http_upstream_module
模块用于定义服务器组,这些服务器组可以通过 proxy_pass
, fastcgi_pass
, uwsgi_pass
, scgi_pass
, memcached_pass
, 和 grpc_pass
指令来引用。
示例配置:
upstream backend { # 定义一个名为backend的上游服务器组
server backend1.example.com weight=5; # 添加一个服务器,权重为5
server backend2.example.com:8080; # 添加一个服务器,默认权重为1,端口为8080
server unix:/tmp/backend3; # 添加一个Unix socket服务器
server backup1.example.com:8080 backup; # 添加一个备用服务器,端口为8080
server backup2.example.com:8080 backup; # 添加另一个备用服务器,端口为8080
}
server { # 定义一个服务器配置
location / { # 匹配所有请求
proxy_pass http://backend; # 代理请求到名为backend的服务器组
}
}
动态可配置的服务器组以及定期健康检查功能是我们商业订阅的一部分:
resolver 10.0.0.1; # 定义DNS解析器
upstream dynamic { # 定义一个名为dynamic的动态可配置服务器组
zone upstream_dynamic 64k; # 定义共享内存区域,大小为64k
server backend1.example.com weight=5; # 添加一个服务器,权重为5
server backend2.example.com:8080 fail_timeout=5s slow_start=30s; # 添加一个服务器,失败超时时间为5秒,慢启动时间为30秒
server 192.0.2.1 max_fails=3; # 添加一个服务器,最大失败次数为3
server backend3.example.com resolve; # 添加一个服务器,使用DNS解析
server backend4.example.com service=http resolve; # 添加一个服务器,使用DNS解析,服务类型为HTTP
server backup1.example.com:8080 backup; # 添加一个备用服务器,端口为8080
server backup2.example.com:8080 backup; # 添加另一个备用服务器,端口为8080
}
server { # 定义一个服务器配置
location / { # 匹配所有请求
proxy_pass http://dynamic; # 代理请求到名为dynamic的服务器组
health_check; # 启用健康检查
}
}
模块介绍 ngx_http_upstream_module
ngx_http_upstream_module
是 Nginx 的一个核心模块,它负责定义一组服务器作为上游服务器,这些服务器用于处理客户端的请求。当 Nginx 作为反向代理服务器时,它会接收客户端的请求,并将这些请求转发到上游服务器。ngx_http_upstream_module
模块定义了如何与上游服务器进行通信,以及如何处理上游服务器的响应。 以下是 ngx_http_upstream_module
模块的一些主要功能:
- 负载均衡:Nginx 可以将请求分发到多个上游服务器,支持多种负载均衡策略,如轮询、加权轮询、IP 哈希、最少连接等。
- 健康检查:Nginx 可以对上游服务器进行健康检查,如果发现某个服务器不可用或者响应超时,它会自动将请求转发到其他健康的服务器。
- 故障转移:如果所有上游服务器都不可用,Nginx 可以配置为返回一个预定义的响应或者重定向到另一个服务器。
- 缓冲和缓存:Nginx 可以缓冲上游服务器的响应,以减少网络延迟和提高吞吐量。它还可以缓存上游服务器的响应,以便在后续的请求中重用。
- 请求头处理:Nginx 可以修改或添加发送到上游服务器的请求头,以及修改从上游服务器接收到的响应头。
- SSL/TLS 终止:Nginx 可以作为 SSL/TLS 终端,处理客户端的加密连接,并与上游服务器建立非加密连接,从而减轻上游服务器的加密处理负担。
- HTTP/2 支持:Nginx 可以作为 HTTP/2 代理,与上游服务器建立 HTTP/1.1 连接,同时支持客户端的 HTTP/2 连接。
- 动态上游配置:Nginx 支持使用 DNS 解析动态更新上游服务器列表,以及使用脚本或 HTTP 接口动态修改上游配置。
- 长连接:Nginx 可以与上游服务器建立长连接,减少频繁建立和关闭连接的开销。
- 日志记录:Nginx 可以记录与上游服务器通信的详细日志,包括请求时间、响应状态码等信息。
在 Nginx 的配置文件中,ngx_http_upstream_module
的配置通常位于 http
块内的 upstream
块中。例如:
http {
upstream myapp1 {
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
server {
listen 80;
location / {
proxy_pass http://myapp1;
}
}
}
在这个配置中,myapp1
是一个上游服务器组,包含了三个服务器。Nginx 将根据配置的负载均衡策略将客户端请求分发到这三个服务器之一。
参考链接
什么是负载均衡? https://cloud.tencent.com/developer/article/1161113
负载均衡 百度百科 https://baike.baidu.com/item/负载均衡/932451
nginx 负载均衡的 6 种例子
1. 负载均衡-故障处理
在 Nginx 中实现故障处理,特别是在负载均衡配置中,主要涉及到检测后端服务器的健康状态,并根据需要自动从负载均衡池中移除不健康的服务器。这可以通过配置健康检查来实现,确保流量只被转发到健康的服务器上。
Nginx 开源版本的故障处理
在 Nginx 开源版中,故障处理通常较为基础,主要依赖于简单的检查,如以下示例所示:
http {
upstream myapp {
server backend1.example.com;
server backend2.example.com down;
server backend3.example.com fail_timeout=30s;
# 设置检测到失败后,服务器标记为失败的超时时间
server backend4.example.com max_fails=3 fail_timeout=30s;
}
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://myapp;
}
}
}
- down: 这表示服务器已知是关闭的,Nginx 不会向其发送任何请求。
- max_fails 和 fail_timeout:
max_fails
指定在fail_timeout
设定的时间内允许失败的最大次数。如果超过这个限制,Nginx 会暂时停止将请求发送到该服务器。
Nginx Plus 的高级故障处理
Nginx Plus 提供了更高级的健康检查功能,可以定期检测后端服务器的健康状态,并根据服务器是否正常响应来自动添加或移除服务器。以下是 Nginx Plus 配置的一个例子:
http {
upstream myapp {
zone myapp 64k;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
# 启用健康检查
health_check;
}
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://myapp;
}
}
}
在 Nginx Plus 中,health_check
指令启用了健康检查,你可以进一步配置这些检查,例如设置检查的频率、失败条件等。
考虑的实践策略
- 使用超时和重试逻辑: 在 Nginx 配置中,可以使用
proxy_connect_timeout
,proxy_read_timeout
, 和proxy_send_timeout
来设置超时,proxy_next_upstream
来定义在哪些错误、超时或 HTTP 状态码下尝试下一个服务器。 - 合理设置 max_fails 和 fail_timeout: 这些参数需要根据具体场景调整,以避免过早地判断服务器不健康。
- 动态调整: 对于 Nginx Plus 用户,利用其动态重新配置功能(如 API 控制),可以实时调整上游服务器列表。
通过这些策略,你可以确保 Nginx 负载均衡环境在面对服务器故障时,能够保持高可用性和稳定性。
2. 负载均衡-平台特定路由
在 Nginx 中实现基于平台特定的路由,即根据请求的来源或者请求的特征(如用户代理、地理位置、请求头等)将流量分配到不同的后端服务器,可以通过配置请求的检测和相应的转发规则来实现。这种方式常用于向不同类型的设备或不同地区的用户提供定制化的内容或服务。
下面我将介绍一些常见的方法来在 Nginx 中设置基于条件的路由:
1. 基于用户代理的路由
这种方法涉及检查User-Agent
请求头,以确定请求来自何种设备(例如,手机、平板或桌面计算机),并据此转发请求。以下是一个示例配置:
http {
upstream desktop {
server desktop1.example.com;
server desktop2.example.com;
}
upstream mobile {
server mobile1.example.com;
server mobile2.example.com;
}
server {
listen 80;
server_name www.example.com;
location / {
if ($http_user_agent ~* 'Mobile') {
proxy_pass http://mobile;
}
if ($http_user_agent ~* 'MSIE') {
proxy_pass http://desktop;
}
# 默认后备
proxy_pass http://desktop;
}
}
}
这个配置检查User-Agent
头部,如果包含“Mobile”,则将请求转发到移动端服务器群组;如果检测到“MSIE”(Internet Explorer),则转发到桌面端服务器群组。
2. 基于地理位置的路由
Nginx 可以通过第三方模块如ngx_http_geoip_module
(需另行安装)使用 MaxMind GeoIP 数据库来确定请求的来源国家,并据此决定路由。这需要在 Nginx 编译时添加 GeoIP 模块支持。
http {
geoip_country /path/to/GeoIP.dat; # 指定GeoIP数据库位置
map $geoip_country_code $target_group {
default international;
CN china;
US united_states;
}
upstream international {
server server1.example.com;
server server2.example.com;
}
upstream china {
server china1.example.com;
server china2.example.com;
}
upstream united_states {
server us1.example.com;
server us2.example.com;
}
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://$target_group;
}
}
}
在这个配置中,根据请求者的国家代码,流量被路由到不同的后端群组。
3. 基于请求头的路由
如果想根据特定的 HTTP 请求头(如自定义头部或 API 版本)路由请求,你可以使用类似的逻辑:
server {
listen 80;
server_name api.example.com;
location / {
if ($http_x_api_version = '1.0') {
proxy_pass http://backend_v1;
}
if ($http_x_api_version = '2.0') {
proxy_pass http://backend_v2;
}
# 默认后备
proxy_pass http://backend_v1;
}
}
这种方式可以根据 API 版本请求头来决定转发到不同的后端服务。
注意事项
- 使用
if
指令要谨慎,因为在 Nginx 的location
块中使用if
有性能影响,并可能导致不预期的行为。更好的实践是使用map
指令进行变量映射。 - 这些示例需要根据实际的运行环境进行测试和调整。
通过以上方法,你可以灵活地根据请求的特点在 Nginx 中实现复杂的路由逻辑,从而优化用户体验和资源利用率。
3. 负载均衡-SSL 终止
在 Nginx 中实现 SSL 终止涉及配置 Nginx 以处理 SSL/TLS 连接,解密接收到的 HTTPS 请求,并将解密后的流量以 HTTP 的形式转发到后端服务器。这种配置不仅加密客户端与服务器之间的通信,而且还可以减轻后端服务器的加密和解密负担。以下是如何配置 Nginx 进行 SSL 终止的步骤:
1. 获取 SSL 证书
首先,你需要一个 SSL 证书和相应的私钥。你可以从证书颁发机构(CA)购买证书,或使用 Let's Encrypt 免费获取证书,或为测试目的创建一个自签名证书。
2. 配置 Nginx
以下是一个基本的 Nginx 配置示例,用于实现 SSL 终止。这个配置假设你已经有了证书(server.crt
)和私钥(server.key
)。
http {
upstream myapp {
server backend1.example.com;
server backend2.example.com;
}
server {
listen 80;
server_name www.example.com;
return 301 https://$host$request_uri; # 强制重定向到HTTPS
}
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate /etc/nginx/ssl/server.crt; # SSL证书
ssl_certificate_key /etc/nginx/ssl/server.key; # SSL私钥
ssl_protocols TLSv1.2 TLSv1.3; # 定义使用的TLS版本
ssl_ciphers HIGH:!aNULL:!MD5; # 定义支持的加密套件
location / {
proxy_pass http://myapp; # 代理到后端应用
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
3. 加载 SSL 配置和重启 Nginx
将以上配置添加到 Nginx 配置文件中,并确保 SSL 证书和密钥文件的路径正确。之后,重新加载 Nginx 配置以使更改生效:
sudo nginx -t # 测试配置文件是否正确
sudo systemctl reload nginx # 重新加载配置
注意事项
- 证书续期:如果你使用的是 Let's Encrypt 证书,记得设置自动续期,因为这些证书有效期较短(通常 90 天)。
- 安全最佳实践:定期更新你的 TLS 配置以禁用旧的协议和加密套件,以保持符合当前的安全最佳实践。
- 性能优化:考虑启用 SSL 会话缓存和 SSL stapling 以提高性能和响应速度。
- 错误处理:配置适当的错误页面和错误处理逻辑,以便在 SSL 握手失败时优雅地处理请求。
通过这种方式配置的 Nginx 可以有效地处理 SSL 终止,保护数据安全,同时优化后端服务器的性能。
4. 负载均衡-实例健康检查
在 Nginx 中实施实例健康检查通常需要依赖于 Nginx Plus 的高级功能,因为 Nginx 开源版本本身并不内建支持健康检查的自动化功能。Nginx Plus 提供了多种健康检查机制,可以动态地从负载均衡池中添加或移除失败的后端服务器。
Nginx Plus 的健康检查配置
如果你使用的是 Nginx Plus,可以按照以下步骤配置健康检查:
配置后端服务器池(upstream): 在
upstream
块中定义后端服务器,并启用健康检查。添加健康检查: 在
upstream
块中使用health_check
指令来启动健康检查。配置健康检查参数: 可以指定健康检查的间隔、超时时间、尝试次数等。
以下是一个具体的示例配置:
http {
upstream myapp {
zone myapp 64k;
server backend1.example.com;
server backend2.example.com;
# 启用健康检查
health_check interval=5 fails=3 passes=2;
}
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://myapp;
}
}
}
在这个例子中,health_check
指令用于启动每 5 秒执行一次的健康检查,如果一个后端连续 3 次检查失败,则认为是不健康的,需要连续 2 次检查成功才认为恢复健康。
Nginx 开源版本的替代方案
对于 Nginx 开源版本用户,虽然没有内置的健康检查功能,但可以通过其他方法间接实现:
- 使用第三方模块:例如
nginx_upstream_check_module
,这是一个非官方的第三方模块,可以添加到 Nginx 中以支持健康检查。 - 通过外部脚本进行健康检查:可以设置一个外部脚本定期检查后端服务器的健康状态,并动态修改 Nginx 配置或通过 Nginx 的 API 动态调整后端服务器权重。
- 结合负载均衡器使用:如果在 Nginx 前面有其他层面的负载均衡器(如 AWS ELB、Google Cloud Load Balancer 等),可以利用这些服务的健康检查功能。
使用这些方法,尽管不能直接通过 Nginx 开源版进行健康检查,但仍然可以实现类似的功能,确保流量只被发送到健康的后端服务器。对于需要严格健康检查的生产环境,推荐使用 Nginx Plus 或其他支持健康检查的负载均衡解决方案。
5.负载均衡-用户沾滞
在 Nginx 中实现用户粘滞(Session Persistence)通常是为了确保同一个客户端在使用基于 Nginx 的负载均衡时,其请求总是被转发到同一个后端服务器上。这对于处理包含用户会话或需要状态持续性的应用程序尤其重要。
Nginx 通过使用模块ngx_http_upstream_module
支持几种粘滞会话的方法。在 Nginx 的开源版本中,你可以通过客户端的 IP 地址来实现简单的粘滞会话。对于更复杂的粘滞会话(如基于 Cookie 的粘滞会话),你需要使用 Nginx Plus,这是 Nginx 的商业版。
使用 Nginx 开源版本通过 IP 哈希实现用户粘滞
这种方法基于客户端 IP 地址的哈希值来决定请求应该路由到哪个服务器。这样,来自同一 IP 地址的请求总是被发送到同一个后端服务器。
下面是一个配置示例:
http {
upstream myapp {
ip_hash;
server backend1.example.com;
server backend2.example.com;
}
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://myapp;
}
}
}
在这个配置中,ip_hash
指令确保所有来自同一源 IP 地址的请求都被代理到相同的后端服务器。
使用 Nginx Plus 进行更高级的用户粘滞
如果你使用 Nginx Plus,可以通过 Cookie 实现更复杂的粘滞会话。以下是一个基于 Cookie 的用户粘滞配置示例:
http {
upstream myapp {
sticky cookie srv_id expires=1h domain=.example.com path=/;
server backend1.example.com;
server backend2.example.com;
}
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://myapp;
}
}
}
在这个配置中,sticky cookie srv_id
指令会创建一个名为srv_id
的 Cookie,以跟踪客户端使用的后端服务器。expires=1h
设置 Cookie 的有效期为 1 小时。
注意事项
- IP 哈希方法不适用于那些 IP 地址经常变化的用户,或者多个用户共享相同 IP 地址的情况(如在同一个网络环境下)。
- 使用 Cookie 的方法提供了更细致的控制,但需要 Nginx Plus。
- 以上方法不适用于 WebSocket 等需要持久连接的协议,这些情况可能需要其他配置策略。
根据你的需求选择合适的方法,并根据实际情况进行调整和优化。
6. 负载均衡-跨区域负载均衡
实现跨区域负载均衡涉及在不同的地理位置分布的数据中心或服务器之间分配流量。这样做可以提高应用程序的可用性和性能,确保用户接近其地理位置的服务器处理请求。Nginx 可以通过几种方式配置来实现这一目标,尽管这通常需要一些高级配置和可能结合使用其他服务或技术。
使用 Nginx 实现跨区域负载均衡的策略:
1. 地理位置感知 DNS
一种常见的方法是使用地理位置感知的 DNS 服务,如 Amazon Route 53、Google Cloud DNS 或其他支持 GeoDNS 功能的服务。这些服务可以根据用户的 IP 地址地理位置,返回最接近用户的服务器地址。然后,你可以在每个地理区域配置一个 Nginx 服务器,作为该区域入口点。
2. Nginx 作为全局负载均衡器
你也可以配置 Nginx 作为全局负载均衡器,使用 Nginx 的配置来分配到不同区域的后端。这通常依赖于$geoip_country_code
变量(需要 GeoIP 模块)来决定用户请求应该转发到哪个区域的服务器。
http {
geoip_country /path/to/GeoIP.dat;
map $geoip_country_code $backend_pool {
default international_pool;
US us_pool;
CA us_pool;
GB eu_pool;
DE eu_pool;
}
upstream international_pool {
server international1.example.com;
server international2.example.com;
}
upstream us_pool {
server us1.example.com;
server us2.example.com;
}
upstream eu_pool {
server eu1.example.com;
server eu2.example.com;
}
server {
listen 80;
location / {
proxy_pass http://$backend_pool;
}
}
}
在这个配置中,根据用户的国家代码,请求被分配到不同的服务器池。
3. 结合其他负载均衡技术
在一些复杂的场景下,可能需要结合使用多种技术来实现跨区域负载均衡,例如结合使用 Nginx 和其他第三方负载均衡器(如 F5, Citrix, 或云服务提供商的负载均衡器),以及可能的容器化服务和编排工具(如 Kubernetes)。
4. Anycast IP 技术
对于要求极高的场景,可以使用 Anycast IP 技术,这允许多个物理位置响应同一个 IP 地址,最近的节点将响应用户请求。这通常涉及更复杂的网络配置和与 ISP 的合作。
注意事项
- 测试和验证:跨区域负载均衡的配置应该在生产部署前进行详细的测试,以确保所有的路由和故障转移机制按预期工作。
- 安全和合规:确保数据在跨区域传输时遵守数据保护法规和合规要求。
- 性能监控:部署跨区域负载均衡后,应持续监控性能,以确保所有区域都提供相同水平的服务质量。
通过这些配置和考虑,你可以利用 Nginx 有效地实现跨区域负载均衡,优化全球用户的访问速度和体验。
nginx 负载均衡例子(故障处理)
创建例子项目
- 创建文件夹 webapp1 webapp2 webapp3
mkdir -p webapp1
mkdir -p webapp2
mkdir -p webapp3
- 文件夹内创建 Dockerfile 和 index.html 文件
Mac 使用 touch Dockerfile
命令
ni webapp1/Dockerfile
Mac 使用 touch index.html
命令
ni webapp1/index.html
- Dockerfile 和 index.html 文件内容如下 Dockerfile
# 使用官方的Nginx镜像作为基础镜像
FROM nginx:latest
# 拷贝你的自定义index.html到Nginx的默认静态文件目录
COPY ./index.html /usr/share/nginx/html/index.html
# 暴露端口80
EXPOSE 80
index.html, 这里不同的文件夹 h1 标题不同,用来区分,nginx 负载均衡访问的不同的服务
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<h1>webapp1</h1>
</body>
</html>
- 创建 nginx default.conf 配置文件
default.conf
upstream myapp {
# server http://host.docker.internal:9001;
# server http://host.docker.internal:9002;
server host.docker.internal:9001;
server host.docker.internal:9002;
server host.docker.internal:9003 backup;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://myapp; # 前端项目
}
}
- 创建 Dockerfile 文件
Dockerfile
# 使用官方的Nginx镜像作为基础镜像
FROM nginx:latest
# 拷贝你的自定义default.conf到Nginx的默认default.conf文件目录
COPY ./default.conf /etc/nginx/conf.d/default.conf
# 暴露端口80
EXPOSE 80
构建运行 webapp1
cd webapp1
docker build -t nginx-webapp1 .
docker run --name webapp1 -d -p 9001:80 nginx-webapp1
构建运行 webapp2
cd webapp2
docker build -t nginx-webapp2 .
docker run --name webapp2 -d -p 9002:80 nginx-webapp2
构建运行 webapp3(backup)
cd webapp3
docker build -t nginx-webapp3 .
docker run --name webapp3 -d -p 9003:80 nginx-webapp3
构建运行 myweb
docker build -t nginx-myweb .
docker run --name myweb -d -p 9000:80 nginx-myweb
测试
1. 停止 webapp1
docker stop webapp1
依然可以返回 webapp2
2. 停止 webapp2
docker stop webapp2
依然可以返回 webapp3
3. 重新启动 webapp1 和 webapp2
webapp3 会访问不到,访问的还是 webapp1 或者 webapp2
docker restart webapp1 webapp2