#Caché

0 关注者 · 975 帖子

  

InterSystems Caché 是一个多模型 DBMS 和应用服务器。

查看此处提供的更多详细信息

文档

文章 Jeff Liu · 十一月 6, 2025 4m read

动机

直到开始新工作,我才了解到ObjectScript。实际上,Objectscript并不是一种年轻的编程语言。与 C++、Java 和 Python 相比,它的社区并不活跃,但我们很想让这里更有活力,不是吗?

我注意到,有些同事在理解大型项目中的类关系时感到棘手。目前还没有易于使用的现代化类图工具适用于ObjectScript。

相关工作

我尝试过相关的工作:

——InterSystems 类视图:
1. https://github.com/intersystems-community/ClassExplorer
这个工具很棒,类图显示清晰美观。但存在Docker构建问题:“#0 0.512 exec ./irissession.sh: no such file or directory”。我猜这是为Studio设计的支持功能,而非VSCode。它似乎需要手动导入项目,且需要一定配置才能使用。

2. https://github.com/gjsjohnmurray/vscode-objectscript-class-view
这是另一个给我带来灵感的伟大作品。类结构清晰,不仅支持项目中的类,也支持库中的类。但看起来像是VSCode大纲的增强版。

——其他语言的 VSCode 类图表视图插件

0
0 11
文章 Nicky Zhu · 十月 28, 2025 2m read

InterSystems 常见问题解答标题

^%GCMP 实用工具可用于比较两个全局变量的内容。

例如,要比较 USER 和 SAMPLES 命名空间中的 ^test 和 ^test,过程将与下面类似:
*以下示例在这两个命名空间中创建了 700 个相同的全局变量,并更改了其中一个的内容,使其成为检测目标。

USER>kill^test
USER>for i=1:1:100 { forj=1:1:7 { set^test(i,j)="Test"_i } }

USER>zn"samples"// change namespace to SAMPLES SAMPLES>kill^test SAMPLES>for i=1:1:100 { forj=1:1:7 { set^test(i,j)="Test"_i } }

SAMPLES>set^test(50,5,1)=1// Change one of the globals created in the SAMPLES namespace. SAMPLES>do^%GCMP Compare global ^test// Global to compare. on directory set: (this system) // Enter in namespace: SAMPLES => // Enter (if this namespace is OK) with global ^test=> // Global to compare on directory set: (this system) // Enter in namespace: SAMPLES => USER // Namespace to compare Output differences on Device: // Destination for output results. Press <Enter> to view in a terminal.// If you enter the full path of the log file name, the output will be sent there. Right margin: 80 =>

Compare global ^test in SAMPLES with global ^test in USER

^test(50,5,1) exists in ^|"SAMPLES"|test but not in ^|"USER"|test // Detects differing globals Time=.001822 SAMPLES>

如果要在不同服务器上的实例之间进行比较,而不是在同一实例中,请使用 ^DATACHECK 实用工具。 有关如何使用 ^DATACHECK 实用工具的说明,请参阅以下相关文章:

如何比较两个数据库中的多个全局变量和例程

0
0 19
InterSystems 官方 Claire Zheng · 六月 19, 2025 4m read

互操作性用户界面现在包括可以在所有互操作性产品中使用的 DTL 编辑器生产配置应用程序的现代化用户体验。您可以在现代化视图与标准视图之间切换。所有其他互操作性屏幕仍采用标准用户界面。请注意,仅对这两个应用程序进行了更改,我们在下面确定了当前可用的功能。

要在升级前试用新屏幕,您可以点击这里,从我们的社区工具包网页中下载 2025.1 版:https://evaluation.intersystems.com/Eval/。请观看“学习服务”中的简短教程构建集成:一种新的用户体验,了解对这些屏幕进行的用户增强!

生产配置 - 配置任务简介
  • 生产配置:在以下版本的生产配置中受支持:
    • 创建/编辑/复制/删除主机
    • 停止/启动主机
    • 编辑生产设置
    • 停止/启动生产
  • 源代码控制集成:支持上述配置功能的源代码控制集成。
  • 分屏 视图:用户可以直接从“生产配置”屏幕打开“规则编辑器”和“DTL 编辑器”,在分屏视图中查看和编辑产品中包含的规则和转换。
  • 增强的筛选功能:使用顶部的搜索框,您可以搜索和筛选各种业务组件,包括多种类别、DTL 和子转换。 使用左侧边栏可以独立于主面板进行搜索,查看各种主机和类别中的搜索结果。
  • 批量编辑主机类别:通过从生产配置中添加主机,您可以为生产添加新类别或编辑现有类别。
  • 可展开路由器:可以展开路由器,内联查看所有规则、转换和连接。
  • 重新设计的主机连接:现在,在选择业务主机时,将呈现直接连接和间接连接,您可以查看消息能够采用的完整路径。 将鼠标悬停在任何出站或入站主机上可以进一步区分连接。如果开启仅显示连接的主机开关,将仅筛选所选主机及其连接。
