#部署

0 关注者 · 38 帖子

软件部署是使软件系统可供使用的所有活动。一般部署过程由几个相互关联的活动组成,这些活动之间可能有过渡。

文章 Nicky Zhu · 十月 31, 2025 20m read

目录

  1. 本文目的
  2. 什么是容器,它们为什么对 IRIS 有意义
     2.1 容器和镜像简介
     2.2 为什么容器对开发者很有用
     2.3 为什么 IRIS 可以很好地与 Docker 配合使用
  3. 先决条件
  4. 安装 InterSystems IRIS 镜像
     4.1 使用 Docker Hub
     4.2 拉取镜像
  5. 运行 InterSystems IRIS 镜像
     5.1 启动 IRIS 容器
     5.2 检查容器状态
     5.3 在容器终端执行代码
     5.4 访问 IRIS 管理门户
     5.5 将容器连接到 VS Code
     5.6 停止或移除容器
     5.7 使用绑定挂载设置特定密码
     5.8 使用持久化 %SYS 卷
      5.8.1 可以使用持久化 %SYS 存储什么
      5.8.2 如何启用持久化 %SYS
  6. 使用 Docker Compose
     6.1 Docker Compose 示例
     6.2 运行 Docker Compose
  7. 使用 Dockerfile 运行自定义源代码
     7.1 Dockerfile 示例
     7.2 Docker Compose 示例
     7.3 了解层、镜像标记和构建与 运行时
     7.4 源代码和初始化脚本
     7.5 使用 Dockerfile 构建镜像
     7.6 在容器化 IRIS 终端中运行指令
  8. 结语和未来计划


1. 本文目的

InterSystems 开发者社区已经有很多优秀的文章解释了 Docker 是什么、最重要的命令以及 InterSystems IRIS 在容器化环境中的多个用例。

本系列文章的目的略有不同。 由于我非常喜欢分步指南,我想创建一份全面的讲解,介绍如何在 InterSystems IRIS 中配置和使用 Docker,我们先从最基础的场景开始,逐步过渡到更高级的场景,例如多命名空间实例、互连容器、与外部系统的集成以及用于了解 UI 的应用程序。

2. 什么是容器,它们为什么对 IRIS 有意义

2.1 容器和镜像简介

按照传统方法,要想运行应用程序,需要将版本与您的操作系统进行匹配,并针对特定目标对其进行打包。 同时,每个应用程序都应当打包,以便专门与某个目标系统配合使用。 如果您希望应用程序在 macOS 和 Windows 上运行,必须更改应用程序设计并针对不同的系统进行打包。Docker 镜像和容器是应用程序部署技术,通过让开发者将软件打包一次并在任何地方运行来解决此问题。

Docker 是一个将软件打包到容器中的软件平台。 Docker 镜像(或容器镜像)是独立的可执行文件,包含创建和运行容器的所有指令(库、依赖项和文件)。 Docker 镜像可共享、可移植,因此您可以一次在多个位置部署同一个镜像。Docker 容器是一个运行时环境,具有运行应用程序代码所需的所有必要组件,无需使用主机依赖项。  

与虚拟机不同,容器是轻量级的。 它们不需要完整的操作系统,只使用特定应用程序所需的二进制文件和库,通过 Docker 引擎直接在主机操作系统上运行,这使其更加高效。 多个隔离的容器可以在同一台计算机上并行启动,互不干扰。

2.2 为什么容器对开发者很有用

  • 隔离:在清晰、可重现的环境中运行,不会影响您的主机系统。
  • 可重现性:确保您的设置在不同的计算机上以相同的方式工作。
  • 轻松设置:使用一个命令,只需几秒钟即可启动 IRIS 实例,无需手动安装。

2.3 为什么 IRIS 可以很好地与 Docker 配合使用

在 Docker 中运行 InterSystems IRIS 有几项优势:

  • 应用程序运行并且可以在隔离的容器中进行测试
  • 可以使用共享版本控制系统(如 Git),无需直接在服务器上操作
  • 容器化环境可以在任何阶段重现,从而在整个软件生命周期中保持一致性。
  • 您的应用程序可以轻松地在每台计算机上运行。

3. 先决条件

要在 Docker 容器中运行 InterSystems IRIS,您必须具有:

4. 安装 InterSystems IRIS 镜像

4.1 使用 Docker Hub

Docker Hub 是 Docker 镜像的中心注册表。 它提供了一个庞大的预构建镜像库,您可以将其作为切入点。 InterSystems 在其中发布官方 IRIS 社区版镜像,您可以下载该镜像以在自己的容器中本地运行 IRIS。 您还可以使用 Docker Hub 推送自己的自定义镜像,以便在团队中共享或分发给社区。Docker Hub 既可以在线使用,也可以嵌入到 Docker Desktop 中。

4.2 拉取镜像

一些常见的 Docker 镜像命令包括:

命令描述
docker pull <image>从 Docker Hub 下载镜像
docker images列出所有本地镜像
docker rmi <image>移除一个或多个镜像

您可以直接在镜像的 Docker Hub 页面上找到确切的拉取命令:

对于 InterSystems IRIS 镜像,该命令为:

docker pull intersystems/iris-community:latest-cd

或者,您可以在 Docker Desktop 搜索栏中搜索 iris-community 并点击 Pull

安装后,您应当拥有在本地镜像中列出的 InterSystems IRIS 镜像:

5. 运行 InterSystems IRIS 镜像

从 Docker Hub 中拉取出 InterSystems IRIS 镜像后,您可以在容器内运行该镜像。

以下是常用的 Docker 容器命令

命令描述
docker run -d <image>以分离模式运行:在后台启动容器并立即将控制权返还给终端。
docker run -p <host>:<container> <img>将主机端口映射到容器端口
docker ps列出正在运行的容器
docker ps -a列出所有容器(包括已停止的容器)
docker exec -it <container> bash在正在运行的容器中执行命令
docker logs <container>查看容器日志
docker stop <container>停止正在运行的容器
docker start <container>启动已停止的容器
docker restart <container>重启容器
docker rm <container>移除容器

5.1 启动 IRIS 容器

您可以通过 Docker Desktop UI 启动名为“my-iris”的 InterSystems IRIS 社区版容器,只需在 Images 面板中点击要运行的镜像的 Run 按钮即可。 对于 InterSystems 镜像,可以指定一些可选的设置,例如在主机上公开哪些端口来与容器内运行的服务进行通信。

可以通过上面显示的菜单完成操作,具体如下:

  • 左侧 → 主机上的端口
  • 右侧 → 容器内的端口

常用 IRIS 端口(容器内)

  • 1972 → 超级服务器端口:由 IRIS 用于网络协议(ObjectScript、JDBC 等)。
  • 52773 → Web 服务器端口:由 IRIS 用于管理门户(Web 界面)。

如果没有显式映射端口,Docker 将在主机上指定随机端口。

或者,可以使用终端来运行容器:

docker run --name my-iris -d --publish 9091:1972 --publish 9092:52773 intersystems/iris-community:latest-cd

在本例中:

  • 主机上的 9091 映射到容器内的 1972(超级服务器)。
  • 主机上的 9092 映射到容器内的 52773(管理门户)。

5.2 检查容器状态

运行此命令后,运行 docker ps 以验证容器是否正常运行。

> docker ps
CONTAINER ID   IMAGE                                   COMMAND                 CREATED         STATUS                            PORTS                                                                                        NAMES
907d4c2b4ab5   intersystems/iris-community:latest-cd   "/tini -- /iris-main"   3 seconds ago   Up 2 seconds (health: starting)   0.0.0.0:9091->1972/tcp, [::]:9091->1972/tcp, 0.0.0.0:9092->52773/tcp, [::]:9092->52773/tcp   my-iris

正在运行的容器也会列在 Docker Desktop Containers 面板中:

相关镜像的状态将是 In Use,如 Images 面板中所示:

5.3 在容器终端执行代码

当容器状态显示 Running 时,表示一切正常。 

您可以进行测试,只需打开容器终端(点击 Docker Desktop 的 Containers 面板内的容器名称并转到 Exec)并输入以下内容即可:

iris session IRIS

这将在 Docker 容器中打开一个 IRIS 终端,您可以在其中使用标准的 ObjectScript 语法来执行命令和脚本。

5.4 访问容器化实例的 IRIS 管理门户

接下来,打开浏览器并导航到:

http://localhost:9092/csp/sys/UtilHome.csp

默认情况下,IRIS 容器使用用户 _SYSTEM 和密码 SYS。登录后需要更改密码。

这将为您提供 IRIS 管理门户的完整访问权限,这样您可以直接从 Web 界面管理命名空间、数据库和其他 IRIS 功能。

5.5 将容器连接到 VSCode IDE

您可以使用映射的超级服务器端口(默认为容器内的 1972,例如主机上的 9091)和 Web 服务器端口(默认为容器内的 52773,例如主机上的 9092)将您喜欢的 IDE(例如 VS Code 或 Studio)连接到 IRIS 容器。 这样您可以直接针对正在运行的容器开发和测试 ObjectScript 代码。

将容器连接到 VSCode:

  • 安装 InterSystems ObjectScript 扩展程序包
  • 打开 InterSystems Server 扩展程序
  • 点击三个点和“Edit server”
  •  
  • 点击“Edit in settings.json”
  • 将此元素添加到“intersystems.servers”json:
"docker_iris": {
    "webServer": {
        "scheme": "http",
        "host": "localhost",
        "port": 9092
    },
    "description": "Connection to Docker container."
}
  • 服务器现已连接。 您可以使用 _SYSTEM 用户登录。
  • 您可以看到,USER 是唯一可用的命名空间:

5.6 停止或移除容器

要停止正在运行的容器,请使用以下命令:

docker stop my-iris

再次启动容器

要再次启动容器,请使用以下命令:

docker start my-iris

移除(删除)容器

要移除容器实例,但移除镜像,请使用:

docker rm my-iris

除非您挂载了卷,否则容器内的所有数据都将丢失(我们将在后续段落中讨论这个问题)。

5.7 使用绑定挂载设置特定密码

在启动容器时,可以使用密码文件设置自定义密码。 该文件将保存在我们的主机上,并使用绑定挂载机制复制到容器中。

当您使用绑定挂载时,主机上的文件或目录将从主机挂载到容器中,从而允许在 Docker 主机上的开发环境和容器之间共享源代码或构建工件。

  • 创建名为 password.txt 的文件,其中仅包含字符串形式的密码(注意! 记下密码,以后会用到)。
  • 复制其路径,本例中为 C:\InterSystems\DockerTest\password\password.txt
  • 运行以下命令:
docker run --name my-iris -d --publish 9091:1972 --publish 9092:52773 --volume "C:\InterSystems\DockerTest:/durable" intersystems/iris-community:latest-cd --password-file /durable/password/password.txt 

容器运行后,可以使用用户 _SYSTEM  和您在密码文件中写下的密码登录。

在 Docker 容器内,您会看到一个 password.txt.done 文件。您的主机文件夹中会有一个相同的文件。

文件扩展名会更改为 .done,以避免密码以纯文本形式保留。 这是 InterSystems IRIS 中对密码文件的标准操作。 因此,在从 password.txt 文件读取密码并将默认 IRIS 用户 (_SYSTEM) 更新为该密码后,出于安全原因,该文件会附加 .done 并移除密码。

您可以使用自定义密码登录管理门户(我告诉过您记下来 :D)。 登录后,InterSystems IRIS 不会强迫您更改密码。

请注意,如果在没有挂载任何持久化卷的情况下移除了容器,然后重启(有关详情,请参阅下一段),则不会再次从 password.txt 文件中读取密码,因为它已被替换为 password.txt.done。 如果是这种情况,将使用标准的“SYS”密码。 

5.8 使用特定的持久化卷启动容器

默认情况下,当您使用 docker rm <container's name> 命令移除正在运行的 Docker 容器时,保存在该容器内的任何内容都将消失。

为了避免丢失数据,InterSystems IRIS 提供了持久化 %SYS 功能。 这可以让实例将所有重要的文件都存储在您的主机上,以便在容器和实例重启后它们仍然存在。

5.8.1 可以使用持久化 %SYS 存储什么?

