
简介
PanguHA是Windows平台的双机热备集群系统,是提供系统高可用性的纯软件解决方案,一般由两个节点构成,分为活动节点及备用节点。通常把正在执行业务的称为活动节点,而作为活动节点的一个备份的则称为备用节点。当活动节点出现问题,导致正在运行的业务不能正常运行时,备用节点此时就会侦测到,并立即接续活动节点来执行业务。从而实现业务的不中断或短暂中断。
运行环境
- 环境 .NET Framework 4.6.1 及以上
软件安装
无需安装,解压后,点击 HA.exe 运行
功能介绍
- IP漂移
IP漂移的作用是实现Web应用、WebApi/Webservice、数据库等的故障转移,除了服务器本机的IP地址外,该软件可以对服务器额外设置一个虚拟IP,然后使用虚拟IP作为代理来访问Web应用或数据库,当双机热备配置完成后,虚拟IP挂载于主节点,当主节点宕机以后,该虚拟IP会漂移到备节点继续提供服务,对客户端来说,这个切换是没有感知的,因为它们还是使用虚拟IP作为代理访问。
主节点出现以下情况将进行IP漂移:
- 宕机
- 网卡异常
- Web服务Url异常(需要配置)
- Windows服务异常(需要配置)
那么该如何操作呢,我们先选一台服务器A作为主节点,在该节点上打开软件,切换到【IP漂移】标签页,然后选择网络适配器(请确保该网卡设置的是静态IP而非自动获取),如下图所示,

目前只支持对一块网卡做虚拟IP,选一个你需要做虚拟IP的那个网段的网卡,然后设置本机IP(假设IP为192.168.56.101)和集群IP(也就是虚拟IP,假设为192.168.56.103,路由器不可设置该IP与Mac绑定),如下图所示,这里需要注意,虚拟IP要和本机IP在同一网段,并且无机器在使用,

然后添加对方IP,如下图所示,

然后点击运行,右下角显示失败重试无需管它,等待稍许时间,可发现左下角显示主节点,这个时候就表明主节点设置成功,虚拟IP已经挂载在当前节点,可通过ipconfig命令查看,对方节点红色是因为对方节点还没运行热备软件,如下图所示

心跳间隔和断联重试设置可以调整主备切换的速度,但也不宜设置得过小,否则会因为一点点网络抖动而切换,频繁切换不是一件好事。【切换】按钮提供了手动切换主备的功能。【停止】按钮将停止心跳检测,不进行主备切换。
配置对方IP后,检测对方热备软件在线情况,异常时发送邮件提醒,防火墙需要开放ICMP和默认端口9999,需要注意使用telnet命令检测时请在两端打开PanguHA软件 如果发现端口已开,软件已开,但是telnet不通,需要检查防火墙是否把HA应用给禁掉了,如下图所示

对方IP颜色对应的含义
- 绿色:正常
- 红色:断联
- 灰色:不监测
正常情况如下图所示

添加本机Url可以对本机的Web服务进行检测,如果发现Web服务的状态码不是200的时候,即服务出现异常时(30s内重试3次),如果在主节点上,则进行切换并邮件提醒。如果在备节点上,则进行邮件提醒(防止主节点服务异常没有可用的备节点)。如下图所示

配置windows服务后,主节点发现Windows服务异常会先进行重启(30s内重试3次),重启失败则进行故障转移。如果是备节点,重启失败发送邮件提醒,如下图所示

接着我们来设置备节点服务器B,假设IP为192.168.56.102,大部分操作都和上面类似,我讲一下需要注意的点,首先两台服务器要能互相ping通,然后两边的集群IP设置是相同的,两台服务器处在同一网段,如下图所示

至此,IP漂移设置告一段落,然后我们来测试一下,我们将主节点服务器关闭,观察备节点是否升级为主节点,也就是虚拟IP是否漂移过来,如下图所示,

可以发现,B服务器从备节点变成了主节点,这个时候访问代理IP将会访问B服务器节点,这样就完成了故障转移的功能。
那么该如何设置Web应用呢,如果使用的是IIS,那么先在两台服务器上部署相同的应用,然后将两边的绑定IP都设置为虚拟IP,如下图所示