DTL 编辑器 - DTL 工具简介
  • 源代码控制集成:支持源代码控制集成。
  • VS Code 集成:用户可以在其 VS Code IDE 中查看此版本的 DTL 编辑器。
  • 嵌入式 Python 支持:此版本的 DTL 编辑器现在支持嵌入式 Python。
  • DTL 测试:可以在此版本的 DTL 编辑器中使用 DTL 测试实用工具。
  • 切换面板布局:DTL 编辑器支持侧面到侧面和顶部到底部布局。 点击顶部功能区的布局按钮可以体验此功能。
  • 撤消/重做:用户可以使用撤消/重做按钮撤消和重做所有尚未保存为代码的操作。
  • “生成空段”参数:GENERATEEMPTYSEGMENTS 参数可用于为缺失的字段生成空段。
  • 子转换查看:用户可以点击眼睛图标,在新选项卡中打开子转换 DTL,查看子转换。
  • 滚动
    • 单独滚动:将光标放置在 DTL 的左右两部分(源和目标)其中之一的上方,并用滚轮或触控板垂直移动各段,可以单独滚动各个部分。
    • 联合滚动:将光标放置在图的中间,可以联合滚动源部分和目标部分。
  • 字段自动补全:自动补全适用于:“源”、“目标”和“条件”字段以及源类、源文档类型、目标类、目标文档类型。
  • 顺序编号:使用可视化编辑器,您可以打开和关闭查看每个段的序数和完整路径表达式的功能。
  • 轻松引用:当操作编辑器中的某个字段获得焦点时,在图形化编辑器中双击某个段会在操作编辑器中的当前光标位置插入相应的段引用。
  • 同步:点击可视化编辑器中的一个元素,可以在操作编辑器中高亮显示相应的行。
📣号召性用语📣

如果您有任何反馈,请通过以下途径提供给我们:

  • 跨所有互操作性的新功能:在 Ideas 门户中输入想法,或在 InterSystems Ideas 门户中参与其他想法。 对于新想法,请在您的帖子上添加“互操作性”标签或对列表中已提出的功能进行投票!
  • 💻跨所有互操作性的一般用户体验反馈:请在下面输入您的反馈或参与其他评论。
  • 🗒对现代化应用程序的建议/反馈(如上所述):请在下面输入您的反馈或参与其他评论。

请考虑利用 Global Masters 的机会,与团队进行互动,参与不公开的指导反馈会议,并获得积分! 点击此处,通过 Global Masters 报名参加这些会议。

如果您希望以私人形式提供任何其他反馈,请通过电子邮件将您的想法或问题发送至:ux@intersystems.com  
 

0
0 47
文章 Michael Lei · 五月 12, 2021 11m read

InterSystems 数据平台和性能 - 第 5 部分 使用 SNMP 进行监控

在之前的帖子中,我展示了如何使用 pButtons 收集历史性能指标。 我首选 pButtons 是因为我知道它随每个数据平台实例(Ensemble、Caché、...)一起安装。 不过,还有其他方法可以实时收集、处理和显示 Caché 性能指标,以进行简单的监视,或进行更重要的并且复杂得多的运营分析和容量计划。 最常见的数据收集方法之一是使用 SNMP(简单网络管理协议)。

SNMP 是 Caché 向各种管理工具提供管理和监控信息的标准方式。 Caché 在线文档包含了 Caché 和 SNMP 之间接口的详细信息。 虽然 SNMP 应该可以直接与 Caché 配合工作,但仍有一些配置技巧和陷阱。 我经历了很多次错误的开始,并且在 InterSystems 其他同事的帮助下,才让 Caché 与操作系统 SNMP 主代理建立对话,所以我写了这篇帖子,希望您可以避免同样的痛苦。

在本帖中,我将介绍如何为 Red Hat Linux 上的 Caché 设置和配置 SNMP,您应该能够对其他 *nix 版本使用相同步骤。 我使用 Red Hat 写这篇文章是因为在 Linux 上进行设置更棘手一些;在 Windows 上,Caché 会自动安装一个 DLL 来与标准 Windows SNMP 服务连接,所以应该更容易配置。

3
2 456
问题 yang xin · 十一月 1, 2024

我们公司在和其他公司合作,需要从Cache2016的数据库中执行sql获取数据

sql的内容是调用存储过程

CALL DHCXXXXice.MKPIQuery_QueryXXXX('K007XXXX.JJR','2024-08-01','2024-08-01')

在java代码中执行会报错误如下

但是通过数据库连接工具却能查询到结果

通过数据库连接工具查询到 该存储过程,可接收参数为8个

尝试  CALL DHCXXXXice.MKPIQuery_QueryXXXX('K007XXXX.JJR','2024-08-01','2024-08-01',null,null,null,null,null)

在通过java连接查询时,依然报Parameter list mismatch错误

通过jdbc连接工具依然能查出结果

0
0 184
文章 Cryze Zhang · 十月 23, 2024 1m read
file2Xml 
一个将文件转换成Studio导出的xml格式的工具

