我有一个脚本,它知道HOSTNAME
它将在哪个脚本上运行,因为它有一个HOSTNAME
变量来说明这一点,并且它是从外部传递的。我想检查HOSTNAME
位于哪个数据中心,并在此基础上,我将从特定计算机复制文件。
- 如果应用程序服务器
HOSTNAME
位于 PHX,那么它应该从holdermachine.phx.host.com
. - 如果应用程序服务器
HOSTNAME
位于 SLC 中,那么它应该从holdermachine.slc.host.com
. - 如果应用程序服务器
HOSTNAME
位于 LVS 中,那么它应该从holdermachine.lvs.host.com
.
现在,对于故障转移情况,如果任何一个holdermachine
发生故障,那么脚本应该从其他数据中心复制holdermachine
(可以随机选择),但是一旦本地数据中心holdermachine
备份,它应该开始从本地数据中心而不是远程数据中心复制holdermachine
。另外,如果可能的话,请发送一封电子邮件,告知此问题holdermachine
已关闭且没有响应,因此开始从远程复制holdermachine
。
截至目前,下面的脚本只会复制文件HOLDER_LOCATION_phx
,我很困惑如何使上述逻辑工作。
#!/bin/bash
export PRIMARY=/test01/primary # copy PRIMARY_PARTITION into this folder
export SECONDARY=/test02/secondary # copy SECONDARY_PARTITION into this folder
readonly HOLDER_LOCATION_phx=(holdermachine.phx.host.com) # we might have more machines in future
readonly HOLDER_LOCATION_slc=(holdermachine.slc.host.com) # we might have more machines in future
readonly HOLDER_LOCATION_lvs=(holdermachine.lvs.host.com) # we might have more machines in future
export HOLDER_LOCATION_1=${HOLDER_LOCATION_phx[0]}
export HOLDER_LOCATION_2=${HOLDER_LOCATION_slc[0]}
export HOLDER_LOCATION_3=${HOLDER_LOCATION_lvs[0]}
PRIMARY_PARTITION=(550 274 2 546 278) # this will have more file numbers and it is being passed from outisde
SECONDARY_PARTITION=(1643 1103 1372 1096 1369 1568) # this will have more file numbers and it is being passed from outisde
export FILE_LOCATION=/batch/data/pk_snapshot
readonly HOSTNAME=$hostname # this is the hostname on which this script will be running where we are copying the files.
readonly FILE_TIMESTAMP=$file_timestamp
export dir3=$FILE_LOCATION/$FILE_TIMESTAMP
# I need to delete before copying the files.
find "$PRIMARY" -mindepth 1 -delete
find "$SECONDARY" -mindepth 1 -delete
do_Copy() {
el=$1
PRIMSEC=$2
scp david@$HOLDER_LOCATION_1:$dir3/new_weekly_2014_"$el"_200003_5.data $PRIMSEC/. || scp david@$HOLDER_LOCATION_2:$dir3/new_weekly_2014_"$el"_200003_5.data $PRIMSEC/. || scp david@$HOLDER_LOCATION_3:$dir3/new_weekly_2014_"$el"_200003_5.data $PRIMSEC/.
}
export -f do_Copy
# copying 10 files in parallel simultaneously in primary and secondary folder
parallel --retries 10 -j 10 do_Copy {} $PRIMARY ::: "${PRIMARY_PARTITION[@]}" &
parallel --retries 10 -j 10 do_Copy {} $SECONDARY ::: "${SECONDARY_PARTITION[@]}" &
wait
echo "All files copied."
现在我需要做的是——
- 检查是否
HOSTNAME
为PHX、SLC、LVS。然后在此基础上开始从本地数据中心复制 - 但是,如果本地数据中心持有者机器出现故障,则从远程数据中心持有者机器复制并发送有关此问题的电子邮件。此外,如果本地数据中心计算机是备份,则开始从本地数据中心计算机而不是远程数据中心计算机进行复制。
我们的应用程序服务器机器名称将是这样的。我们唯一需要检查的是.phx.
or .slc.
or.lvs.
部分。而且phx
,slc
也没有必要lvs
总是在同一位置,因为有时机器名称有一些额外的内容,然后后面跟着.phx.
or.slc.
或.lvs.
,所以我们需要正确检查它。
appservermachineA.phx.host.com
appservermachineB.slc.host.com
appservermachineC.lvs.host.com
答案1
有几种方法可以相当轻松地拉出零件。例如:foo.bar.baz.code.provider.com
datacenter="$(echo "$HOSTNAME" | rev | cut -d. -f3 | rev)"
如果您的数据中心名称与这样的简单模式不匹配,您可以使用语句case
,并基于完整 shell 模式进行匹配:
case "$HOSTNAME" in
*phx.provider.com) DATACENTER="dc1" ;;
*lax.otherprovider.com) DATACETNER="dc2" ;;
*.weirdness.*) DATACENTER="dc3" ;;
# ⋮
esac
对于您的故障转移案例,您需要决定如何确定计算机已关闭。如果scp
返回非零退出状态,最简单的方法是尝试不同的机器。这就是你正在做的事情||
。
(那里还有其他一些东西 - 例如,我很确定parallel
call 不起作用,因为它适用于命令,而不是 shell 函数)
答案2
根据 @derobert 的回答,你可以这样做:
#!/usr/bin/env bash
primary="/test01/primary" # copy primary_partition into this folder
secondary="/test02/secondary" # copy secondary_partition into this folder
holder_location_phx=("holdermachine.phx.host.com") # we might have more machines in future
holder_location_slc=("holdermachine.slc.host.com") # we might have more machines in future
holder_location_lvs=("holdermachine.lvs.host.com") # we might have more machines in future
primary_partition=(550 274 2 546 278) # this will have more file numbers and it is being passed from outisde
secondary_partition=(1643 1103 1372 1096 1369 1568) # this will have more file numbers and it is being passed from outisde
file_location="/batch/data/pk_snapshot"
file_timestamp="$file_timestamp"
dir3="$file_location"/"$file_timestamp"
# I need to delete before copying the files.
find "$primary" -mindepth 1 -delete
find "$secondary" -mindepth 1 -delete
## Find where we are and choose the primary and alternative
## targets accordingly.
case "$HOSTNAME" in
*phx.host.com)
datacenter=("${holder_location_phx[@]}")
alternative1=("${holder_location_slc[@]}")
alternative2=("${holder_location_lvs[@]}")
;;
*lax.host.com)
datacenter=("${holder_location_lax[@]}")
alternative1=("${holder_location_phx[@]}")
alternative2=("${holder_location_lvs[@]}")
;;
*lvs.host.com)
datacenter=("${holder_location_lvs[@]}")
alternative1=("${holder_location_slc[@]}")
alternative2=("${holder_location_phx[@]}")
;;
*) echo "uknown host, exiting." && exit 1 ;;
# ⋮
esac
do_copy() {
el=$1
primsec=$2
scp david@"${datacenter[0]}":"$dir3"/new_weekly_2014_"$el"_200003_5.data "$primsec"/ || scp david@"${alternative1[0]}":"$dir3"/new_weekly_2014_"$el"_200003_5.data "$primsec"/ || scp david@"${alternative2[0]}":"$dir3"/new_weekly_2014_"$el"_200003_5.data "$primsec"/
}
export -f do_copy
# copying 10 files in parallel simultaneously in primary and secondary folder
parallel --retries 10 -j 10 do_copy {} "$primary" ::: "${primary_partition[@]}" &
parallel --retries 10 -j 10 do_copy {} "$secondary" ::: "${secondary_partition[@]}" &
wait
echo "all files copied."
请注意,我完全不确定您的parallel
电话是否有效。我还修复了您的脚本中的一些其他问题并对其进行了一些简化。自从您提到您稍后可能希望将其扩展到更多服务器以来,我保留了数组结构。请注意,如果这样做,您将需要循环访问数组中存储的服务器名称。目前,我只是使用每个元素中的第一个元素(例如${datacenter[0]}
)。