一些示例包括:

  • 配置文件(iris.cpfhttpd.conf
  • Web 网关配置和日志 (/csp)
  • 系统数据库(IRISUSERIRISSECURITYIRISTEMP 等)
  • 日志、写入镜像文件 (WIJ) 和临时文件
  • 日志文件(messages.logSystemMonitor.log 等)
  • 许可证密钥 (iris.key)
  • 您创建的任何其他数据库

5.8.2 如何启用持久化 %SYS

首先,从主机中选择一个文件夹,如 C:\InterSystems\DockerTest

  • 在 Linux 上,创建 irisowner 用户并为其授予目录所有权,确保 IRIS 可以写入该文件夹:
adduser irisowner
chown -R irisowner:irisowner /InterSystems/DockerTest
  • 在 Windows 上,您可以跳过这一段,因为 Docker Desktop 将使用您当前的 Windows 用户权限挂载该文件夹。

然后,挂载您的主机文件夹并使用 ISC_DATA_DIRECTORY 变量告知 IRIS 将其持久化数据写入何处:

  --volume "C:\InterSystems\DockerTest:/durable" --env ISC_DATA_DIRECTORY=/durable/iris

在终端上运行的完整指令是:

docker run --name my-iris -d --publish 9091:1972 --publish 9092:52773 --volume "C:\InterSystems\DockerTest:/durable" --env ISC_DATA_DIRECTORY=/durable/iris intersystems/iris-community:latest-cd --password-file /durable/password/password.txt

此时,您可以检查您的容器,看到一个持久化文件夹已装载并包含目录 iris/(对于持久化 %SYS)和 password/。 在主机上,您也可以看到以下两个目录:

如果容器停止并被移除,当您使用相同的 Docker Compose 命令重新创建容器时,IRIS 将使用 iris/ 文件夹中的数据恢复其先前的状态(用户、配置、日志、数据库等),因此不会丢失任何内容。 您可以通过创建 Web 应用程序、停止并移除容器,然后再次创建来进行测试。 如果不使用持久化 %SYS 功能,每次移除容器并启动新实例时,%SYS 内的任何更改都会丢失。

请注意,如果删除了 iris/ 文件夹,下次启动 IRIS 容器时,由于无法找到先前的 %SYS 数据,它将像在全新安装中一样进行初始化。 将创建一个全新的 iris/ 文件夹。

6. 使用 Docker Compose 

到目前为止,您一直在使用一个长命令 docker run 启动 InterSystems IRIS。 这虽然可行,但很快就会难以使用普通的 Shell 命令来管理一切。

Docker Compose 是一个 YAML 配置文件,用于定义如何运行一个或多个容器。这简化了整个应用程序栈的控制,使管理服务、网络和卷变得更加容易。 只需一个命令,即可从配置文件创建并启动所有服务。

以下是 Docker compose 的常用命令

命令描述
docker compose up -d以分离模式启动 docker-compose.yml 中定义的所有服务(默认情况下,使用当前文件夹中的 docker-compose.yml 文件)。
docker compose -f ./path/to/docker-compose.yml up -d从另一个目录中的 compose 文件启动服务。
docker compose down停止并移除由 docker compose up 创建的所有容器、网络和卷。
docker compose ps列出由 Compose 管理的容器。
docker compose logs查看 Compose 文件中定义的所有服务的日志。
docker compose logs <service>查看特定服务(例如,iris)的日志。
docker compose exec <service> bash在由 Compose 管理的正在运行的容器内打开一个 Shell。
docker compose stop停止正在运行的容器,但不将其移除。
docker compose start启动之前停止的容器。
docker compose restart重启 Compose 文件中定义的所有容器。
docker compose build构建或重建由 Dockerfile 定义的服务。
docker compose pull拉取服务的最新镜像。
docker compose config验证并查看 Compose 文件中的合并配置。

6.1 Docker Compose 示例

要使用 Docker Compose,必须创建一个 docker-compose.yml 文件,其中包含您要创建和启动的容器的所有配置。

这样一来,以下命令:

docker run --name my-iris -d --publish 9091:1972 --publish 9092:52773 --volume "C:\InterSystems\DockerTest:/durable" --env ISC_DATA_DIRECTORY=/durable/iris intersystems/iris-community:latest-cd --password-file /durable/password/password.txt

可被替换为下方的 docker-compose.yml

# docker-compose.yml     
services:
  iris:
    container_name: my-iris
    image: intersystems/iris-community:latest-cd
    init: true
    volumes:
      # System/persistent data (IRIS installation, databases, etc.)# On Windows, you can use either: "C:\\InterSystems\\DockerTest:/durable"
      - C:/InterSystems/DockerTest:/durable
    ports:
      - "9092:52773"# Management Portal / REST APIs
      - "9091:1972"# SuperServer port
    environment:
      - ISC_DATA_DIRECTORY=/durable/iris
    # Use the password file to log within the container
    command: --password-file /durable/password/password.txt

6.2 运行 Docker Compose 

在保存 Docker Compose 文件的目录中打开一个终端(或使用 -f 选项)并运行以下命令:

docker compose up -d

您的 IRIS 容器将以 Docker Compose 文件中指定的确切配置启动。

在 Docker Desktop 中,您现在可以看到一个名为“dockertest”的 Compose 栈(它采用保存 Docker Compose 的文件夹的名称)已经创建并与容器“my-iris”相关联:

7. 使用 Dockerfile 运行自定义源代码

到目前为止,您一直在直接从官方 Docker 镜像运行 InterSystems IRIS。 不过,在构建镜像时,我们可能需要自动加载镜像中的 ObjectScript 类或其他自定义代码。

Dockerfile是一个文本文件,其中包含从基础镜像(如 intersystems/iris-community:latest-cd)开始构建镜像的指令。 使用 Dockerfile,我们可以将自定义源代码添加到容器中,并在构建镜像时运行自定义命令。

7.1 Dockerfile 示例

下一个示例提供了一个执行以下操作的 Dockerfile:

  • 从官方 InterSystems IRIS 镜像启动镜像。
  • 将应用程序代码从 src/ 文件夹复制到容器。
  • 运行脚本来导入类并初始化容器化的应用程序,然后将日志保存到日志文件中。
  • 公开默认的 InterSystems IRIS 端口。

7.2 Docker Compose 示例

您还应当修改 Docker Compose,以指定从当前文件夹中的 Dockerfile 构建镜像:

# docker-compose.yml     
services:
  iris:
    container_name: my-iris
    build: # this tells Docker to build a new image based on the one specified in the Dockerfile
      context: .        # build the image from local Dockerfile
      dockerfile: Dockerfile
    image: my-modified-iris-image:latest   # give the new image a new tag to avoid overriding the base image
    init: true
    volumes:
      # System/persistent data (IRIS installation, databases, etc.)# On Windows, you can use either: "C:\\InterSystems\\DockerTest:/durable"
      - C:/InterSystems/DockerTest:/durable
    ports:
      - "9092:52773"# Management Portal / REST APIs
      - "9091:1972"# SuperServer port
    environment:
      - ISC_DATA_DIRECTORY=/durable/iris
    # Use the password file to log within the container
    命令:--password-file /durable/password/password.txt

7.3 了解层、镜像标记和构建与 运行时

在 Docker 中,正如什么是镜像?中所述,有两个重要的原则需要牢记:

  1. 镜像不可变:创建完镜像后,将无法进行修改。 您只能生成新的镜像或在镜像上添加更改。
  2. 容器镜像由层组成:每一层代表一组添加、移除或修改文件的文件系统更改。

执行 Dockerfile 中指定的指令时,新层会添加到镜像中。 这些层也将显示在镜像信息中。

考虑到这一点,务必区分 Docker 在构建时(当它从 Dockerfile 创建镜像时)和运行时(当它从该镜像启动容器时)的作用。

以下每个 Dockerfile 指令都在构建时执行:

  • COPY:将文件复制到镜像中
  • RUN:执行命令并将结果保存为新的镜像层
  • ENTRYPOINT:不改变文件系统,而是定义将在运行时启动的默认进程
  • EXPOSE:设置元数据,指示镜像打算使用哪些端口

运行时,Docker 不会重建镜像,而是在镜像上添加一个容器层。容器运行时所做的所有更改(如新文件、编辑、日志)都会进入这个临时层。

从上一个 Docker Compose 示例来看:

build: # this tells Docker to build a new image based on the one specified in the Dockerfile
  context: .        # build the image from local Dockerfile
  dockerfile: Dockerfile
image: my-modified-iris-image:latest   # give the new image a new tag to avoid overriding the base image

这些指令通过拉取基础镜像并按照 Dockerfile 中的描述进行修改,告知 Docker 创建一个名为“my-modified-iris-image:latest”的新镜像(这称为标签)。 用其他名称标记新镜像非常重要。如果我们不在新创建的镜像上放置标签,基础镜像会被新镜像覆盖。 官方镜像仍在 Docker Hub 上提供,但此本地版本会对其进行映射,并且每个引用该标签的项目现在都会不知不觉地使用包含多个新层的自定义镜像。

为了避免这种情况,请务必使用不同的标签来创建新的单独镜像,同时确保官方基础镜像干净、可重用。

7.4 源代码和初始化脚本

此时,我们应至少创建一个类,并将其放在 src/ 文件夹中。 该类将被复制到容器中,并通过 iris.script 文件导入,该文件包含在构建镜像时导入类和初始化应用程序所需的所有指令。

在项目文件夹中创建一个名为 src/DockerStepByStep 的新目录并创建以下类文件:

Class DockerStepByStep.cheers Extends%RegisteredObject
{

ClassMethod sayHi() As%Status { Set sc = $$$OKw"Hi mom!",! Return sc }

}

在项目的根目录中,创建一个名为 iris.script 的文件:

// Unexpire passwords for dev modezn"%SYS"Do##class(Security.Users).UnExpireUserPasswords("*")

// Load classes from durable sourcezn"USER"// Import classesset importPath = "/opt/irisapp/src"write"Loading classes at '", importPath, "' ...", ! set errors = ""do$System.OBJ.Import(importPath,"cuk",,.errors) if errors = 0 { write"Classes loaded successfully", ! } else { write errors, " errors occurred while loading classes!", ! }

halt

7.5 使用 Dockerfile 构建镜像

首次运行时,您可以使用以下命令从 Dockerfile 构建镜像(--build 标记会强制 Docker 从您的 Dockerfile 重建镜像):

docker-compose up --build

对于其他运行,如果 Dockerfile 未被修改,则可以简单地运行:

docker-compose up -d

开始构建镜像后,您会在终端中看到以下日志:

PS C:\InterSystems\DockerTest> docker-compose up --build
[+] Building 21.5s (13/13) FINISHED
 => [internal] load local bake definitions                                                                     0.0s
 => => reading from stdin 530B                                                                                 0.0s
 => [internal] load build definition from Dockerfile                                                           0.0s
 => => transferring dockerfile: 1.73kB                                                                         0.0s
 => [internal] load metadata for docker.io/intersystems/iris-community:latest-cd                              10.0s
 => [internal] load .dockerignore                                                                              0.0s
 => => transferring context: 2B                                                                                0.0s 
 => [1/6] FROM docker.io/intersystems/iris-community:latest-cd@sha256:93488df381f5868649e7bfc33a9083a3e86a22d  0.9s 
 => => resolve docker.io/intersystems/iris-community:latest-cd@sha256:93488df381f5868649e7bfc33a9083a3e86a22d  0.0s 
 => [internal] load build context                                                                              0.0s 
 => => transferring context: 147B                                                                              0.0s
 => [2/6] WORKDIR /opt/irisapp                                                                                 0.0s
 => [3/6] COPY src src                                                                                         0.1s 
 => [4/6] COPY iris.script .                                                                                   0.1s
 => [5/6] RUN mkdir -p /opt/irisapp/logs                                                                       0.3s
 => [6/6] RUN iris start IRIS &&     iris session IRIS < iris.script > /opt/irisapp/logs/build.log 2>&1 &&     4.5s 
 => exporting to image                                                                                         4.5s 
 => => exporting layers                                                                                        3.3s 
 => => exporting manifest sha256:3ce316cefa21a3707251c4287005a15b02e6dc0151b24baf2a82f76064792250              0.0s 
 => => exporting config sha256:00238e19edef86b29149d2eb89ff75f4d1465ba0d9a2ac4494a14d3bd3746a94                0.0s 
 => => exporting attestation manifest sha256:3579cab5c8accc7958090276deb60bd7dbbc2ecbf13af8e7fa8c4ff2dfe91028  0.0s 
 => => exporting manifest list sha256:17b969c340f57d611cc7603287cc6db50cffd696258a72b5648ece0a919676ac         0.0s 
 => => naming to docker.io/intersystems/iris-community:latest-cd                                               0.0s 
 => => unpacking to docker.io/intersystems/iris-community:latest-cd                                            0.9s 
 => resolving provenance for metadata file                                                                     0.0s 
[+] Running 3/3
 ✔ intersystems/iris-community:latest-cd  Built                                                                0.0s 
 ✔ Network dockertest_default             Created                                                              0.1s 
 ✔ Container my-iris                      Created                                                              0.2s 

在第 6/6 步中,iris.script 文件被执行到容器化的 IRIS 实例中,日志保存在路径 /opt/irisapp/logs/build.log 中。

要查看日志,可以运行以下指令:

docker exec -it my-iris cat /opt/irisapp/logs/build.log

您应当看到以下记录,这些记录会告知您类编译的结果:

Node: buildkitsandbox, Instance: IRIS

USER>

USER>

%SYS>

%SYS>

%SYS>

%SYS>

USER>

USER>

USER>

USER> Loading classes at '/opt/irisapp/src' ...

USER>

USER>

Load of directory started on 09/16/202507:46:28 Loading file /opt/irisapp/src/DockerStepByStep/cheers.cls as udl

Compilation started on 09/16/202507:46:28 with qualifiers 'cuk' Class DockerStepByStep.cheers is up-to-date. 编译在 0.005s 内成功完成。

Load finished successfully.

USER> Classes loaded successfully

USER>

USER>

在 Docker Desktop 上,您可以看到一个名为“my-modified-iris-image”的新镜像已创建,并且正在与基础官方镜像一起运行。

如果检查这些镜像,您会发现自定义镜像由 31 层组成,而不是原始镜像的 25 层。 新层与 Dockerfile 在构建时执行的指令相对应:

7.6 在容器化 IRIS 终端中运行指令

要测试这些类,您可以在容器化 IRIS 实例中激活 IRIS 终端。 为此,请执行以下指令:

docker exec -it my-iris iris session IRIS

此时,您可以使用以下命令从 USER 命名空间调用 ClassMethod:

do##class(DockerStepByStep.cheers).sayHi()

最后,您应当看到以下输出:

PS C:\InterSystems\DockerTest> docker exec -it my-iris iris session IRIS

Node: 41c3c7a9f2e4, Instance: IRIS

USER>do##class(DockerStepByStep.cheers).sayHi() Hi mom!

8. 结语和未来计划

我们已经完成了在 Docker 中运行 InterSystems IRIS 的整个周期:

  • 拉取镜像
  • 启动并配置容器
  • 使用持久化 %SYS 来持久化数据
  • 使用自己的代码和脚本构建自定义镜像

以上内容足以让您在容器化环境中试验 IRIS 并将其用于开发。

您可以访问 GitHub 仓库,其中包含最后一部分讨论的所有文件(Docker Compose、Dockerfile、iris.script 等)。

敬请期待下一篇文章!

1
0 15
文章 Claire Zheng · 九月 23, 2025 2m read

大家好! 我最近才加入 InterSystems,但发现尽管我们推出了完全免费且出色的社区版,但大家并不是十分清楚如何获取。 因此我决定编写一份指南,详细介绍获取 InterSystems IRIS 社区版的所有不同方式:

以容器形式获取 InterSystems IRIS 社区版

对于刚刚接触 InterSystems IRIS 开发的伙伴,推荐使用社区版的容器化实例,在我看来,这是最简单直接的方式。 InterSystems IRIS 社区版可以在 DockerHub 上获取;如果您有 InterSystems SSO 帐户,还可以在 InterSystems 容器注册表中获取。

在这两种情况下,您都需要使用 docker CLI 拉取所需镜像:

docker pull intersystems/iris-community:latest-em
// or
docker pull containers.intersystems.com/intersystems/iris-community:latest-em

接下来,您需要启动容器:要从容器外部与 IRIS 进行交互(例如使用管理门户),您需要发布一些端口。 以下命令将运行 IRIS 社区版容器,并发布超级服务器和 Web 服务器端口;请注意,此时不能运行其他依赖 1972 或 52773 端口的程序!

docker run --name iris -d --publish 1972:1972 --publish 52773:52773 intersystems/iris-community:latest-em

在云端获取 InterSystems IRIS 社区版

您可能想要完全避免本地安装的一系列操作,如果是这种情况,您可以借助 InterSystems IRIS 社区版的云部署实现环境搭建和运行。 所有主流云提供商均受支持;有关详细信息,请参阅我们的云合作伙伴页面。 本例将重点介绍如何在 AWS 上部署。

先在 AWS Marketplace 中找到 InterSystems IRIS 社区版:

您可以点击“查看购买选项”,并登录您的帐户查看订阅页面:

 

向下滚动,点击“订阅”,填写必填信息,然后点击“部署”,将 IRIS 社区版部署为云节点! 有关详细信息,请参阅我们关于将 InterSystems IRIS 部署到云端的文档。

以安装套件形式获取 InterSystems IRIS 社区版

如果您倾向于将 InterSystems IRIS 直接安装到自己的机器上使用,且不想处理容器,可从 InterSystems 评估服务下载适合您系统的安装套件。要下载安装套件,您需要有 InterSystems SSO 登录帐户;但好消息是,如果您有开发者社区帐户,就说明您已有 InterSystems SSO 帐户! 如果您没有此帐户,可以点击“注册新帐户”并完成后续步骤:

登录后,您应会看到以下页面;点击“下载社区版”开始下载安装套件:

 

系统将提示您填写关于所需 InterSystems IRIS 的具体版本和安装平台的信息:

 

对于大部分用例,您需要选择“InterSystems IRIS 社区版”以及您的平台可用的最新版本。 同意《服务条款》后,您便可下载安装套件! 按照平台特定文档中的安装说明进行操作,一切就搞定啦!

0
0 29
文章 Hao Ma · 十月 28, 2024 4m read

CPF merge(合并)

Automating Configuration of InterSystems IRIS with Configuration Merge

CPF merge通过合并一个人工编辑的merge file, 自动的配置新创建的iris instance, 或者修改已有的iris instance。适用于:

  • 修改iris的系统配置(cpf文件中的内容),比如系统参数,创建或者配置用户,角色,权限, 创建或者配置命名空间,数据库; 配置mirror, ECP连接等等。
  • 操作不在cpf文件中的内容,比如 CreateApplication, CreateSSLConfig 等等, 一般是在 [Action]部分实现

Caché 和早期的IRIS版本提供了manifest功能,用来做IRIS实例的配置。 Manifest很繁琐,而且各个版本的配置中有细微的区别,非常难以管理。 如今有了CPF merge, maifest的所有功能都可以在CPF merge实现, 因此manifest在新版IRIS中也就完全被替代了。

figure

执行merge

执行merge可以在操作系统命令行下执行, 如下面的例子

# 第2个参数可选,如果为空,自动使用系统当前的iris.cpf
$ iris merge iris /external/irismerge.conf /usr/irissys/iris.cpf

然而, 在执行docker run命令或者docker-compose里不用这么麻烦。 IRIS镜像提供了一个功能, 通过加入ISC_CPF_MERGE_FILE环境变量,IRIS会自动实现CPF合并。 比如下面的compose配置:

iris2024:      
        image: containers.intersystems.com/intersystems/irishealth-arm64:2024.1
        container_name: iris-a
        volumes:
            - ./iris2024:/external
        environment: 
            - TZ=CST-8
            - ISC_CPF_MERGE_FILE=/external/merge.cpf

IMPORTANT:

当使用配置合并部署容器时(如 使用合并文件部署 InterSystems IRIS 容器 中所述),只要容器在运行,ISC_CPF_MERGE_FILE(它在容器中是持久的)指定的合并文件就会持续受到更新监控,更新发生时,iris 合并命令会立即对其进行合并。这意味着您可以随时通过更新合并文件来更新容器化实例的配置,从而更容易自动重新配置容器化实例和群集。

merge文件的Example

配置IRIS参数

[config]
bbsiz=-1
globals=0,0,1024,0,0,0
routines=512
gmheap=256000

[SQL]
DefaultSchema=user
TimePrecision=6

[SqlSysDatatypes]
TIMESTAMP=%Library.PosixTime

创建用户和权限

CreateUser:Name=SQLAdmin,PasswordHash=fce110ae1f79b9d7e20367a3352efeb48ef22cc8810c4598791f3fb752eabcfe7b2d9ce75099e626b03a62fc6a146f1ca772789ebbcea276674c558c63af4f7b,9ffbbc8ef25086e4d4da87e20c6ea43e8ebb6d1ab64815aef3b1f7e8964dbd87efe68c8464a6b40865efc7d0d568c601e2a49917326dfd78197b68f1bde59db2,10000,SHA512
GrantAdminPrivilege:Grantee=SQLAdmin,Namespace=USER,AdminPriv="%DB_OBJECT_DEFINITION,%BUILD_INDEX"

CreateUser:Name=CCHUser,Password=Demo1234
GrantAdminPrivilege:Grantee=SQLAdmin,Namespace=HCC,AdminPriv="%DB_HCC,%BUILD_INDEX"

创建命名空间

# part of merge.cpf
[Actions]
CreateResource:Name=%DB_DEMO,Description="The DEMO database"
CreateDatabase:Name=DEMO,Directory=/usr/irissys/mgr/demo,Resource=%DB_DEMO,
CreateNamespace:Name=DEMO,Globals=DEMO,Interop=1

创建Web Application

[Actions]
CreateApplication:Name=/csp/demo, InboundWebServicesEnabled=1, AutheEnabled=1, DispatchClass=HCC.Interface.RestHandler, NameSpace=DEMO
CreateApplication:Name=/csp/demo,NameSpace=HCC,AutheEnabled=36,DispatchClass=HCC.Interface.RestHandler,
CreateApplication:Name=/test2,NameSpace=HCC,AutheEnabled=$$$AuthePassword+$$$AutheUnauthenticated,Enabled=1,Description="test2"
ModifyApplication:Name=/test2,MatchRoles=":%DB_HSCUSTOM:%DB_HSLIB:%DB_IRISSYS:%HS_DB_HCC:%HS_DB_HSSYS",ErrorPage=%CSP.Error

System Security Setting

System > Security Management > Authentication/Web Session Options - (security settings)

  • Allow Unauthentication access
  • Allow O/S authentication
# example
ModifyService:Name=%Service_Monitor,Enabled=1,ClientSystems=192.168.1.1
ModifyService:Name=%Service_DocDB,Enabled=1,AutheEnabled=$$$AuthePassword
ModifyService:Name=%Service_Terminal,AutheEnabled=$$$AuthePassword+$$$AutheUnauthenticated+$$$AutheOS
ModifyService:Name=%Service_Mirror,Enabled=1

其他还有更多的用法,请参见在线文档。

0
0 82
文章 Hao Ma · 十月 28, 2024 3m read

使用iris-main

iris-main是IRIS镜像的的ENTRYPOINT程序。 在Container中,ENTRYPOINT 指令允许你指定一个可执行程序或者脚本,作为容器启动后运行的主程序。这个程序会在容器启动时自动执行。

执行docker ps 命令可以看到当前container的ENTRYPOINT是什么:

hma@CNMBP23HMA demo % docker ps
CONTAINER ID   IMAGE                         COMMAND                 CREATED      STATUS      PORTS                                                               NAMES
8f31a857dc90   .../irishealth:2024.2   "/tini -- /iris-main"   3 days ago   Up 3 days   2188/tcp, 52773/tcp, 53773/tcp, 54773/tcp, 0.0.0.0:1980->1972/tcp   iris-a

hma@CNMBP23HMA demo %

我们可以用root进入container, 在根目录下查看iris-main的帮助, 或者查看在线文档的帮助-iris-main

使用的iris-main例子

以下的compose文件中, 使用了--check-caps false关闭了LInux的能力检查(capability check), 使用--key /install/iris.key加载了IRIS的license文件,并且配置了--after /install/installer.sh,它定义在container启动执行install.sh脚本。

iris-a:      
        image: containers.intersystems.com/intersystems/irishealth-arm64:2024.2
        container_name: iris-a
        hostname: irisa
        ports:
            - 1980:1972
            - 52773:52773
        environment:
            - TZ=CST-8
        volumes:
            - ./install:/install
        command: 
            --check-caps false
            --key /install/iris.key
            --after /install/installer.sh

附: iris-main的帮助

# 用root进入container, 在根目录下查看iris-main的帮助
root@irisa:/# /iris-main --help

USAGE:

   /iris-main  [--check-caps <bool>] [--monitorCPF <bool>] [--monitorKey
               <bool>] [--ISCAgentPort <integer>] [--ISCAgent <bool>] [-k
               <license key>] [-p <password file>] [-t <command>] [-c
               <command>] [-e <command>] [-a <command>] [-b <command>] [-l
               <log file>] [-s <bool>] [-u <bool>] [-d <bool>] [-i
               <instance>] [--] [--version] [-h]


Where:

   --check-caps <bool>
     Does nothing; retained for backwards compatibility

   --monitorCPF <bool>
     Monitor InterSystems IRIS CPF merge file and apply if changes detected

   --monitorKey <bool>
     Monitor InterSystems IRIS license key and update if changes detected

   --ISCAgentPort <integer>
     Set the port for ISC Agent. The default value is 2188

   --ISCAgent <bool>
     Start ISC Agent before starting IRIS. If this argument is not
     specified, it defaults to true

   -k <license key>,  --key <license key>
     Copies the InterSystems IRIS license key from the directory specified
     to the active data directory

   -p <password file>,  --password-file <password file>
     File containing desired InterSystems IRIS password

   -t <command>,  --terminate <command>
     Execute a shell command on application shutdown, after any other
     arguments are processed

   -c <command>,  --create <command>
     Execute a shell command at application startup, before any other
     arguments are processed

   -e <command>,  --exit <command>
     Execute shell commands after stopping InterSystems IRIS (via 'iris
     stop')

   -a <command>,  --after <command>
     Execute shell commands after starting InterSystems IRIS (via 'iris
     start')

   -b <command>,  --before <command>
     Execute shell commands before starting InterSystems IRIS (via 'iris
     start')

   -l <log file>,  --log <log file>
     InterSystems IRIS log file to be redirected to stdout for monitoring
     via 'docker logs'

   -s <bool>,  --nostu <bool>
     Start InterSystems IRIS with the 'nostu' option for maintenance,
     single user access mode

   -u <bool>,  --up <bool>
     Start InterSystems IRIS (via 'iris start') on container startup

   -d <bool>,  --down <bool>
     Stop InterSystems IRIS (via 'iris stop') on container shutdown

   -i <instance>,  --instance <instance>
     The InterSystems IRIS instance name to start/stop

   --,  --ignore_rest
     Ignores the rest of the labeled arguments following this flag.

   --version
     Displays version information and exits.

   -h,  --help
     Displays usage information and exits.


   iris-main

root@irisa:/#
0
0 85
文章 Hao Ma · 十月 28, 2024 2m read

把CSP.conf保存在container之外

在创建webgateway的container时,可以使用ISC_DATA_DIRECTORY=参数, 选择把CSP文保存在主机而不仅仅是container内部。如下面的例子: 使用volumnes映射了主机的./dur-wg-a目录到container的/dur目录, 而command中的ISC_DATA_DIRECTORY=/dur会讲webgateway的配置文件, log文件等保存在主机。

webgateway-apache:
        image: containers.intersystems.com/intersystems/webgateway-arm64:2024.1
        container_name: wg-tls
        hostname: wg-tls
        ports:
            - "8080:80"
            - "4433:443"
        volumes:
            - ./webgateway/csp:/external
            - ./dur-wg-a:/dur
        environment:
            - TZ=CST-8
            - ISC_CSP_CONF_FILE=/external/CSP-apache.conf
            - ISC_CSP_INI_FILE=/external/CSP-merge.ini
            - ISC_DATA_DIRECTORY=/dur

需要注意的是,这种情况下, 当配置了ISC_CSP_CONF_FILE时,比如把定制的CSP.conf放在了/dur/CSP.conf, 实际上是创建了一个link到/etc/apache2/mods-available, 而最终会链接到/etc/apache2/mods-enabled. 真正工作的CSP.conf还是在/etc/apache2/mods-enabled.

在apache2加载网站

虽然绝大多数情况WebGateway Container只用于连接IRIS,但如果在测试或者演示环境中,希望在apache2中加入自己的网站或者网页, 可以简单的参考下面的说明。

在默认的apache2.conf里面默认的定义了3个directory, <Directory /usr/share>, <Directory /usr/share>,<Directory /var/www/>,而在sites-enabled里面是这么配置的

root@ac6fdedbac6b:/etc/apache2# cat sites-enabled/000-default.conf
<VirtualHost *:80>
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/html
	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
root@ac6fdedbac6b:/etc/apache2#

因为000-default.conf是默认生效的配置文件,因此把自动的网站放在/拷贝到/var/www/html目录是最简单的方案。 注意您的网站如果有js或者其他可执行的文件, 网站目录和文件的权限应该是755.

0
0 89
文章 Hao Ma · 十月 28, 2024 7m read

上一篇文章使用人工配置的方法简单的配置了webgateway container. 接下来来介绍如何在docker-compose里做自动化部署。

先总结我们要做的事情:

  1. 配置到IRIS的连接。定义连接的iris的IP地址或者DNS, 以及连接的用户名密码 以及其他的对默认值的修改。
  2. 配置apache2的配置文件,保证到IRIS的HTTP请求能发送给CSP Webgateway。
  3. 很多时候,用户会希望使用HTTPS访问IRIS,因此需要在apache2上支持TLS。

这些是最基本的功能。除此之外, 用户还可能会要求建立WebGateway到IRIS的TLS连接,或者在Apache2部署自己的网页等等。后面的文章会一一介绍。

配置CSP.ini

上一篇文章中,我通过Webgateway管理页面定义了Webgateway到IRIS的连接,其实是定义了webgateway的配置文件CSP.ini。 无论WebServer是什么类型,IIS,Apache, Nginx, CSP.ini的都是一样的。在Linux中, CSP.ini位于/opt/webgateway/bin目录。

InterSystems提供了一个工具叫 CSP merge。 简单的说,就是可以定义一个被合并的文件, webgateway运行时会不停的扫描这个文件,发现有内容的修改,就把修改后的配置项合并到工作中的CSP.ini中去。 具体的内容您可以参见在线文档-CSP.ini merge feature

CSP merge的merge文件不需要定义所有的配置项,理论上,只定义需要修改的部分就可以。但注意在一个配置部分(section)内部, 配置项之间是有关系的,单独定义其中的一项配置是不会生效的。

比如, 这是原始的CSP.ini中的LOCAL服务器的配置部分:

因此,merge文件里正确的LOCAL部分是:

[LOCAL]
Ip_Address=127.0.0.1
TCP_Port=1972
Minimum_Server_Connections=3
Maximum_Session_Connections=6
Connection_Security_Level=0  ; 0:password, 1:kerberos...
Username=CSPSystem
Password=]]]U1lT
SSLCC_Protocol_Min=16
SSLCC_Protocol_Max=32
SSLCC_Key_Type=2
SSLCC_Cipher_Suites=ALL:!aNULL:!eNULL:!EXP:!SSLv2
SSLCC_Cipher_Suites_1_3=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256

如果您只希望修改Ip_Address, 因此在被合并的文件中定义

[LOCAL]
Ip_Address=192.168.1.2
TCP_Port=1972

而这样的定义会 造成加载失败。也就是说,CSP merge需要合并完整的Section。上面的例子中定义了这个服务器的地址,但没有定义连接它的账户和密码,这是不能接受的。

我习惯用比较完整的配置文件做合并,下面是一个例子。文件名可以任意,这里我命名为CSP-merge.ini:

[APP_PATH_INDEX]
/=Enabled
/csp=Enabled

[APP_PATH:/]
Default_Server=LOCAL
Alternative_Server_0=1~~~~~~LOCAL

[APP_PATH:/csp]
Default_Server=LOCAL
Alternative_Server_0=1~~~~~~LOCAL

[SYSTEM]
IRISCONNECT_LIBRARY_PATH=/opt/webgateway/bin
System_Manager=*.*.*.*
SM_Timeout=28800
Server_Response_Timeout=60
No_Activity_Timeout=86400
Queued_Request_Timeout=60
Default_Server=LOCAL
RELOAD=1  ; reload csp gateway setting in one minute

[SYSTEM_INDEX]
LOCAL=Enabled

[LOCAL]
Ip_Address=iris-a
TCP_Port=1972
Minimum_Server_Connections=3
Maximum_Session_Connections=6
Connection_Security_Level=0  ; 0:password, 1:kerberos...
Username=CSPSystem
Password=]]]U1lT
SSLCC_Protocol_Min=16
SSLCC_Protocol_Max=32
SSLCC_Key_Type=2
SSLCC_Cipher_Suites=ALL:!aNULL:!eNULL:!EXP:!SSLv2
SSLCC_Cipher_Suites_1_3=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256