通过此工具可以将本地文件转换成xml格式文件,然后通过Studio导入到服务器中,而不再需要其他工具将文件传至服务器。

下面以为ensemble2016自带的一个示例界面增加背景图为例。
http://localhost:57772/csp/samples/cinema/Cinema.csp

1.选择数据版本信息并录入web应用程序(SMP--系统--安全管理--Web 应用程序)

确定此示例界面的Web应用程序为:/csp/samples

2.点击“选择文件”,选择需要转换的文件
选择本地电脑要作为背景图的图片

3.录入每个文件导入后相对于web应用程序的路径和导入后的文件名

想要放到cinema下,故相对于web应用程序的路径为:cinema
想要将文件命名为:search_bg.jpg

4.勾选最终需要转换的文件,并点击“转换”

5.录入转换出的xml文件名,点击“确定”

6.转换出的xml文件就可以通过Studio直接导入库中了

然后修改下Search.csp的样式代码,就可以使用此背景图了

工具地址:

0
0 122
文章 Michael Lei · 九月 27, 2024 9m read

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

  • Git 101
  • Git 流程(开发流程)
  • GitLab 安装
  • GitLab 工作流
  • 持续交付
  • GitLab 安装和配置
  • GitLab CI/CD
  • 为何使用容器
  • 容器基础架构
  • 使用容器的 CD

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

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

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

第四篇文章中,我们编写了 CD 配置。

第五篇文章中,我们讨论了容器以及使用容器的方式(和原因)。

第六篇文章中,我们将探讨运行包含容器的持续交付管道所需的主要组件以及这些组件如何协同运行。

在这篇文章中,我们将构建上一篇文章中探讨的持续交付配置。

工作流

在持续交付配置中,我们会:

  • 将代码推送到 GitLab 仓库
  • 构建 docker 镜像
  • 进行测试
  • 将镜像发布到 docker 注册表
  • 将旧容器换为注册表中的新版本

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

我们开始吧。

构建

首先,我们需要构建镜像。

我们的代码通常存储在仓库中,CD 配置位于 gitlab-ci.yml 中,但为了提高安全性,我们会在构建服务器上存储几个服务器特定的文件。

GitLab.xml

包含 CD 挂钩代码。 该代码是在上一篇文章中开发的,并在 GitHub 上提供。 这是一个小型库,用于加载代码、运行各种挂钩以及测试代码。 作为更好的替代方案,您可以使用 git 子模块将此项目或类似项目包含到您的仓库中。 最好选择子模块,因为子模块更容易保持最新状态。 另一个替代方案是在 GitLab 上为版本添加标签,并使用 ADD 命令加载这些版本。

iris.key

许可证密钥。 或者,它可以在容器构建过程中下载,而不是存储在服务器上。 将密钥存储在仓库中非常不安全。

pwd.txt

包含默认密码的文件。 将这类文件存储在仓库中也非常不安全。 此外,如果您在单独的服务器上托管生产环境,它可能有不同的默认密码。

load_ci.script

初始脚本,它执行以下任务:

  • 实现操作系统身份验证
  • 加载 GitLab.xml
  • 初始化 GitLab 实用工具设置
  • 加载代码

set sc = ##Class(Security.System).Get("SYSTEM",.Properties) write:('sc) $System.Status.GetErrorText(sc) set AutheEnabled = Properties("AutheEnabled") set AutheEnabled = $zb(+AutheEnabled,16,7) set Properties("AutheEnabled") = AutheEnabled set sc = ##Class(Security.System).Modify("SYSTEM",.Properties) write:('sc) $System.Status.GetErrorText(sc) zn "USER" do ##class(%SYSTEM.OBJ).Load(##class(%File).ManagerDirectory() _ "GitLab.xml","cdk") do ##class(isc.git.Settings).setSetting("hooks", "MyApp/Hooks/") do ##class(isc.git.Settings).setSetting("tests", "MyApp/Tests/") do ##class(isc.git.GitLab).load() halt

请注意,第一行有意留空。

由于某些设置可以是服务器特定的,脚本不会存储在仓库中,而是单独存储。 如果此初始挂钩始终相同,将其存储在仓库中即可。

gitlab-ci.yml

现在,继续持续交付配置:

构建镜像:
  stage: build
  tags:
    - test
  script:
    - cp -r /InterSystems/mount ci
    - cd ci
    - echo 'SuperUser' | cat - pwd.txt load_ci.script > temp.txt
    - mv temp.txt load_ci.script
    - cd ..
    - docker build --build-arg CI_PROJECT_DIR=$CI_PROJECT_DIR -t docker.domain.com/test/docker:$CI_COMMIT_REF_NAME .

这里会执行哪些操作?

首先,由于 docker build 只能访问基础构建目录的子目录(本例中是仓库根目录),我们需要将“秘密”目录(包含 GitLab.xmliris.keypwd.txt 和 load_ci.script 的目录)复制到克隆的仓库中。