其他Tomcat等web服务器也是类似的道理,如果绑定虚拟IP导致服务启动失败,绑定0.0.0.0即可。
- 执行管理
执行管理功能是在IP漂移的基础上,对可执行文件exe或Windows服务做切换配置,配置的进程和windows服务只会在主节点上运行,备节点将会关闭配置的进程和windows服务
那么该如何操作呢,假设我们已经配置完成了IP漂移,然后我们要控制WindowsFormsApp1.exe这个程序的切换,我们只要在A,B两台服务器上都对这个程序进行配置即可,如下图所示,

可以看到,配置的进程会在主节点上运行(不小心手动关闭了也会自动启动),在备节点上关闭(不小心启动了也会自动关闭),当主节点A宕机后,备节点B升级为主节点,就会将配置的进程自动开启,这样就实现了进程的切换,windows服务也是同样的配置方法。
- 文件同步
注意事项:该功能谨慎使用于数据库文件的同步!
文件同步功能是在IP漂移功能基础上进行的,因为该软件的定位并非单纯地做文件同步,而是作为文件服务器来使用的,所以也要搭配虚拟IP来使用。在配置之前需要先设置共享文件夹,如下图所示,

保证IP路径可以访问,即A可以访问B的文件夹IP路径,B可以访问A的文件夹IP路径,如下图所示

然后我们将软件切换到【文件同步标签页】,在A服务器上做A->B的同步设置,如下图所示

在B服务器上做B->A的同步设置,如下图所示

然后两边都点击启动,虽然两边都配置了同步路径并启动,但同步任务只会在主节点上运行,当主节点A宕机,备节点B升级为主节点,然后会开启同步任务。文件同步是实时的,右上角的镜像周期是为了防止备节点不小心修改、删除文件,是为了保持备节点的文件始终和主节点一模一样,并非指同步文件需要5分钟延迟。
- Mysql同步(基于数据库)
部署之前请确保两个节点结构和数据完全一致
详见视频教程:
软件可以快速地部署Mysql双主复制,配合IP漂移功能,即可搭建Mysql高可用架构。那么该如何操作呢,我们将软件切换到【Mysql主从】,根据上面的文字提醒,先在A,B两台服务器做相应配置,如下图所示

然后A,B都重启Mysql服务。
然后在A服务器输入相关信息做A主B从的设置,然后点击部署按钮,如下图所示,右下角会提示部署成功,

接着在B服务器上输入相关信息做B主A从的设置,与上面类似,点击部署按钮,有如下成功提示,如下图所示

至此,Mysql双主复制搭建完成,除此之外需要保证mysql.user表内有%账号,这样才能保证虚拟IP可以访问mysql。结合IP漂移功能,可以做服务器级别宕机的双机切换,即主节点A服务器宕机后,备节点B升级为主节点,虚拟IP指向B节点,继续提供mysql服务。
如果在下面填写本机Mysql服务名称并开启健康检测,则可以做数据库应用级别的宕机切换,即主节点A的mysql服务挂了,则备节点B可以检测到,然后做虚拟IP的转移,B升级为主节点,继续提供mysql服务。同时,如果备节点的mysql服务挂了,则会发送邮件提醒。如下图所示