Tip1: [SYSTEM]中配置RELOAD=1, 可以让webgateway setting每分钟检查一次csp-merge.ini, 如果有修改,会实时的执行合并。

Tip2: 想了解更多的CSP.ini的配置项的内容,请访问在线文档- Define a Server Access Profile for Your InterSystems IRIS Instance

Tip3: 在生产系统中,定义SYSTEM部分的: System_Manager=*.*.*.*是不安全的。

自动部署CSP合并文件

简单的说明: CSP-merge.ini文件位于host中的./webgateway文件夹,通过volumes映射到container的/external文件夹。 通过定义环境变量ISC_CSP_INI_FILE,docker启动时会执行CSP文件的合并。

 webgateway-apache:
      image: containers.intersystems.com/intersystems/webgateway-arm64:2024.1
      container_name: wg-apache
      hostname: wg-apache
      ports:
          - "8080:80"
      volumes:
          - ./webgateway:/external
      environment:
          - TZ=CST-8 
          - ISC_CSP_INI_FILE=/external/CSP-merge.ini

后面介绍如何配置apache2访问IRIS服务地址。

配置Apache2

配置apache2可以参考apache2的主页面,配置文件的结构如下:

apache2的主配置文件/etc/apache2/apache2.conf包含(includes)了其他自子目录下的被enabled的配置文件,结构如下图:

root@wg-a:/etc/apache2# cat apache2.conf
...
# It is split into several files forming the configuration hierarchy outlined
# below, all located in the /etc/apache2/ directory:
#
#	/etc/apache2/
#	|-- apache2.conf
#	|	`--  ports.conf
#	|-- mods-enabled
#	|	|-- *.load
#	|	`-- *.conf
#	|-- conf-enabled
#	|	`-- *.conf
# 	`-- sites-enabled
#	 	`-- *.conf

CSP.conf是怎么工作的

InterSystems Webgateway是apache2的一个工作的module. 它的配置文件是/etc/apache2/mods-available/CSP.conf。在webgateway container启动时,apache2会执行这个module的生效(enable), 这时会在/etc/apache2/mods-enabled目录中创建一个链接到原始文件。

默认的CSP.conf的内容如下:

root@wg-a:/etc/apache2# cat /etc/apache2/mods-available/CSP.conf

CSPModulePath "${ISC_PACKAGE_INSTALLDIR}/bin/"
CSPConfigPath "${ISC_PACKAGE_INSTALLDIR}/bin/"

<Location "/csp/bin/Systems/">
    SetHandler csp-handler-sa
</Location>
<Location "/csp/bin/RunTime/">
    SetHandler csp-handler-sa
</Location>

<Directory "${ISC_PACKAGE_INSTALLDIR}/bin/">
    AllowOverride None
    Options None
    Require all granted
    <FilesMatch "\.(log|ini|pid|exe)$">
         Require all denied
    </FilesMatch>
</Directory>
root@wg-a:/etc/apache2#

修改CSP.conf

以上的CSP.conf中只有使用CSP module的内容,而并没有访问IRIS的URL的部分。 , 需要一个个的添加要发送到webgateway模块的URL。必须的有这几个:/csp, /api,/isc, 其他还包括您自己定义的URL, 也需要创建对应的<Location>

以下是要添加的内容:

# 添加要发送给IRIS的URL
<Location "/csp">CSP On</Location>
<Location "/api">CSP On</Location>
<Location "/isc">CSP On</Location>
<Location "/customerURL">CSP On</Location>

Tip1: 如果您确认此container只用于连接IRIS, 您可以定义<Location />将所有的请求发送给webgateway模块。但注意访问http://localhost:8080时会返回错误404,apache2原本会把请求发到/var/www/html/index.html,修改后会把这个请求发给IRIS。

自动部署CSP.conf的修改

配置container是新的CSP.conf通过SC_CSP_CONF_FILE加入,这个不是合并, 是整个覆盖替换原始的配置文件。以下是compose文件的示意,同样,CSP-apache.conf文件位于host的./webgateway文件夹,通过volumes映射到container的/external文件夹。

webgateway-apache:
      image: containers.intersystems.com/intersystems/webgateway-arm64:2024.1
      container_name: wg-apache
      hostname: wg-apache
      ports:
          - "8080:80"
      volumes:
          - ./webgateway:/external
      environment:
          - TZ=CST-8 
          - ISC_CSP_INI_FILE=/external/CSP-merge.ini
          - ISC_CSP_CONF_FILE=/external/CSP-apache.conf

要修改CSP.conf, 如果要在container外面修改,需要修改ISC_CONF-FILE的内容, 然后重启container. /dur里面的CSP.conf不能改, 改了保存后会自动改回来。

配置Apache2的TLS

方法1. 用命令开启

配置HTTPS访问apache2最简单的方式打开apache2内置的ssl模块,并使default-ssl.conf生效。如下面的脚本文件中的操作:

root@wg-a:/etc/apache2# a2enmod ssl 
root@wg-a:/etc/apache2# ls -l mods-enabled/ssl*
lrwxrwxrwx 1 root root 26 Oct  9 09:00 mods-enabled/ssl.conf -> ../mods-available/ssl.conf
lrwxrwxrwx 1 root root 26 Oct  9 09:00 mods-enabled/ssl.load -> ../mods-available/ssl.load
root@wg-a:/etc/apache2# a2ensite default-ssl
Enabling site default-ssl.
To activate the new configuration, you need to run:
  service apache2 reload
root@wg-a:/etc/apache2# service apache2 reload
 * Reloading Apache httpd web server apache2                                                                                            *
root@wg-a:/etc/apache2#

方法2. 设置自己的配置

因为已经Copy了一个CSP.conf进去,其实可以在这个文件里配置SSL的部分, 好处是不用单独写一个文件, 坏处是从维护的角度,把CSP module的配置和SSL的配置写在一个文件不是很合理。

# 加入下部分到CSP.conf, 其中使用了自己的TLS配置,而不是openssl的证书和key. 
LoadModule ssl_module /usr/lib/apache2/modules/mod_ssl.so
<VirtualHost *:443>
    SSLEngine on
    SSLCertificateFile "/external/cert/sslwebcert.crt"
    SSLCertificateKeyFile "/external/cert/sslwebkey.key"
</VirtualHost>

或者使用ssl mod的 conf

<VirtualHost _default_:443>
		ServerAdmin webmaster@localhost
		DocumentRoot /var/www/html
		ErrorLog ${APACHE_LOG_DIR}/error.log
		CustomLog ${APACHE_LOG_DIR}/access.log combined
		SSLEngine on
		SSLCertificateFile	/etc/ssl/certs/ssl-cert-snakeoil.pem
		SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
		<FilesMatch "\.(cgi|shtml|phtml|php)$">
				SSLOptions +StdEnvVars
		</FilesMatch>
		<Directory /usr/lib/cgi-bin>
				SSLOptions +StdEnvVars
		</Directory>
</VirtualHost>
0
0 122
文章 Hao Ma · 十月 28, 2024 6m read

IRIS image下载

参考:下载Images的在线文档

https://containers.intersystems.com网站上获得可以下载的InterSystems的各种docker镜像。如果只是安装Community版本, 不需要注册。如果是下载安装正式的版本,需要在网站注册,然后获得Login Token登陆。

#;这一部有可能需要科学上网,否则无法正常登陆

hma@CNMBP23HMA ~ % docker login -u="hma" -p="k8zIqpoafIUaViP2BA4gCZdcC4EeKyb0svSjnyVtcWMb" containers.intersystems.com
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Login Succeeded

# pull iris image,webgateway,Passhash, arbiter, etc.
hma@CNMBP23HMA ~ % docker pull containers.intersystems.com/intersystems/healthconnect-arm64:latest-cd
hma@CNMBP23HMA ~ % docker pull containers.intersystems.com/intersystems/webgateway-arm64:latest-cd
...

Tips

  • 下载社区(Community)版本的镜像不用在网站注册,使用时也不需要安装license。社区版内置内置了一个13个月的license。而正式版本IRIS Continer安装需要从InterSystems处获得IRIS docker版的专用license。

  • 标记latest-cd(Continuous delivery)latest-em(Extended maintenance), latest-preview是最新的"持续交付"版本, "扩展维护"版本,以及"开发预览版"。 您也可以选择指定专门的版本,比如当前最新的GA版本2024.2。同时,如果硬件是ARM芯片,请选择带有“-arm64"后缀的版本。

  • WebGateway-nginx是nginx服务器的版本,而WebGateway镜像内置了apache2服务。

简单的搭建测试环境

我要使用的iris 2024的版本,其中再没有之前的内置的PWS(Private Web Server), 也就是说您当前以及无法从http://localhost:52773/csp/sys/UtilHome.csp登录管理门户了。因此我用docker-compose来创建下面的例子。docker-compose用来编排多个container共同工作。它自动的创建一个单独的docker network, 其中的所有service, 也就是docker container可以通过container name通信。

如果是简单的测试环境, 可以直接用docker run运行IRIS Container。 我们先来run一个最简单的社区版:

compose.yaml

services:
    iris-a:      
        image: containers.intersystems.com/intersystems/irishealth-community-arm64:2024.2
        container_name: iris-a
        hostname: irisa
        ports:
            - 1980:1972
            - 52773:52773
        environment:
            - TZ=CST-8
    webgateway-apache:
        image: containers.intersystems.com/intersystems/webgateway-arm64:2024.1
        container_name: wg-apache
        hostname: wg-apache
        ports:
            - "8080:80"
        environment:
            - TZ=CST-8

说明两点: 1. 在IRIS2024中52773端口已经无法使用,所以不需要再被映射到主机。 2. TZ=CST-8是把container的时区设置为上海。

运行后可以看到两个container都已经工作

hma@CNMBP23HMA demo % docker-compose up -d
[+] Running 3/3
 &#x2714; Network demo_default  Created                                                                                         0.0s
 &#x2714; Container wg-apache   Started                                                                                         0.0s
 &#x2714; Container iris-a      Started                                                                                         0.0s
hma@CNMBP23HMA demo % docker ps
CONTAINER ID   IMAGE                                                                        COMMAND                 CREATED         STATUS         PORTS                                                               NAMES
cfa4cc730c14   containers.intersystems.com/intersystems/irishealth-community-arm64:2024.2   "/tini -- /iris-main"   6 seconds ago   Up 5 seconds   2188/tcp, 52773/tcp, 53773/tcp, 54773/tcp, 0.0.0.0:1980->1972/tcp   iris-a
63e983d90034   containers.intersystems.com/intersystems/webgateway-arm64:2024.1             "/startWebGateway"      6 seconds ago   Up 5 seconds   0.0.0.0:8080->80/tcp, 0.0.0.0:4433->443/tcp                         wg-apache
hma@CNMBP23HMA demo %

查看iris container

这时,虽然还无法登录iris的管理门户,您可以使用docker exec进入iris container查看iris实例已运行。 注意两点:

  1. 默认登录的用户是irisowner
  2. IRIS的安装路径是/usr/irissys.
hma@CNMBP23HMA installer_cch % docker ps
CONTAINER ID   IMAGE                                                              COMMAND                 CREATED         STATUS         PORTS                                                                              NAMES
59e2424757db   containers.intersystems.com/intersystems/irishealth-arm64:2024.1   "/tini -- /iris-main"   6 seconds ago   Up 5 seconds   0.0.0.0:1972->1972/tcp, 2188/tcp, 53773/tcp, 0.0.0.0:52773->52773/tcp, 54773/tcp   iris
hma@CNMBP23HMA installer_cch % docker exec -it iris bash
irisowner@59e2424757db:~$ iris list

Configuration 'IRIS'   (default)
	directory:    /usr/irissys
	versionid:    2024.1.0.263.0
	datadir:      /usr/irissys
	conf file:    iris.cpf
	status:       running, since Wed Oct 23 12:32:45 2024
	SuperServers: 1972
	state:        warn
	product:      InterSystems IRISHealth
irisowner@59e2424757db:~$ iris session iris
Node: 59e2424757db, Instance: IRIS

USER>halt
irisowner@59e2424757db:~$