接下来,首次终端访问需要用户名/密码,因此我们会将这些信息添加到 load_ci.script 中(这也是 load_ci.script 开头一行留空的原因)。

最后,我们会构建 docker 镜像并适当地为其添加标签:docker.domain.com/test/docker:$CI_COMMIT_REF_NAME

其中,$CI_COMMIT_REF_NAME 是当前分支的名称。 请注意,镜像标签的第一部分应与 GitLab 中的项目名称相同,这样才能在 GitLab 的“注册表”标签页中看到它(“注册表”标签页中提供了关于添加标签的说明)。

Dockerfile

构建 docker 镜像是通过 Dockerfile 完成的,具体如下:

FROM docker.intersystems.com/intersystems/iris:2018.1.1.611.0

ENV SRC_DIR=/tmp/src ENV CI_DIR=$SRC_DIR/ci ENV CI_PROJECT_DIR=$SRC_DIR

COPY ./ $SRC_DIR

RUN cp $CI_DIR/iris.key $ISC_PACKAGE_INSTALLDIR/mgr/
&& cp $CI_DIR/GitLab.xml $ISC_PACKAGE_INSTALLDIR/mgr/
&& $ISC_PACKAGE_INSTALLDIR/dev/Cloud/ICM/changePassword.sh $CI_DIR/pwd.txt
&& iris start $ISC_PACKAGE_INSTANCENAME
&& irissession $ISC_PACKAGE_INSTANCENAME -U%SYS < $CI_DIR/load_ci.script
&& iris stop $ISC_PACKAGE_INSTANCENAME quietly

我们从基本的 iris 容器开始。

首先,我们将仓库(和“秘密”目录)复制到容器中。

接下来,我们将许可证密钥和 GitLab.xml 复制到 mgr 目录中。

然后,我们将密码更改为 pwd.txt 中的值。 请注意,此操作会删除 pwd.txt。

之后,实例启动并执行 load_ci.script。

最后,iris 实例停止。

以下是作业日志(部分日志,跳过了加载/编译日志):

Running with gitlab-runner 10.6.0 (a3543a27)
  on docker 7b21e0c4
Using Shell executor...
Running on docker...
Fetching changes...
Removing ci/
Removing temp.txt
HEAD is now at 5ef9904 Build load_ci.script
From http://gitlab.eduard.win/test/docker
   5ef9904..9753a8d  master     -> origin/master
Checking out 9753a8db as master...
Skipping Git submodules setup
$ cp -r /InterSystems/mount ci
$ cd ci
$ echo 'SuperUser' | cat - pwd.txt load_ci.script > temp.txt
$ mv temp.txt load_ci.script
$ cd ..
$ docker build --build-arg CI_PROJECT_DIR=$CI_PROJECT_DIR -t docker.eduard.win/test/docker:$CI_COMMIT_REF_NAME .
Sending build context to Docker daemon  401.4kB

Step 1/6 : FROM docker.intersystems.com/intersystems/iris:2018.1.1.611.0 ---> cd2e53e7f850 Step 2/6 : ENV SRC_DIR=/tmp/src ---> Using cache ---> 68ba1cb00aff Step 3/6 : ENV CI_DIR=$SRC_DIR/ci ---> Using cache ---> 6784c34a9ee6 Step 4/6 : ENV CI_PROJECT_DIR=$SRC_DIR ---> Using cache ---> 3757fa88a28a Step 5/6 : COPY ./ $SRC_DIR ---> 5515e13741b0 Step 6/6 : RUN cp $CI_DIR/iris.key $ISC_PACKAGE_INSTALLDIR/mgr/ && cp $CI_DIR/GitLab.xml $ISC_PACKAGE_INSTALLDIR/mgr/ && $ISC_PACKAGE_INSTALLDIR/dev/Cloud/ICM/changePassword.sh $CI_DIR/pwd.txt && iris start $ISC_PACKAGE_INSTANCENAME && irissession $ISC_PACKAGE_INSTANCENAME -U%SYS < $CI_DIR/load_ci.script && iris stop $ISC_PACKAGE_INSTANCENAME quietly ---> Running in 86526183cf7c . Waited 1 seconds for InterSystems IRIS to start This copy of InterSystems IRIS has been licensed for use exclusively by: ISC Internal Container Sharding Copyright (c) 1986-2018 by InterSystems Corporation Any other use is a violation of your license agreement

%SYS> 1

%SYS> Using 'iris.cpf' configuration file

This copy of InterSystems IRIS has been licensed for use exclusively by: ISC Internal Container Sharding Copyright (c) 1986-2018 by InterSystems Corporation Any other use is a violation of your license agreement

1 alert(s) during startup. See messages.log for details. Starting IRIS

Node: 39702b122ab6, Instance: IRIS

Username: Password:

Load started on 04/06/2018 17:38:21 Loading file /usr/irissys/mgr/GitLab.xml as xml Load finished successfully.

USER>

USER>

[2018-04-06 17:38:22.017] Running init hooks: before

[2018-04-06 17:38:22.017] Importing hooks dir /tmp/src/MyApp/Hooks/

