背景交代
公司在阿里云上有一个模块叫mrs,一共120台,它是跟云录像有关的,这个服务一直都是云服务器里没有公网但是购买了公网SLB,然后20个为一组配置到一个SLB里,这个SLB是按流量收费的。但是最近到了年末,各种账目审核,领导发现这个SLB的费用太惊人了,这么搞不够挣的。但是实在没办法,因为云录像嘛,肯定流量很大,如图:
纵然流量大,但是开源节流也是必须的,于是领导就责令开发赶快想出一个办法,减少SLB的费用。于是开发们拉上运维就吭哧吭哧的开始算经济账,最后确定每一个云服务器买7M带宽,然后流量全部走公网,把SLB的架构舍弃掉。
但是开发在这个模块V2.0里有一个变化,就是Zookeeper需要读取到每一台设备的外网IP,同时这个外网IP必须跟机器是一一对应的,这样模块才能正常工作。
原来的zookeeper在servermap是长这样的:
1
2
3
4["内网IP"] = {app = "mrs", weight = 100},
["内网IP"] = {app = "mrs", weight = 100},
["内网IP"] = {app = "mrs", weight = 100},
剩下略
而现在开发要求改成这样:
1
2
3
4["内网IP"] = {app = "mrs",mrsReportIp = "对应的外网IP",weight = 100},
["内网IP"] = {app = "mrs",mrsReportIp = "对应的外网IP",weight = 100},
["内网IP"] = {app = "mrs",mrsReportIp = "对应的外网IP",weight = 100},
剩下略
那么这就要把两个文件合并起来了,而且是在合并后做到一对一,不能把IP搭配串了。
准备工作
首先,阿里云的网页控制台是无法做到“包年包月的服务器批量永久升级基础带宽”的,只能通过API实现。那么开启了外网IP之后,服务器就会有一个对应的外网IP地址,然后在控制台里,点击“导出资源列表”,只选择服务器名称
、内网IP
和外网IP
。
然后在生成的excel表格里,剪除掉不需要的服务器以及服务器名称,然后保证“内网IP”在前,“外网IP”在后的样式,而且不要服务器名只保留IP,然后把这个文件复制到linux里,起个名,比如叫IP.txt
,如图:
1
2
3
4
5[root@paas-online-crs-001 tmp]# cat IP.txt
10.161.236.231 3.3.3.3
10.161.235.150 2.2.2.2
10.51.10.182 4.4.4.4
10.117.219.72 1.1.1.1
再把已经使用的zookeeper复制一下,放到一个叫mingdan.txt
的文件里,如图:
1
2
3
4
5[root@paas-online-crs-001 tmp]# cat mingdan.txt
["10.117.219.72"] = {app = "mrs", weight = 100},
["10.161.235.150"] = {app = "mrs", weight = 100},
["10.161.236.231"] = {app = "mrs", weight = 100},
["10.51.10.182"] = {app = "mrs", weight = 100},
脚本思路
我最开始打算用awk
的NR
、FNR
去写,但是发现由于我这个文本的结构太过复杂。awk
对付这样的力不从心,稍不好就把人搞得无法自拔,于是就考虑使用python的字典。
各位都知道,字典里key是不能重复的,而我又不想把这个脚本搞得太复杂,就想在mingdan.txt
里的每一行加上序号,用这个序号去当key,而后面的内网IP就作为value,这样保证一一对应。加序号的方法很多,你可以在vim
状态下:set number
,然后手动复制粘贴。不过我是用的是如下两个命令:
1
2sed -i 's/^[ \t]*//g' mingdan.txt #这一步是添加每一行序号
sed -i 's/\t/ /g' mingdan.txt #添加序号之后,会生成一个ta
然后mingdan.txt
就成了这样:
1
2
3
4
5[root@paas-online-crs-001 tmp]# cat mingdan.txt
1 ["10.117.219.72"] = {app = "mrs", weight = 100},
2 ["10.161.235.150"] = {app = "mrs", weight = 100},
3 ["10.161.236.231"] = {app = "mrs", weight = 100},
4 ["10.51.10.182"] = {app = "mrs", weight = 100},
万事俱备,现在就要把IP.txt
和mingdan.txt
按照相同的内网IP整合成一个文件!
脚本正文
这个脚本是不怕mingdan.txt
和IP.txt
的IP顺序的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#coding=utf-8
import re
fd = {} #先设置一个新的空字典叫fd
#以下都是最后拼字符串用的
aaa = '["'
bbb = '"] = {app = "mrs",mrsReportIp = "'
ccc = '",weight = 100},'
#首先先判断mingdan.txt里是否存在
for l in open('mingdan.txt', 'r'):
ar = re.split(r'[ ""]',l) #做分割,把内网IP切出来
print "ip is :" + ar[2] #确认是否分割出来的是内网IP地址
fd[ar[0]] = ar[2] #把这个内网IP地址当作value,前面的序号就是key
with open('out.txt', 'w') as fw:
for l in open('IP.txt', 'r'):
ar = l.split()
if ar[0] in fd.values(): #如果IP.txt里面的内网IP与字典fd里的value相符合
fw.write(aaa + ar[0] + bbb + ar[1] + ccc) #拼成一个完整的字符串
fw.write('\n') #保存文件
print('文件整合完毕,请查看out.txt的结果!')
执行结果
执行效果输出如下:
1
2
3
4
5
6[root@paas-online-crs-001 tmp]# cat out.txt
["10.117.219.72"] = {app = "mrs",mrsReportIp = "1.1.1.1",weight = 100},
["10.161.235.150"] = {app = "mrs",mrsReportIp = "2.2.2.2",weight = 100},
["10.161.236.231"] = {app = "mrs",mrsReportIp = "3.3.3.3",weight = 100},
["10.51.10.182"] = {app = "mrs",mrsReportIp = "4.4.4.4",weight = 100},
[root@paas-online-crs-001 tmp]#