一、脚本编写规范化的必要性

      脚本编写不当产生的影响,在问题描述中已经有所介绍。此处再对可能会导致HA进程卡住的情况做进一步说明,这种情况,现象是HaDebug 相关命令执行无正常回显,这会导致软件的高可用功能无法正常使用。

      写脚本时,请至少记住以下三个严禁:
严禁在脚本中写死循环语句;
严禁在批处理脚本中调用GUI图形化操作界面(.exe);
严禁写日志追踪打印语句(如ping -t、tail -f)等会导致程序一直不能自然结束的语句。


      请确保脚本是可执行文件,假如不可执行,也会被当成脚本不能自然结束的情况处理,从而导致HA进程异常。








二、高可用切换脚本编写规范

1、Windows

      如果脚本内容中包含需要调用图形化界面的语句,必须使用autoit软件来编写符合其语法规范的脚本并转换为可执行程序(.exe)做为HA切换脚本使用。Autoit软件的用法此处不做详细介绍,如想了解,请戳FAQ:


      假如不使用Autoit软件去编写需要调用图形化程序的脚本,则可能出现脚本在Dos下能正常执行,但放在高可用中却无法正常执行的现象。

      如果脚本内容中包含cd到对应盘符去执行命令的,请注意先切换盘符,确认路径已经正常切换。如下是一个在脚本中正确切换路径的例子:

rem 有盘符切换的,要特别注意路径问题,只有先切换到对应的盘符,cd到其下的路径才能正常切换
E:
cd E:\jiaoben\
rem 执行该路径下需要执行的脚本
start /i file_count.bat


      以下脚本实现监控8080端口是否正常监听。端口监控脚本内容:


@echo off&setlocal enabledelayedexpansion
 
rem 使用result存放命令行的输出结果
 
for /f  %%i in ('netstat -ano ^| find "LIST" ^| find /c "0:8080"') do (
set result=%%i
)
 
rem 如果命令行查询到8080端口的监听,则往文件中写true,否则写false
rem 注意判断条件后要写空格,else前后要写空格,写文件的路径因为有特殊符号因此最好使用双引号引起来
 
if !result! == 1 (
echo true > "C:\Program Files (x86)\info2soft-i2node\scripts\result_of_monit.txt"
) else (
echo false > "C:\Program Files (x86)\info2soft-i2node\scripts\result_of_monit.txt"
)


      假如需要在脚本中调用另一个脚本,请参考如下脚本调用的例子。假如正确编写了脚本但在高可用切换时没有正常执行调用,请尝试将i2node以应用方式运行。

rem 有盘符切换的,要特别注意路径问题,只有先切换到对应的盘符,cd到其下的路径才能正常切换
D:
cd D:\ekp_bak\
rem 有调用脚本,并且是类似java程序,会一直在前台显示的,需要加/i参数
start /i i2tomcat.bat



2、Linux

      Linux系统下,脚本存放路径是/etc/sdata/scripts/,该路径不可更改。注意脚本需要有可执行权限。

      以下脚本实现监控 httpd 进程是否存在。进程监控脚本内容:


#!/bin/sh
    count=`ps -ef|grep http|grep -v grep`
    if [ "$?" != "0" ];then
echo  "false" > /etc/sdata/scripts/result.txt
else
echo "true" > /etc/sdata/scripts/result.txt
fi





注意:
    以上脚本因判断条件不够,仅能判断进程退出的情况。并不能监控进程变成僵尸进程(zombie)的情况。如进程假死的情况也要监控到,还需要继续改善脚本。
    
ps aux | grep srepd | grep -v 'grep'| grep -e 'Z',可以打印僵尸进程列表。需要进行双重判断,来判断进程是否有在正常运行。





      另外,如果需要脚本中调用脚本,则需要注意调用的写法,否则可能会出现执行执行能够执行完,但在高可用中执行却出现不能完整调用的情况。如下是一个脚本中再调用脚本的例子:

#!/usr/bin/env bash
A=1
export A
 
case $1 in
 
        *)
                echo -e "==> 执行第一个脚本调用…\n"
                /test/1.sh
                
                echo -e "==> 等待10秒后执行第二个脚本调用…\n"
                sleep 10
                /test/2.sh ;;
esac




3、自定义脚本编写注意事项

      自定义脚本需注意脚本的输出只能是true 或 false,且不要以追加的方式写入结果文件。也即,请使用 “>”,不要使用追加符号。

      自定义脚本的输出文件路径必须是绝对路径,如果使用相对路径,会出现监控到失败后无法输出false,进而无法自动切换问题。


      自定义脚本和输出文件均需要放置在规定的位置。Windows需要放置在 \i2Soft installation Path\scripts\下。Linux需要放置在 /etc/sdata/scripts/下。

      自定义脚本监控时,添加的脚本文件会定时执行,注意这个脚本执行的时间一定不能大于“间隔时间”* ”最大失败次数“,并且脚本必需有返回。也即:
①脚本必须能在fail时间内(t=间隔时间x最大失败次数)执行完;
②脚本如有调用,每一个被调用的脚本都必须有结束标记,更不能写死循环

      监控结果输出文件中如果写入的是false,会引起切换或者警告,如果文件中写入的为true,则不会有任何改变。

      Windows脚本必须是以.bat或者.cmd为后缀的批处理文件;Linux脚本必须是可执行文件(必须有可执行属性)。
      对于依赖环境变量的程序,比如JAVA,需要在脚本中加入相关程序依赖运行的环境变量;因为HA脚本是独立运行的,不会自动读取所有自定义启停程序的环境依赖变量。



       手动执行脚本可以拉起服务,HA调用脚本不成功,这通常是由于在CMD或shell控制台执行时的环境变量与 HA调用时的环境变量差异导致。这需要人为来更改脚本来实现,因为这样的脚本通过计划任务来调用也存在不成功的可能,脚本具体更改方法如下 。
windows 节点
         复制附件中的update_env.bat脚本,分别为 【start.bat和stop.bat】, 将脚本内容末尾调用的ha_start.bat修改为真实的需要被调用的启动脚本或释放脚本。然后HA的规则中调用的脚本分别为【start.bat和stop.bat】。

Linux 节 点
          更改start.sh以及stop.shl脚本头部,将【#!/bin/bash】更改为【#!/usr/bin/env bash】,注意env和bash之间有空格。 
          在shell控制台执行命令【echo $PATH】,假设输出内容为“/usr/local/bin:/usr/sbin”,将PATH的内容复制,在start.sh和stop.sh脚本第二行加入【PATH=/usr/local/bin:/usr/sbin】,注意,此处只是示例,PATH内容按实际复制的输入。

Linux脚本标准化举例说明:
问题:ha切换收不到脚本停止的信息
 
start.sh
#!/bin/bash

export DISPLAY=:0
systemctl start mariadb
sleep 10
cd /etc/sdata/scripts
nohup ./startServer &

exit

 
改成

 
start.sh
#!/usr/bin/env bash
PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin

export DISPLAY=:0
systemctl start mariadb
sleep 10
cd /etc/sdata/scripts
str=$"\n"
nohup ./startServer  >/dev/null 2>&1 &
sstr=$(echo -e $str)
echo $sstr
exit