[2018-04-06 17:38:22.374] Executing hook class: MyApp.Hooks.Global

[2018-04-06 17:38:22.375] Executing hook class: MyApp.Hooks.Local

[2018-04-06 17:38:22.375] Importing dir /tmp/src/

Loading file /tmp/src/MyApp/Tests/TestSuite.cls as udl

Compilation started on 04/06/2018 17:38:22 with qualifiers 'c' Compilation finished successfully in 0.194s.

Load finished successfully.

[2018-04-06 17:38:22.876] Running init hooks: after

[2018-04-06 17:38:22.878] Executing hook class: MyApp.Hooks.Local

[2018-04-06 17:38:22.921] Executing hook class: MyApp.Hooks.Global Removing intermediate container 39702b122ab6 ---> dea6b2123165 [Warning] One or more build-args [CI_PROJECT_DIR] were not consumed Successfully built dea6b2123165 Successfully tagged docker.domain.com/test/docker:master Job succeeded

请注意,我使用的是 GitLab Shell 执行器,而不是 Docker 执行器。 当您需要从镜像内部提取某些内容时,将使用 Docker 执行器,例如在 Java 容器中构建 Android 应用程序并且只需要一个 apk 时。 在我们的示例中,我们需要整个容器,因此需要使用 Shell 执行器。 因此,我们通过 GitLab Shell 执行器运行 Docker 命令。

 

运行

我们构建了镜像,接下来要运行镜像。如果是功能分支,我们销毁旧容器并启动新容器即可。 如果是环境,我们可以运行临时容器,在测试成功的情况下,可以替换环境容器(此内容留给读者作为练习)。

脚本如下。

destroy old:
  stage: destroy
  tags:
    - test
  script:
    - docker stop iris-$CI_COMMIT_REF_NAME || true
    - docker rm -f iris-$CI_COMMIT_REF_NAME || true

此脚本会销毁当前运行的容器,并且始终都会成功(默认情况下,如果 docker 尝试停止/移除不存在的容器,则会失败)。

接下来,我们启动新镜像并将其注册为环境。 Nginx 容器 使用 VIRTUAL_HOST 环境变量和 expose 指令(用于了解要代理的端口)自动代理请求。

run image:
  stage: run
  environment:
    name: $CI_COMMIT_REF_NAME
    url: http://$CI_COMMIT_REF_SLUG. docker.domain.com/index.html
  tags:
    - test
  script:
    - docker run -d
      --expose 52773
      --env VIRTUAL_HOST=$CI_COMMIT_REF_SLUG.docker.eduard.win
      --name iris-$CI_COMMIT_REF_NAME
      docker.domain.com/test/docker:$CI_COMMIT_REF_NAME
      --log $ISC_PACKAGE_INSTALLDIR/mgr/messages.log

 

测试

我们来运行一些测试。

test image:
  stage: test
  tags:
    - test
  script:
    - docker exec iris-$CI_COMMIT_REF_NAME irissession iris -U USER "##class(isc.git.GitLab).test()"

发布

最后,我们将镜像发布到注册表中

publish image:
  stage: publish
  tags:
    - test
  script:
    - docker login docker.domain.com -u dev -p 123
    - docker push docker.domain.com/test/docker:$CI_COMMIT_REF_NAME

可以使用 GitLab 秘密变量传递用户名/密码。

现在,我们可以在 GitLab 中看到该镜像:

其他开发者可以从注册表中拉取该镜像。 “环境”标签页上提供了我们所有的环境,可以轻松进行浏览:

 

结论

在这一系列文章中,我介绍了持续交付的常规方式。 这是一个涉及面非常广的话题,您应将这一系列文章视为方法集合,而不是确定性内容。 如果您想自动构建、测试和交付应用程序,可以选择持续交付(一般情况)和 GitLab(特殊情况)。 利用持续交付和容器,您可以根据需要自定义工作流。

链接

后续内容

就是这些! 希望我已介绍了持续交付和容器的基础知识。

但还有一些主题我没有介绍(可能后面会介绍),特别是关于容器的内容:

  • 数据可以在容器外持久保持,以下是相关文档
  • kubernetes 等编排平台
  • InterSystems Cloud Manager
  • 环境管理 – 创建临时环境以进行测试,在功能分支合并后移除旧环境
  • Docker compose 可以实现多容器部署
  • 缩减 docker 镜像大小并缩短构建时间
  • ...
0
0 110
文章 Michael Lei · 九月 27, 2024 2m read

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

  • Git 101
  • 流程(开发流程)
  • GitLab 安装
  • GitLab 工作流
  • 持续交付
  • GitLab 安装和配置
  • GitLab CI/CD
  • 为何使用容器?
  • 容器基础架构
  • 使用容器的 GitLab CI/CD

第一篇文章中,我们介绍了 Git 基础知识,以及为什么对 Git 概念的高层次理解对于现代软件开发如此重要,以及如何使用 Git 开发软件。

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

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

第四篇文章中,我们编写了 CD 配置。

