【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 

实际测试这个操作会导致调度程序不断地在两个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

查看返回结果

【PERL】内网环境使用Killcx关闭指定TCP连接_第1张图片

安装模块

接下来就可以正式开始安装了,首先,我们的环境是无法连接外网的,这就注定没法直接CPAN安装,需要手动把相关的依赖安装上,去官网进行下载:metacpan
【PERL】内网环境使用Killcx关闭指定TCP连接_第2张图片
安装killcx需要以下三个包:
【PERL】内网环境使用Killcx关闭指定TCP连接_第3张图片
依次安装三个模块:

perl Makefile.PL 
make
make install
[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

安装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.
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

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

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

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

关闭连接

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

killcx destip:destport

【PERL】内网环境使用Killcx关闭指定TCP连接_第4张图片
随后,调度程序会抛出异常,跳过接口调用的过程,从而正常启动

你可能感兴趣的:(运维,大数据,perl,tcp/ip,网络)