• 【PERL】内网环境使用Killcx关闭指定TCP连接


    前言

    近日在生产环境我们要进行调度服务迁移,几天的夜间工作中,多次遇到一个业务逻辑导致的问题:在调度重启的过程中,会通过Yarn的资源接口获取正在运行的任务进行Kill操作,这个操作本身是为了防止调度重启期间有计算任务被遗漏,索性从重启那一刻起,所有状态为运行中、失败的任务都会在随后重启完成后进行提交,因此,在Yarn上要把之前提交的任务都干掉,防止重复;正常来说,这个过程是没有问题的,但是在Yarn上有大量任务运行的时候,资源接口返回值将会是一个很庞大的数据量,这回导致两个可能的问题:

    • 数据大的直接无法返回,超出最大限制
    • 数据虽然能够返回,但是依旧要很长时间
      在这里插入图片描述

    基于此,调度服务会在这个步骤卡住非常长的时间,影响业务。

    正文

    由于本次操作存在一些特殊性,这个任务kill的操作并不是必要的,因此想要尝试对其进行人工的接入,中断这个持续时间过久的操作,并且和开发人员了解相关情况后,得知该操作过程开始后,如果失败,并不会引起主进程的退出,只是会进行异常抛出,因此主要的考虑手段大概是两个方向:

    • 防火墙限制
    • 对已建立的socket连接进行关闭

    尝试防火墙禁止连接

    这是优先采取的方式,具体的操作步骤如下:

    • 等待调度程序启动到进行Yarn资源接口交互步骤;
    • 在Yarn的resourcemanager节点开启防火墙策略;
    iptables -I INPUT -s 1.1.1.1 -ptcp --dport 23140 -j REJECT 
    iptables -I OUTPUT -s 1.1.1.1 -ptcp --dport 23140 -j REJECT 
    
    • 1
    • 2

    实际测试这个操作会导致调度程序不断地在两个RM间反复横跳,尝试连接到一个RM上,而且没有退出或者中断的异常,一直持续下去:

    在这里插入图片描述
    此方法不行;

    尝试关闭已建立TCP连接

    linux本身不提供命令进行tcp连接的关闭,网上你会搜到一堆netstat命令结合kill进行连接关闭的博文,请记住,kill命令会直接干掉进程,而不是只关闭一个连接这么简单,生产环境在不知道命令造成的结果之前,不要轻易结合kill使用;

    经过多方搜索,发现两个工具可以进行TCP连接的关闭,一个是tcpkill,一个是killcx,此处使用的是killcx;

    Killcx的工作原理是使用一个伪造的SeqNum创建一个伪造的SYN包,欺骗远程客户端IP/端口并将其发送到服务器。它将派生一个子进程,该子进程将捕获服务器响应,从ACK包中提取所需值,并使用它们发送一个欺骗的RST包。然后连接将被关闭。

    Killcx安装

    前提条件

    请确定你的服务器可以使用perl并进入对应命令行

    perl -MCPAN -e shell
    
    • 1

    查看返回结果

    在这里插入图片描述

    安装模块

    接下来就可以正式开始安装了,首先,我们的环境是无法连接外网的,这就注定没法直接CPAN安装,需要手动把相关的依赖安装上,去官网进行下载:metacpan
    在这里插入图片描述
    安装killcx需要以下三个包:
    在这里插入图片描述
    依次安装三个模块:

    perl Makefile.PL 
    make
    make install
    
    • 1
    • 2
    • 3
    [root@hostname:/tmp/perl-mod/NetPacket-1.7.2]
    # perl Makefile.PL 
    Checking if your kit is complete...
    Looks good
    Warning: prerequisite Socket 1.87 not found. We have 1.82.
    Writing Makefile for NetPacket
    
    [root@hostname:/tmp/perl-mod/NetPacket-1.7.2]
    # make 
    cp lib/NetPacket/UDP.pm blib/lib/NetPacket/UDP.pm
    cp lib/NetPacket/IPv6.pm blib/lib/NetPacket/IPv6.pm
    cp lib/NetPacket/ICMPv6.pm blib/lib/NetPacket/ICMPv6.pm
    cp lib/NetPacket/IPX.pm blib/lib/NetPacket/IPX.pm
    cp lib/NetPacket/TCP.pm blib/lib/NetPacket/TCP.pm
    cp lib/NetPacket/IGMP.pm blib/lib/NetPacket/IGMP.pm
    cp lib/NetPacket/USBMon.pm blib/lib/NetPacket/USBMon.pm
    cp lib/NetPacket/Ethernet.pm blib/lib/NetPacket/Ethernet.pm
    cp lib/NetPacket.pm blib/lib/NetPacket.pm
    cp lib/NetPacket/ICMP.pm blib/lib/NetPacket/ICMP.pm
    cp lib/NetPacket/ARP.pm blib/lib/NetPacket/ARP.pm
    cp lib/NetPacket/IP.pm blib/lib/NetPacket/IP.pm
    Manifying blib/man3/NetPacket::ICMPv6.3pm
    Manifying blib/man3/NetPacket::IPv6.3pm
    Manifying blib/man3/NetPacket::UDP.3pm
    Manifying blib/man3/NetPacket::IPX.3pm
    Manifying blib/man3/NetPacket::TCP.3pm
    Manifying blib/man3/NetPacket::IGMP.3pm
    Manifying blib/man3/NetPacket::USBMon.3pm
    Manifying blib/man3/NetPacket::Ethernet.3pm
    Manifying blib/man3/NetPacket.3pm
    Manifying blib/man3/NetPacket::ARP.3pm
    Manifying blib/man3/NetPacket::ICMP.3pm
    Manifying blib/man3/NetPacket::IP.3pm
    
    [root@hostname:/tmp/perl-mod/NetPacket-1.7.2]
    # make install
    Installing /usr/local/share/perl5/NetPacket.pm
    Installing /usr/local/share/perl5/NetPacket/UDP.pm
    Installing /usr/local/share/perl5/NetPacket/IP.pm
    Installing /usr/local/share/perl5/NetPacket/USBMon.pm
    Installing /usr/local/share/perl5/NetPacket/Ethernet.pm
    Installing /usr/local/share/perl5/NetPacket/ARP.pm
    Installing /usr/local/share/perl5/NetPacket/ICMP.pm
    Installing /usr/local/share/perl5/NetPacket/IPv6.pm
    Installing /usr/local/share/perl5/NetPacket/ICMPv6.pm
    Installing /usr/local/share/perl5/NetPacket/IPX.pm
    Installing /usr/local/share/perl5/NetPacket/TCP.pm
    Installing /usr/local/share/perl5/NetPacket/IGMP.pm
    Installing /usr/local/share/man/man3/NetPacket::Ethernet.3pm
    Installing /usr/local/share/man/man3/NetPacket.3pm
    Installing /usr/local/share/man/man3/NetPacket::ICMP.3pm
    Installing /usr/local/share/man/man3/NetPacket::IP.3pm
    Installing /usr/local/share/man/man3/NetPacket::USBMon.3pm
    Installing /usr/local/share/man/man3/NetPacket::IPv6.3pm
    Installing /usr/local/share/man/man3/NetPacket::TCP.3pm
    Installing /usr/local/share/man/man3/NetPacket::IGMP.3pm
    Installing /usr/local/share/man/man3/NetPacket::ARP.3pm
    Installing /usr/local/share/man/man3/NetPacket::UDP.3pm
    Installing /usr/local/share/man/man3/NetPacket::ICMPv6.3pm
    Installing /usr/local/share/man/man3/NetPacket::IPX.3pm
    Appending installation info to /usr/lib64/perl5/perllocal.pod
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    安装Net-Pcap时可能会报错:

    looking for -lpcap... no
            - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    You appear to lack the pcap(3) library. 
    
    If it is installed in a non-standard location, please try setting the LIBS
    and INC values on the command line.
    
    Or get the sources and install the pcap library from http://www.tcpdump.org/
    
    If you install the pcap library using a system package, make sure to also
    install the corresponding -devel package, which contains the C headers needed
    to compile this module.
            - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    需要先yum安装perl-Net-Pcap包和libpcap-devel包:

    yum -y install perl-Net-Pcap libpcap-devel
    
    • 1

    随后再次安装模块即可,待三个模块安装好后,就可以使用killcx了,软件包可以从官方源下载:killcx
    在这里插入图片描述

    关闭连接

    接下来我们尝试关闭一个tcp连接:

    killcx destip:destport
    
    • 1

    在这里插入图片描述
    随后,调度程序会抛出异常,跳过接口调用的过程,从而正常启动

  • 相关阅读:
    父域 Cookie实现sso单点登录
    前端Sortable拖拽实现排序
    GaussDB CN服务异常实例分析
    RNN笔记(刘二大人)
    spring service事务传播
    [Android]Jetpack Compose设置颜色
    linux每处理器内存分配
    HTML5+CSS3+JS小实例:打散文字随机浮动特效
    腾讯云轻量级服务器和云服务器什么区别?轻量服务器是干什么用的
    小程序实现人脸识别功能
  • 原文地址:https://blog.csdn.net/Meepoljd/article/details/126348303