第五篇文章中,我们讨论了容器与如何(以及为什么)使用它们。

在本文中,我们将探讨运行使用容器的持续交付管道所需的主要组件,以及它们如何协同工作。

我们的配置如下所示:

在这里,我们可以看到三个主要阶段的分离:

  • 构建
  • 传送
  • 运行

构建

在之前的部分中,构建通常是增量式 – 我们计算当前环境与当前代码库之间的差异,并修改我们的环境以与代码库相对应。 使用容器时,每次构建都是完整构建。 构建的结果是一个可以通过依赖关系在任何地方运行的镜像。

传送

在我们的镜像构建并通过测试后,它会被上传到注册表 – 用于托管 docker 镜像的专用服务器。 在那里,它可以替换具有相同标签的旧镜像。 例如,由于对 master 分支的新提交,我们构建了新镜像 (project/version:master),如果测试通过,我们可以用相同标签的新镜像替换注册表中的旧镜像,这样,所有拉取 project/version:master 的人都会获得新版本。

运行

最后,我们的镜像部署完成。 CI 解决方案(如 GitLab)可以控制此流程,也可以由专门的编排器控制,但目的都一样 – 执行一些镜像,定期检查健康状态,如果有新镜像版本可用就进行更新。

查看 docker 网络研讨会以了解这些不同阶段的解释。

或者,从提交的角度来看:<

在我们的交付配置中,我们会:

  • 将代码推送到 GitLab 仓库
  • 构建 docker 镜像
  • 测试该镜像
  • 将镜像发布到我们的 docker 注册表
  • 用新版本替换注册表中的旧容器

为此,我们需要:

  • Docker
  • Docker 注册表
  • 注册域(可选但推荐)
  • GUI 工具(可选)

 

Docker

首先,我们需要在某个地方运行 docker。 我建议从一台运行主流 Linux 发行版(如 Ubuntu、RHEL 或 Suse)的服务器开始。 不要使用面向云的发行版(如 CoreOS、RancherOS 等) - 它们并不适合初学者。 别忘了将存储驱动程序切换为 devicemapper。 

如果我们在讨论大规模部署,那么使用像 Kubernetes、Rancher 或 Swarm 这样的容器编排工具可以自动执行大多数任务,但我们不会探讨它们(至少在这一部分中)。

 

Docker 注册表

这是我们需要运行的第一个容器,它是一个无状态、可扩缩的服务器端应用程序,作用是存储和分发 Docker 镜像。
您应当在想要实现以下目的时使用注册表:

  •  严格控制您的镜像存储位置
  •  完全掌控您的镜像分发管道
  •  将镜像存储和分发紧密整合到您的内部开发工作流中

此处提供了注册表的文档

连接注册表和 GitLab

注:GitLab 包含内置注册表。 您可以运行它而不使用外部注册表。 请阅读本段中链接的 GitLab 文档。

要将您的注册表连接到 GitLab,您需要运行支持 HTTPS的注册表 – 我使用 Let's Encrypt 获取证书,并按照此 Gist 获取证书并将其传递到容器中。 在确认注册表可以通过 HTTPS 访问后(您可以从浏览器检查),请按照这些说明将注册表连接到 GitLab。根据您的需要和 GitLab 安装情况,这些说明会有所不同。就我而言,配置是将注册表证书和密钥(正确命名且具有正确的权限)添加到 /etc/gitlab/ssl 并将以下行添加到 /etc/gitlab/gitlab.rb 中:

registry_external_url 'https://docker.domain.com'
gitlab_rails['registry_api_url'] = "https://docker.domain.com"

重新配置 GitLab 后,我可以看到一个新的注册表标签页,其中提供了如何正确为新构建的镜像添加标签以便它们会出现在这里的信息。

 

在我们的持续交付配置中,我们将为每个分支自动构建一个镜像,如果镜像通过测试,那么我们会将其发布到注册表并自动运行,因此我们的应用程序将在所有“状态”下自动可用,例如,我们可以访问:

  • 几个功能分支,网址为 <featureName>.docker.domain.com
  • 测试版本,网址为 master.docker.domain.com
  • 试生产版本,网址为 preprod.docker.domain.com
  • 生产版本,网址为 prod.docker.domain.com

为此,我们需要一个域名并添加一条通配符 DNS 记录,将 *.docker.domain.com 指向 docker.domain.com 的 IP 地址。 另一种选项是使用不同的端口。

Nginx 代理

由于我们有几个功能分支,需要将子域自动重定向到正确的容器。 为此,我们可以使用 Nginx 作为反向代理。 此处提供了一份指南

GUI 工具

要开始使用容器,您可以使用命令行或 GUI 界面之一。 有许多可用工具,例如:

  • Rancher
  • MicroBadger
  • Portainer
  • Simple Docker UI
  • ...

它们允许您从 GUI 而不是 CLI 创建和管理容器。 下面是 Rancher 的外观:

 

GitLab Runner

