前言
生产环境下我们部署和使用IRiS引擎,往往采用其主备镜像模式,虽然此架构简单但是往往我们需要持续在电脑前点击或者操作1到2小时,如果中间有个环节出现了问题有时我们可能需要部署一天.
接下来我分享的是IRIS自带的一个功能帮助我们部署---manifest-安装清单。他的主要使用方式是提前通过配置约定好我们期望的安装设置,在安装的过程中由IRIS程序直接执行脚本,简化IRIS集群的部署,减少运维人员的操作步骤,让我们有更多的精力放在实际项目和业务上。
1 简介
%Installer 实用程序允许您定义描述和配置特定 InterSystems IRIS 配置的安装清单,而不是分步安装过程。为此,我们需要创建一个类,其中包含描述所需配置的 XData 块,使用包含通常在安装期间提供的信息(超级服务器端口、操作系统等)的变量。我们还可以在类中包含一个使用 XData 块生成代码以配置实例的方法。本文提供了安装清单的示例,您可以复制和粘贴这个示例尝试使用。
定义清单后,可以在安装期间、从终端会话或代码调用它。注意:清单必须在 %SYS 命名空间中运行。
2 Manifest的最终成品
此成品展示的是一个一键安装主、备、仲裁的机器命令,此方法的使用可以便捷快速的安装主备环境,其基本每一行都有注释其说明:
Include %occInclude
/// Classname: App.MirrorInstall <br/>
/// Summary: 镜像安装清单 <br/>
/// Version: 1.0 <br/>
/// Date: 2023年09月13日 14:23:24 <br/>
/// Author: 王喆 <br/>
Class App.MirrorInstall
{
XData Install [ XMLNamespace = INSTALLER ]
{
<Manifest>
<!-- 镜像配置 -->
<Log Text="镜像名称 " Level="0"/>
<Var Name="MirrorName" Value="MIRRORSET" />
<Log Text=" 虚拟IP " Level="0"/>
<Var Name="VituralIP" Value="192.168.98.110/24" />
<Log Text="仲裁机IP " Level="0"/>
<Var Name="ArbiterNode" Value = "192.168.98.103|2188" />
<Log Text="网卡名称 " Level="0"/>
<Var Name="PrimaryNetworkAdapter" Value = "Ethernet0" />
<Log Text="主机IP " Level="0"/>
<Var Name="MasterIP" Value = "192.168.98.101" />
<Log Text="主机端口 " Level="0"/>
<Var Name="MasterPort" Value = "2188" />
<Log Text="主机名称 " Level="0"/>
<Var Name="MasterName" Value = "IRIS01" />
<Log Text="备机网卡名称 " Level="0"/>
<Var Name="BackupNetworkAdapter" Value = "Ethernet0" />
<Log Text="备机IP " Level="0"/>
<Var Name="BackupIP" Value = "192.168.98.102" />
<Log Text="备机名称 " Level="0"/>
<Var Name="BackupName" Value = "IRIS02" />
<Log Text="实例名称 " Level="0"/>
<Var Name="InstanceName" Value = "IRISHEALTH" />
<Log Text="镜像模式: 主机1或者备机0 " Level="0"/>
<!-- <Var Name="MirrorModel" Value="1" />-->
<!-- 安装文件所在的目录 -->
<!-- <Var Name="INSTALLERDIR" Value = "D:\deploy" /> -->
<!-- 实例所在的安装目录 -->
<!-- <Var Name="PRODDIR" Value = "C:\InterSystems\IRISHealth" /> -->
<!-- 激活 -->
<!-- 通用内存堆的大小。 -->
<SystemSetting Name="Config.config.gmheap" Value="1048576"/>
<!-- 通用内存堆的大小。 -->
<SystemSetting Name="Config.config.locksiz" Value="134217728"/>
<!-- 错误日志中的最大条目数。 -->
<SystemSetting Name="Config.config.errlog" Value="10000"/>
<!-- 用于缓存例程缓冲区的共享内存大小。 -->
<SystemSetting Name="Config.config.routines" Value="256"/>
<!-- 为 8KB 数据库缓存分配的内存 一般为内存的一半 -->
<SystemSetting Name="Config.config.globals8kb" Value="1000"/>
<!-- 写入图像日志文件目录。 -->
<SystemSetting Name="Config.config.wijdir" Value="D:/cache/wij"/>
<!-- 日志文件的主要位置。 -->
<SystemSetting Name="Config.Journal.CurrentDirectory" Value="E:/cache/journal"/>
<!-- 日志文件的备用位置。 -->
<SystemSetting Name="Config.Journal.AlternateDirectory" Value="D:/cache/journal"/>
<!-- Caché 清除已完成日志文件之前的天数 -->
<SystemSetting Name="Config.Journal.DaysBeforePurge" Value="3"/>
<!-- 在此连续备份数后 -->
<SystemSetting Name="Config.Journal.BackupsBeforePurge" Value="3"/>
<!-- 最大IRISTempSizeAtStart -->
<SystemSetting Name="Config.Startup.MaxIRISTempSizeAtStart" Value="10"/>
<IfDef Var="INSTALLERDIR">
<Log Text=" 激活 " Level="0"/>
<Invoke Class="App.MirrorInstall" Method="ConfigureInstance" CheckStatus="0">
<Arg Value="${INSTALLERDIR},${PRODDIR}"/>
</Invoke>
</IfDef>
<!-- 创建命名空间 -->
<Log Text="BKLINIK 命名空间存在与否判断 " Level="0"/>
<If Condition='(##class(Config.Namespaces).Exists("BKLINIK")=0)'>
<Log Text="不存在开始创建 " Level="0"/>
<Namespace Name="BKLINIK" Create="yes" Code="BKLINIKAPP" Ensemble="1" Data="BKLINIKMSG">
<Configuration>
<!-- 消息的目录 -->
<Database Name="BKLINIKMSG" Dir="D:/DB/BKLINIKMSG" Create="yes"/>
<!-- 代码的目录 -->
<Database Name="BKLINIKAPP" Dir="D:/DB/BKLINIKAPP" Create="yes"/>
<!-- 配置映射 -->
<ClassMapping Package="HS" From="HSLIB"/>
<ClassMapping Package="HSMOD" From="HSLIB"/>
<ClassMapping Package="SchemaMap" From="HSLIB"/>
<RoutineMapping Routines="HS.*" From="HSLIB" />
<RoutineMapping Routines="HSMOD.*" Type="INC" From="HSLIB" />
<RoutineMapping Routines="HSMOD.*" From="HSLIB" />
<RoutineMapping Routines="SchemaMap*" Type="INC" From="HSLIB" />
<GlobalMapping Global="%SYS" From="IRISSYS" />
<GlobalMapping Global="%SYS("HealthShare")" From="HSSYS"/>
<GlobalMapping Global="EnsHL7.Annotation("HealthShare_2.5")" From="HSLIB" />
<GlobalMapping Global="EnsHL7.Description("HealthShare_2.5")" From="HSLIB" />
<GlobalMapping Global="EnsHL7.Schema("HealthShare_2.5")" From="HSLIB" />
<GlobalMapping Global="IRIS.Msg("HS")" From="HSLIB" />
<GlobalMapping Global="IRIS.Msg("HSErr")" From="HSLIB" />
<GlobalMapping Global="IRIS.Msg("HSFHIRErr")" From="HSLIB" />
<GlobalMapping Global="IRIS.Msg("HSFHIRXErr")" From="HSLIB" />
<GlobalMapping Global="IRIS.MsgNames("HS")" From="HSLIB" />
<GlobalMapping Global="IRIS.MsgNames("HSErr")" From="HSLIB" />
<GlobalMapping Global="IRIS.MsgNames("HSFHIRErr")" From="HSLIB" />
<GlobalMapping Global="IRIS.MsgNames("HSFHIRXErr")" From="HSLIB" />
</Configuration>
</Namespace>
<Log Text="创建命名空间 BKLINIK 结束" Level="0"/>
<Log Text="Production启动" Level="0"/>
<Namespace Name="BKLINIK" Create="no">
<Log Text=" 设置web应用程序 " Level="0"/>
<CSPApplication
Url="/csp/bklinik"
Directory="${CSPDIR}bklinik"
AuthenticationMethods="64"
IsNamespaceDefault="true"
Grant="%ALL" />
<CSPApplication
Url="/csp/bklinik/services"
Description=""
Directory="${CSPDIR}bklinik\services"
Resource=""
Grant="%ALL"
Recurse="1"
LoginClass=""
CookiePath="/csp/bklinik/services"
AuthenticationMethods="64"/>
<Log Text=" 导入代码 " Level="0"/>
<!-- 如果设置了 SourceDir 就加载其中的文件 -->
<!-- <IfDef Var="SourceDir"> -->
<!-- <Log Text="SourceDir已定义-从脱机安装 ${SourceDir}" Level="0"/>-->
<Import File="${INSTALLERDIR}\distr\"/>
<!-- 设置命名空间的Production自动启动 前提得有这个-->
<!-- <Production Name="BKLINIKPKG.FoundationProduction" AutoStart="1" /> -->
<!-- </IfDef> -->
<Log Text=" 导入代码成功 " Level="0"/>
</Namespace>
</If>
<Log Text=" 镜像 " Level="0"/>
<IfDef Var="MirrorModel">
<Log Text="Master已定义-从脱机安装 ${主机}" Level="0"/>
<If Condition='(${MirrorModel}=1)' >
<!-- 创建主镜像 -->
<Log Text=" 创建主镜像 " Level="0"/>
<Invoke Class="App.MirrorInstall" Method="CreateMirror" CheckStatus="0">
<Arg Value="${MirrorName},${VituralIP},${ArbiterNode},${PrimaryNetworkAdapter},${MasterIP},${MasterName}"/>
</Invoke>
</If>
<If Condition='(${MirrorModel}=0)' >
<!-- 加入镜像 -->
<Log Text=" 加入镜像 " Level="0"/>
<Invoke Class="App.MirrorInstall" Method="JoinMirror" CheckStatus="0">
<Arg Value="${MirrorName},${MasterName},${MasterIP},${MasterPort},${BackupNetworkAdapter},${BackupIP},${InstanceName}"/>
</Invoke>
</If>
</IfDef>
</Manifest>
}
/// MethodName: setup <br>
/// Summary: 入口点方法,您需要调用,在类编译时,它从清单生成CachéObjectScript代码之后,您可以从终端运行此安装程序: <br>
/// Parameter: Set pVars("Namespace")="NewNamespace"
/// Set pVars("SourceDir")="C:\deploy\distr\"
/// set pVart("MirrorModel")=1
/// Do ##class(App.MirrorInstall).setup(.pVart) <br>
/// Return: { Boolean } <br>
/// Date: 2023年09月13日 15:39:05 <br>
/// Author: 王喆 <br>
ClassMethod setup(ByRef pVars, pLogLevel As %Integer = 0, pInstaller As %Installer.Installer, pLogger As %Installer.AbstractLogger) As %Status [ CodeMode = objectgenerator, Internal ]
{
Quit ##class(%Installer.Manifest).%Generate(%compiledclass, %code, "Install")
}
/// MethodName: ConfigureInstance <br>
/// Summary: 激活的方法 <br>
/// Parameter: { Object } <br>
/// Return: { %Status } <br>
/// Date: 2023年09月13日 14:24:17 <br>
/// Author: 王喆 <br>
ClassMethod ConfigureInstance(InstallerDir As %String, ProdDir As %String) As %Status
{
Set tSC = $ZF(-1,"copy "_ InstallerDir _ "\iris.key "_ProdDir_"\mgr\iris.key")
Set tSC = ##class(%SYSTEM.License).Upgrade()
Set tSC = $ZF(-1,"net start ISCAgent")
//do ##class()
Quit tSC
}
/// MethodName: CreateMirror <br>
/// Summary: 创建镜像 <br>
/// Parameter: { Object } <br>
/// Return: { %Status } <br>
/// Date: 2023年09月13日 14:24:52 <br>
/// Author: 王喆 <br>
ClassMethod CreateMirror(MirrorName As %String, VituralIP As %String, ArbiterNode As %String, PrimaryNetworkAdapter As %String, MasterIP As %String, MasterName As %String) As %Status
{
ZNspace "%SYS"
#; Start %Service_Mirror 开启镜像服务
Set tSC = ##class(Security.Services).Get("%Service_Mirror",.properties)
Set properties("Enabled")=1
Set tSC = ##class(Security.Services).Modify("%Service_Mirror",.properties)
Set MirrorInfo("VirtualAddress") = VituralIP
Set MirrorInfo("ArbiterNode") = ArbiterNode
If "" '= MasterIP{
Set MirrorInfo("ECPAddress") = MasterIP
}
If "" '= PrimaryNetworkAdapter{
Set MirrorInfo("VirtualAddressInterface") = PrimaryNetworkAdapter
}
#; if "" '= MasterName
#; Set MasterName = ##class(SYS.Mirror).DefaultSystemName()
Try {
Set tSC = ##class(SYS.Mirror).CreateNewMirrorSet(MirrorName,MasterName,.MirrorInfo)
If $$$ISERR(tSC){
Set errobj = ##class(%Exception.General).%New()
Set errobj.Name = "Error #",errobj.Code = $SYSTEM.Status.GetErrorCodes(tSC),errobj.Data = $SYSTEM.Status.GetOneStatusText(tSC,1)
Throw errobj
}
}
Catch ex {
Write ex.DisplayString()
}
//Create Mirror Se1t
//do ##class(SYS.Mirror).
Quit tSC
}
/// MethodName: JoinMirror <br>
/// Summary: 加入镜像 <br>
/// Parameter: { Object } <br>
/// Return: { %Status } <br>
/// Date: 2023年09月13日 14:25:19 <br>
/// Author: 王喆 <br>
ClassMethod JoinMirror(MirrorName As %String, MasterName As %String, MasterIP As %String, MasterPort As %Integer, BackupNetworkAdapter As %String, BackupIP As %String, InstanceName As %String) As %Status
{
ZNspace "%SYS"
//Start %Service_Mirror
Set tSC = ##class(Security.Services).Get("%Service_Mirror",.properties)
Set properties("Enabled")=1
Set tSC = ##class(Security.Services).Modify("%Service_Mirror",.properties)
If "" '= BackupNetworkAdapter{
Set LocalInfo("VirtualAddressInterface") = BackupNetworkAdapter
}
If "" '= BackupIP{
Set LocalInfo("ECPAddress") = BackupIP
}
Try {
Set SysName = ##class(SYS.Mirror).DefaultSystemName()
Set tSC = ##class(SYS.Mirror).JoinMirrorAsFailoverMember(MirrorName,SysName,InstanceName,MasterIP,MasterPort,.LocalInfo)
If $$$ISERR(tSC){
Set errobj = ##class(%Exception.General).%New()
Set errobj.Name = "Error #",errobj.Code = $SYSTEM.Status.GetErrorCodes(tSC),errobj.Data = $SYSTEM.Status.GetOneStatusText(tSC,1)
Throw errobj
}
}
Catch ex {
Write ex.DisplayString()
}
Quit tSC
}
}
ObjectScriptObjectScript
3 安装清单执行
3.1 前置条件:
- 特别注意:windows server r2 2012 先安装2022版本的IRIS务必去微软官网下载Windows8.1-KB2999226-x64.msu并安装(必须)
- 预先安装 Java环境推荐Java8(必须)
- 服务器磁盘分区得有C盘 D盘 E盘可用(推荐)
- 部署包解压路径 D:\deploy(可选)
- 安装浏览器(可选)
3.2安装脚本
以管理员权限运行cmd,进入D://deploy 执行安装程序,其在安装时候就可以配置好镜像:
主机执行:
./IRISHealth-2022.1.2.574.0-win_x64.exe INSTALLERMANIFEST="D:\deploy\distr\MirrorInstall.xml" INSTALLERMANIFESTPARAMS="MirrorModel=1,PRODDIR=C:\InterSystems\IRISHealth,INSTALLERDIR=D:\deploy,GlobalBuffers=32768,RoutineCache=1000" INSTALLERMANIFESTLOGFILE="D:\deploy\mirrorLog.txt" INSTALLERMANIFESTLOGLEVEL="3"
Shell SessionShell Session
备机执行:
./IRISHealth-2022.1.2.574.0-win_x64.exe INSTALLERMANIFEST="D:\deploy\distr\MirrorInstall.xml" INSTALLERMANIFESTPARAMS="MirrorModel=0,PRODDIR=C:\InterSystems\IRISHealth,INSTALLERDIR=D:\deploy,GlobalBuffers=32768,RoutineCache=1000" INSTALLERMANIFESTLOGFILE="D:\deploy\mirrorLog.txt" INSTALLERMANIFESTLOGLEVEL="3"
Shell SessionShell Session
脚本解释:
./IRISHealth-2022.1.2.574.0-win_x64.exe // 安装程序
INSTALLERMANIFEST="D:\deploy\distr\MirrorInstall.xml" // 安装清单所在的目录
INSTALLERMANIFESTPARAMS=" // 安装的时候传入的参数
MirrorModel=1, // 1-主机 0-备机
PRODDIR=C:\InterSystems\IRISHealth, // 你想安装的目录
INSTALLERDIR=D:\deploy, // 安装文件所在的目录
GlobalBuffers=32768, // Global内存的大小
RoutineCache=1000" // Routine内存的大小
INSTALLERMANIFESTLOGFILE="D:\deploy\mirrorLog.txt" // 安装时候记录的日志位置
INSTALLERMANIFESTLOGLEVEL="3" // 日志级别
ObjectScriptObjectScript
好了以上是我本次分享的关于IRIS关于Manifest的相关内容,本文只对manifest做了示例,具体的如何使用及其步骤在官网中描述的比较清楚,如果有需要大家可以去官网看看。
如果您觉得对你有帮助就给我点个赞吧,感激不尽!!!
这个只能支持2022版本的IRIS吗?
不是,应该任何版本的IRIS都可以 我用过最旧的是2020版本的。Ensemble我没试过,但如果有Installer这个类的话应该可以
点赞过百,出详细安装教程和完整脚本程序压缩包🤭🤭🤭🤭
不明觉厉
就是一个安装镜像的快捷方式而已,官网已经很详细的描述好了步骤,我这核心点是分享一下我的脚本