查看Webgateway Container

  1. 从浏览器打开 http://localhost:8080, 可以看到apache2的主页面。
  2. 访问http://localhost:8080/csp/bin/Systems/Module.cxw?CSPSYS=0&CSPSYSreferer=_CSP.Portal.Home.zen,可以进入Webgateway的配置页面。 这里一定注意:访问http://localhost:8080/csp/bin/Systems/Module.cxw会得到500错误。当前状态下一定要带着参数访问这个网址。
  3. 配置webgateway到iris的连接:在当前页面,你需要设置。
    • Server Local的IP/DNS和Port:这里是iris container的名字iris-a,和iris-a container的superserver端口1972
    • 登录iris的账户密码:CSPSystem, SYS

保存设置,然后在"Test Server Connection"页面测试连接,你将看到连接成功的结果。

  1. 尽量webgateway已经成功连接了IRIS, 但配置还没有完。要成功访问IRIS管理页面,你需要修改一个apache2的配置文件CSP.conf

    • 使用docker exec -it wg-apache bash进入container.
    • 修改/etc/apache2/mods-available/CSP.conf配置文件,如下:
    # 原始文件的内容
    
    CSPModulePath "${ISC_PACKAGE_INSTALLDIR}/bin/"
    CSPConfigPath "${ISC_PACKAGE_INSTALLDIR}/bin/"
    
    <Location "/csp/bin/Systems/">
        SetHandler csp-handler-sa
    </Location>
    <Location "/csp/bin/RunTime/">
        SetHandler csp-handler-sa
    </Location>
    <Directory "${ISC_PACKAGE_INSTALLDIR}/bin/">
        AllowOverride None
        Options None
        Require all granted
        <FilesMatch "\.(log|ini|pid|exe)$">
             Require all denied
        </FilesMatch>
    </Directory>
    
    # 自己添加的内容
    <Location "/csp">
        CSP On
    </Location>
    <Location "/api">
        CSP On
    </Location>
    <Location "/isc">
        CSP On
    </Location>
    
    • 用命令行service apache2 restart重启apache2, 或者从container里退出重启wg-apache container.
    • 从浏览器访问http://localhost:8080/csp/sys/UtilHome.csp, 您应该已经可以成功访问IRIS了。

总结

虽然题目是'简单的搭建测试环境', 但实际上还是有非常多的步骤,主要是集中在webgateway到IRIS的连接上。 如果您熟悉docker-compose,您知道这样人工的配置一个container是不合适的。而后面的章节我会专门有一章节如何在docker-compose里自动配置webgateway。之所以还要介绍webgateway的人工配置步骤,是因为这些知识是自动配置webgateway的背景知识,而且在做debug时非常关键。

另外,后面我还会介绍webgateay-nginx的配置。

0
0 195
文章 Hao Ma · 十月 28, 2024 1m read

我在3年前写过同样内容的文章。随着IRIS版本的更新,安装的细节有了些变化,而且,尤其是2024年以后的版本不再使用PWS(Private Web Server), 安装最新版本的IRIS通常同时要安装一个外部的Web服务器,Apache或者nginx。 另外, 大家对自动部署的需要越来越多,因此我也会在下面的内容里面包括自动部署,配置iris, 安装软件等等内容。希望给各位一个基本完整的介绍。

内容列表如下:

基础篇

  • IRIS images的下载和docker run
  • apache-webgateway container到iris的连接
  • nginx-webgateway container到iris的连接
  • iris-main和在container外保存iris数据
  • 配置iris的新方法:CPF merge ...

随时更新

0
0 147
文章 Michael Lei · 九月 27, 2024 8m read

在这一系列文章中,我想向大家介绍并探讨使用 InterSystems 技术和 GitLab 进行软件开发可以采用的几种方式。 我将介绍以下主题:

  • Git 101
  • Git 流程(开发流程)
  • GitLab 安装
  • GitLab 工作流
  • 持续交付
  • GitLab 安装和配置
  • GitLab CI/CD

第一篇文章中,我们介绍了 Git 基础知识、深度理解 Git 概念对现代软件开发至关重要的原因,以及如何使用 Git 开发软件。

第二篇文章中,我们介绍了 GitLab 工作流 – 一个完整的软件生命周期流程,并介绍了持续交付。

第三篇文章中,我们介绍了 GitLab 安装和配置以及将环境连接到 GitLab

在这篇文章中,我们将介绍编写 CD 配置。

计划

环境

首先,我们需要多个环境以及与之对应的分支:

环境分支交付有权提交的角色有权合并的角色
测试master自动开发者、所有者开发者、所有者
预生产preprod自动所有者
生产prod半自动(按下按钮进行交付)

所有者

开发周期

作为示例,我们将使用 GitLab 流程开发一个新功能,并使用 GitLab CD 进行交付。

  1. 在功能分支中开发功能。
  2. 对功能分支进行审查并将其合并到 master 分支中。
  3. 一段时间(合并了多个功能)后,将 master 分支合并到 preprod 分支中
  4. 一段时间(用户测试等)后,将 preprod 分支合并到 prod 分支中

具体如下图所示(我用草图标出了我们需要为 CD 开发的部分):

  1. 开发和测试
    • 开发者将新功能的代码提交到单独的功能分支中
    • 功能稳定后,开发者将功能分支合并到 master 分支中
    • 来自 master 分支的代码被交付到测试环境,在其中进行加载和测试
  2. 交付到预生产环境
    • 开发者创建从 master 分支到 preprod 分支的合并请求
    • 仓库所有者在一段时间后批准合并请求
    • 来自 preprod 分支的代码被交付到预生产环境
  3. 交付到生产环境
    • 开发者创建从 preprod 分支到 prod 分支的合并请求
    • 仓库所有者在一段时间后批准合并请求
    • 仓库所有者按下“部署”按钮
    • 来自 prod 分支的代码被交付到生产环境

也可以用示意图形式表示此流程:

应用程序

应用程序由两部分组成:

  • 在 InterSystems 平台上开发的 REST API
  • 客户端 JavaScript web 应用程序

阶段

通过上面的计划,我们可以确定需要在持续交付配置中定义的阶段:

  • 加载 – 将服务器端代码导入 InterSystems IRIS
  • 测试 – 测试客户端和服务器代码
  • 封装 – 构建客户端代码
  • 部署 – 使用 Web 服务器“发布”客户端代码

以下是它在 gitlab-ci.yml 配置文件中的样式:

stages:
  - load
  - test
  - package
  - deploy

脚本

加载

下面我们来定义脚本。 脚本文档。 我们先来定义用于加载服务器端代码的脚本 load server

load server:
  environment:
    name: test
    url: http://test.hostname.com
  only:
    - master
  tags:
    - test
  stage: load
  script: csession IRIS "##class(isc.git.GitLab).load()"

脚本会执行哪些操作?

  • load server 是脚本名称
  • 接下来,我们来描述此脚本运行的环境
  • only: master – 告知 GitLab 此脚本仅应在向 master 分支进行提交时运行
  • tags: test 指定此脚本仅应在具有 test 标签的运行程序上运行
  • stage 指定脚本的阶段
  • script 定义要执行的代码 在本例中,我们从 isc.git.GitLab 类调用类方法 load

重要说明

对于 InterSystems IRIS,请将 csession 替换为 iris session

对于 Windows,请使用:irisdb -s ../mgr -U TEST "##class(isc.git.GitLab).load()

现在,我们来编写相应的 isc.git.GitLab 类。 此类中的所有入口点如下所示:

ClassMethod method()
{
    try {
        // code
        halt
    } catch ex {
        write !,$System.Status.GetErrorText(ex.AsStatus()),!
        do $system.Process.Terminate(, 1)
    }
}

请注意,可以通过两种方式结束此方法:

  • 停止当前进程 – 在 GitLab 中注册为成功完成
  • 调用  $system.Process.Terminate – 异常终止进程,GitLab 将此情况注册为错误

因此,加载代码如下:

/// Do a full load
/// do ##class(isc.git.GitLab).load()
ClassMethod load()
{
    try {
        set dir = ..getDir()
        do ..log("Importing dir " _ dir)
        do $system.OBJ.ImportDir(dir, ..getExtWildcard(), "c", .errors, 1)
        throw:$get(errors,0)'=0 ##class(%Exception.General).%New("Load error")
    halt
} catch ex {
    write !,$System.Status.GetErrorText(ex.AsStatus()),!
    do $system.Process.Terminate(, 1)
}

}

调用了两个实用方法:

  • getExtWildcard – 获取相关文件扩展名列表
  • getDir – 获取仓库目录

如何获取目录?

执行脚本时,GitLab 会先指定很多环境变量。 其中一个环境变量是 CI_PROJECT_DIR – 克隆仓库以及运行作业位置的完整路径。 我们可以通过 getDir 方法轻松获取:

ClassMethod getDir() [ CodeMode = expression ]
{
##class(%File).NormalizeDirectory($system.Util.GetEnviron("CI_PROJECT_DIR"))
}


测试

以下是测试脚本:

load test:
  environment:
    name: test
    url: http://test.hostname.com
  only:
    - master
  tags:
    - test
  stage: test
  script: csession IRIS "##class(isc.git.GitLab).test()"
  artifacts:
    paths:
      - tests.html

有哪些更改? 当然是名称和脚本代码,但还添加了工件。 工件是作业成功完成后附加到作业的文件和目录列表。 本例中,测试完成后,我们可以生成重定向到测试结果的 HTML 页面,并使其可以通过 GitLab 访问。

请注意,加载阶段有很多复制粘贴的内容 – 环境是相同的,脚本部分(例如环境)可以单独标记并附加到脚本。 我们来定义测试环境:

.env_test: &env_test
  environment:
    name: test
    url: http://test.hostname.com
  only:
    - master
  tags:
    - test

现在,我们的脚本如下:

load test:
  <<: *env_test
  script: csession IRIS "##class(isc.git.GitLab).test()"
  artifacts:
    paths:
      - tests.html

接下来,我们使用 UnitTest 框架执行测试。