与之前相同,要在其他服务器上执行脚本,我们需要安装 GitLab 运行程序。 我在第三篇文章中探讨过这一点。

请注意,您需要使用 Shell 执行器而不是 Docker 执行器。 当您需要从镜像内部提取某些内容时,将使用 Docker 执行器,例如在 Java 容器中构建 Android 应用程序并且只需要一个 apk 时。 在我们的示例中,我们需要整个容器,因此需要使用 Shell 执行器。

 

结论

开始运行容器十分容易,并且有许多工具可供选择。

使用容器的持续交付与常规的持续交付配置在以下几个方面有所不同:

  • 依赖关系的需求在构建时得到满足,并且在镜像构建后无需考虑依赖关系。
  • 可重现性 – 您可以通过本地运行相同的容器轻松重现任何现有环境。
  • 速度 – 由于容器仅包含您显式添加的内容,它们的构建速度更快,更重要的是,它们仅需构建一次并在需要时使用。
  • 效率 – 同上,与虚拟机等相比,容器产生的开销更少。
  • 可扩缩性 – 使用编排工具,您可以根据工作负载自动扩缩应用程序,并且仅消耗当前所需的资源。

后续内容

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

0
0 148
文章 Michael Lei · 九月 27, 2024 4m read

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

  • Git 101
  • Git 流程(开发流程)
  • GitLab 安装
  • GitLab 工作流
  • 持续交付
  • GitLab 安装和配置
  • GitLab CI/CD
  • 为何使用容器
  • 使用容器的 GitLab CI/CD

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

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

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

第四篇文章中,我们编写了 CD 配置。

在这篇文章中,我们将介绍容器以及使用容器的方法(和原因)。

这篇文章假设读者熟悉 docker 和容器的概念。 如果您想了解容器镜像,请查阅 @Luca Ravazzolo 撰写的文章。

优势

使用容器有诸多优势:

  • 可移植性
  • 效率
  • 隔离
  • 轻量
  • 不可变性

下面我们来具体介绍这些优势。

可移植性

容器将应用程序与运行所需的一切(如配置文件和依赖项)打包在一起。 这样一来,您可以在您本地台式机、物理服务器、虚拟服务器、测试、暂存、生产环境以及公共云或私有云等不同环境中轻松、可靠地运行应用程序。

可移植性的另一个优势是,在您构建 Docker 镜像并确认它可以正常运行后,它便可以在任何运行 docker 的位置(目前是 Windows、Linux 和 MacOS 服务器)运行。

效率

实际上,您只需要运行应用程序进程,而不需要运行所有系统软件等。 容器恰好可以满足这一需求 – 容器仅会运行您明确需要的进程,而不运行其他进程。 由于容器不需要单独的操作系统,占用的资源较少。 虚拟机的大小通常为几千兆字节,而容器的大小通常只有几百兆字节,因此在一台服务器上运行的容器数量要比虚拟机多得多。 由于容器对底层硬件的利用率更高,您需要的硬件更少,从而降低了裸机成本和数据中心成本。

隔离

容器会将应用程序与其他一切隔离开,同时多个容器可以在同一台服务器上运行,它们可以完全彼此独立。 容器之间的任何交互都应明确声明。 如果一个容器发生故障,它不会影响其他容器,并且可以快速重新启动。 得益于这种隔离机制,安全性也得到了保障。 例如,利用裸机上的 Web 服务器漏洞可能会让攻击者访问整个服务器,但如果使用的是容器,攻击者只能访问 Web 服务器容器。

轻量

由于容器不需要单独的操作系统,只需几秒钟即可启动、停止或重新启动,从而可以加快所有相关开发流程并缩短生产时间。 您可以更快地开始工作,并且无需花费任何时间进行配置。

不可变性

不可变基础架构由不可变组件组成,每次部署时都会替换这些组件,而不是就地更新。 这些组件通过每次部署构建一次的通用镜像启动,可以进行测试和验证。不可变性减少了不一致情况,并且可以轻松地在应用程序的不同状态之间进行复制和移动。 详细了解不可变性

新可能

利用上文提到的所有优势,我们可以通过全新的方式管理基础架构和工作流。

编排

裸机或虚拟机环境存在一个问题 – 它们具有个体性,这一问题会在使用过程中带来许多意外,而这些意外通常不尽如人意。 解决这一问题的方法是基础架构即代码 – 利用 DevOps 团队为源代码使用的版本控制方法,采用描述性模型管理基础架构。

通过基础架构即代码,无论环境的起始状态如何,部署命令始终会将目标环境设为相同的配置。 要实现这一点,可自动配置现有目标,也可以丢弃现有目标并重新创建全新的环境。

因此,利用基础架构即代码,团队会更改环境描述并对配置模型进行版本控制,而配置模型通常采用 JSON 等归档完好的代码格式。 发布管道会执行该模型,以配置目标环境。 如果团队需要进行更改,则可以编辑源代码,而不是目标环境。

借助容器,这一切都可以实现,并且实施起来简单得多。 关闭容器并启动一个新容器只需几秒钟,而配置新虚拟机则需要几分钟。 我甚至都没有提到将服务器回滚到空白状态。