- Mysql/Sqlserver/PostgreSQL数据同步(基于软件)
使用须知:同步机制采用订阅发布合并复制,合并复制要求表拥有主键(复合主键也行),并且会增加辅助字段,所以在业务系统中Insert语句需要指定字段(辅助字段无需指定)。
详见视频教程:
Sqlserver清空备节点数据脚本:
-- 设置目标数据库名称
Use B;
DECLARE @DatabaseName NVARCHAR(128) = N'B';
-- 验证数据库是否存在
IF NOT EXISTS (SELECT 1 FROM sys.databases WHERE name = @DatabaseName)
BEGIN
RAISERROR(N'错误:数据库 "%s" 不存在!', 16, 1, @DatabaseName);
RETURN;
END;
-- 声明变量
DECLARE @SchemaName NVARCHAR(128),
@TableName NVARCHAR(128),
@FullTableName NVARCHAR(255),
@SqlStatement NVARCHAR(MAX);
-- 创建游标获取所有用户表
DECLARE tableCursor CURSOR LOCAL FAST_FORWARD FOR
SELECT
s.name AS SchemaName,
t.name AS TableName
FROM
sys.databases db
INNER JOIN
sys.tables t ON db.name = @DatabaseName
INNER JOIN
sys.schemas s ON t.schema_id = s.schema_id
WHERE
db.name = @DatabaseName
AND t.type = 'U'; -- 只获取用户表
-- 开始处理
OPEN tableCursor;
FETCH NEXT FROM tableCursor INTO @SchemaName, @TableName;
WHILE @@FETCH_STATUS = 0
BEGIN
BEGIN TRY
-- 构造完整表名和SQL语句
SET @FullTableName = QUOTENAME(@SchemaName) + '.' + QUOTENAME(@TableName);
SET @SqlStatement = N'USE ' + QUOTENAME(@DatabaseName) + N';
TRUNCATE TABLE ' + @FullTableName;
-- 执行截断操作
EXEC sp_executesql @SqlStatement;
PRINT N'成功截断表: ' + @FullTableName;
END TRY
BEGIN CATCH
PRINT N'错误截断表: ' + @FullTableName + N' | 错误信息: ' + ERROR_MESSAGE();
END CATCH
FETCH NEXT FROM tableCursor INTO @SchemaName, @TableName;
END;
-- 清理资源
CLOSE tableCursor;
DEALLOCATE tableCursor;
PRINT N'操作完成!请检查输出信息确认结果。';
PostgreSQL清空备节点数据脚本:
DO $$
DECLARE
table_name TEXT;
BEGIN
-- 获取所有用户表
FOR table_name IN
SELECT tablename
FROM pg_tables
WHERE schemaname = 'public'
LOOP
-- 清空表并重置序列
EXECUTE 'TRUNCATE TABLE ' || quote_ident(table_name) || ' RESTART IDENTITY CASCADE';
RAISE NOTICE '已清空表: %', table_name;
END LOOP;
END
$$;
Sqlserver自动创建主键脚本(遍历某个库所有表,1.如果有主键则跳过。2.如果有自增列却没有主键,则将自增列设置为主键。3.如果没有自增列也没有主键,则自动创建Bigint类型的自增主键):
DECLARE @DatabaseName NVARCHAR(128) = N'AA-1' -- 替换为你的数据库名称
-- 切换到目标数据库
USE [AA-1] -- 这里也需要替换为实际的数据库名称
DECLARE @TableSchema NVARCHAR(128)
DECLARE @TableName NVARCHAR(128)
DECLARE @ColumnName NVARCHAR(128)
DECLARE @Sql NVARCHAR(MAX)
DECLARE @PKName NVARCHAR(128)
-- 创建游标遍历所有用户表
DECLARE table_cursor CURSOR FOR
SELECT
TABLE_SCHEMA,
TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND TABLE_CATALOG = @DatabaseName
OPEN table_cursor
FETCH NEXT FROM table_cursor INTO @TableSchema, @TableName
WHILE @@FETCH_STATUS = 0
BEGIN
-- 检查表是否有主键
IF NOT EXISTS (
SELECT 1
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu
ON tc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME
WHERE tc.CONSTRAINT_TYPE = 'PRIMARY KEY'
AND tc.TABLE_SCHEMA = @TableSchema
AND tc.TABLE_NAME = @TableName
AND tc.TABLE_CATALOG = @DatabaseName
)
BEGIN
-- 检查表是否有自增列
IF EXISTS (
SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @TableSchema
AND TABLE_NAME = @TableName
AND TABLE_CATALOG = @DatabaseName
AND COLUMNPROPERTY(
OBJECT_ID(QUOTENAME(@TableSchema) + '.' + QUOTENAME(@TableName)),
COLUMN_NAME,
'IsIdentity'
) = 1
)
BEGIN
-- 获取自增列名
SELECT @ColumnName = COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @TableSchema
AND TABLE_NAME = @TableName
AND TABLE_CATALOG = @DatabaseName
AND COLUMNPROPERTY(
OBJECT_ID(QUOTENAME(@TableSchema) + '.' + QUOTENAME(@TableName)),
COLUMN_NAME,
'IsIdentity'
) = 1
-- 设置自增列为主键
SET @PKName = 'PK_' + @TableName
SET @Sql = N'ALTER TABLE ' + QUOTENAME(@TableSchema) + '.' + QUOTENAME(@TableName) +
N' ADD CONSTRAINT ' + QUOTENAME(@PKName) +
N' PRIMARY KEY (' + QUOTENAME(@ColumnName) + N')'
PRINT N'为表 ' + @TableSchema + '.' + @TableName + N' 设置自增列为主键: ' + @Sql
EXEC sp_executesql @Sql
END
ELSE
BEGIN
-- 创建PanguId自增主键
SET @PKName = 'PK_' + @TableName
SET @Sql = N'
IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @Schema
AND TABLE_NAME = @Table
AND COLUMN_NAME = ''PanguId'')
BEGIN
ALTER TABLE ' + QUOTENAME(@TableSchema) + '.' + QUOTENAME(@TableName) +
N' ADD PanguId bigint IDENTITY(1,1) NOT NULL
END
ALTER TABLE ' + QUOTENAME(@TableSchema) + '.' + QUOTENAME(@TableName) +
N' ADD CONSTRAINT ' + QUOTENAME(@PKName) +
N' PRIMARY KEY (PanguId)'
PRINT N'为表 ' + @TableSchema + '.' + @TableName + N' 创建PanguId自增主键'
EXEC sp_executesql @Sql,
N'@Schema NVARCHAR(128), @Table NVARCHAR(128)',
@Schema = @TableSchema, @Table = @TableName
END
END
ELSE
BEGIN
PRINT N'表 ' + @TableSchema + '.' + @TableName + N' 已有主键,跳过处理'
END
FETCH NEXT FROM table_cursor INTO @TableSchema, @TableName
END
CLOSE table_cursor
DEALLOCATE table_cursor
- 邮件提醒
如果需要进行邮件提醒,则需要在【邮件提醒】标签页做相关配置,默认是设置了163的SMTP服务器,也可设置其他邮箱服务器,发件人需要是SMTP服务器所指的邮箱类型,收件人可以是其他邮箱,授权码需要登录163邮箱进行设置,如下图所示

