使用 Nginx 反向代理 Docker 内部容器 空闲链接超时分析及解决

前言

随着容器化技术的普及,Docker 已经成为了开发和运维的常用工具。在常见的 Docker 应用场景中,经常使用到反向代理来对内部的多个容器进行统一访问。而 Nginx 作为一款高性能的反向代理服务器,成为了众多选择之一。然而,在实际的应用中,我们会发现 Nginx 和 Docker 结合后,会遇到一些问题。本文就是希望分享一下使用 Nginx 反向代理 Docker 内部容器时,如何避免空闲链接超时的问题。

背景

在使用 Docker 部署多个容器时,我们经常会使用 Nginx 进行反向代理,统一对外服务。而这个过程中,我们会发现有一些问题:

  1. 空闲链接超时
  2. 无法获取真实 IP 地址
  3. 无法加密连接

本文主要解决空闲链接超时的问题。

空闲链接超时

在 Nginx 中,有一个参数 proxy_read_timeout,默认值是 60 秒。如果在 60 秒内没有从后端服务器接收到任何数据,就会报错 "upstream timed out (110: Connection timed out) while reading response header from upstream",意思就是超时了。

如果后端服务器返回的内容很慢,在默认的 timeout 内没有返回完,会导致 Nginx 在返回的数据中出现一些缺失或异常比如一些字体或图片加载异常等视觉上的问题。

但是,如果我们将 proxy_read_timeout 改得越小,那么就会越容易因为延迟或者网络问题而出现错误,而我们实际上又不能一味地降低 timeout。这时,就需要换个思路,从如何保持背后的服务长时间活跃的角度考虑问题。

空闲链接超时原因

空闲链接超时是因为反向代理服务器在一段时间内没有接收到任何响应,导致连接中断。这种情况通常发生在后端容器在长时间闲置后,一段时间内没有任何响应。

这与 Docker 容器的内部网络有关。容器之间的网络是虚拟的,从容器内部看,容器之间的通信是直接的,但从宿主机器的角度看,docker0 接口为多个容器提供了虚拟的网关 IP,同时也给容器外部的主机提供了一个访问容器的接入点。和容器外部的世界保持联通,依赖于 Docker 的路由机制,该机制是基于 IPtables 实现的。由于容器数量变化多端,可以想象这条路由规则列表会非常长。当然这些路由规则也是可以重新加载的,而流量转发、负载均衡都是在路由阶段实现的,联通已经建立,容器之间的通信具备了始终出现的条件。然而这个过程不是实时的,可能会出现短暂的不可达性。

解决方案

为了解决这个问题,我们需要让 Nginx 定期往后端容器服务器发送一些请求,保持连接处于活跃状态,避免空闲连接超时。

方案一:定时 Nginx 请求

可以在 Nginx 的配置文件中通过 HTTP 模块实现定期向后端容器服务器发送一个类似心跳的请求,保持连接处于活跃状态。

示例代码:

---- -
    -------- ------- -
        ------ ---------------
    -
    
    ------ -
        ------ ---
        ----------- ------------
        -------- - -
            ---------- ---------------
            ---------------- ---- ------
            ---------------- --------- -------------
            ---------------- --------------- ---------------------------

            - ------------
            ------------------ ----
            ---------------- ---------- ---
            ---------------- ---- ------
            ------------------------- ----
            --------------- ----
            ------------------ -------------
            ---------------------- ---
            ----------- ----
            ------------------ -----
            ------------------ -----
            ------------ -----

            -------------- -------------
            - ------------ ----
            - ----- ---- -----------
            ----------------- -----
        -
    -
-

这样就可以避免空闲连接超时问题,但有一个缺点是,在请求过程中会占用额外的带宽。

方案二:使用 TCP Keepalive

Nginx 提供了一种更优雅的方法来解决这个问题,就是使用 TCP Keepalive。TCP Keepalive 是 TCP 协议中的一种机制,用于检测长时间没有数据交换的连接,发送一个空闲探测包以确定连接是否仍然保持活动状态。

首先在 Nginx 配置文件中开启 keepalive 模块:

---- -
    ----------------- ---
    ------------------ -------
    ---

其中 keepalive_timeout 参数设置的是空闲连接的时间,我们可以把这个值设得足够大,比如 300 秒。

在服务端也需要进行相应的配置,来定期发送 TCP Keepalive 空闲探测包。在 CentOS 上配置 TCP Keepalive 如下:

- ---- ---- - -------------------------------------
- ---- - - --------------------------------------
- ---- - - ---------------------------------------

这样,Nginx 客户端和服务端之间的空闲连接就可以被保持活跃了。

总结

本文介绍了如何使用 Nginx 反向代理 Docker 内部容器时,避免空闲链接超时的问题。我们可以通过定时发送请求或使用 TCP Keepalive 机制来保持连接处于活跃状态,避免因空闲链接超时而出现的错误。

在实际的生产环境中,我们需要选择合适的方法来解决问题,以便提高服务的可靠性和稳定性。同时,还需要针对不同的问题进行深入的分析和解决方案的优化,才能取得更好的效果。

来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/64c8e7a15ad90b6d04150507


