如何在本地端口上模拟网络延迟?

Posted

技术标签:

【中文标题】如何在本地端口上模拟网络延迟?【英文标题】:How to simulate network delay on a local port? 【发布时间】:2017-12-09 08:15:11 【问题描述】:

我想看看 HTTP 客户端如何对连接超时做出反应,即有服务器在端口上侦听,但建立连接的过程太慢以至于客户端放弃并返回连接超时。连接不应该被拒绝,也不应该被接受,然后是套接字超时。

到目前为止,我已经尝试通过覆盖ServerSocket 来引入网络延迟,想象我可以写出这样的东西......

public SlowServerSocket extends ServerSocket 
    // (This method doesn't actually exist).
    @Override
    public void processBytesPassedOnByOperatingSystem(byte[] bytes) 
        Thread.sleep(delay);
        // Client has already returned a connection timeout.
        super.processBytesPassedOnByOperatingSystem(bytes);
    

...但是当我达到那个抽象级别时我遇到了死胡同(它似乎隐藏在本机方法中)。我的假服务器接受连接,然后什么也不做,导致套接字超时。

我也在网上寻找解决方案,我从 JMeter 库中找到了SlowSocket,但它似乎用于客户端(而且我认为我无法覆盖客户端,以便它使用SlowSocket)。

有什么建议吗?

【问题讨论】:

注意:我找到了这个答案,***.com/questions/100841/…,它建议连接到不可路由的地址,例如“10.255.255.1”。但是,我不确定它是否是最可靠/便携的解决方案。 可能还值得继承 SecurityManager 并覆盖 checkAccept() 方法以使其休眠,然后调用 System.setSecurityManager(overridenSecurityManager)。想法来自这里:***.com/questions/7800960/… 【参考方案1】:

我想看看 HTTP 客户端如何对连接超时做出反应,即有一个服务器正在侦听一个端口,但是建立连接的过程太慢以至于客户端放弃并返回一个连接超时。

您的要求在术语上体现了矛盾。当对等 host 根本没有响应时,会发生连接超时,通常是因为防火墙。它与服务器应用程序缓慢无关。服务器不会“建立连接”:TCP 堆栈会。

不应拒绝连接

如果有监听过程就不会了,除了下面的情况。

它不应该被接受,然后是套接字超时。

这正是您编写的代码将产生的结果。

然而,并且当且仅当服务器平台不是Windows,还有另一种产生连接超时的方法:让积压队列填满。为此,请让服务器执行所有正常的套接字设置步骤,但根本不调用accept(),并让客户端执行大量连接尝试。但是如果服务器平台是Windows,就会产生连接拒绝。

【讨论】:

所以当“TCP堆栈”(对不起,我对这方面的知识很少)无法连接到目标端口时,连接被拒绝,因为该端口上没有进程监听?当 TCP 数据包甚至没有到达目的地/响应没有及时返回时,连接就会超时? @Pig 如果没有监听进程,或者积压队列已满且服务器平台为Windows,则连接被拒绝。我已经说过了。如果对等方没有及时响应或根本没有响应,则连接超时。我也说过了。【参考方案2】:

我也在网上寻找解决方案,我从 JMeter 库中遇到了 SlowSocket,但它似乎是在客户端使用的(而且我认为我无法覆盖客户端所以它使用的是 SlowSocket)。

您可以使用Sniffy 来模拟网络延迟 - 它与 Java TCP 堆栈无缝集成,并且不需要从应用程序端进行任何更改。见documentation on emulating network issues。

demo.sniffy.io 提供在线演示 - 单击右下角的小部件,转到 “网络连接” 选项卡并设置 延迟 为 1000 毫秒 en.wikipedia.org。刷新浏览器页面,您会看到加载页面需要多花 1 秒时间。 javaagent integration 也可用于非 Web 应用程序。

免责声明:我是Sniffy的作者

【讨论】:

但它会模拟慢速连接阶段吗?如果是,怎么做? TCP 中的连接阶段基本上为第一个数据包增加了额外的往返行程(SYN 和 SYN-ACK 数据包不带应用程序数据;它仅与 ACK 数据包一起发送)。在 Java 应用程序中,无法访问 IP 数据包,因此 Sniffy 使用一些启发式方法来添加延迟,如下所述:sniffy.io/docs/latest/#_emulating_network_issues;在客户端的 Socket.connect() 方法中添加了指定的延迟 这不是我们要求的。他想看看他的现有客户端如何对连接超时做出反应,而你所做的任何事情都不会导致。 @EJP Sniffy 允许测试 现有 客户端如何对网络延迟做出反应,而无需修改它们。您只需将 -javaagent:sniffy... 添加到命令行参数。在给定延迟后模拟超时异常也是可能的。 所以,再次告诉我们它是如何产生连接超时的。当我之前两次问这个问题时,你在上面给出的答案是不充分的。延迟 client 不会导致连接超时。只有服务器或网络可以做到这一点。

以上是关于如何在本地端口上模拟网络延迟?的主要内容,如果未能解决你的问题,请参考以下文章

混沌工程之ChaosMesh使用之模拟POD网络延迟

混沌工程之ChaosMesh使用之模拟POD网络延迟

弱网测试:使用netem模拟网络延迟丢包损坏重复和乱序等网络问题

linux 下使用 tc 模拟网络延迟和丢包

linux 下使用 tc 模拟网络延迟和丢包

linux 下使用 tc 模拟网络延迟和丢包