- 前言
- 读者对象
- 如何阅读本书
- 勘误和支持
- 致谢
- 第 1 篇 高性能网站构建
- 第 1 章 深入理解 DNS 原理与部署 BIND
- 第 2 章 全面解析 CDN 技术与实战
- 第 3 章 负载均衡和高可用技术
- 第 4 章 配置及调优 LVS
- 第 5 章 使用 HAProxy 实现 4 层和 7 层代理
- 第 6 章 实践 Nginx 的反向代理和负载均衡
- 第 7 章 部署商业负载均衡设备 NetScaler
- 第 8 章 配置高性能网站
- 第 9 章 优化 MySQL 数据库
- 第 2 篇 服务器安全和监控
- 第 10 章 构建企业级虚拟专用网络
- 第 11 章 实施 Linux 系统安全策略与入侵检测
- 第 12 章 实践 Zabbix 自定义模板技术
- 第 13 章 服务器硬件监控
- 第 3 篇 网络分析技术
- 第 14 章 使用 tcpdump 与 Wireshark 解决疑难问题
- 第 15 章 分析与解决运营商劫持问题
- 第 16 章 深度实践 iptables
- 第 4 篇 运维自动化和游戏运维
- 第 17 章 使用 Kickstart 完成批量系统安装
- 第 18 章 利用 Perl 编程实施高效运维
- 第 19 章 精通 Ansible 实现运维自动化
- 第 20 章 掌握端游运维的技术要点
- 第 21 章 精通手游运维的架构体系
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
最佳实践 87:多进程编程技巧
在本章的前言部分,提到使用 Perl 可以进行多进程编程。如果一个任务涉及大量不同的操作对象,例如批量下载很多 URL 的文件、批量在不同的服务器执行相同的指令等,都可以使用多进程编程。使用多进程编程,可以得到以下好处。
- 最大化服务器执行效率。多进程编程,可以充分利用服务器多 CPU 的计算能力,提高并发执行的数量,减少任务执行的时间。
- 某个子任务超时或者失败不会导致整个任务时间增加。因为使用了多进程,每个进程单独处理一个子任务,这样可以做到隔离子任务间的相互影响,某个子任务的超时和失败,不会影响其他子任务的执行等待时间。
让我们来看一个基本的多进程编程的实例,在该实例中,我们创建 3 个子进程。
#!/u sr/bin/perl
use strict;
use warnings;
print "Process ID: $$";
my $maxforks = 3;
my $forks = 0;
for ( 1 .. $maxforks ) {
my $pid = fork;#父进程调用 fork 函数,函数参考 perldoc -f fork
if ( not defined $pid ) { #fork 返回 undef,则说明创建子进程失败,例如在超过了系统最大进程数等的情况下
warn 'Could not fork';
next;
}
if ($pid) { #fork 对父进程的返回值是子进程的进程号(pid)
$forks++;
print
"In the parent process PID ($$), Child pid: $pid Num of fork child processes: $forks \n";
}
else {#进入子进程执行代码
print "In the child process PID ($$) \n";
sleep 1;
print "Child ($$) exiting \n";
exit;
}
}
for ( 1 .. $forks ) {
my $pid = wait();#wait 函数返回值为已完成执行的子进程的进程号(pid),函数参考 perldoc -f wait
print "Parent saw $pid exiting \n";
}
print "Parent ($$) ending \n";
在上面的一个案例中,使用 fork 进行子进程创建,然后在程序内部进行了子进程的管理(创建数量限制、子进程退出状态管理等)。可以看到,这样操作起来比较繁杂。幸运的是,在 Perl 中,通过 CPAN,可以下载和使用 Parallel::ForkManager 模块进行多进程自动化管理。在下面一个例子中,使用该模块同时启动 30 个子进程登录服务器拷贝指定文件保存到对应的指定文件夹中。
#!perl
use strict;
use warnings;
use Parallel::ForkManager;
sub convert {
my ($in) = @_;
$in =~ s/\//./g;
$in =~ s/\:/../g;
return $in;
}
my $xiv = $ARGV[0];
my $inputfile = 'hosts_' . $xiv . '_all.dat';
open( FILEIN, '<', $inputfile ) or die $!;
my $pm = Parallel::ForkManager->new(30); #指定同时执行的子进程的数量上限是 30
while (<FILEIN>) {
#输入的文件内容格式如下
#10.18.33.130 xiv3-nj-p001 180.96.46.70
chomp;
my $host;
if (/^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})\s+(.*)/) {
$host = $1;
}
$pm->start and next;#创建的子进程进入执行周期
my @files = (
'/bin/iptables.sh',
'/etc/fstab',
'/etc/group',
'/etc/hosts',
'/etc/hosts.allow',
'/etc/modprobe.conf',
'/etc/ntp.conf',
'/etc/passwd',
'/etc/rc.local',
'/etc/rc.d/rc.local',
'/etc/shadow',
'/etc/snmp/snmpd.conf',
'/etc/sudoers',
'/etc/sysconfig/network',
'/etc/sysconfig/network-scripts/ifcfg-bondeth1',
'/etc/sysconfig/network-scripts/ifcfg-eth0',
'/etc/sysconfig/network-scripts/ifcfg-eth1',
'/etc/sysconfig/network-scripts/ifcfg-lo:0',
'/etc/sysconfig/static-routes',
'/etc/sysctl.conf',
'/etc/yum.conf',
'/etc/yum.repos.d/CentOS-Base.repo',
'/root/.bashrc',
'/root/.ssh/authorized_keys',
'/root/iptables_min_forFF14.sh',
'/tmp/__pcheck.chkconfig3on.txt',
'/tmp/__pcheck.rpm.txt',
'/tmp/__pcheck.sysctl-A.txt'
);
system("ssh root\@$host 'rpm -qa |sort > /tmp/__pcheck.rpm.txt'");
system("ssh root\@$host 'sysctl -A |sort > /tmp/__pcheck.sysctl-A.txt'");
system("ssh root\@$host 'chkconfig --list|grep '3:on'|sort > /tmp/__pcheck.chkconfig3on.txt'");
foreach my $file (@files) {
my $converted = &convert($file);
system("mkdir -p /tmp/checklog/$xiv/$converted/");
system("scp root\@$host:$file /tmp/checklog/$xiv/$converted/$host.txt");
}
$pm->finish;#结束子进程执行
}
close(FILEIN); #父进程关闭文件描述符
$pm->wait_all_children;#等待所有子进程执行完成
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论