配置完后,可先点击【邮件测试】,确认邮件发送没问题,然后点击【保存配置】,如下图所示

以下情况会进行邮件提醒:
- VIP切换时,会发送邮件提醒
- 在添加对方IP后,主节点会对它们进行监测,对方IP连接异常时会发送邮件提醒(防止主节点宕机没有备节点可以切换)
- 在添加本机Web服务Url后,备节点如果检测到Web服务异常后,会发送邮件提醒(防止主节点Web服务异常没有可用的备节点)
- 在添加本机Windows服务后,备节点如果检测到Windows服务异常,会发送邮件提醒(防止主节点Windows服务异常没有可用的备节点)
- 在开启Mysql健康检测的情况下,备节点断联或同步异常,会发送邮件提醒(防止主节点宕机切换后数据异常)
- Sqlserver数据同步异常停止任务时会发送邮件
邮件格式如下图所示,

关于开机自启动
- 在【IP漂移】点击运行成功后,会保存相关信息,下次打开软件将自动运行
- 在【执行管理】配置后,下次打开将自动运行
- 在【文件同步】配置后,下次打开将自动运行
- 在【mysql主从配置】开启健康检测成功后,会保存mysql设置的相关信息,下次打开软件将自动开启健康检测
- 在【数据同步】添加任务后,下次打开将自动运行
- 将软件设置为快捷方式,然后Win+R输入shell:startup,将快捷方式拖入该目录
- Win+R输入gpedit.msc打开组策略,依次展开计算机配置—>Windows设置—>安全设置—>本地策略—>安全选项—>用户账户控制:以管理员批准模式运行所有管理员,设置为已禁用
- Win+R输入control userpasswords2,取消【要使用本计算机,用户必须输入用户名和密码】
清除配置
删除Config文件夹即可
