- 前言
- 读者对象
- 如何阅读本书
- 勘误和支持
- 致谢
- 第 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;#等待所有子进程执行完成
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论