扩缩

基于之前的描述,您可能认为基础架构即代码本身是静态的。 并不是这样,因为编排工具也可以根据当前工作负载提供横向扩缩(进行更多相同的配置)。 您仅应运行目前需要的容器,并相应地扩缩应用程序。 这样还可以降低成本。

结论

容器可以简化开发流程。 消除了环境之间的不一致,可以更轻松地进行测试和调试。 可以通过编排构建可扩缩应用程序。可以轻松实现部署或回滚到不可变历史的任意点。

组织希望在更高层级上处理任务,其中所有上述问题均已得到解决,并且我们发现调度程序和编排程序以自动方式为我们处理更多的任务。

后续内容

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

0
0 100
文章 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
问题 water huang · 九月 3, 2024

我使用%SYSTEM.WorkMgr的多进程(multicompile=1)来处理数据,但是我发现执行完WaitForComplete后,%SYSTEM.WorkMgr创建的进程没有马上结束,

他们的状态是evtw,如果我执行了很多次这样的操作,进程就会越来越多,它会导致服务器卡顿等异常,但是过一会儿他们会消失,留一个它不会消失。它产生的子进程其实是可以使用$System.Process.Terminate(pid) 来结束,但是这样结束术后,它会有错误信息我的问题是如何正确的结束%SYSTEM.WorkMgr产生的子进程,如何避免服务器因此受到影响甚至宕机,为什么他会导致服务器出问题,有什么办法能再使用完成后,把 %SYSTEM.WorkMgr相关的进程正确的快速结束掉

0
0 112
文章 Cryze Zhang · 八月 18, 2024 1m read

由于个人习惯,更喜欢将代码文件使用xml格式导入导出,但是有时后翻代码,xml格式的阅读体验没那么好,如果要是导入到studio又太麻烦,所以实现了一个在线工具,解析xml内容,将其转换为在Studio看到的内容,即所谓的UDL(Universal Definition Language)格式。
小工具地址

https://ttykx.com/demos/cos/xml2Udl.html

1.选择xml文件,读取内容。

 

2.解析项目,按项目显示原xml内容

 

3.转为UDL格式内容

 

0
0 99
文章 Michael Lei · 七月 25, 2024 1m read

InterSystems 常见问题FAQ 

要编译包含映射修饰符的类rountine,请指定编译器修饰符“/mapped=1”或“/mapped”。例如,执行以下操作:

[示例 1] 获取类列表并编译

do$System.OBJ.GetClassList(.list,"/mapped")
 // build your classes starting from .listdo$System.OBJ.Compile(.list) 

[示例 2] 编译所有类 

do$system.OBJ.CompileAll("/mapped") 
0
0 83
文章 Michael Lei · 七月 18, 2024 1m read

InterSystems 常见问题系列

可以通过 TRY-CATCH 来完成:

#dim ex As%Exception.AbstractExceptionTRY {
    //Code that causes an error
  }
  CATCH ex {
     do ex.Log()
  }

如果用了 ^%ETN, 从BACK 接入点 (BACK^%ETN)处调用.

请参考另外一篇文章: 如何使用命令获得应用错误 (^ERRORS)

0
0 77
文章 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
文章 Michael Lei · 七月 7, 2024 1m read

InterSystems 常见问题系列FAQ

如果要让超时功能失效, 在DSN设置查询超时为disabled:

Windows Control Panel > Administrative Tools > Data Sources (ODBC) > System DSN configuration

如果勾选了Disable query timeout , 超时就会失效.

如果想在应用侧修改,你可以在ODBC API 层设置:在连接数据源之前,调用ODBC SQLSetStmtAttr功能设置SQL_ATTR_QUERY_TIMEOUT 属性 

0
0 91
文章 Michael Lei · 七月 7, 2024 1m read

InterSystems 常见问题FAQ

如果您想在InterSystems 产品启动时执行一个操作系统可执行文件,命令或者程序,可以在SYSTEM^%ZSTART routine里面写明流程 ( %ZSTART routine在 %SYS 命名空间里面创建).

在 SYSTEM^%ZSTART 里面写代码之前, 请确保他可以在任何情况下能正常工作

如果 ^%ZSTART routine 写的不对,或者没有响应或者发生错误,InterSystems 产品可能会无法启动。

更多信息,请参考一下文档。

About writing %ZSTART and %ZSTOP routines [IRIS]
About writing %ZSTART and %ZSTOP routines

0
0 92
文章 Michael Lei · 七月 7, 2024 4m read

InterSystems  常见问题系列FAQ

InterSystems 产品里数据 (表、对象、实例数据) 是存在global 变量里的。
每个global 的数据大小可以从管理门户中中点击属性查看Management Portal > System > Configuration > Local Database > Globals page, 然后在global 属性页点击计算大小Calculate Size 按钮。
你可以在终端上调用^%GSIZE  来在命名空间里显示数据大小,方法如下.

0
0 83