猜你喜欢

  • RESTful API 中的数据排序技巧

    前言 在 Web 开发中,RESTful API 已成为一种广泛使用的服务端架构风格,它具有简单、可扩展、可维护等诸多优点。而在 RESTful API 中,数据的排序也是一个非常重要的功能。

    1 年前
  • 深究 ES8 中的 async generators 和 iterators 优点

    ES8 中的 async generators 和 iterators 提供了方便的处理异步数据流的方法。在前端开发中,这种技术可以用于处理图形界面上的事件响应,网络数据传输等方面。

    1 年前
  • Webpack 优化之使用 HappyPack 加速打包

    前言 随着前端技术的快速发展,项目代码量和复杂度不断增加,导致前端构建工具 webpack 的打包时间变得越来越长。 在我们的日常开发中,时间也是非常宝贵的,长时间的等待会影响我们的工作效率。

    1 年前
  • 使用 Chai 进行单元测试时如何忽略特定警告信息

    在进行单元测试时,我们通常需要根据测试用例的预期结果来断言函数是否正确地执行了相应的操作。这就是测试驱动开发(TDD)的基本思想。而 Chai 是 JavaScript 开发中常用的一个断言库,它可以...

    1 年前
  • Axios 拦截器在 SPA 应用中的应用详解

    在现代 Web 开发中,前端框架和库随处可见,其中 SPA(Single Page Application)应用使用广泛。在大型 SPA 应用中,我们通常需要使用 Ajax 技术进行前端和后端的数据交...

    1 年前
  • 无障碍系统的安全测试与验证

    前言 在当今数字化时代,越来越多的人已适应了数字产品的便捷性和使用体验,但是一部分人却无法享受到这些便利,比如那些行动不便、视力欠佳、听力有损或认知受限等人群。为了让所有人都能够自如地使用数字化产品,...

    1 年前
  • Serverless 架构的自动化测试与 CI/CD

    随着云计算的快速发展,Serverless 架构也越来越受到开发者的重视。Serverless 架构的最大优势是让开发者专注业务逻辑,而无需关注底层基础设施的运维,从而提高开发效率。

    1 年前
  • Redux 中的状态更新与最新技术实践

    在前端开发中,状态管理是非常重要的一环。Redux 是一个流行的 JavaScript 状态管理库,它提供了一种可预测的状态管理模式,使得开发者可以更轻松地维护复杂的应用程序状态。

    1 年前
  • RxJS 的路由模式在 Angular 编程中的应用

    随着前端应用的复杂化,前端路由成为开发者应当掌握的知识点之一。Angular 作为一款流行的前端框架,提供了一个强大的路由系统,但是在实际开发中,开发者往往需要处理的问题并不仅限于简单的路由跳转。

    1 年前
  • Redis 数据结构的内存优化技巧

    Redis 是目前最流行的 NoSQL 数据库之一,在实际应用中往往用于缓存、队列等高性能应用场景中。在使用 Redis 的过程中,我们经常会遇到一些内存占用的问题,如何优化 Redis 的内存使用成...

    1 年前
  • PWA 的离线与 Manifest 概念浅析及使用案例分享

    什么是 PWA? PWA 全称为“Progressive Web App”,中文名为“渐进式网络应用程序”。简单理解,PWA 就是一种使用新技术使传统网站具有类似原生应用的能力和用户体验的应用程序,可...

    1 年前
  • Fastify 框架与 NestJS 的对比优势分析

    前端开发中,框架选择一直是个热点话题。Fastify 和 NestJS 都是目前比较流行的 JavaScript 框架,本文将对这两个框架进行对比分析,帮助开发者快速了解选用何种框架更适合自己的项目。

    1 年前
  • 如何设计自定义元素的 API

    引言 在 Web 开发中,自定义元素是 DOM 中的一部分,其允许我们创建属于我们自己的 HTML 标签,并为这些标签自定义属性和方法。通常情况下,我们往往使用自定义元素来扩展标准的 HTML 元素,...

    1 年前
  • 使用 Express.js 和 Socket.io 构建实时 Web 应用

    前言 在现代化的 Web 应用中,实时性是一个非常重要的特性。例如,现代的聊天应用和协作应用都需要实时更新内容,以提供更多的用户体验。为了实现实时性,我们通常使用 WebSocket 技术,但是在开发...

    1 年前
  • Kubernetes v1.8:PVC vs CSI 的可扩展性和持久性

    前言 Kubernetes 是一款支持自动部署,扩缩容和管理容器化应用程序的开源平台,已成为最受欢迎的容器编排引擎之一。在 Kubernetes 中,存储是一个非常重要的问题。

    1 年前
  • Koa 框架中 post 请求 body 解析的方法指南

    Koa 是一个轻量级的 Node.js Web 框架,由 Express 的原班人马打造而来。在 Koa 中,我们可以使用一个中间件 koa-bodyparser 来解析 POST 请求的 body ...

    1 年前
  • Angular 中如何实现图表展示

    在 Web 应用开发中,图表展示是非常重要的一项功能。在 Angular 中,有很多优秀的图表库可供选择,如 ngx-charts、angular-highcharts、ng2-charts 等等。

    1 年前
  • 如何在 Deno 中使用 TypeScript 进行开发

    什么是 Deno? Deno 是一个用 TypeScript 和 Rust 编写的新型 JavaScript 和 TypeScript 运行时环境,它由 Node.js 的创始人 Ryan Dahl ...

    1 年前
  • 使用 CSS Flexbox 布局实现多栏布局

    在前端开发中,实现多栏布局是经常遇到的问题。而使用 CSS Flexbox 布局,可以轻松实现多栏布局。本文将介绍使用 CSS Flexbox 布局实现多栏布局的方法,包括概念、属性和示例代码等。

    1 年前
  • ES6 中的 Promise 链式调用使用详解

    ES6 中的 Promise 链式调用使用详解 Promise 是一种在 JavaScript 中处理异步操作的方式。在 ES6 中,Promise 得到了很好的支持,使得我们能够更加便捷地管理异步操...

    1 年前

相关推荐

    暂无文章