我有一台 AWS EC2 VM。我想在同一台机器上运行一组 PostgreSQL 服务器。当我在脚本中使用服务器的 IP 地址时,每个脚本几乎需要 5 秒钟。但是当我使用环回地址而不是服务器 IP 时,每个脚本几乎不需要 1 秒钟。
这可能是什么问题?
我在不同的服务器上执行了相同的活动,脚本在 IP 和环回地址上花费的时间几乎相同。
答案1
默认情况下,在 Linux 上,当在服务器本身上配置了 IP 地址时,从系统本身到服务器(公共)IP 地址的流量将不会转到实际 NIC 或通过线路传输出去。
默认情况下,Linux 使用单个网络堆栈,并且所有配置的 IP 地址的通信都将位于 Linux 内核的网络堆栈内存中,即使源 IP 地址和目标 IP 地址与不同的 NIC 相关联。
因此,与该 IP 地址通信时的网络速度应与环回接口相同,并且仅受系统速度的限制,而不受网络上行链路的线速的限制(通常会超过该上行链路的带宽)。
当这些速度存在显著差异时,就会想到一些默认行为的显著例外:
服务器的公共 IP 地址(或您使用的 DNS 名称解析为的任何地址)是不是配置的 IP 地址该系统。
请与 核对ip addr
。- 例如,在许多云部署中,与实例关联的公共 IP 地址是在提供商网络中配置和维护的 NAT 构造,并且该公共 IP 地址未在服务器本身中配置。(这也是允许您使用管理层从一个系统中删除该公共 IP 地址并将其分配给另一个系统的原因。)就您的系统而言,从服务器到该公共 IP 地址的流量不会有本地目的地。它需要先传输,然后外部 NAT 映射才会将其定向回。
- 类似地,主机名/公共 IP 地址可能与负载均衡器/反向代理相关联,并且当应用程序尝试寻址自身时,请求将通过负载均衡器路由回节点(甚至可能是完全不同的节点)。
- 系统可以有策略路由已启用。这可以强制系统将不同 NIC 上的不同 IP 地址之间的流量通过线路发送到外部网络。使用 进行检查
ip rule list
。 - 网络命名空间允许 Linux 内核设置多个网络堆栈,每个堆栈都有自己的 IP 和路由设置。不同网络命名空间之间的流量通常也会在系统本身之外路由,并且比环回接口慢得多。使用
ip netns list
我对 Postgres 不太熟悉,但通常情况下,支持以下服务可以获得最佳性能:unix域套接字除了 TCP/IP 连接之外,还可以使用套接字连接,而不是使用本地主机或外部 IP 地址,因为这样可以省去在 IP 数据包中构建数据的开销。
因此,不要使用外部 IP 地址或本地主机 127.0.0.1 地址,而是启用并连接到 Postgresql 套接字。