/// do ##class(isc.git.GitLab).test()
ClassMethod test()
{
    try {
        set tests = ##class(isc.git.Settings).getSetting("tests")
        if (tests'="") {
            set dir = ..getDir()
            set ^UnitTestRoot = dir
        $$$TOE(sc, ##class(%UnitTest.Manager).RunTest(tests, "/nodelete"))
        $$$TOE(sc, ..writeTestHTML())
        throw:'..isLastTestOk() ##class(%Exception.General).%New("Tests error")
    }
    halt
} catch ex {
    do ..logException(ex)
    do $system.Process.Terminate(, 1)
}

}

本例中,测试设置是相对于存储单元测试的仓库根目录的路径。 如果此处为空,则跳过测试。 writeTestHTML 方法用于输出重定向到测试结果的 html:

ClassMethod writeTestHTML()
{
    set text = ##class(%Dictionary.XDataDefinition).IDKEYOpen($classname(), "html").Data.Read()
    set text = $replace(text, "!!!", ..getURL())
set file = ##class(%Stream.FileCharacter).%New()
set name = ..getDir() _  "tests.html"
do file.LinkToFile(name)
do file.Write(text)
quit file.%Save()

}

ClassMethod getURL() { set url = ##class(isc.git.Settings).getSetting("url") set url = url _ $system.CSP.GetDefaultApp("%SYS") set url = url_"/%25UnitTest.Portal.Indices.cls?Index="_ $g(^UnitTest.Result, 1) _ "&$NAMESPACE=" _ $zconvert($namespace,"O","URL") quit url }

ClassMethod isLastTestOk() As %Boolean { set in = ##class(%UnitTest.Result.TestInstance).%OpenId(^UnitTest.Result) for i=1:1:in.TestSuites.Count() { #dim suite As %UnitTest.Result.TestSuite set suite = in.TestSuites.GetAt(i) return:suite.Status=0 $$$NO } quit $$$YES }

XData html { <html lang="en-US"> <head> <meta charset="UTF-8"/> <meta http-equiv="refresh" content="0; url=!!!"/> <script type="text/javascript"> window.location.href = "!!!" </script> </head> <body> If you are not redirected automatically, follow this <a href='!!!'>link to tests</a>. </body> </html> }

封装

我们的客户端是一个简单的 HTML 页面:

<html>
<head>
<script type="text/javascript">
function initializePage() {
  var xhr = new XMLHttpRequest();
  var url = "${CI_ENVIRONMENT_URL}:57772/MyApp/version";
  xhr.open("GET", url, true);
  xhr.send();
  xhr.onloadend = function (data) {
    document.getElementById("version").innerHTML = "Version: " + this.response;
  };

var xhr = new XMLHttpRequest(); var url = "${CI_ENVIRONMENT_URL}:57772/MyApp/author"; xhr.open("GET", url, true); xhr.send(); xhr.onloadend = function (data) { document.getElementById("author").innerHTML = "Author: " + this.response; }; } </script> </head> <body onload="initializePage()"> <div id = "version"></div> <div id = "author"></div> </body> </html>

要进行构建,需要将 ${CI_ENVIRONMENT_URL} 替换为其值。 当然,实际应用程序可能需要 npm,但此处仅为了举例说明。 脚本如下:

package client:
  <<: *env_test
  stage: package
  script: envsubst < client/index.html > index.html
  artifacts:
    paths:
      - index.html

部署

最后,我们将 index.html 部署到 Web 服务器根目录,以部署客户端。

deploy client:
  <<: *env_test
  stage: deploy
  script: cp -f index.html /var/www/html/index.html

就是这些!

多个环境

如果您需要在多个环境中执行相同(相似)的脚本,应该如何操作? 脚本部分也可以是标签,因此下面给出了在测试和预生产环境中加载代码的示例配置:

stages:
  - load
  - test

.env_test: &env_test environment: name: test url: http://test.hostname.com only: - master tags: - test

.env_preprod: &env_preprod environment: name: preprod url: http://preprod.hostname.com only: - preprod tags: - preprod

.script_load: &script_load stage: load script: csession IRIS "##class(isc.git.GitLab).loadDiff()"

load test: <<: *env_test <<: *script_load

load preprod: <<: *env_preprod <<: *script_load

通过这种方式,我们便无需复制粘贴代码。

有关完整的 CD 配置,请参阅此处。 该配置遵循在测试、预生产和生产环境之间移动代码的原始计划。

结论

可以将持续交付配置为自动执行任何所需的开发工作流。

链接

后续内容

在下一篇文章中,我们将创建利用 InterSystems IRIS Docker 容器的 CD 配置。

0
0 104
文章 Michael Lei · 九月 26, 2024 4m read

在这一系列文章中,我想向大家介绍并探讨使用 InterSystems 技术和 GitLab 进行软件开发可以采用的几种方式。 我将介绍以下主题:

  • Git 101
  • Git 流程(开发流程)
  • GitLab 安装
  • GitLab 工作流
  • 持续交付
  • GitLab 安装和配置
  • GitLab CI/CD

第一篇文章中,我们介绍了 Git 基础知识、深度理解 Git 概念对现代软件开发至关重要的原因,以及如何使用 Git 开发软件。

第二篇文章中,我们介绍了 GitLab 工作流 – 一个完整的软件生命周期流程,并介绍了持续交付。

在这篇文章中,我们将探讨:

  • GitLab 安装和配置
  • 将环境连接到 GitLab

GitLab 安装

我们将在本地安装 GitLab。 可以通过多种方式安装 GitLab – 通过源代码、软件包安装,以及在容器中安装。 我不会在这里详细介绍所有步骤,请参阅相关指南。 但仍需要注意几点:

前提条件:

  • 单独的服务器 – 由于 GitLab 属于 Web 应用程序,并且需要占用大量资源,最好在单独的服务器上运行
  • Linux
  • (可选,但强烈建议采用)域 – 运行页面和保护整个安装时需要

配置

首先,您可能需要发送包含通知的电子邮件

接下来,建议安装 Pages。 正如我们在上一篇文章中所讨论的 – 可以将脚本中的工件上传到 GitLab。 用户可以下载这些工件,但能够直接在浏览器中打开工件将非常有用,为此我们需要使用页面。

需要使用页面的原因:

由于 html 页面会在加载时重定向,可以使用 html 页面将用户重定向到我们需要的位置。 例如,下列代码生成的 html 页面会将用户重定向到上次执行的单元测试(生成 html 时):

ClassMethod writeTestHTML()
{
  set text = ##class(%Dictionary.XDataDefinition).IDKEYOpen($classname(), "html").Data.Read()
  set text = $replace(text, "!!!", ..getURL())

set file = ##class(%Stream.FileCharacter).%New() set name = "tests.html" do file.LinkToFile(name) do file.Write(text) quit file.%Save() }

ClassMethod getURL() { set url = "http://host:57772" set url = url _ $system.CSP.GetDefaultApp("%SYS") set url = url_"/%25UnitTest.Portal.Indices.cls?Index="_ $g(^UnitTest.Result, 1) _ "&$NAMESPACE=" _ $zconvert($namespace,"O","URL") quit url }

XData html { <html lang="en-US"> <head> <meta charset="UTF-8"/> <meta http-equiv="refresh" content="0; url=!!!"/> <script type="text/javascript">window.location.href = "!!!"</script> </head> <body> If you are not redirected automatically, follow this <a href='!!!'>link to tests</a>. </body> </html> }

我使用页面时遇到了错误(浏览工件时出现 502 错误) - 解决方法

 

将环境连接到 GitLab

要运行 CD 脚本,需要使用环境,即配置好的用于运行应用程序的服务器。 假设有一个安装了 InterSystems 产品(例如 InterSystems IRIS,但也可以使用 Caché 和 Ensemble)的 Linux 服务器,可以通过以下步骤将环境连接到 GitLab:

  1. 安装 GitLab 运行程序
  2. 在 GitLab 中注册运行程序
  3. 允许运行程序调用 InterSystems IRIS
有关安装 GitLab 运行程序的

重要说明 - 安装 GitLab 运行程序后请勿克隆服务器。否则,结果将不可预测,并且大多数情况下的结果都不尽如人意。

在 GitLab 中注册运行程序

运行初始程序后:

sudo gitlab-runner register

您会看到多个提示,大部分步骤都非常简单,但有几步比较复杂:

请输入用于此运行程序的 gitlab-ci 令牌

有多个令牌可用:

  • 一个令牌用于整个系统(在管理设置中提供)
  • 一个令牌用于每个项目(在项目设置中提供)

由于您连接运行程序是为特定项目运行 CD,需要指定此项目的令牌。

请输入此运行程序的 gitlab-ci 标签(以逗号分隔):

在 CD 配置中,您可以筛选针对具体标签运行的脚本。 因此,在最简单的情况下,请指定一个将作为环境名称的标签。

请输入执行器:ssh、docker+machine、docker-ssh+machine、kubernetes、docker、parallels、virtualbox、docker-ssh、shell:
docker

如果您使用的是没有 docker 的普通服务器,请选择 shell。我们将在后续部分讨论 docker。

允许运行程序调用 InterSystems IRIS

将运行程序连接到 GitLab 后,我们需要允许运行程序与 InterSystems IRIS 交互,为此:

  1. gitlab-runner 用户应能够调用会话。 为此,请将该用户添加到 cacheusr 组:
    • usermod -a -G cacheusr gitlab-runner
  2. 在 InterSystems IRIS 中创建gitlab-runner 用户,并为其指定相应角色以执行 CD 任务(写入到数据库等)
  3. 允许进行操作系统级身份验证

对于 2 和 3,可以采用其他方式,例如传递用户名/密码,但我认为操作系统身份验证是更好的选择。

结论

在本部分中:

  • 我们安装了 GitLab
  • 将环境连接到 GitLab

后续内容

在下一部分中,我们将编写持续交付配置。

0
0 102
文章 Michael Lei · 九月 26, 2024 7m read

在这一系列文章中,我想向大家介绍并探讨使用 InterSystems 技术和 GitLab 进行软件开发可以采用的几种方式。 我将介绍以下主题:

  • Git 101
  • Git 流程(开发流程)
  • GitLab 安装
  • GitLab 工作流
  • 持续交付
  • GitLab 安装和配置
  • GitLab CI/CD

上一篇文章中,我们介绍了 Git 基础知识、深度理解 Git 概念对现代软件开发至关重要的原因,以及如何使用 Git 开发软件。 我们的侧重点仍是软件开发的实现部分,但本部分会介绍:

  • GitLab 工作流 - 从想法到用户反馈的完整软件生命周期流程
  • 持续交付 – 软件工程方式,团队通过这种方式在短周期内制作软件,从而确保软件可以随时实现可靠发布。 它的目的是更快速、更频繁地构建、测试和发布软件。

GitLab 工作流


GitLab 工作流是软件开发流程整个生命周期中可能采取的操作的逻辑序列。

GitLab 工作流会考虑我们在上一篇文章中探讨的 GitLab 流程。 具体如下:

  1. 想法:每个新提议都始于一个想法。
  2. 问题:探讨想法最有效的方法是为它创建问题。 您的团队和协作者可以在问题跟踪器中帮助您完善和改进问题。
  3. 计划:在讨论达成一致意见后,就可以开始编码了。 但首先,我们需要将问题指定至里程碑和问题看板,以此确定工作流的优先级并进行组织。
  4. 编码:现在,一切安排就绪后,我们就可以编写代码了。
  5. 提交:对草稿满意后,我们便可将代码提交到具有版本控制的功能分支。 上一篇文章详细介绍了 GitLab 流程。
  6. 测试:使用 GitLab CI 运行我们的脚本,以构建并测试应用程序。
  7. 审查:在脚本能够正常运行且测试和构建成功后,我们便可以让代码接受审查并获得批准。
  8. 暂存:现在应该将代码部署到暂存环境,以检查一切是否按预期进行,或者我们是否仍需要进行调整。
  9. 生产:如果一切顺利,便可将代码部署到生产环境!
  10. 反馈:现在可以回顾之前的流程,并检查有哪些阶段的工作需要改进。

再次说明,流程本身不是新的(或者 GitLab 独有的),并且可以通过其他工具来实现。

我们来讨论一下其中的几个阶段以及这些阶段涉及的内容。 还提供文档

问题和计划

GitLab 工作流的开始阶段以问题为中心,问题是指一个功能、一个错误或其他在语义上独立的工作。

问题有多个目的,例如:

  • 管理:问题具有截止日期、指定人员、用时和估计等, 可以帮助跟踪问题解决情况。
  • 行政管理:问题是里程碑的一部分,我们可以通过看板跟踪软件从一个版本过渡到另一个版本的进展。
  • 开发:问题具有与之相关的讨论和提交。

在计划阶段,我们可以按问题的优先级、里程碑、看板将问题分组,并获得问题的概览。

开发在前一部分进行了讨论,只需按照您希望使用的任何 git 流程执行操作即可。 我们开发了新功能并将其合并到 master 分支后,接下来应怎样操作?

持续交付

持续交付是一种软件工程方式,团队通过这种方式在短周期内制作软件,从而确保软件可以随时实现可靠发布。 它的目的是更快速、更频繁地构建、测试和发布软件。 这种方式允许对生产中的应用程序进行更多增量更新,从而帮助缩减交付更改的成本、缩短时间,以及降低风险。 简单且可重复的部署过程对于持续交付非常重要。

GitLab 中的持续交付

在 GitLab 中,持续交付配置按仓库以 YAML 配置文件形式定义。

  • 持续交付配置是一系列连续的阶段
  • 每个阶段都有一个或多个并行执行的脚本

脚本定义了一个操作以及执行该操作需要满足的条件:

  • 要执行的操作(运行 OS 命令、运行容器)?
  • 何时运行脚本:
    • 触发脚本的条件(特定分支)?
    • 之前的阶段失败时是否运行?
  • 手动运行还是自动运行?
  • 脚本在什么环境中运行?
  • 执行脚本后保存哪些工件(这些工件会从环境上传到 GitLab,以便轻松访问)?

环境是配置好的服务器或容器,可用于运行脚本。

运行程序用于在特定环境中执行脚本。 运行程序连接到 GitLab,并根据需要执行脚本。

运行程序可以部署在服务器上、容器上,甚至部署在本地机器上。

持续交付是如何实现的?

  1. 新提交推送到仓库中。
  2. GitLab 检查持续交付配置。
  3. 持续交付配置包含适用于所有情况的全部脚本,因此要过滤出应针对这一特定提交运行的一组脚本(例如提交到 master 分支仅会触发与 master 分支相关的操作)。 这组脚本称为管道
  4. 管道是在目标环境中执行的,执行结果会保存并显示在 GitLab 中。

例如,下面是提交到 master 分支后执行的一个管道:

管道包含四个阶段,各阶段连续执行

  1. 加载阶段会将代码加载到服务器中
  2. 测试阶段会运行单元测试
  3. 封装阶段包含两个并行运行的脚本:
    • 构建客户端
    • 导出服务器代码(主要用于提供信息)
  4. 部署阶段会将构建的客户端移动到 Web 服务器目录中。

我们可以看到,每个脚本都成功运行,如果其中一个脚本运行失败,则默认不会运行后面的脚本(但我们可以更改此行为):

如果我们打开脚本,可以查看日志并确定脚本运行失败的原因:

Running with gitlab-runner 10.4.0 (857480b6)
 on test runner (ab34a8c5)
Using Shell executor...
Running on gitlab-test...
Fetching changes...
Removing diff.xml
Removing full.xml
Removing index.html
Removing tests.html
HEAD is now at a5bf3e8 Merge branch '4-versiya-1-0' into 'master'
From http://gitlab.eduard.win/test/testProject
 * [new branch] 5-versiya-1-1 -> origin/5-versiya-1-1
 a5bf3e8..442a4db master -> origin/master
 d28295a..42a10aa preprod -> origin/preprod
 3ac4b21..7edf7f4 prod -> origin/prod
Checking out 442a4db1 as master...Skipping Git submodules setup$ csession ensemble "##class(isc.git.GitLab).loadDiff()"

[2018-03-06 13:58:19.188] Importing dir /home/gitlab-runner/builds/ab34a8c5/0/test/testProject/

[2018-03-06 13:58:19.188] Loading diff between a5bf3e8596d842c5cc3da7819409ed81e62c31e3 and 442a4db170aa58f2129e5889a4bb79261aa0cad0

[2018-03-06 13:58:19.192] Variable modified var=$lb("MyApp/Info.cls")

Load started on 03/06/2018 13:58:19 Loading file /home/gitlab-runner/builds/ab34a8c5/0/test/testProject/MyApp/Info.cls as udl Load finished successfully.

[2018-03-06 13:58:19.241] Variable items var="MyApp.Info.cls" var("MyApp.Info.cls")=""

Compilation started on 03/06/2018 13:58:19 with qualifiers 'cuk /checkuptodate=expandedonly' Compiling class MyApp.Info Compiling routine MyApp.Info.1 ERROR: MyApp.Info.cls(version+2) #1003: Expected space : '}' : Offset:14 [zversion+1^MyApp.Info.1] TEXT: quit, "1.0" } Detected 1 errors during compilation in 0.010s.

[2018-03-06 13:58:19.252] ERROR #5475: Error compiling routine: MyApp.Info.1. Errors: ERROR: MyApp.Info.cls(version+2) #1003: Expected space : '}' : Offset:14 [zversion+1^MyApp.Info.1] > ERROR #5030: An error occurred while compiling class 'MyApp.Info' ERROR: Job failed: exit status 1

编译错误导致脚本失败。

结论

  • GitLab 支持软件开发的所有主要阶段。
  • 持续交付可以帮助您自动执行软件构建、测试和部署任务。

后续内容

在下一篇文章中,我们将:

  • 安装 GitLab。
  • 将它连接到多个安装了 InterSystems 产品的环境。
  • 编写持续交付配置。

我们来探讨一下持续交付的运作方式。

首先,我们需要多个环境以及与之对应的分支。 代码进入此分支,并交付到目标环境:

环境分支交付有权提交的角色有权合并的角色
测试master自动开发者、所有者开发者、所有者
preprod预生产自动所有者
prod生产半自动(按下按钮进行交付)

所有者

作为示例,我们将使用 GitLab 流程开发一个新功能,并使用 GitLab CD 进行交付。

  1. 在功能分支中开发功能。
  2. 对功能分支进行审查并将其合并到 master 分支中。
  3. 一段时间(合并了多个功能)后,将 master 分支合并到 preprod 分支中
  4. 一段时间(用户测试等)后,将 preprod 分支合并到 prod 分支中

具体如下图所示:

  1. 开发和测试
    • 开发者将新功能的代码提交到单独的功能分支中
    • 功能稳定后,开发者将功能分支合并到 master 分支中
    • 来自 master 分支的代码被交付到测试环境,在其中进行加载和测试
  2. 交付到预生产环境
    • 开发者创建从 master 分支到 preprod 分支的合并请求
    • 仓库所有者在一段时间后批准合并请求
    • 来自 preprod 分支的代码被交付到预生产环境
  3. 交付到生产环境
    • 开发者创建从 preprod 分支到 prod 分支的合并请求
    • 仓库所有者在一段时间后批准合并请求
    • 仓库所有者按下“部署”按钮
    • 来自 prod 分支的代码被交付到生产环境

也可以用示意图形式表示此流程:

 

0
0 98
文章 Michael Lei · 九月 26, 2024 6m read

大家都搭建了测试环境。

有些人很幸运,可以在完全独立的环境中运行生产。

-- 佚名

.

在这一系列文章中,我想向大家介绍并探讨使用 InterSystems 技术和 GitLab 进行软件开发可以采用的几种方式。 我将介绍以下主题:

  • Git 101
  • Git 流程(开发流程)
  • GitLab 安装
  • GitLab 工作流
  • GitLab CI/CD
  • 包含容器的 CI/CD

第一部分将介绍现代软件开发的基础 – Git 版本控制系统和各种 Git 流程。

Git 101

虽然我们将主要探讨软件开发的概况以及 GitLab 如何帮助我们实现这一目标,但 Git,或者说 Git 设计中的几个基础的高级概念对于更好地理解后面的概念非常重要。

也就是说,Git 是基于这些概念的版本控制系统(还有更多概念,但这几个概念最为重要):

  • 非线性开发意味着,虽然我们的软件是从版本 1 到版本 2、再到版本 3 相继发布的,但实际上从版本 1 到版本 2 的升级是并行完成的 – 多名开发者会同时开发许多功能/错误修复。
  • 分布式开发意味着开发者独立于一个中央服务器或其他开发者,可以轻松地在自己的环境中进行开发。
  • 合并 – 基于前面提到的两个概念,我们会发现很多不同的版本同时存在,我们需要将它们统一成一个完整的状态。

我的意思不是说 Git 发明了这些概念。 Git 并没有发明这些概念, 而是使这些概念变得简单、流行,并加入了多个相关创新概念,也就是说,架构即代码/容器化改变了软件开发。

核心 git 术语

仓库是存储数据以及关于数据的元信息的项目。

  • “从物理层面来讲”,仓库是磁盘上的目录。
  • 仓库用于存储文件和目录。
  • 仓库还会存储每个文件的完整变更历史。

仓库可以:

  • 存储在您自己的计算机本地
  • 远程存储在远程服务器上

但从 git 的角度来看,本地仓库与远程仓库之间没有特殊的区别。

提交是仓库的固定状态。 很显然,如果每次提交都存储仓库的完整状态,我们的仓库很快就会变得非常大。 因此,提交会存储差异,也就是当前提交与其父提交之间的差异。

不同的提交可以具有不同数量的父提交:

  • 0 个 – 仓库中的第一个提交没有父提交。
  • 1 个 – 一切如常 - 我们的提交改变了仓库中的某些内容,就像在父提交期间一样
  • 2 个 – 当我们有两个不同的仓库状态时,我们可以将它们合并成一个新状态。 该状态和该提交就会有 2 个父提交。
  • >2 个 – 当我们将 2 个以上的不同仓库状态合并为一个新状态时,就会有 2 个以上的父提交。 这一概念与我们的讨论并没有特别大的关系,但它确实存在。

现在,对于父提交,每个与之不同的提交都被称为子提交。 每个父提交可以有任意数量的子提交。

分支是对提交的引用(或指针),如下图所示:

该图像显示的仓库具有两个提交(灰色圆圈),第二个圆圈是 master 分支的头部。 在我们添加更多提交后,仓库开始变成下图所示的状态:

这是最简单的情况。 我们的开发者一次负责处理一个更改。 但通常会有很多开发者同时负责处理不同的功能,我们需要使用提交树显示仓库中的变化。

提交树

我们从相同的起始状态开始。 仓库具有两个提交:

但现在,两名开发者在同时工作,为了避免相互干扰,他们在单独的分支中工作:

一段时间后,他们需要合并所做的更改,为此,他们创建了合并请求(也叫拉取请求), 顾名思义,该请求可将两个不同的仓库状态(本例中,我们要将 develop 分支合并到 master 分支中)合并为一个新状态。 接受相应审查并获得批准后,仓库状态如下图所示:

开发继续进行:

Git 101 - 总结

主要概念:

  • Git 是一个非线性的分布式版本控制系统。
  • 仓库用于存储数据以及关于数据的元信息。
  • 提交是仓库的固定状态。
  • 分支是对提交的引用。
  • 合并请求(也叫拉取请求)是将两个不同的仓库状态合并为一个新状态的请求。

如果您想了解更多关于 Git 的信息,可以阅读相关书籍

Git 流程

现在,读者已熟悉基本的 Git 术语和概念,我们来探讨一下如何使用 Git 管理软件生命周期的开发部分。很多实践(称为流程)介绍了使用 Git 的开发流程,但我们只会探讨其中两个:

  • GitHub 流程
  • GitLab 流程

GitHub 流程

GitHub 流程非常简单。 具体如下:

  1. 从仓库创建一个分支。
  2. 将更改提交到新分支
  3. 从您的分支发送一个拉取请求,其中包含您提议的更改,以发起讨论。
  4. 根据需要在您的分支上提交更多更改。 您的拉取请求将自动更新。
  5. 在分支准备好合并后,立即合并拉取请求。

我们需要遵守几条规则:

  • master 分支始终可部署(并且可正常运行!)
  • 不直接在 master 分支中进行开发
  • 在功能分支中进行开发
  • master 分支 == 生产* 环境**
  • 需要尽可能频繁地部署到生产环境

* 不要与“Ensemble 生产”混淆,这里的“生产”是指正式。

** 环境是配置好的代码运行位置,可以是服务器、虚拟机,甚至可以是容器。

如下图所示:

有关 GitHub 流程的更多信息,请参阅此处。 我们还提供了图解指南

GitHub 流程非常适合小型项目,如果您刚开始使用 Git 流程,可以尝试一下。 不过,GitHub 也会使用 GitHub 流程,因此也可以在大型项目中使用 GitHub 流程。

GitLab 流程

如果您还没有准备好立即部署到生产环境,GitLab 流程提供 GitHub 流程 + 环境。 具体做法是:在功能分支中进行开发(与上例相同),合并到 master 分支中(与上例相同),但这里有一个不同之处: master 分支仅等同于测试环境。 除此之外,还有链接到可能存在的各种其他环境的“环境分支”。

通常存在三个环境(可以根据需要创建更多环境):

  • 测试环境 == master 分支
  • 预生产环境 == preprod 分支
  • 生产环境 == prod 分支

进入其中一个环境分支的代码应立即移至相应的环境中,此流程可通过以下方式完成:

  • 自动(我们将在第 2 部分和第 3 部分探讨)
  • 半自动(与自动方式相同,唯一的区别是应按下按钮授权部署)
  • 手动

完整的流程是:

  1. 在功能分支中开发功能。
  2. 对功能分支进行审查并将其合并到 master 分支中。
  3. 一段时间(合并了多个功能)后,将 master 分支合并到 preprod 分支中
  4. 一段时间(用户测试等)后,将 preprod 分支合并到 prod 分支中
  5. 在我们进行合并和测试时,多个新功能已开发完毕并合并到 master 分支中,因此转到  3。

具体如下图所示:

有关 GitLab 流程的更多信息,请参阅此处

结论

  • Git是一个非线性的分布式版本控制系统。
  • Git 流程可用作软件开发周期的准则,有多种 Git 流程可供选择。

链接

讨论问题

  • 您使用 Git 流程吗? 使用哪一种?
  • 您为普通项目使用多少个环境?

后续内容

在接下来的部分中,我们将:

  • 安装 GitLab。
  • 探讨一些建议的调整。
  • 讨论 GitLab 工作流(不要与 GitLab 流程混淆)。

敬请关注。

0
0 129
文章 Yongfeng Hou · 十一月 23, 2023 3m read

        IRISHealth以其完备且系统化的安全特性在医疗行业的数据库中独树一帜,这些特性包括安全认证、安全授权、安全审计、数据加密以及安全配置。其中数据传输无疑是其中最重要的一环。为此,IRISHealth采用了SSL/TLS技术来对传输的数据进行加密,有效保障了从IRIS数据平台的超级服务数据传输、Telnet服务数据传输、java/.net/Studio客户端的访问数据传输、MIRROR与DB的数据传输,到DBServer和ECPApp之间的数据传输的安全性。


        本文是在两个IRISHealth2021实例之间进行ECP服务通信的示例,一个作为DBServer,一个作为ECPApp,两个实例之间通过使用SSL/TLS的ECP协议进行TCP的加密传输通信。

1.IRIS的DB和ECP环境:

DBServer 

ECPApp

10.1.30.231  10.1.30.232

 

2. CA证书的环境:

5
3 380
文章 Hao Ma · 五月 24, 2023 4m read

Manifest也许应该被翻译成“清单”, 字典上是这么解释的: 提供船舶及其货物和其他物品、乘客和船员的全面细节的文件,供海关官员使用,比如:飞机上的乘客或货物清单; 一辆货运列车的车厢清单。

在计算机语言中, Manifest可以是各种格式,用的最多的是xml和json,在IRIS中,manifest是xml格式的, 放在objectscript类的XDATA块里。

编写mainfest

IRIS用manifest来做配置。内部工具*%install*, 会读取manifest, 生成真正的objectscript代码来配置IRIS。我们来看个基本的例子。

基本用法

下面的User.Manifest.cls` ,它配置了IRIS的global buff, bbsize等等, 然后还创建了一个命名空间。

Include %occInclude
Class User.Manifest
{

ClassMethod setup(ByRef pVars, pLogLevel As %Integer = 3, pInstaller As %Installer.Installer, pLogger As %Installer.AbstractLogger) As %Status [ CodeMode = objectgenerator, Internal ]
{      
   Quit ##class(%Installer.Manifest).%Generate(%compiledclass, %code, "MyInstall")
}

XData MyInstall [ XMLNamespace = INSTALLER ]{
<Manifest>
	<SystemSetting Name="Config.config.gmheap" Value="50000"/>
   <SystemSetting Name="Config.config.locksiz" Value="5000000"/>
   <SystemSetting Name="Config.config.routines" Value="256"/>
   <SystemSetting Name="Config.config.globals8kb" Value="600"/>
   <SystemSetting Name="Config.config.wijdir" Value="/cache/wij"/>
   <SystemSetting Name="Config.Journal.CurrentDirectory" Value="/journal1"/>
   <SystemSetting Name="Config.Journal.AlternateDirectory" Value="/journal2"/>
   <SystemSetting Name="Config.Miscellaneous.EnableLongStrings" Value="1"/>
   <Namespace Name="TUOTANTO" Create="yes" Code="TUOTANTO-R" Data="TUOTANTO-D">
   	<Configuration>
    		<Database Name="TUOTANTO-R" Create="yes" Dir="/cache/database/TUOTANTO-R"/>
    		<Database Name="TUOTANTO-D" Create="yes" Dir="/cache/database/TUOTANTO-D"/>
    	</Configuration> 
    </Namespace>   
</Manifest>
}
}


稍微解释一下代码:

  • Include %occInclude是必须的

  • setup()用来读取manifest的内容,完成配置工作。用户基本不用修改这个method。

  • mainifest本身的逻辑层次很清楚,要配置什么内容查查文档都可以。上面的manifest只是个示意,真正用起来可以需要非常多的配置项,比如namespace, database的配置,有很多的标签可选。

传参数给manifest

调用manifest的method, 也就是例子里的setup(), 注意第一个参数是ByRef pVars。这是objectscript里常用的By referrence的传参方式。请看下面的例子:

Include %occInclude
Class User.Manifest
{

ClassMethod main(){
   Set pVars("Namespace")="MYNAMESPACE"
   Set pVars("AnotherKey")= "AnotherValue"
   $$$ThrowOnError(..CreateNamespace(.pVars))
}

ClassMethod CreateNamespace(ByRef pVars, pLogLevel As %Integer = 3, pInstaller As %Installer.Installer, pLogger As %Installer.AbstractLogger) As %Status [ CodeMode = objectgenerator, Internal ]{      
   Quit ##class(%Installer.Manifest).%Generate(%compiledclass, %code, "CreateNamespace")
}

XData CreateNamespace [ XMLNamespace = INSTALLER ]{
<Manifest>
	<Log Text="This is the content of ${AnotherKey}" Level="0" />
   <Namespace Name="${Namespace}" Create="yes" Code="${Namespace}" Data="${Namespace}" Ensemble="1">
		<Configuration>
			<Database Name="${Namespace}" Create="yes" Dir="${MGRDIR}/${Namespace}" Resource="%DB_${Namespace}" PublicPermissions="RW" MountAtStartup="true" />
		</Configuration>	
	</Namespace>
</Manifest>
}
}

上面code在main()里定义了一个pVars, 放了两个key-value, 用来调用CreateName()。 定义的namespace在manifest用到了, Anotherkey被用在了log里, 只是一个示意。

注意这个定义: Dir="${MGRDIR}/${Namespace}"。 其中的MGRDIR不需要自己定义。Manifest有一堆自己定义的Variable, 用的最多的是 CFGDIR, CSPDIR, INSTALLDIR, MGRDIR, PORT等等。具体列表见文档。

更多的用法

下面这个例子包括了import文件和copy文件, SourceDirNamespace是传入的参数。导入文件要在一个namespace的定义里面, 拷贝文件和命名空间无关。

<Manifest>	
   <Namespace Name="${Namespace}">
		<Import File="${SourceDir}/code.xml" Flags="ck" Recurse="1"/>
	</Namespace>
   <CopyDir Src="${SourceDir}/xslfiles" Target="${CSPDIR}/xslt" IgnoreErrors="0"/>
   <CopyFile Src="${SourceDir}/a.html" Target="${CSPDIR}/hcc" IgnoreErrors="0"/>
</Manifest>

CSPApplication

在manifest里定义cspapplication不难,麻烦的是不同的版本使用的标签上会有修改。下面给了一个例子。

<Manifest>
	<Namespace Name="flagger">
      <CSPApplication CSPZENEnabled="1" LoginClass="/csp/flagger/Flagger.LoginAuth.cls" CustomErrorPage="/csperror.csp" ChangePasswordPage="/csp/flagger/ChangePassword.cls" AutoCompile="1" Url="/csp/flagger" IsNamespaceDefault="1" InboundWebServicesEnabled="1" Recurse="1" AuthenticationMethods="64" DefaultTimeout="900" Directory="${CSPDIR}flagger" UseSessionCookie="2" CookiePath="/csp/flagger/" ServeFiles="1" ServeFilesTimeout="3600"/>
   </Namespace>
</Manifest>

调用代码的例子

<Manifest>
	<Role Name="${PMGNAMESPACE}" Description="Works User Role for ${PMGNAMESPACE} Namespace" Resources='"_tInstaller.Evaluate("${PMGDbResource}:RW,PMG:RWU")_"' RolesGranted="" />
	<!-- set locale -->
	<Namespace Name="%SYS" Create="no">
		<Log Text="Changing the Locale" Level="0" />
		<Invoke Class="Config.NLS.Locales" Method="Install" CheckStatus="true">
			<Arg Value="chew" />		
		</Invoke>
    </Namespace>
   <Namespace Name="flagger">
   	<Invoke Class="IRISConfig.Installer" Method="LoadTransactionalData" CheckStatus="true">
			<Arg name="pNamespace" Value="${Namespace}"/>
		</Invoke>
   </Namespace>
</Manifest>

创建User, Role

<Manifest>
	<User Username="ISC" PasswordVar="PASSWORD" Roles="%All" Fullname="ISC" Comment=""/>
   <Role Name="${PMGNAMESPACE}" Description="Works User Role for ${PMGNAMESPACE} Namespace" Resources='"_tInstaller.Evaluate("${PMGDbResource}:RW,PMG:RWU")_"' RolesGranted="" />
</Manifest>

Nampespace Mapping

<Manifest>
    <Namespace Name="FHIRNS">
		<Configuration>
			<Database Name="FHIRNS"/>
            <GlobalMapping Global="%SYS" From="IRISSYS"/> 
            <GlobalMapping Global="OAuth2.*" From="HSSYS"/> 
            <GlobalMapping Global="SchemaMap.*" From="HSLIB"/> 
            <ClassMapping Package="HS" From="HSLIB"/>
            <ClassMapping Package="HS.Local" From="HSCUSTOM"/>
            <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.*" From="HSLIB"/>
		</Configuration>
	</Namespace>
</Manifest>

其他还有很多的用法。想了解更多,可以看看文档说明里的Tag列表, 和template

怎么执行cls文件

Using the Manifest

在Terminal里执行

%SYS>do ##class(MyPackage.MyInstaller).setup()

或者, 带上参数

%SYS>set vars("SourceDir")="c:\myinstaller"
%SYS>set vars("Updated")="Yes"
%SYS>do ##class(MyPackage.MyInstaller).setup(.vars,3)

During IRIS安装

Export the manifest class as DefaultInstallerClass.xml to the same directory where the InterSystems IRIS install (either .msi, setup_irisdb.exe, or irisinstall) is run. It is imported into %SYS and compiled, and the setup() method is executed.

那么是irisinstall里面的什么语句在执行manifest呢?

# script, 用ISC_INSTALLER_MANIFEST, installer-manifest-example.xml

[root@silent jhvinstall]# cat cache_install.sh
#!/bin/bash
echo -n "Installing Cache..."
ISC_INSTALLER_MANIFEST=$3 ISC_PACKAGE_INSTANCENAME=$1 ISC_PACKAGE_INSTALLDIR=$2 ISC_PACKAGE_UNICODE="Y" ISC_PACKAGE_INITIAL_SECURITY="Minimal" ISC_PACKAGE_MGRUSER="cacheusr" ISC_PACKAGE_MGRGROUP="cacheusr" 
ISC_PACKAGE_USER_PASSWORD="sys" ./cinstall_silent

[root@silent jhvinstall]# ./cache_install.sh CACHE6 "/cache/tmpcache6" "/tmp/installer-manifest-example.xml"
Installing Cache...

写一个脚本执行

这里给一个脚本的例子,简短,但内容很丰富。

#!/bin/bash
# Usage install.sh [instanceName] [password]
instanceName=$1
password=$2
DIR=$(pwd)
ClassImportDir=$DIR/install
NameSpace="ENSDEMO"
CspPath="/csp/ensdemo"
SrcDir=$DIR/src/CLS
DirFront=$DIR/src/CSP/csp/demo

irissession $instanceName -U USER <<EOF 
SuperUser
$password
do \$system.OBJ.ImportDir("$ClassImportDir","*.cls","cubk",.errors,1)
write "installer导入成功"
Set pVars("DirBin")="$DIR/ENSDEMO"
Set pVars("DirFront")="$DirFront"
Set pVars("NAMESPACE")="$NameSpace"
Do ##class(App.Installer).setup(.pVars)
zn "%SYS"
set props("DeepSeeEnabled")=1
set sc=##class(Security.Applications).Modify("$CspPath", .props)
zn "$NameSpace"
do \$system.OBJ.ImportDir("$SrcDir","*.cls","cubk",.errors,1)
halt
EOF
1
0 197
文章 Michael Lei · 二月 5, 2023 1m read

通常,如果你想部署一个解决方案,你需要手动添加项目、配置你的查找表和默认配置。
如果您拥有执行这些操作的所有权限,那也没关系。如果您想部署到客户的生产服务器,但您没有权限,则需要在文档中指明系统部署必须执行的所有步骤。

0
0 205
文章 Michael Lei · 十二月 7, 2022 11m read

大家好!

这是关于使用 Docker 初始化 IRIS 实例的系列文章中的第三篇。 这次,我们将关注企业缓存协议(Enterprise Cache Protocol,ECP)。

ECP 允许以一种非常简单的方式将某些 IRIS 实例配置为应用程序服务器,将其他实例配置为数据服务器。 有关详细的技术信息,请参阅官方文档。

本文旨在介绍:

  • 如何编写数据服务器的初始化脚本,以及如何编写一个或多个应用程序服务器的初始化脚本。
  • 如何使用 Docker 在这些节点之间建立加密连接。

为此,我们通常使用我们在以前的 Web 网关中已经看到的一些工具,以及描述 OpenSSL、envsubst 和 Config-API 等工具的镜像文章。

要求

ECP 不适用于 IRIS 社区版。 因此,需要访问全球响应中心才能下载容器许可证并连接到 containers.intersystems.com 注册表。

准备系统

系统必须与容器共享一些本地文件。 需要创建特定用户和组来避免出现“访问被拒绝”错误。

0
0 186
文章 Chang Liu · 九月 22, 2022 2m read

1,准备

    本次安装环境:Kylin-Server-10-SP2-Release-Build09-20210524-x86_64.iso

    安装系统适配的对应版本:HealthConnect-2021.1.2.338.0-lnxubuntux64.tar.gz;ISCAgent-2021.1.2.338.0-lnxubuntux64.tar.gz

     系统语言选择:English(必要)

2,安装HealthConnect+webgateway

  2.1  新建所需用户组

  groupadd iscagent

 2.2  解压文件

2.3 安装

  本次安装,使用root用户及root用户组安装,超级端口改为51773

3,安装ISCAgent

  3.1安装说明

  ISCAgent是healthconnect的镜像服务,若是单机使用,则不需要安装。

  3.2  解压文件

    

 3.3  安装

 

3.3  加入服务

3.3.1   新建文件

  /etc/systemd/system 下创建文件,ISCAgent.service,内容如下:

 [Unit]

Description=InterSystems Agent

After=syslog.target network-online.target

[Service]

8
0 421
文章 Tete Zhang · 十月 26, 2022 3m read

上线一个新的集成平台production或者组件是需要很多精力的,用户常常需要对每一个组件所满足的需求和所能提供的功能,使用到的协议,以及组件对系统资源的调用有深入细致的了解。在配置好一个production之后,您可能需要将这个production推送到测试或者正式环境,或者需要将一个写好的组件代码应用到不同的项目上。这些时候,production的导出功能可以方便您传输production或组件的配置和代码。

导出

需要导出production时,您可以移步到管理门户 - Interoperability - 相应的命名空间 - 列表 - Production 页面,选择您需要导出的production,再点击页面上的导出键进行导出。如下图1所示:

在弹出的对话框中,您可以选择在导出文件中您想包括的内容。如下图2所示:

您也可以通过管理门户 - Interoperability - 相应的命名空间 - 配置 - Production 页面,点击“Production 设置” - “操作”选项卡 - “导出”键进行导出。弹出的对话框同样如图2所示,会自动包括大部分production及其组件所需要的类。如果需要添加或更改导出的类,可以在此对话框进行操作。

0
1 216
文章 Hao Ma · 九月 17, 2022 10m read

把数据库添加进Mirror

以往的经验里, 用户在把数据库添加到镜像时遇到过各种各样的问题,以致必须请求外部帮助才能解决。除了步骤本身比较繁琐,很大的原因是阅读文档不细致。还有一个,就是对英文水平不太高的用户,有些英文句式并不是很好懂,比如说,文档中有这一句其实非常关键:

If you attempt to add a new database to the mirror on a nonprimary member that was not created as a mirrored database on the primary, but rather added to the mirror after it was created, an error message notes this and you cannot complete the operation.

我用最好的翻译器DeepL翻译后的中文是:

如果你试图在一个非主要成员上向镜像添加一个新的数据库,而这个数据库并不是在主要成员上作为镜像数据库创建的,而是在创建后添加到镜像中的,那么就会出现错误信息提示,你无法完成操作。

很讨厌的是它没用说明错误信息是什么,以致于很多用户, 当他们在Backup成员中把一个数据库添加到镜像时,遇到相关的错误时,没有把问题和这句话关联起来,这个错误提示是这样的:

“错误 #2105: 与成员 SERVERA/IRIS 中的相匹配的数据库 :mirror:AUGEST:DEMO 未被创建为镜像数据库”。

或者用英文,

ERROR #2105: Matching mirrored DB :mirror:AUGEST:DEMO in member SERVERA/IRIS was not created as mirrored DB

我来解释一下这句话,它说的是: ”嘿, 你在本机要添加的:mirror:AUGEST:DEMO数据库, 它在主镜像成员SERVERA/IRIS里, 未被创建为镜像数据库。“

如果您看了我的解释, 还觉得莫名其秒,我相信您其实是没懂这个关键点:

“一个数据库创建成镜像数据库,和创建成普通数据库后面后再添加到镜像里,它们是不同的。”

关于这一点,其实文档也有说明,啰嗦,但说明了原因。直接上翻译:

创建镜像数据库(即添加一个不含数据的新数据库)的过程与向镜像添加现有数据库的过程不同。作为镜像数据库创建的数据库上的Global操作从一开始就被记录在镜像Journal中,因此镜像可以访问它所需要的所有数据,以便在镜像成员之间同步数据库。但现有数据库在被添加到镜像之前的Global操作包含在非镜像Journal文件中,镜像不能访问这些文件。由于这个原因,一个现有的数据库在被添加到镜像后,必须在主故障转移成员上进行备份,并在备份故障转移成员和它要所在的任何异步成员上进行恢复。一旦这样做了,你必须激活并赶上数据库,使其与主数据库保持同步。

清楚了这个关键, 您才能理解为什么安装步骤分为下面的两个类型,

  • 创建新的镜像数据库
  • 将已有的数据库加入镜像

TIP: 另外,还有一个值得提醒的:只有用户自己的数据库可以被加入镜像。系统本身的数据库, 比如IRISSYS, IRISLIB, IRISTEMP等等,都不能加入镜像。早期有些版本可以,NOMORE!

创建新的镜像数据库

  • 主镜像成员的系统维护界面上,选择System Administration – Configuration – System Configuration – Local Databases , 选择Create New Database. 在数据库创建向导窗口,在“镜像数据库?”下拉菜框,选择'是‘(Yes)

<img src="/sites/default/files/inline/images/image-20220915132341910.png" alt="" style="zoom: 33%/>

创建成功后,维护界面会回到数据库创建页面。在下面数据库列表里,您可以看到的NEWDB前面加入了镜像的名称AUGUEST。

查看镜像监视器, 您会看到这个数据库已经成功添加入了镜像,状态为“一般”。英文原文为“Normal”,请无视优秀的翻译。

Tip: 要把数据库从镜像里移除,在“系统操作>镜像监视器“里操作。

这时候您如果去其他的镜像成员的镜像监视器里查看, 会发现如下的内容, 表示这个成员已经收到了Primary的消息:"嘿,我主机上把这个数据库加到了镜像里。"

  • 在每一个镜像成员中, 无论是backup还是异步成员,创建相同名字的本地数据库。同样的操作,选择相同的文件路径,同样在“镜像数据库?”下拉框回答Yes。创建好之后,您会看到镜像监视器里,这个数据库已经添加成功。如果在您当前操作的机器上查看镜像监视器, 您会发现和Primary里看到的稍有不同, 象这样:

​ (注意它的状态是Dejournaling, 表示它在正常的接收或者准备接收主机发来的数据同步)

  • 检查数据库工作正常
    • 在所有的镜像成员上一个个的创建使用NEWDB的命名空间。在各个机器上必须保持一致,一样的名称,一样的资源等等。(理论上不必要,但维护中非常必要)
    • 在Primary上做一个数据库操作。我喜欢在“系统资源管理器>SQL"页面执行SQL语句,比如CREATE TABLE Persons(Id int, Name varchar(255))。注意先要切换到创建的命名空间
    • 在所有的镜像成员上, 查看“系统资源管理器>SQL"页面, 确认表Persons同步到了所有的镜像成员。

这里如果您遇到上面提到的“Error 2105“, 那就是这个数据库在Primary上先是创建成一般数据库,然后加入的镜像,那您应该按下面的步骤操作了。

如果有人好奇:在Primary上的这种区别,Backup是怎么知道的,它不是还没加入到镜像吗? 故事是这样的: 镜像日志中同步的不是只有镜像数据库的数据的修改, 还包括IRISSYS, IRISAUDIT,等库的内容。NEWDB在主成员中是怎么加入到镜像的, IRISSYS里的Global Set是不一样的,而这个set, 是同步给备用成员backup的。 又一个没用的知识。

将已有的数据库加入镜像

已有的(Existing)数据库是指原本在主成员里按普通数据库创建的,然后加入镜像的数据库。

这样的情况,哪怕同样名称,配置的数据库在其他成员上已经有了。能直接加入镜像吗?比如你主成员上有个User, 备用成员上也有,您能在主机, 备机直接把它们加入镜像吗?

答案是肯定不行。系统根本没法保证这两个库里面已有的数据是一样的。您要在主成员上备份数据库,在其他成员恢复, 而恢复操作成功后,在其他成员上,这个数据库自动变成了“镜像数据库”, 也就是加入了镜像。

这个同名的数据库要先在其他成员上创建。创建成普通数据库。如果其他成员上已经有了,也不用删除,就直接用主机的备份文件覆盖就好。

以下是详细的步骤:

  • 在主机的“系统>配置>本地数据库“页面, 点击添加到镜像按钮。然后在跳出窗口中选中您要添加的数据库,可以一次选多个。 数据库很大或者多个数据库同时加入是,可以选中”在后台运行“。通常这个添加动作是在秒级时候内完成的,无所谓是否后台运行。
  • 到镜像监视器查看添加的结果。被添加的数据库状态这时候应该是"一般"(Normal) 。

  • 到其他镜像成员的镜像监视器查看, 您会看到主机来的通知引发的提醒:

  • 在备机检查自己的数据库状态。如果没有DEMO或者USER数据库,那么创建它们,创建时下拉框”是否镜像?”选择否或者NO。之后在本地数据库列表中它们应该是这样,注意没有在镜像里。
  • 在Primary做数据库的在线备份, 用于后面步骤里到其他成员上去做数据库恢复。

    以下过程仅供参考:

# 在主成员备份,并发送给备份成员serverb

%SYS>do ^BACKUP


1) Backup
2) Restore ALL
3) Restore Selected or Renamed Directories
4) Edit/Display List of Directories for Backups
5) Abort Backup
6) Display Backup volume information
7) Monitor progress of backup or restore

Option? 1


*** The time is: 2022-09-17 15:27:48 ***

                 InterSystems IRIS Backup Utility
              --------------------------
What kind of backup:
   1. Full backup of all in-use blocks
   2. Incremental since last backup
   3. Cumulative incremental since last full backup
   4. Exit the backup program
1 => 1
Specify output device (type STOP to exit)
Device: /isc/FullDBList_user.cbk => /isc/setmirror.cbk
Backing up to device: /isc/setmirror.cbk
Description:


Backing up the following directories:
 /isc/data/demo/
 /isc/iris/mgr/user/


Start the Backup (y/n)? => y
Journal file switched to:
/isc/jrnpri/MIRROR-AUGEST-20220917.011


Starting backup pass 1
Backing up /isc/data/demo/ at 09/17/2022 15:28:26
Copied 82 blocks in 0.004 seconds

Finished this pass of copying /isc/data/demo/

Backing up /isc/iris/mgr/user/ at 09/17/2022 15:28:28
Copied 908 blocks in 0.475 seconds

Finished this pass of copying /isc/iris/mgr/user/

Backup pass 1 complete at 09/17/2022 15:28:29

Starting backup pass 2
Backing up /isc/data/demo/ at 09/17/2022 15:28:31
Copied 2 blocks in 0.000 seconds

Finished this pass of copying /isc/data/demo/

Backing up /isc/iris/mgr/user/ at 09/17/2022 15:28:33
Copied 2 blocks in 0.000 seconds

Finished this pass of copying /isc/iris/mgr/user/

Backup pass 2 complete at 09/17/2022 15:28:33

Starting backup pass 3

Journal file '/isc/jrnpri/MIRROR-AUGEST-20220917.010' and the subsequent ones are required for recovery purpose if the backup were to be restored

Journal marker set at
offset 197572 of /isc/jrnpri/MIRROR-AUGEST-20220917.011

 - This is the last pass - Suspending write daemon
Backing up /isc/data/demo/ at 09/17/2022 15:28:35
Copied 2 blocks in 0.000 seconds

Finished this pass of copying /isc/data/demo/

Backing up /isc/iris/mgr/user/ at 09/17/2022 15:28:35
Copied 2 blocks in 0.001 seconds

Finished this pass of copying /isc/iris/mgr/user/

Backup pass 3 complete at 09/17/2022 15:28:35

***FINISHED BACKUP***

Global references are enabled.

Backup complete.


1) Backup
2) Restore ALL
3) Restore Selected or Renamed Directories
4) Edit/Display List of Directories for Backups
5) Abort Backup
6) Display Backup volume information
7) Monitor progress of backup or restore

Option?
%SYS>!scp /isc/setmirror.cbk root@172.16.58.102:/isc
Enter passphrase for key '/root/.ssh/id_rsa':
root@172.16.58.102's password:
setmirror.cbk                                                                                            100% 8448KB  49.4MB/s   00:00

%SYS>

  • 在其他成员上恢复数据库,这里分两种情况:

    • 其他成员上没有这个数据库: 比如我的serverb没有DEMO数据库,要做的是:创建一个DEMO数据库,使用和servera一样的设置,除了在下拉框“镜像数据库?“,回答”NO“
    • 其他成员上有这个库,比如备机serverb里有User, 不用管它,下面我们就可以直接把它覆盖掉。

    请参考下面的数据库恢复过程。 提醒一点:不要使用第一个选项“All Directories", 该选项不能用其他机器的备份文件恢复本机。

# 在Backup成员serverb上执行,恢复用源文件拷贝自servera

%SYS>do ^DBREST

                        Cache DBREST Utility
         Restore database directories from a backup archive

Restore: 1. All directories
         2. Selected and/or renamed directories
         3. Display backup volume information
         4. Exit the restore program
    1 => 2

Do you want to set switch 10 so that other processes will be
prevented from running during the restore? Yes =>

Specify input file for volume 1 of backup 1
 (Type STOP to exit)
Device: /isc/setmirror.cbk

This backup volume was created by:
   IRIS for UNIX (Red Hat Enterprise Linux 7 for x86-64) 2022.1

The volume label contains:
   Volume number      1
   Volume backup      SEP 17 2022 03:28PM Full
   Previous backup    SEP 16 2022 09:11AM Full
   Last FULL backup   SEP 16 2022 09:11AM
   Description
   Buffer Count       0
   Mirror name        AUGEST
   Failover Member    SERVERA/IRIS
Is this the backup you want to start restoring? Yes =>
This backup was made on the other mirror member.
Limit restore to mirrored databases? yes

For each database included in the backup file, you can:

 -- press RETURN to restore it to its original directory;
 -- type X, then press RETURN to skip it and not restore it at all.
 -- type a different directory name.  It will be restored to the directory
    you specify.  (If you specify a directory that already contains a
    database, the data it contains will be lost).

/isc/data/demo/ (:mirror:AUGEST:DEMO) =>
/isc/iris/mgr/user/ (:mirror:AUGEST:USER) =>

Do you want to change this list of directories? No =>

Restore will overwrite the data in the old database. Confirm Restore? No => Yes

***Restoring /isc/data/demo/ at 15:47:09
82 blocks restored in 0.0 seconds for this pass, 82 total restored.
Expanding /isc/iris/mgr/user/ ...

Expanding /isc/iris/mgr/user/ from 1 MB to 654 MB

***Restoring /isc/iris/mgr/user/ at 15:47:12
908 blocks restored in 0.0 seconds for this pass, 908 total restored.

***Restoring /isc/data/demo/ at 15:47:12
2 blocks restored in 0.0 seconds for this pass, 84 total restored.

***Restoring /isc/iris/mgr/user/ at 15:47:12
2 blocks restored in 0.0 seconds for this pass, 910 total restored.

***Restoring /isc/data/demo/ at 15:47:12
2 blocks restored in 0.0 seconds for this pass, 86 total restored.

***Restoring /isc/iris/mgr/user/ at 15:47:12
2 blocks restored in 0.0 seconds for this pass, 912 total restored.


Specify input file for volume 1 of backup following SEP 17 2022  03:28PM
 (Type STOP to exit)
Device:

Do you have any more backups to restore? Yes => no
Mounting /isc/data/demo/ which is a mirrored DB
    /isc/data/demo/       ... (Mounted)

Mounting /isc/iris/mgr/user/ which is a mirrored DB
    /isc/iris/mgr/user/   ... (Mounted)

Journal records for mirrored DBs were restored successfully.
%SYS>
  • 检查数据库列表中的状态,注意它们已经成了AUGEST的镜像数据库了, 而且它们是只读模式
  • 在serverb上查看镜像监视器,确认它们的状态是Dejournaling

后面您可以像上面提到的,在主机上操作数据, 确认数据修改同步给了备机。到此这部分工作才算结束。

如果只有外部备份文件:

按照文档上的说法,如果用外部备份在非主成员恢复,恢复后需要在镜像监视器的”镜像数据库列表里“点击"ACtiviate", 直到看到状态为Caaught up为至。请参考文档,我不是很清楚细节。

其他的镜像操作

这里我说说怎么删除镜像, 以及其他的一些常用操作的要点, 比如什么时候使用“SET NO FAILOVER”等等。 TO BE CONTINUED...

0
0 383
文章 Hao Ma · 九月 17, 2022 8m read

Mirror的配置

这里详细介绍了主成员(Primary)和备用成员(Backup)的设置过程。 虽然也包括了异步成员配置的章节,其实我没有真的操作,我认为应该没有特别需要注意的。

配置Mirror应该有这么几步:

1. 启动Mirror服务

进入系统管理界面,选择系统管理>配置>镜像设置>启动镜像服务,勾选服务已启动, 保存退出。这是可以看到菜单栏的创建镜像条目已经从灰色变成正常的白色,表示您已经可以创建镜像。

仅仅是打开服务,并没有修改Journal文件

2. 创建镜像,添加主成员

在管理界面进入“系统>配置>镜像设置>创建镜像”,从这里开始镜像的创建工作。创建镜像的同时,这一步还包括把本机做为第一个镜像成员加入到镜像。第一个镜像成员被加入后会成为主镜像成员, 菜单里的英文是“Primary Failover Member"。

Warning: 如果本机的ISCAgent没有启动, 您会得到提示“错误 #2118: ISCAgent不在本地系统中启动”。另外,特殊情况下,您还可能会碰到错误提示:“错误 #2136: 实例的版本高于ISCAgent的版本”。

镜像的设置

如下面的截图,创建镜像需要提供这些配置信息:

image-20220803171131292
  • 镜像名称:可以是任意的名称, 和各个服务器/成员的名称无关。

  • 需要SSL/TLS:如果您不勾选此选项,会得到“强烈建议使用SSL/TLS"的提示信息。SSL/TLS的配置需要您提供:

    • 包含受信任证书颁发机构X.509证书的文件,也就是CA的证书

    • 此服务器的凭据和私钥。

    • 加密设置:如果您不懂TLS, 建议保持默认选项。

    以下是我在servera上为mirror配置的TLS

    image-20220425154635371
    • Warning: 必须输入您的服务器的私钥密码。否则会出现“错误 #2207:需要转移密钥文件密码“

    • 加密设置可以选择只用TLSv1.2

  • 使用仲裁程序: Yes, 选中。仲裁的地址格式是IP地址/子网掩码,端口默认2188

  • 使用虚拟IP: 在某些情况下,比如云部署,可能无法配置虚拟IP。请参见在线文档中相应的内容。图中使用的是前面规划的VIP地址172.16.58.100和它的网口"ens33"。

  • Failover成员的压缩模式,对于异步成员的压缩模式:

    默认的选择是“选中的系统”,中文翻译有误,应该是“System Selected",也就是系统的选择。压缩模式是指从主镜像到备用镜像的同步数据是不是要压缩传送。压缩的好处是占有更少的带宽,更低的延时,提高了接收方的响应时间。同时,发送和接收方也要相应的付出压缩解压的开销。

​ 当前的IRIS版本只在使用TLS做镜像同步时会对消息压缩。到备用镜像成员使用LZ4算法,到异步成员使用 Zstd算法。

​ 你也可以不用“系统选择”而是人工选定“不压缩”或者“压缩”。如果选择“压缩”,你还要从zlib, Zstd, LZ4里指定 使用的算法。

​ 更详细的内容,请查看在线文档中这部分内容

  • Allow Parallel Dejournaling:

    默认的选项时“Failover Memebers and DR"。其他选项还包括“Failover Members"和“All Members"。

    Parallel Dejournaling增加了镜像数据同步时的throughput。但在某些情况下,轻微的增加了查询的inconsistent。详细说明请查看在线文档中的Parallel Dejournaling说明

  • 高级设置

    • Quality of Service Timeout: 默认8000msec。您可以阅读在线文档有关QoS的章节
    • 此故障转移成员镜像专用地址: 网络规划中说的“内网地址”。
    • 此故障转移成员镜像代理地址:ISCAgent工作的地址,也就是“外网地址”。

主镜像成员信息

这里需要填入本机的信息:

  • 镜像成员名称:默认是主机名和iris实例名的组合。比如我的Linux主机名servera, iris实例名为iris, 那么默认的名称就是"SERVERA/IRIS"。您可以按您机构的命名规范修改。
  • 超级服务器地址:默认为本机的hostname,比如我的linux服务器主机名为servera,菜单里就会自动填入'servera'。但如果您网络里没有DNS服务器,或者仅仅是为了避免其他服务器无法用servera找到本机,那么如图中这样在这里直接配置IP地址也是个不错的选择。
  • 代理端口(Agent Port): 本地ISCAgent服务的TCP端口,默认2188。

检查配置结果

配置结束后您需要做的是:

  • 确认Mirror状态

    到维护界面的“系统>镜像监视器“, 您会看到如下的Mirror状态显示。

image-20220426154450827

注意:图中连接状态显示:此成员未连接仲裁程序,这是正常的。目前Mirror中只配置了一个Primary Member主成员,它不会去尝试连接Arbiter。这个方式叫Agent-Control方式。

只有在有主备都配置成功后,系统才会尝试两个mirror members和arbiter通信,成功后进入arbiter-control方式。

  • 确认Journal文件已经切换,并使用了新名称。

    在上图的窗口, 点击“镜像监视器”中的“查看镜像journal文件”按钮,可以跳转到"系统>Journals"页面。您可以发现正在工作的Journal文件从“20220426.002”换成了以“MIRROR-APRIL"开头的新文件。

    下图显示的是所有Journal文件, 而且是已经配置了journal第2天的抓图。

image-20220426154751902
  • 查看虚拟IP已经绑定在本机的“外部网络接口”上。
# 可以看到vip 172.16.58.103已经绑定在接口ens33

[root@servera ~]# ip -4 -br addr
lo               UNKNOWN        127.0.0.1/8
ens33            UP             172.16.58.101/24 172.16.58.103/24
ens36            UP             172.16.159.101/24
[root@servera ~]#

常见的故障

有2个常见的故障值得一提:

  1. 错误 #2174 创建/加入镜像组1%失败, 因为镜像日志文件%2已存在

    创建mirror的时候会修改mirror名字。可删除mirror的时候并不会把journal名字修改回去。 如果在同一天,删除了一个mirror,用相同的名字再此创建,就会出这个错误。 解决的办法:换一个mirror名字。或者删除journal (测试环境)

  2. ERROR #2086: Agent is unreachable with ens22|2188,

造成的原因是配置镜像成员时用了主机名但无法找到主机,解决要么添加DNS, 要么把配置里的hostname改成IP地址。

另外,还有出现过在主机上创建mirror会报错 “ can't access mirror-journal“, 似乎也和hostname的寻址有关,忘掉细节了, 待补。

3. 添加Backup镜像成员

您要在要第二台IRIS服务器做操作,添加这个IRIS到已有的MIRROR,然后转去主镜像(Primary Member)上去检查是否添加成功。

上一个步骤里我的演示是在servera操作的, 而以下是在Serverb上操作怎么把这个服务器上的iris加入mirror。

  • 进入管理界面"系统管理>配置>镜像配置", 启动镜像服务。

  • 进入管理界面”系统管理>配置>镜像配置>加入为故障转移“ (System Administration>Configuration>Mirror Settings>Join as Failover),

​ 您需要填写mirror name和“其他故障转移成员的信息”。简单说,要填写这个Mirror的Primary成员的信息。 包括: Primary member的Agent地址, 端口(Agent Port), IRIS实例名。 如下图所示:( 注意这里的Agent的IP地址是ens33的地址)。

image-20220427133147896
  • 这之后您会被要求配置本机作为第2个mirror成员的信息 包括:

    • 镜像成员名称: 这里用SERVERB/IRIS
    • 超级服务器地址:这里用172.16.58.102
    • 代理端口:这里用默认值2188
    • 虚拟IP的网络接口:这里用ens33
    • SSL/TLS要求:像配置主镜像成员一样配置证书。
    • 镜像专用地址: 172.16.159.102
    • 代理地址: 172.16.58.102

    以上的所有配置项的如果您还有不清楚的, 请再看看上一步的主成员的配置,他们是一致的。

Warning: 在这一步上如果看到如下的错误,说明连接servera出了问题,很大的可能是IP的连接问题,或者更可能是您在主镜像成员,或者Backup镜像成员的“超级服务器地址”的配置中,使用了主机名servera, serverb,而不是IP地址,而这个host名字底层并没有找到。如果是这样的话,在镜像配置中用IP代替主机名通常能解决问题。

错误 #2088: 使用172.16.159.101,1972无法访问ECP与镜像成员SERVERA/IRIS的连接

  • 回到servera的编辑镜像页面, 会看到最下面出现了一个“未决断成员”的组件。“允许”它并选择向serverb授权后, 这时您将看到提示信息,显示“此成员为主成员. 更改将发送给其它成员.”。

注意: 这一步只有在配置了SSL/TLS的情况下才出现。 如果没有配置SSL/TLS,主成员不需要同意授权,会自动把Backup加到Mirror里

Warning: 在主镜像成员,也就是servera的镜像编辑页面,最上面有个“添加新异步成员”的按钮,它和您当前的操作无关。您正在添加的serverb是第二个同步成员。

servera批准请求

  • 验证添加成功

    通常需要10秒钟以上的时间,两台机器会协商各自的镜像状态,会尝试连接Arbiter,成功后将镜像的自动切换模式由Agent-Control, 提升到Arbiter-Control。通常是通过查看主成员(这里是servera)的管理页面的镜像状态页面确认,如下面这张图:

image-20220427150617245

Warning: 镜像配置成功后,您还是可以登录Backup成员的维护管理页面。其中的“镜像监视器”显示的内容,如您从下图所见, 和主成员的相同页面是一致的。唯一的区别是顶部的按钮, 多了”设置no failover"和“降级为DR成员“两个按钮。 记住这一点有助于您日常维护中清楚的分辨您登录的是那个mirror成员的SMP。

image-20220427150700670

4. 添加异步(Async)成员

在需要添加入Mirror的异步成员服务器上操作,进入IRIS维护界面, 选择System>Administration>Configuration>Mirror Settings>Join as Async。如果选项为灰不可选,先启动服务。

在Join Mirror as Async页面填入创建的镜像名称,主镜像成员的信息,具体选项见上节中加入Backup成员的内容。

最后, 您需要提供本机的信息,这里要选择异步成员类型,它们是:

  • Disaster Recovery: 容灾服务器,需要的时候可以升级到Backup。
  • Read-Only Reporting: 报告服务器,只能查询,永远不能升级到Backup。
  • Read-Write Reporting:可写的报告服务器,如果您有其他的应该需要操作镜像中的数据库的话。它同样不能升级到Backup。在它上面的数据库修改不会传递到其他镜像成员。
0
0 421
文章 Hao Ma · 九月 17, 2022 7m read

因为篇幅太长, 我把它分为3篇贴在社区

配置前的准备

配置Mirror前要准备三件事儿:

  1. 规划网络连接。
  2. 在所有的服务器中启动ISCAgent服务。
  3. 准备服务器的SSL/TLS证书。可选, 但非常推荐。

我假设您在动手前一定已经对Mirror的原理和架构已经不陌生了,对镜像成员,DR(灾备)成员, Arbiter, ISCAgent等术语已经自动切换的概念有大概的认识。如果不是这样,请先阅读在线文档,或者这篇文章。

规划网络连接

Mirror应该配置两个网段:一个用于IRIS和外部的通信;另一个用于两个Mirror成员间的内部通信,也就是数据的同步。 尽管不是必须的,但Mirror作为一个高可用方案,为了保证服务器之间的内部通信不受和外部连接的干扰,把内部通信放在单独的网段是通常的做法,尤其是在生产环境。

下图来自IRIS的在线文档:其中绿色所示的是IRIS提供服务的网段,IRIS到所有外部系统的连接,ECP应用服务器,和Arbiter在工作在这个网段。紫色的“Data Center Private LAN for Mirror Communication"用于内部通信,准确的说, 用于journal的同步。为了方便, 我会在后面的步骤中简单的把这两个网段简单的称为外网网段内网网段

Mirror的网络链接

也是来自在线文档,上图的IP地址配置像这个样子。(请忽略C栏和D栏,它们是DR服务器的地址)

mirror网络配置

在安装配置Mirror之前, 您需要检查的是:

( Agent address用的是公网地址,但书上有句话:When attempting to contact this member’s agent, other members try this address first. Critical agent functions (such as those involved in failover decisions) will retry on the mirror private and superserver addresses (if different) when this address is not accessible. Because the agent can send journal data to other members, journal data may travel over this network. )

  • ServerA, ServerB, Arbiter三台机器的在绿色网段可以相互访问。ServerA, ServerB的1972端口可以访问,Arbiter的2188端口可以访问。
  • ServerA, ServerB在紫色网段可以互相访问2188端口。
  • Virtual IP绑定在Server A, 并且IRIS的服务和连接通过Virtual IP提供。

下面是我用的两个服务器的网络配置,因为不方便使用(懒的修改)上图的地址,我自己做的地址配置如下

Virtual IP Address
Arbiter Address172.16.58.100
Member-Specific Mirror AddressserverAserverB
SuperServer Address172.16.58.101172.16.58.102
Mirror Private Address172.16.159.101172.16.159.102
Agent Address172.16.58.101172.16.58.102

其中172.16.58.0网段为外网网段; 172.16.159.0网段为内网网段。 在操作系统上查看IP, 是这个样子:

servera

#servera上的端口配置
[root@servera mgr]# ip -4 -br addr
lo               UNKNOWN        127.0.0.1/8
ens33            UP             172.16.58.101/24
ens36            UP             172.16.159.101/24
[root@servera mgr]# firewall-cmd --list-ports
1972/tcp 52773/tcp 2188/tcp
[root@servera ~]#


#serverb上的端口配置
[root@serverb isc]# ip -4 -br addr
lo               UNKNOWN        127.0.0.1/8
ens33            UP             172.16.58.102/24
ens36            UP             172.16.159.102/24
[root@serverb isc]# # firewall-cmd --list-ports
1972/tcp 52773/tcp 2188/tcp

在所有的镜像成员启动ISCAgent服务

无论是同步成员,异步成员,还是Arbiter,它们之间的通信都依赖ISCAgent服务。在操作系统上,它是一个独立于IRIS的服务,IRIS的默认安装也没有把它设置为自动启动,所以您需要在安装IRIS的机器,也就是同步,异步成员上手工启动这个服务。至于Arbiter,您可以理解Arbiter就是一个装了ISCAgent服务的机器,可以是任何一台客户的机器,装上ISCAgent, 能帮助IRIS主备成员自动切换判断,它就是Arbiter了。简单说, 您需要

  1. 在Mirror的所有成员上启动ISCAgent
  2. 在一台机器上安装ISCAgent并启动,它从此就是这个Mirror的Arbiter了。

Arbiter需要和IRIS服务器用相同的操作系统吗?没必要。很多客户的IRIS装在Linux上,而Arbiter是一个Windows机器, 跑着和IRIS无关的业务, 都不用是Server版的Windows。

默认配置下, ISCAgent通过TCP的2188端口和远端连接,启动ISC Agent后请检查防火墙,保证2188端口访问是可以访问的。

下面是具体的配置细节。

在Mirror的所有成员上启动ISCAgent

IRIS服务器不需要单独安装ISCAgent。 你需要做的是启动服务,并服务器重启后ISCAgent能自动启动。

  • Windows: 进入管理工具—服务,选择ISCAgent,将启动类型改为自动。点启动ISCAgent,并确认服务已启动。
  • Linux: 使用systemctl启动ISCAgent, 并加入系统自启动列表。
[root@servera isc]# systemctl start ISCAgent
[root@servera isc]# systemctl status ISCAgent
● ISCAgent.service - InterSystems Agent
   Loaded: loaded (/etc/systemd/system/ISCAgent.service; disabled; vendor preset: disabled)
   Active: active (running) since Fri 2022-04-15 10:26:20 CST; 11s ago
  Process: 3651 ExecStart=/usr/local/etc/irissys/ISCAgent (code=exited, status=0/SUCCESS)
 Main PID: 3653 (ISCAgent)
   CGroup: /system.slice/ISCAgent.service
           ├─3653 /usr/local/etc/irissys/ISCAgent
           └─3654 /usr/local/etc/irissys/ISCAgent

Apr 15 10:26:20 servera systemd[1]: Starting InterSystems Agent...
Apr 15 10:26:20 servera systemd[1]: Started InterSystems Agent.
Apr 15 10:26:20 servera ISCAgent[3653]: Starting
Apr 15 10:26:20 servera ISCAgent[3654]: Starting ApplicationServer on *:2188
[root@servera isc]#systemctl enable ISCAgent
Created symlink from /etc/systemd/system/multi-user.target.wants/ISCAgent.service to /etc/systemd/system/ISCAgent.service.
[root@servera isc]#

Arbiter(仲裁服务)

你需要到WRC的下载网址下载ISCAgent的软件。下面是在Linux下安装ISCAgent的过程。

[root@serverc isc]# cd ISCAgent-2022.1.0.164.0-lnxrh7x64
[root@serverc ISCAgent-2022.1.0.164.0-lnxrh7x64]# ls
agentinstall  cplatname  dist  package  tools
[root@serverc ISCAgent-2022.1.0.164.0-lnxrh7x64]# ./agentinstall

Your system type is 'Red Hat Enterprise Linux (x64)'.

Please review the installation options:
------------------------------------------------------------------
ISCAgent version to install: 2022.1.0.164.0
------------------------------------------------------------------

Do you want to proceed with the installation <Yes>? yes

Starting installation...

Installation completed successfully
[root@serverc ISCAgent-2022.1.0.164.0-lnxrh7x64]

安装后同上一小节使用systemctl命令启动。

准备服务器的SSL/TLS证书

您的每个服务器需要准备两个证书:一个本机的证书, 一个是CA的证书。(如果是公开证书也要吗,openssl应该是没有,除非自己去下载)。 如果您使用的是IRIS自带的PKI签发的self-signed证书,那么每台服务器不仅仅要自己的证书,非CA所在的服务器要:“获取证书颁发机构证书”(‘Get Certificate Authority Certificate’)。这个选项“证书颁发机构客户端的”从证书颁发机构获取证书页面。

举例: servera, serverb为镜像成员。

[root@servera mgr]# ls *.cer *.key
iris.key  iscCA.cer  iscCASigned.cer  iscCASigned.key

忽略iris.key。 其他的iscCA.cer是CA的证书, iscCASigned.cer是servera的证书, iscCASigned.key是servera的私钥。

同样, 在serverb:

[root@serverb ~]# cd /isc/iris/mgr
[root@serverb mgr]# ls *.cer *.key
iris.key  iscCA.cer  iscCASignedserverb.cer  iscCASignedserverb.key
[root@serverb mgr]#

增加gmheap的大小

Mirror成员间的数据同步默认使用“Parallel dejournaling", 也就是多个进程并行处理同步数据,而这要求增大gmheap资源。

gmheap又被称为shared memory heap(SMH)。它的默认配置是38MB, 但在实际的生产系统中,gmheap通常配置比这要大。

每一个"parallel dejournalling job"需要增加200M的gmheap。比如说, 为了支持4个并行的同步任务, gmheap至少需要800M。如果系统资源足够,最多可以有16个并行同步任务。

折中的考虑,当您配置镜像时,请将您系统的gmheap值增加为1GB。

后面我们进入正式的Mirror的配置工作。Mirror的配置和把数据库添加入镜像。

0
0 413
文章 Hao Ma · 一月 30, 2021 4m read

IIS在Windows Server里是默认安装,在Windows7和Windows10里面需要用户到"控制面板>程序"里面找到"Turn Windows features on or off"的设置来启动。 本文假设IIS已经在用户的服务器上启动,并且正常工作。

通常情况下,当IRIS安装在Windows系统时,用户会在同一台机器上使用IIS,很少有单独安装一台IIS服务器给远程IRIS提供Web服务器的,当然这样也绝无问题。

有两个软件包可以安装CSP Gateway。一个是IRIS的安装包。在IRIS的安装过程中, 如果有IIS正在工作, 那么安装程序会自动的安装CSP Gateway。 2018年以前的Ensemble或者Cache'的版本的安装过程中会跳出一个询问框,让用户选择是否"安装CSP网关。。。”。而后来的版本大多不做询问而自动为用户做了选择。 如果需要强制安装或者不安装CSP Gateway,那么需要在安装中选"Customer Component"设置。

另一个软件包是单独的CSP Gateway安装包, 可以在InterSystems的WRC或者工程师处得到。这是一个只有10多兆的很小的安装包,它只安装CSP Gateway, 并不安装IRIS实例,适合在单独的IIS硬件服务器上安装CSP Gateway; 或者, 当一个服务器上已有了IRIS, 但后来想添加IIS服务和CSP Gateway,用这个单独的安装包也很方便。

单独的CSP Gateway的安装会在IIS的工作目录“C:\Inetpub"下添加子目录CSPGateway,或者WebGateway, 然后在IIS的default Website上添加CSP Gateway的配置。整个配置相当简单。下面的步骤是在Windows10上单独安装Web Gateway安装包2020.1连接同一台服务器上的IRIS的的过程。

其中后面配置CSP Gateway访问IRIS应用的部分可以参考Apache上配置CSP Gateway的文档。

CSP Gateway安装

  1. 使用浏览器访问 http://localhost, 显示IIS的欢迎主页, 确认IIS已工作。
  2. 打开WebGateway-20201.1.xxxx-win_x64应用程序开始安装。安装时会提示用户输入连接的IRIS Server的IP地址和端口。默认的Application Name用CSP,IP地址端口使用localhost, 51773。安装过程会重启IIS服务,安装结束后用户不用手工重启。
  1. 安装后的检查IIS
  • 检查Web Gateway安装后的文件。 确认在IIS的安装目录(默认为C:\inetput)下安装了CSPGateway子目录, 其中包含若干dll文件。它们是IIS中用到的CSP Gateway的模块,在不同的CSP Gateway版本中这些Dll文件的数量和名字稍有不同。
  • 创建了c:/intersystems/WebGateway的文件夹,早些的版本中并不创建这个目录。
  • 打开IIS配置界面, 确认在Default Site下安装了CSP application. 在某些版本的Web Gateway安装后, /csp被安装为Virtual Directory, 关于IIS中application和virtual diectory的区别请自行查询, 无论安装成那种类型, 对csp的使用和配置没有区别。使用HealthConnect 2018以前版本的安装包安装的CSP Gateway生成CSP和ensemble两个Application。
  1. 查看CSP Gateway登录页面。

登录http://localhost/csp/bin/Systems/Module.cxw。 在主页上会显示Web Gateway的版本, Web Server Type是"Microseof-IIS"。配置文件和日志文件在c:\Inetpub\CSPGateway目录下。 (如果是打开时出现HTTP错误500.19, 你需要重启IIS)

  1. 查看连接的IRIS Server。

从左边菜单栏进入Server Access配置界面。其中csp是默认安装的IRIS连接。2018以前的版本可能用的是LOCAL。不管怎么说,使用"Edit Server"打开,可以看到连接的IRIS的端口和设置。

配置UserName"CSPSystem"和Password "SYS",并保存。

在左边菜单栏,使用"Test Server Connection"测试到“csp"的连接,测试成功会显示IRIS的版本。

Test Server Connection
Server connection test was successful: csp (localhost:51773)
$ZVersion: IRIS for Windows (x86-64) 2020.2 (Build 199U) Tue Apr 28 2020 17:17:56 EDT
  1. 访问IRIS维护主页 (可选)

从链接 http://WebServer/csp/sys/Utilhome.csp 访问IRIS维护主页System Management Portal应该可以成功了,但您会发现有部分网页内容(element)无法加载。这是因为在默认的安装中,只将"csp cls zen cxw"这4种类型的请求发送给CSP Gateway, 而被称为Static file的文件,比如.js, .css, .png等等类型的文件并没有被发送给CSP Gateway. 这是另外的一个安全机制,强制客户人工的配置是否需要从Web服务器访问IRIS维护主页。如果答案是NO, 那么访问IRIS维护页面就只能通过PWS,用IRIS服务器的52773的接口。 如果用户认为从Web服务器访问IRIS维护页面是必要的, 需要修改CSPFileTypes配置,把任意类型的请求发送给IRIS。

  1. 访问IRIS上的其他Web Application

IRIS上其他的Web Application, 比如”/api", ”/test"等等,通常情况下当Web Application被添加后,配置会自动同步到Web Gateway, 用户不用去Web Gateway的页面配置路由。但IIS上必须填写响应的配置,才能把请求从IIS发送到CSP Gateway. 这样操作:

  • 添加applications。如下图所示, 在IIS的default site下添加了两个新application, test和api.
  • 为每个applcation配置"Handler Mappings"。使用右边动作栏中的”Add Module Mapping",而不是另3种动作。 还要注意不要勾选"Request Restrictions"的"invoke handler only if request is mapped to"选择框,这样在"Handler Mappings"页面看到的Path Type一栏中显示的是"Unspecified", 否则会显示"File"或者其他内容。
  • 测试访问一些应用, 比如

http://172.16.58.200/api/mgmnt/v2/
http://172.16.58.200/test/test.webservice1.cls

一般情况下,到目前为止IIS已经能够正常工作,将需要的请求发送给IRIS。如果出现故障或者需要调整CSP gateway的配置,请参考[WebGateway系列_配置Apache连接IRIS]

3
0 484
文章 Michael Lei · 五月 3, 2022 6m read

所有源代码均在: https://github.com/antonum/ha-iris-k8s 

在上一篇文章中,我们讨论了如何在k8s集群上建立具有高可用性的IRIS,基于分布式存储,而不是传统的镜像。作为一个例子,那篇文章使用了Azure AKS集群。在这一篇中,我们将继续探讨k8s上的高可用配置。这一次,基于Amazon EKS(AWS管理的Kubernetes服务),并将包括一个基于Kubernetes 快照进行数据库备份和恢复的选项。

安装

开始干活. 首先需要一个AWS账户,安装 AWS CLI,kubectl 和 eksctl 工具. 要创建新的集群,请运行以下命令:

eksctl create cluster \
--name my-cluster \
--node-type m5.2xlarge \
--nodes 3 \
--node-volume-size 500 \
--region us-east-1

这个命令需要大约15分钟,部署EKS集群并使其成为你的kubectl工具的默认集群。你可以通过运行以下代码来验证你的部署:

0
0 564
文章 Hao Ma · 四月 19, 2022 26m read

本文档只是给您一个大致的概念,方便您了解IRIS安装的方方面面。并非官方安装手册或者安装建议。生产环境的安装请仔细研究并参照IRIS官方的安装文档

操作系统的选择

IRIS支持多种Linux系统。详细的列表请参见各个版本的支持列表,比如这个是最新的2021IRIS的支持列表。需要注意的是, CentOS只支持作为测试系统, 并不支持生产系统的安装。

官方文档是以Redhat为主介绍的IRIS安装, 这是IRIS在生产环境中最常用的Linux系统之一。另一个Ubantu, InterSystems提供的docker版本是安装在Ubantu上的。

我自己测试的时候喜欢使用CentOS, 所以后面有具体安装步骤中,使用的CentOS上的记录。

服务器的配置

对于生产系统,安装前需要一个硬件配置方案,这个方案通常是您的项目的实施部门根据用户需求提供的。

对于测试系统,只有一个最小的磁盘的要求:1.5G。无论是实体服务器, 虚拟服务器,或者docker container,根据您要测试的内容, 一切以方便为准。如果不做性能测试,我个人经常使用的CentOS虚拟机是2核CPU, 2G或4G内存,没有运行不流畅的问题。

磁盘分区

标准的Linux磁盘分区并不适合IRIS的生产运行。哪怕要创建一个尽量接近生产的测试环境,建议您安装软件前要有一个完整的磁盘分区规划。在官方文档中,创建IRIS服务器分区有以下原则:

0
1 1024
文章 Michael Lei · 三月 6, 2022 3m read

我们所有的工作环境都是Ensemble 2017.2。但我们最近将迁移到IRIS for Health 2021.1版本。这是一个复杂的过程,但经过仔细考虑,我们找到了实现这一目标的方法。

我们有一个开发服务器和两个生产服务器的镜像,采用Failover模式。我们有40多个名称空间在使用中,有些有HL7集成,有些有Soap服务、Rest服务、文件处理......什么都有点。我们需要确定向IRIS的迁移不会出现问题,最重要的是,我们需要不惜一切代价避免服务中断。因此,我们必须做的第一件事是建立一个计划。

0
1 165
文章 Michael Lei · 十二月 30, 2021 1m read

对于那些在某种程度上需要测试ECP的水平可扩展性(计算能力和/或用户和进程的并发性),但又懒得建立环境、配置服务器节点等的人来说,我刚刚在Open Exchange上发布了OPNEx-ECP部署的应用/示例。 

0
0 156
文章 Michael Lei · 七月 6, 2021 16m read

供应商或内部团队要求说明如何为 VMware vSphere 上运行的_大型生产数据库_进行 CPU 容量规划。

总的来说,在调整大型生产数据库的 CPU 规模时,有几个简单的最佳做法可以遵循:

  • 为每个物理 CPU 核心规划一个 vCPU。
  • 考虑 NUMA 并按理想情况调整虚拟机规模,以使 CPU 和内存对于 NUMA 节点是本地的。
  • 合理调整虚拟机规模。 仅在需要时才添加 vCPU。

通常,这会引出几个常见问题:

  • 由于使用超线程技术,VMware 创建的虚拟机的 CPU 数量可以是物理 CPU 数量的两倍。 那不就是双倍容量吗? 创建的虚拟机不应该有尽可能多的 CPU 吗?
  • 什么是 NUMA 节点? 我应该在意 NUMA 吗?
  • 虚拟机应该合理调整规模,但我如何知道什么时候合理?

我以下面的示例回答这些问题。 但也要记住,最佳做法并不是一成不变的。 有时需要做出妥协。 例如,大型生产数据库虚拟机很可能不适合 NUMA 节点,但我们会看到,其实是没问题的。 最佳做法是指必须针对应用程序和环境进行评估和验证的准则。

0
0 956