搜索​​​​

      清除过滤器
      文章
      Li Yan · 一月 13, 2021

      面向 Microsoft Azure Resource Manager (ARM) 的 InterSystems 示例参考架构

      本文提供了一个参考架构,作为示例说明基于 InterSystems Technologies(适用于 Caché、Ensemble、HealthShare、TrakCare 以及相关的嵌入式技术,例如 DeepSee、iKnow、Zen 和 Zen Mojo)提供的强大性能和高可用性应用。Azure 有两种用于创建和管理资源的不同部署模型:Azure Classic 和 Azure Resource Manager。 本文中的详细信息基于 Azure Resource Manager (ARM) 模型。 摘要 Microsoft Azure 云平台为基础设施即服务 (IaaS) 提供功能丰富的环境,其作为云提供完备的功能,支持所有的 InterSystems 产品。 与任何平台或部署模型一样,必须留心以确保考虑到环境的各个方面,例如性能、可用性、操作和管理程序。 本文将阐述所有这些方面。 性能 在 Azure ARM 中,有多个可用于计算虚拟机 (VM) 的选项以及相关的存储选项,与 InterSystems 产品最直接相关的是网络连接 的IaaS 磁盘,其作为 VHD 文件存储在 Azure 页面的 Blob 存储中。 还有其他几个选项,例如_ Blob(块)、文件_等,但是这些选项更特定于单个应用程序的要求,而非支持 Caché 的操作。 磁盘存储有两种类型的存储:“高级存储”和“标准存储”。 高级存储更适合这样的生产工作负载:要求保证可预测的低延迟每秒输入/输出操作 (IOP) 和吞吐量。 标准存储是针对非生产或存档类型工作负载的更经济选择。 选择特定的 VM 类型时务必小心,因为并非所有的 VM 类型都可以访问高级存储。 虚拟 IP 地址和自动故障转移 大多数 IaaS 云提供商缺乏提供虚拟 IP (VIP) 地址的能力,这种地址通常用在数据库故障转移设计中。 为解决这一问题,Caché 中增强了几种最常用的连接方法,尤其是 ECP 客户端和 CSP 网关,从而不再依赖 VIP 功能使它们实现镜像状态感知。 xDBC、直接 TCP/IP 套接字等连接方法,或其他的直接连接协议,均需要使用 VIP。 为解决这些问题,InterSystems 数据库镜像技术使用 API 与 Azure 内部负载均衡器(ILB)交互以实现类 VIP 功能,使得 Azure 中的那些连接方法实现自动故障转移,从而在 Azure 中提供完整而强大的高可用性设计 。 有关详细信息,请参见社区文章无虚拟 IP 地址的数据库镜像。 备份操作 无论使用传统的文件级备份,还是基于快照的备份,在云部署中执行备份都面临着挑战。 如今,在 Azure ARM 平台中,使用 Azure Backup 和 Azure Automation Run Books 配合 InterSystems 外部冻结及解冻 API 功能,即可实现这一切,从而实现真正的 24x7 全天候操作弹性并确保干净的常规备份。 或者,可以在 VM 本身中部署备份代理,利用文件级备份,并结合逻辑卷管理器 (LVM) 快照,来使用市面上的许多第三方备份工具。 示例架构 作为本文档的一部分,这里为您提供一个示例 Azure 架构,作为您特定应用部署的入门参考,并可用作各种部署的可能性的指南。 此参考架构显示了一个强大的 Caché 数据库部署,其中包括可实现高可用性的数据库镜像成员、使用 InterSystems 企业缓存协议(ECP)的应用程序服务器、使用 InterSystems CSP 网关的 Web 服务器,以及内部和外部 Azure 负载均衡器。 Azure 架构 在 Microsoft Azure 上部署任何基于Caché 的应用都需要特别注意某些方面。 本部分讨论通用的方面,对于您的应用的特定技术要求不做阐述。 本文档中提供了两个示例,一个基于_ InterSystems TrakCare 统一医疗信息系统,另一个基于完整的 InterSystems HealthShare 健康信息学平台部署,包括:_Information Exchange、Patient Index、Health Insight、Personal Community 和 Health Connect。 虚拟机 Azure 虚拟机 (VM) 分为两层:基本层和标准层。 两种类型提供对规模的选择。 基本层不提供标准层中的某些功能,例如负载均衡和自动伸缩。 因此,将标准层用于 TrakCare 部署。 标准层 VM 具有不同规模,按不同系列分组,即: A、D、DS、F、FS、G 和 GS。 DS、GS 和新的 FS 支持 Azure 高级存储的使用。 生产服务器通常需要使用高级存储来实现可靠性、低延迟和高性能。 因此,本文档中详细介绍的示例 TrakCare 和 HealthShare 部署架构将使用 FS、DS 或 GS 系列 VM。 注意,并非所有的虚拟机规模在所有区域中都可用。 有关虚拟机规模的详细信息,请参见: Windows 虚拟机规模 Linux 虚拟机规模 存储 TrakCare 和 HealthShare 服务器需要 Azure 高级存储。 高级存储将数据存储在固态硬盘 (SSD) 上,以低延迟提供高吞吐量;而标准存储将数据存储在硬盘驱动器 (HDD) 上,会导致性能的降低。 Azure 存储属于冗余且高度可用的系统,但是,请务必注意,可用性集合当前不提供跨存储故障域的冗余,在极少数情况下,这可能会导致问题。 Microsoft 有缓解方案,并正在努力使此过程对最终客户广泛可用且更容易使用。 建议您直接与当地的 Microsoft 团队合作以确定是否需要任何缓解方案。 当针对高级存储帐户配置磁盘时,IOPS 和吞吐量(带宽)取决于磁盘的大小。 当前,有三种类型的高级存储磁盘:P10、P20 和 P30。 每种对 IOPS 和吞吐量都有特定的限制,如下表所示。 高级磁盘类型 P4 P6 P10 P15 P20 P30 P40 P50 磁盘容量 32GB 64GB 128GB 256GB 512GB 1024GB 2048GB 4096GB 每个磁盘的 IOPS 120 240 500 1100 2300 5000 7500 7500 每个磁盘的吞吐量 25MB/s 50MB/s 100MB/s 125MB/s 150MB/s 200MB/s 250MB/s 250MB/s 注意:确保给定的 VM 上有足够的可用带宽来驱动磁盘流量。 例如,STANDARD_DS13 VM 具有每秒 256 MB 的专用带宽,可用于所有高级存储磁盘流量。 这意味着连接到该虚拟机的四个 P30 高级存储磁盘的吞吐量限制为每秒 256 MB,而不是四个 P30 磁盘理论上可以提供的每秒 800 MB 的速度。 有关高级存储磁盘的更多详细信息和限制,包括预配置的容量、性能、大小、IO 大小、缓存命中率、吞吐量目标和限制,请参阅: 高级存储 高可用性 InterSystems 建议在已定义的可用性集合中拥有两个或更多虚拟机。 之所以需要此配置,是因为在计划内或计划外的维护活动期间,至少有一个虚拟机可用于满足 99.95% 的 Azure SLA。 这很重要,因为在数据中心更新期间,VM 会被并行关闭、升级并以不特定的顺序重新联机,导致应用程序在此维护窗口期不可用。 因此,高度可用的架构需要每种服务器至少部署两台,这些服务器包括负载均衡 Web 服务器、数据库镜像、多个应用程序服务器等。 有关 Azure 高可用性最佳做法的更多信息,请参见: 管理可用性 Web 服务器负载均衡 基于 Caché 的应用程序可能需要外部和内部负载均衡 Web 服务器。 外部负载均衡器用于通过 Internet 或 WAN(VPN 或 Express Route)进行的访问,而内部负载均衡器则通常用于内部流量。 Azure 负载均衡器是 4 层 (TCP, UDP) 的负载均衡器,可在负载均衡器集合中定义的云服务或虚拟机中的健康服务实例之间分配传入的流量。 Web 服务器负载均衡器必须配置客户端 IP 地址会话持续性(2 个元组)和可能的最短探测超时(当前为 5 秒)。 TrakCare 需要在用户登录期间保持会话持续性。 Microsoft 提供的下图显示了 ARM 部署模型中一个简单的 Azure 负载均衡器示例。 有关 Azure 负载均衡器的功能(例如分配算法、端口转发、服务监视、源 NAT )和其他类型的可用负载均衡器的详细信息,请参阅: 负载均衡器概述 除了 Azure 外部负载均衡器,Azure 还提供 Azure 应用程序网关。 Application Gateway 是一个 L7 负载均衡器 (HTTP/HTPS),支持基于 cookie 的会话相关性和 SSL 终端(SSL 卸载)。 SSL 卸载可减轻 Web 服务器的加密/解密开销,因为 SSL 连接会在负载均衡器处终止。 这种方法简化了管理,因为 SSL 证书是在网关中部署和管理,而不是在 Web 场中的所有节点上。 有关详细信息,请参阅︰ 应用程序网关概述 使用 Azure Resource Manager 为 SSL 卸载配置应用程序网关 数据库镜像 在 Azure 上部署基于 Caché 的应用程序时,要为 Caché 数据库服务器提供高可用性,需要使用同步数据库镜像,以在给定的主 Azure 区域中提供高可用性,并可能使用异步数据库镜像将数据复制到辅助 Azure 区域中的热备用数据库中,以根据您的运行时间服务水平协议要求来进行灾难恢复。 数据库镜像是两个数据库系统的逻辑分组,也就是所说的故障转移成员,它们在物理上是仅通过网络连接的独立系统。 在这两个系统之间进行仲裁后,镜像会自动将其中一个指定为主系统。 另一个自动成为备份系统。 外部客户端工作站或其他计算机通过镜像虚拟 IP (VIP) 连接到镜像,该虚拟 IP 在镜像配置期间指定。 镜像 VIP 会自动绑定到镜像主系统上的接口。 注意:在 Azure 中,无法配置镜像 VIP,因此已设计了替代解决方案。 当前,在 Azure 中部署数据库镜像时,建议在同一 Azure 可用性集中配置三个 VM(主 VM、备份 VM、仲裁器)。 这样可确保在任何给定的时间,Azure 都可以保证至少与其中两个 VM 以 99.95% 的 SLA 建立外部连接,并且每个 VM 都位于不同的更新域和故障域中。 这样可以为数据库数据本身提供足够的隔离和冗余。 可在下列位置找到更多详细信息: Azure 可用性集 Azure 服务水平协议 (SLA) 包括 Azure 在内的任何 IaaS 云提供程序所面临的挑战,就是在没有虚拟 IP 功能的情况下,如何处理连接到应用程序的客户端的自动故障转移。 为了保持客户端连接的自动故障转移,已采取了两种策略。 首先,InterSystems 对 CSP 网关进行了增强,使其能够感知镜像,以此使得采用 CSP 网关的 Web 服务器到数据库服务器的连接不再需要 VIP。 CSP 网关将自动与两个镜像成员进行协商,并重定向到确定的主镜像成员。 如果使用 ECP 客户端,则将与其已经具备的镜像感知协同工作。 其次,CSP 网关和 ECP 客户端外部的连接仍然需要类 VIP 功能。 InterSystems 建议将轮询方法与_ mirror_status.cxw _运行状况检查状态页面介绍的内容结合使用,该页面在社区文章无虚拟 IP 地址的数据库镜像中进行了详细说明。 Azure 内部负载均衡器 (ILB) 将提供单一 IP 地址作为类 VIP 功能,将所有网络流量定向到主镜像成员。 ILB 只会将流量分配给主镜像成员。 此方法不会依赖轮询,且在镜像配置内的任何镜像成员成为主成员时,允许立即重定向。 在某些使用 Azure Traffic Manager 的灾难恢复方案中,可将此方法与轮询结合使用。 备份与恢复 备份操作有多个选项。 以下 3 个选项可供您通过 InterSystems 产品进行 Azure 部署。 下面的前 2 个选项采用快照类型的过程,该过程会在创建快照之前将数据库写入到磁盘的操作挂起,然后在快照成功后恢复更新。 可采取以下高级别步骤通过任一快照方法来创建洁净的备份: 通过数据库冻结 API 调用暂停对数据库的写入。 创建操作系统和数据磁盘的快照。 通过数据库解冻 API 调用恢复 Caché 写入。 将设施存档备份到备份位置 可以定期添加诸如完整性检查之类的其他步骤,以确保洁净且一致的备份。 决定使用哪种选项取决于您组织的运营要求和策略。 InterSystems 可与您详细讨论各种选项。 Azure 备份 如今,在 Azure ARM 平台中,使用 Azure Backup 和 Azure Automation Run Books 配合 InterSystems 外部冻结及解冻 API 功能,即可实现备份操作,从而实现真正的 24x7 全天候操作弹性并确保干净的常规备份。 有关管理和自动化 Azure 备份的详细信息,可在此处找到。 逻辑卷管理器快照 或者,可以在 VM 本身中部署单个备份代理,利用文件级备份,并结合逻辑卷管理器 (LVM) 快照,来使用市面上的许多第三方备份工具。 该模型的主要优点之一是能够对基于 Windows 或 Linux 的 VM 进行文件级恢复。 此解决方案需要注意的几点是,由于 Azure 和大多数其他 IaaS 云提供商都不提供磁带媒体,因此所有的备份存储库对于短期归档均基于磁盘,并利用 Blob 或存储桶类型的低成本存储来进行长期保留 (LTR)。 强烈建议您使用此方法来使用支持重复数据删除技术的备份产品,以最有效地利用基于磁盘的备份存储库。 这些具有云支持的备份产品的示例包括但不限于:Commvault、EMC Networker、HPE Data Protector 和 Veritas Netbackup。 InterSystems 不会验证或认可一种备份产品是否优于其他产品。 Caché 在线备份 对于小型部署,内置 Caché 在线备份工具也是可行的选择。 该 InterSystems 数据库在线备份实用工具通过捕获数据库中的所有块来备份数据库文件中的数据,然后将输出写入顺序文件。 这种专有的备份机制旨在使生产系统的用户不停机。 在 Azure 中,在线备份完成后,必须将备份输出文件和系统正在使用的所有其他文件复制到 Azure 文件共享中。 该过程需要在虚拟机中编写脚本并执行。 Azure 文件共享应使用 Azure RA-GRS 存储帐户以实现最大可用性。 注意,Azure 文件共享的最大共享大小为 5TB,最大文件大小为 1TB,每个共享(所有客户端共享)的最大吞吐量为 60 MB/s。 在线备份是入门级方法,适合于希望实施低成本备份解决方案的小型站点。 但是,随着数据库的增大,建议将使用快照技术的外部备份作为最佳做法,因为其具有以下优势:备份外部文件、更快的恢复时间,以及企业范围的数据和管理工具。 灾难恢复 在 Azure 上部署基于 Caché 的应用程序时,建议将包括网络、服务器和存储在内的灾难恢复 (DR) 资源放置在不同的 Azure 区域中。 指定的 DR Azure 区域所需的容量取决于您组织的需求。 在大多数情况下,以 DR 模式运行时需要 100% 的生产能力,但是,在需要更多的生产能力作为弹性模型之前,可以配置较小的生产能力。 异步数据库镜像用于连续复制到 DR Azure 区域的虚拟机。 镜像使用数据库事务日志在 TCP/IP 网络上复制更新,其采用对主系统性能影响最小的方式。 强烈建议对这些 DR 异步镜像成员配置压缩和加密。 互联网上希望访问应用程序的所有外部客户端都将通过 Azure Traffic Manager 作为 DNS 服务进行路由。 Microsoft Azure Traffic Manager(ATM)用作交换机,负责将流量定向到当前活动的数据中心。 Azure Traffic Manager 支持多种算法来确定如何将最终用户路由到各个服务端点。 有关各种算法的详细信息,可在此处找到。 本文档中,“优先级”流量路由方法将与 Traffic Manager 端点监视和故障转移结合使用。 有关端点监视和故障转移的详细信息,可在此处找到。 Traffic Manager 的工作是向每个端点发出常规请求,然后验证响应。 如果端点未提供有效的响应,则 Traffic Manager 会将其状态显示为“降级”。 它将不会再被包含在 DNS 响应中,而是会返回一个备用的可用端点。 通过这种方式,将用户流量从失败的端点定向到可用端点。 使用上述方法,只有特定区域和特定镜像成员才允许流量通过。 这由端点定义控制,可从 InterSystems CSP 网关的 mirror_status 页面设置端点定义。 只有主镜像成员才能通过监控器探测来报告 HTTP 200 为“成功”。 Microsoft 提供的下图在高级别上显示了优先级流量例程算法。 Azure Traffic Manager 会产生一个所有客户端都可以连接到的端点,例如:“ https://my-app.trafficmanager.net ”。 此外,可以配置 A 记录来提供虚 URL,例如“ https://www.my-app-domain.com ”。Azure Traffic Manager 必须配置一个包含两个区域端点地址的配置文件。 在任何给定时间,只有其中的一个区域会根据端点监视在线报告。 这样可以确保流量在给定的时间仅流向一个区域。 区域之间的故障转移无需其他步骤,因为端点监控将检测到主 Azure 区域中的应用程序已关闭,并且该应用程序现在位于辅助 Azure 区域中。 这是因为 DR 异步镜像成员被提升为主成员,然后允许 CSP 网关将 HTTP 200 报告给 Traffic Manager 端点监视。 上述解决方案有很多替代方案,可以根据您组织的运营要求和服务水平协议进行自定义。 网络连接 根据您应用程序的连接要求,有多种连接模型可用:使用 Internet、IPSEC VPN 的连接模型,或使用 Azure Express Route 的专用链接。 选择方法取决于应用程序和用户需求。 三种方法的带宽使用情况各不相同,最好与您的 Azure 代表或 Azure 门户联系以确认给定区域的可用连接选项。 如果您正在使用 Express Route,则可为灾难恢复方案启用包括多线路和多区域访问在内的多个选项。 与 Express Route 提供商合作以了解他们支持的高可用性和灾难恢复方案至关重要。 安全 决定在公共云提供程序中部署应用程序时需要格外小心。 应遵循您组织的标准安全策略或专门为云开发的新安全策略,以维护您组织的安全合规性。 就客户端数据中心之外的数据以及物理安全控制方面,云部署的风险逐渐加大。 强烈建议对静态数据(数据库和日志)及飞行数据(网络通信)使用 InterSystems 数据库和日志加密,分别使用 AES 和 SSL/TLS 加密。 与所有加密密钥管理一样,您需要按照您组织的政策记录并遵循正确的程序,以确保数据安全,防止不必要的数据访问或安全漏洞。 当允许通过互联网进行访问时,可能需要第三方防火墙设备来实现其他功能,例如入侵检测、拒绝服务保护等。 架构图示例 下图说明了典型的 Caché 安装,其以数据库镜像(同步故障转移和 DR 异步)、使用 ECP 的应用程序服务器,以及多个负载均衡 Web 服务器的方式提供高可用性。 TrakCare 示例 下图说明了典型的 TrakCare 部署,其中包含多个负载均衡 Web 服务器,两个作为 ECP 客户端的 EPS 打印服务器,以及数据库镜像配置。 虚拟 IP 地址仅用于与 ECP 或 CSP 网关不关联的连接。 ECP 客户端和 CSP 网关可感知镜像,不需要 VIP。 下图中的示例参考架构包括活动或主区域中的高可用性,可在主 Azure 区域不可用的情况下,执行灾难恢复到另一个 Azure 区域。 同样,在此示例中,数据库镜像包含 TrakCare DB、TrakCare Analytics 和 Integration 命名空间,这些都在一个镜像集群中。 TrakCare Azure 参考架构图 - 物理架构 另外,下图显示了该架构的逻辑图,包含架构所安装的相关高级软件产品及其功能用途。 TrakCare Azure 参考架构图 - 逻辑架构 HealthShare 示例 下图显示了一个典型的 HealthShare 部署,其具有多个负载均衡 Web 服务器,以及多个 HealthShare 产品,包括 Information Exchange、Patient Index、Personal Community、Health Insight 和 Health Connect。 这些产品中的每一个都包含一对数据库镜像,以在 Azure 可用性集合中提供高可用性。 虚拟 IP 地址仅用于与 ECP 或 CSP 网关不关联的连接。 HealthShare 产品之间用于 Web 服务通信的 CSP 网关可感知镜像,不需要 VIP。 下图中的示例参考架构包括活动或主区域中的高可用性,可在主 Azure 区域不可用的情况下,执行灾难恢复到另一个 Azure 区域。 HealthShare Azure 参考架构图 - 物理架构 另外,下图显示了该架构的逻辑图,包含架构所安装的相关高级软件产品、连接要求、方法及相应的功能用途。 HealthShare Azure 参考架构图 - 逻辑架构
      文章
      Louis Lu · 三月 12, 2021

      第 1 天:使用 InterSystems Object 和 SQL 进行开发

      原文在这里。 原作者YURI MARX GOME 我正在参加 Joel Solon 讲授的“使用 InterSystems Objects 和 SQL 进行开发”课程。 课程非常好,我将在这里分享一些从培训中总结的提示。 第 1 天的提示: 1. InterSystems IRIS 统一了:InterSystems IRIS Database (Caché)、IRIS Interoperability (Ensemble)、IRIS Business Intelligence (DeepSee) 和 IRIS Text Analytics (iKnow)。 2. IRIS 为多模型:对象、关系、文档和多维。 3. 互操作性:从 Java、.NET 和其他语言(如 ObjectScript)进行原生访问;ODBC 和 JDBC 数据访问,SOAP/REST 服务访问;数据路由、转换和工作流驱动消息;支持 ESB 的 SOA 架构。 4. IRIS 是事务和分析的结合。 5. IRIS 使用 ECP(用户量的分布式缓存)和Sharding进行水平数据量扩展。 6. 使用 Cloud Manager 在公共或私有容器中部署。 7. 3 种待开发 IDE 选项:VSCode(最受欢迎)、Studio(仅限 Windows)、Atelier(已弃用)。 8. 适用于 CLI 命令的终端工具。 9. 基于浏览器的管理门户。 10. IRIS 支持多平台(UNIX,Linux,Windows),并为 Linux 提供了 Docker 选项。 11. 提供年度版本 20##.1(EM - 扩展维护)和季度版本(CD - 连续交付)。 12. IRIS 区分大小写,推荐采用驼峰表示法。 13. 类是方法和属性的容器。 14. 方法执行特定任务,不允许方法重载(类中具有两个同名方法)。 15. 有 2 种类型的方法:ClassMethod(与对象实例不关联的操作)和 Method(与对象实例相关联的操作)。 16. 使用 ##class() 运行类方法并创建实例(利用 %New 或 %OpenId)以执行 Methods。 17. 方法参数的默认类型为 %String。 18. 符号 ... 表示变量参数。 示例:Method Sample(a As %String, b... as %String) as %Status。 19. 将参数作为方法调用方传递时: 如果使用 . 则作为引用传递; 参数是可选的,您可以使用 $data() 借助调用方传递的参数进行测试。 20. string 是变量的默认类型。 21. ObjectScript 支持动态类型。 22. 在 ObjectScript 中,0 为 false,其他值为 true。 23. 软件包允许您将类整理到文件夹中。 24. 如果在类或方法中使用导入,则不需要将限定名称引用到类。 25. 持久类(存储在磁盘中)扩展 %Persistent。 26. 持久类具有保持类特性/值的属性。 27. 每个持久类都有一个唯一的不可变 ID 编号。 PS 1:我用 40,000 积分兑换了这个为期 5 天的课程(价值 2800 美元) (https://globalmasters.intersystems.com/rewards/34/reward_redemptions/new) PS 2:Joel Solon 是一位出色的讲师(提供了优秀的 IRIS 认证提示) PS 3:课程材料非常好,课程资源、工具和支持都很棒。 明天我会发布第 2 天的总结。
      文章
      Louis Lu · 四月 15, 2021

      第 2 天:使用 InterSystems Objects 和 SQL 进行开发

      原文在这里 原作者YURI MARX GOMES 我正在参加 Joel Solon 讲授的“使用 InterSystems Objects 和 SQL 进行开发”课程。 课程非常好,我将在这里分享一些从培训中总结的提示。 第 2 天的提示: 1. 您可以创建持久类(在数据库中具有对应表的类,用于保持类属性)。 2. 持久类示例: Class dc.Person extends (%Persistent) { Property Name As %String; Property BirthDate As %Date; } 3. 扩展 %Persistent 时,您将获得 %New() 以在内存中创建新实例,获得 %Save() 以保存到数据库,获得 %Id() 以获取该实例在数据库中的唯一 ID,以及获得 %OpenId() 以使用数据库值加载实例。 4. 持久类允许您调用 %Deleteid() 以从数据库中删除一个实例,调用 %DeleteExtent() 以删除所有保存的对象(没有 where 时删除!),调用 %ValidateObject() 以验证保存前传递的数据(验证是否必需、大小等)。 5. 持久类具有 %IsModified() 和 %Reload(),前者用于检查内存中的数据变化(参见评论中 joel 的提示),后者用于获取这些变化。 6. 要在尝试 %Save() 或 %Delete() 时获得可能的错误,请执行:set status = person.%Save(), write status。 如果保存成功,将返回 1。 7. 我们可以使用 do $system.Status.DisplayError(status) 查看错误详细信息。 8. 要调用持久类方法,请执行:##class(dc.Person).%Save()。 9. 要调用持久实例方法,执行:..Method()。 引用属性也一样,请执行:write ..Name。 10. 要从程序或终端内存中移除对象或变量,请使用 kill person 或 set person = ""。 如果仅使用 kill,将从内存中移除所有引用(不是从数据库中移除,在数据库中使用 killextent)。 11. 如果要通过实用工具方法填充测试数据,请使用 %Populate 扩展持久类,然后调用 Populate(行数)方法。 12. 您可以通过继承%SerialObject(不具有 ID 的持久类,因为它必须与另一个持久类相连)创建嵌入式类。 示例: Class dc.Contact Extends %SerialObject { Property Phone As %String; Property Email As %String; } 13. 此序列将成为您的持久类的一个属性: Class dc.Person extends (%Persistent) { Property Name As %String; Property BirthDate As %Date; Property Contact As dc.Contact; } 14. 在 IRIS 数据库中,将仅创建一个具有 Contact 属性的Person表。 15. 您可以创建索引来获得唯一性或调整查询。 示例:Index NameIndex On Name [Unique]。 16. 创建索引时,如果表不为空,则需要在管理门户中重建索引。 17. 要创建构造函数方法,请重写 %OnNew()。 这是在调用 %New() 时调用的回调方法。 还有其他回调方法。 18. IRIS 对 JSON 有很好的支持。 您可以通过调用 set name = {}.%FromJSON("{""Name"":""Yuri""}") 将 JSON 加载到对象。 19. 您可以从对象执行编写 JSON:name.%ToJSON()。 20. IRIS 和 Caché 中存在 JSON 数组(感谢 @RobertC..Cemper 提醒),但是只在 IRIS 中我们才有 JSON 的格式化程序和zwrite 写入 JSON。 明天我会发布第 3 天的总结。 PS:这是一份总结,课程中实际教授了更多内容。
      文章
      Louis Lu · 四月 15, 2021

      第 4 天:使用 InterSystems Objects 和 SQL 进行开发

      我正在参加 Joel Solon 讲授的“使用 InterSystems Objects 和 SQL 进行开发”课程。 课程非常好,我将在这里分享一些从培训中总结的提示。 第 4 天的提示: 1. 所有数据都存储在global中,global名称以 ^ 开头。 global示例:^animal。 global可以有多个数据位置(“子数据”)。 示例:^animal("大象","吃草")。 2. 可从任意系统范围(命名空间)访问 ^%* global。 3. global使 IRIS 能够支持多模型数据(对象、关系、文档、多维等)。 4. 要查看global,请转到 Management Portal > Explorer > Globals > Select Global > View,或者在终端中输入 do ^%G 或 zwrite ^global。 5. 在持久类和 SQL 表之间有自动对应关系: 包对应于是 SQL Schema; 类是Table; 属性是列; 方法是存储过程(使用 sqlProc 时); 类之间的关系是 SQL 外键约束(必须为双向)。 对象是行。 6. 一个表可以对应多个类,但序列类serial是持久类表的一部分(没有特定的表)。 7. 一个类可以对应多个表。 8. 我们有一些类类型: Non-registered:不是类对象(仅限方法的容器); Registered:瞬态对象; Persistent:类似于SQL表中持久化保存; Serial:嵌入主持久化表中的持久表(Serial为嵌入式); Datatype:非类对象用于执行新的验证和转换为基础数据类型。 9. 类的组成可包括: 属性; 方法; Class queries:SQL Select 语句; Parameters:配置类行为的用户常量或系统常量; 外键:参照完整性; 索引:提高性能并创建独特值; 触发器:触发与持久性事件关联的方法; XData:与该类关联的 XML 或 JSON 定义; 存储:数据存储的描述。 10. 按照惯例,类的首字母大写。 示例:CountryOrigin。 参数均为大写。 示例:COLORNUMBER。 11. 类特性限定/配置一个类。 示例 [SqlTableName = Animal] 可设置SQL表名。 [Final] 不允许继承。 [Private] 不允许为非子类调用方法或使用属性。 12. IRIS 在内部生成 Get 和 Set 属性,这些属性不可见,但可以通过声明改变行为。 13. 可以重写超类的方法,为此,请重复类名、参数。 可以增加参数的数量,不可减少。 14. 使用 ##super() 调用基类方法。 15. 要创建抽象类,请使用 [Abstract] 并防止实例化。 16. 可以继承多个类。 例如,Class Person extends (%Persistent, %Animal)。 (Persistent 必须是 extends 中的第一个类,参见评论中 joel 的提示) 17. REST 是表述性状态转移。 它基于 HTTP 协议。 使用 HTTP 谓词:GET(选择)、POST(插入)、PUT(更新)和 DELETE(删除)。 18. 要将您的类作为 REST 资源公开,请从 %CSP.REST 扩展。 19. 在 XData 块中使用 URLMap 配置 REST 服务的路由。 使用门户,创建一个 Web 应用程序,启用 REST 并指定 Dispatch 类。 20. %JSONAdaptor 提供了对象与 JSON 之间的转换。 使用 obj.%JSONImport(jsonObj) 将 DynamicObject 分配到对象。 使用 obj.%JSONExportToString(.jsonString) 将 JSON 字符串写入对象。 21. %JSON.Formatter 格式化 JSON 字符串以便人类阅读。
      文章
      Louis Lu · 四月 15, 2021

      第 3 天:使用 InterSystems Objects 和 SQL 进行开发

      我正在参加 Joel Solon 讲授的“使用 InterSystems Objects 和 SQL 进行开发”课程。 课程非常好,我将在这里分享一些从培训中总结的提示。 第 3 天的提示: 1. 您可以使用 %Dictionary 类查看类目录,并在 INFORMATION_SCHEMA 表中查看 sql 对象。 2. 可以在 ObjectScript 方法中以动态 SQL 或嵌入式 SQL 使用 SQL。 3. 您可以使用 ?(例如:where country = ?)将参数传递到动态 SQL 字符串, 使用冒号(例如:where country = :variable)将参数传递到嵌入式 SQL。 4. 动态 SQL 示例(来自 Intersystems 文档): SET tStatement = ##class(%SQL.Statement).%New(,"Sample") SET myquery = 3 SET myquery(1) = "SELECT TOP ? Name,DOB,Home_State" SET myquery(2) = "FROM Person" SET myquery(3) = "WHERE Age > 60 AND Age < 65" SET qStatus = tStatement.%Prepare(.myquery) IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT} DO tStatement.%Display() WRITE !,"End of %Prepare display" 5. 嵌入式 SQL 示例(来自 Intersystems 文档): #SQLCompile Select=Display &sql(SELECT DOB INTO :a FROM Sample.Person) IF SQLCODE<0 {WRITE "SQLCODE error ",SQLCODE," ",%msg QUIT} ELSEIF SQLCODE=100 {WRITE "Query returns no results" QUIT} WRITE "1st date of birth is ",a,! DO $SYSTEM.SQL.Util.SetOption("SelectMode",1) WRITE "changed select mode to: ",$SYSTEM.SQL.Util.GetOption("SelectMode"),! &sql(SELECT DOB INTO :b FROM Sample.Person) WRITE "2nd date of birth is ",b 6. 嵌入式 SQL 示例 - 插入: &sql(INSERT INTO Sample.Person (Name, Age, Phone) VALUES (:name, :age, :phone) 7. 如果您需要使用 SQL 批量处理数据,处理单个记录,请使用 Persistent Object API。 8. 您可以创建 SQLQuery 方法,如果在方法中使用 [SqlProc],将在 SQL 端中创建一个 SQL 存储过程。 9. 从终端可以进入 SQL Shell,要从终端进入 SQL 命令,请执行 do $system.SQL.Shell()。 10. 持久类具有系统生成的 ID,如果需要由您控制的 ID,您可以使用具有一个或多个属性的 IDKEY 索引。 例如,SocialNumber [IdKey, PrimaryKey, Unique] 上的索引键。 11. 当两个或多个进程同时尝试处理相同数据时,有两种控制并发的策略:悲观型和乐观型。 12. 要获取悲观控制,请使用 %OpenId(ID, 4) 锁定对象,其中 4 会将表锁定为互斥访问。 在进程运行后,可以释放锁定。 13. 要进行乐观控制(针对 Web 应用),在您的持久类中创建 Parameter VERSIONPROPERTY = "Version"; Property Version as %Integer [ InitialExpression = 1 ]。 IRIS 会在每次实例更新时递增属性版本,这样可以协调更新顺序,而不是锁定表。 14. 当您有更新、插入或删除数据的方法时,请使用事务保持数据一致。 示例: Transfer(from,to,amount) // Transfer funds from one account to another { TSTART &SQL(UPDATE A.Account SET A.Account.Balance = A.Account.Balance - :amount WHERE A.Account.AccountNum = :from) If SQLCODE TRollBack Quit "Cannot withdraw, SQLCODE = "_SQLCODE &SQL(UPDATE A.Account SET A.Account.Balance = A.Account.Balance + :amount WHERE A.Account.AccountNum = :to) If SQLCODE TROLLBACK QUIT "Cannot deposit, SQLCODE = "_SQLCODE TCOMMIT QUIT "Transfer succeeded" } 15. InterSystems IRIS 的架构基于命名空间(数据库的逻辑组)和数据库。 16. 要在数据库中保存的数据有两种类型:数据(global)和代码(源代码 - 过程)。 17. 您可以使用 ECP(企业缓存协议)对数据库进行水平处理扩展,这样可以在同一命名空间访问查看多个服务器中不同的数据库。 18. 您可以使用Sharding(仅限 IRIS)进行水平数据量扩展(分布式数据库分区),这样可以将数据分区到分布式节点(如 MongoDB)。 19. 数据库的最大容量是 32TB。 20. 要从一个命名空间更改为另一个命名空间,请执行 zn "Namespace" 或 set $namespace = "Namespace"。 PS 1:课程详细展示了如何进行事务控制,这非常重要。 明天我会发布第 4 天的总结。
      文章
      Michael Lei · 五月 24, 2021

      InterSystems 最佳实践系列之数据平台和性能 - 第 6 部分 Caché 存储 IO 配置文件

      我本人和其他技术架构师经常需要向客户和供应商说明 Caché IO 要求以及 Caché 应用程序使用存储系统的方式。 在向客户和供应商说明典型的 Caché IO 配置文件和事务性数据库应用程序的要求时,下面的表格很有用。  原始表格由 Mark Bolinsky 创建。 在以后的帖子中,我将讨论更多关于存储 IO 的内容,所以现在贴上这些表格也作为将来文章的参考。  * * * [本系列其他帖子的列表](https://cn.community.intersystems.com/post/intersystems-数据平台的容量规划和性能系列文章)   * * * 拥有设置良好的存储(如存储阵列)以提供可预测的磁盘 IO 性能,支持高可用性功能并为应用程序提供存储冗余、可伸缩性和可靠性,这几点至关重要。 ## Caché 存储 IO 配置文件 根据所选的存储阵列技术,物理层的磁盘存储可分为池或磁盘组。 如果可能,出于可用性和性能考虑,应根据预期的 IO 配置文件对存储进行分区。 例如,数据和日志(事务日志)应该在不同的物理磁盘组上,因为它们有不同的 IO 配置文件,这也是出于可用性考虑,因为数据磁盘组中的损坏可以通过与损坏隔离的单独磁盘组中的日志来恢复。 同样,备份应该在单独的磁盘组中。 存储配置有多种选择,具体取决于操作系统、存储供应商和阵列型号。 具体要求因应用程序而异,需要特别注意物理和逻辑配置,包括物理和逻辑组或池的分配、RAID 类型、文件系统类型和并发性、分配的 GB 空间等。 下表详细介绍了 Caché 的读写 IO 配置文件: ![](/sites/default/files/inline/images/2016-11-14_09-45-42.png) ## Caché 存储 IO 要求 我发现存储瓶颈是影响数据库系统性能的最常见问题之一。 一个常见的问题是只针对 GB 容量来调整存储大小,而不是分配足够多的独立磁盘来支持预期的每秒输入/输出操作数 (IOPS)。 尽管 SSD 和分层存储现在更加常见,但必须小心以确保 IOPS 可用。 为了保证可被最终用户接受的响应时间,需要具有最低 IO 性能配置文件的磁盘阵列。 根据是否使用单独的应用程序 (ECP) 服务器,要求会略有不同。 下表详细说明了预期的存储响应时间和关于 IO 配置文件的备注。   ![](/sites/default/files/inline/images/2016-11-14_09-45-09.png) ## 缺少了什么? 在与供应商交谈之前,您需要估计您的应用程序预期将驱动的 IOPS ,以便配置存储选项以满足上述要求。 本系列的第 1 和第 2 部分给出了如何收集指标的示例。
      文章
      Weiwei Gu · 十二月 1, 2022

      InterSystems 几款主要产品的功能对比清单(Cache/Ensemble vs. IRIS For Health / Health Connect )

      InterSystems 是一家已经深耕数据库平台领域达44年的公司,成立于1978年,现在已经在全球的80多个国家开展相关业务,每天有超过10亿患者的电子病历数据都跑在以我们的数据库平台构建的应用系统之上。 我们的客户遍布国内外,国内的大几百家三甲医院客户,中国复旦排行榜上超过1/3的顶级医院都在使用我们产品(包括北京协和医院,华西医院,湘雅等等),我们的技术合作伙伴,如东华医为,嘉和,和仁等也都是国内医疗信息领域的著名厂商。 而在国外,我们也有非常多的顶级客户,仅仅以美国举例,美国最顶级的排名前20的所有医院,无一例外全部都是使用的interSystems公司的数据库平台产品。 美国排名前20的所有顶级医院 2020-2021《美国新闻与世界报道》(U.S. News & World Report)最顶级医院名单(前20家医疗机构)均应用InterSystems公司的数据库平台: Mayo Clinic, Rochester, Minnesota (明尼苏达州罗彻斯特市梅奥诊所)Cleveland Clinic(克利夫兰诊所) Johns Hopkins Hospital, Baltimore(巴尔的摩约翰霍普金斯医院)(tie). New York-Presbyterian Hospital-Columbia and Cornell, New York(纽约长老会医院 ) (tie). UCLA Medical Center, Los Angeles(加州大学洛彬矶分校医学中心)Massachusetts General Hospital, Boston(波士顿麻省总医院 )Cedars-Sinai Medical Center, Los Angeles(洛杉矶Cedars-Sinai医疗中心 )UCSF Medical Center, San Francisco(旧金山加州大学旧金山分校医疗中心 )NYU Langone Hospitals, New York(纽约大学朗格尼医学中心)Northwestern Memorial Hospital, Chicago(芝加哥西北纪念医院)University of Michigan Hospitals-Michigan Medicine, Ann Arbor(安娜堡密歇根大学医学院)Brigham and Women’s Hospital, Boston(波士顿哈佛医学院教学附属医院布列根和妇女医院)Stanford Health Care-Stanford Hospital, Stanford, California(斯坦福医疗中心)Mount Sinai Hospital, New York(纽约西奈山医院)Hospitals of the University of Pennsylvania-Penn Presbyterian, Philadelphia(费城宾夕法尼亚大学-宾夕法尼亚长老会医院)Mayo Clinic-Phoenix(凤凰城梅奥诊所)Rush University Medical Center, Chicago(芝加哥拉什大学医学中心)(tie). Barnes-Jewish Hospital, St. Louis(圣路易斯巴恩斯医院)(tie). Keck Hospital of USC, Los Angeles(洛杉矶南加州大学凯克医院)Houston Methodist Hospital(休斯顿卫理公会医院) InterSystems 公司久负盛名的两款产品: Cache 与 Ensemble , 以其稳定性好,速度快著称,在国内外均有无数医院用户。 自2018年底InterSystems 公司推出其新一代的 IRIS for Health 数据库平台后,基于新产品更高的性能表现及更强大的功能与扩展能力,我们鼓励所有的Cache 及Ensemble 老用户逐渐向最新一代的IRIS 以及Health Connect 平台迁移。以获得更好的性能及用户体验,并且在未来可以支撑更多新的发展需求。 Cache 与 Ensemble 的最新版本也止于2018年,未来我们将继续对使用这两款产品的客户提供支持服务,但不会在其之上开发新的功能。 以下附件中,提供了截止目前这两款产品Cache / Ensemble 与其新的下一代的产品 IRIS for Health / Health Connect 的功能清单对比,可点击参考:
      文章
      姚 鑫 · 一月 22, 2023

      第五十三章 使用 ^SystemPerformance 监视性能 - InterSystems IRIS Linux 平台性能数据报告

      # 第五十三章 使用 ^SystemPerformance 监视性能 - InterSystems IRIS Linux 平台性能数据报告 - `%SS` - 使用 `ALL^%SS` 命令在运行过程中采集了四个样本。 - `Configuration *` - 来自服务器的 `IRIS` 实例名称和主机名、完整的 `IRIS` 版本字符串、许可客户名称和许可订单号。 - `cpf file *` - 当前活动配置文件的副本。 - `irisstat -c` - 使用命令 `irisstat cache -p-1 -c-1 -e1 -m8 -n2 -N127` 在运行过程中以均匀的间隔采集四个样本。以下是对每个参数的简要说明: - `-p-1`: 对进程表进行采样以包括进程和全局状态信息。 - `-c-1`: 对共享内存的计数器部分进行采样以显示日志、锁、磁盘和资源使用统计信息。 - `-e1`: SYSLOG 错误表。 - `-m8`: 文件表,其中包括所有 `IRIS.DAT` 文件及其属性。 - `-n2`: 网络结构表,包括本地到远程数据库的映射。 - `-N127`: 客户端和服务器连接的 `ECP` 统计信息。 - `irisstat -D` - 使用命令 `irisstat cache --f1 -D10,100` 在运行过程中以均匀的间隔采集八个样本。以下是对每个参数的简要说明: - `-fl`: 基本标志。 - `-D10,100`: 在 `10` 秒的总采样周期内,每 `100` 毫秒对块碰撞进行采样。 - `df -m *` - 有关挂载文件系统的信息,包括挂载点、逻辑卷和可用空间; `df -m` 命令的输出。 - `free -m` - 以 `MB` (`-m`) 为单位的内存使用统计信息。 - `iostat` - `CPU` 和磁盘吞吐量。 - `license *` - 使用 `Decode^%LICENSE` 和 `counts^%LICENSE` 的 `IRIS` 许可使用信息。 - `mgstat` - 使用 `^mgstat` 实用程序在运行过程中获取 `IRIS` 特定数据。请参阅 `Monitoring Guide `的 `Monitoring Performance Using ^mgstat` 部分。 - `Profile *` - 有关创建此日志的 `^SystemPerformance` 配置文件的信息。 - `ps:` - 使用命令 `ps -efly` 在运行过程中以均匀的间隔采集四个样本。 - `sar -d` - 磁盘(块)设备吞吐量和延迟统计信息。 - `sar -u` - CPU 使用率统计信息包括 `iowait` 百分比。 - `vmstat -n - CPU`、排队、分页统计。只打印一个标题 (`-n`) 。 - `CPU *` - 从 `lscpu` 和 `/proc/cpuinfo` 收集的信息 - `Linux info *` - 一般操作系统和硬件信息;包括 `uname -a`、`lsb_release -a`、`id` 和 `ulimit -a` 命令的输出以及从 `/etc/issue.net`、`/proc/partitions` 和 `/dev/mapper` 收集的信息。 - `ipcs *` - 进程间通信配置信息,包括共享内存、信号量和消息队列; `ipcs -a` 命令的输出。 - `mount *` - 有关所有文件系统及其挂载选项的信息。 - `fdisk -l *` - `/proc/partitions` 中提到的所有设备的分区表。仅当启动 `^SystemPerformance` 配置文件运行的用户具有 `root` 访问权限时才包括在内。 - `ifconfig *` - 当前活动网络接口的状态信息。 - `sysctl -a *` - 内核和系统参数设置。
      文章
      姚 鑫 · 二月 2, 2023

      第六十四章 使用 SNMP 监控 IRIS - 扩展 InterSystems IRIS MIB

      # 第六十四章 使用 SNMP 监控 IRIS - 扩展 IRIS MIB 应用程序员可以添加托管对象定义并扩展 `IRIS` 子代理为其提供数据的 `MIB`。这不是一个完整的 `MIB` 编辑器或` SNMP` 工具包;相反,它是一种添加简单应用程序指标的方法,可以通过 `SNMP` 浏览或查询这些指标。 注意:对象必须遵循基本的 `IRIS SNMP` 结构,对 `SNMP` 表结构的支持有限(仅支持整数值索引),并且不会创建 `SNMP` 陷阱(请参阅新选项卡类中的 `%Monitor.AlertOpens`) 对管理信息的 `SNMP` 结构有一个基本的了解是很有帮助的。 要创建这些对象,请执行以下操作: 1. 在继承 `%Monitor.Adaptor` 的类中创建 `IRIS` 对象定义。 2. 执行 `SNMP` 类方法以在 `SNMP` 中启用这些被管理对象,并创建 `MIB` 定义文件供管理应用程序使用。实现此目的的方法是 `MonitorTools.SNMP.CreateMIB()`。 该方法为 `%Monitor` 数据库中定义的特定应用程序创建私有企业 `MIB` 树的一个分支。除了为应用程序创建实际的 `MIB` 文件之外,该方法还创建了 `MIB` 树的内部轮廓。 `IRIS` 子代理使用它来注册 `MIB` 子树,为 `GETNEXT` 请求遍历树,并引用特定对象方法以在 `GET` 请求中收集实例数据。 所有托管对象定义都使用与 `IRIS` 企业 `MIB` 树相同的通用组织,即:`application.objects.table.row.item.indices`。所有表格的第一个索引是 `IRIS` 应用程序 `ID`。所有应用程序都必须向 IANA 注册以获得自己的私有企业编号,这是 `CreateMIB()` 方法中的参数之一。 要禁用 `SNMP` 中的应用程序,请使用 `MonitorTools.SNMP.DeleteMIB()` 方法。这会删除应用程序 `MIB` 的内部轮廓,因此 `IRIS` 子代理不再注册或回答对该私有企业 MIB 子树的请求。 # `IRIS SNMP` 陷阱 除了通过 `SNMP` 查询提供的对象数据和指标外, `IRIS` 还可以发送异步警报或 `SNMP` 陷阱。下表描述了 `IRIS` 特定的 `SNMP` 陷阱。 ### IRIS SNMP 通知对象(陷阱) Trap Name (Number)| Description ---|--- irisStart (1) | IRIS 实例已启动。 irisStop (2)| IRIS 实例正在关闭。 irisDBExpand (3)| IRIS 数据库已成功扩展。 irisDBOutOfSpace (4)| IRIS 数据库的未来扩展可能会受到限制;文件系统上的可用空间不足,无法再扩展 10 次,或者可用空间不足 `50 MB`。 irisDBStatusChange (5)| IRIS 数据库的读/写状态已更改。 irisDBWriteFail (6) |写入 IRIS 数据库失败。它包括写入失败的 IRIS 错误代码。 irisWDStop (7)| IRIS 实例的写入守护进程已停止。 irisWDPanic (8) | IRIS 实例的写入守护进程已进入“恐慌panic”模式;也就是说,写入守护进程缓冲区不足,必须将数据库块直接写入磁盘,而无需先将它们提交到写入映像日志 (WIJ) 文件。 irisLockTableFull (9)| IRIS 实例的锁表已满,导致后续 `Locks` 失败。 irisProcessFail (10)|进程异常退出 IRIS(由于访问冲突)。 irisECPTroubleDSrv (11)| IRIS 数据库与此 `ECP` 数据服务器的连接遇到了严重的通信问题。 irisECPTroubleASrv (12)|从该 `ECP` 应用程序服务器到远程 IRIS 数据库的连接遇到了严重的通信问题。 irisAuditLost (13)| IRIS 未能记录审核事件。最可能的原因是审计数据库的空间有问题,这需要操作员的帮助。 irisLoggedError (14)|`messages.log` 文件中记录了一个“严重”错误。此陷阱包括在 `irisSysErrorMsg` 中定义的错误消息。 irisLicenseExceed (15)| 许可证请求已超出当前可用或允许的许可证数量。 irisEventLogPost (16)| 互操作性事件日志中发布的条目。 irisAppAlert (100)| 这是一个通用陷阱, IRIS 应用程序可以使用它通过 SNMP 生成警报。有关如何使用此陷阱的详细信息,请参阅 `%Monitor.Alert.External` 类方法。 下表描述了可以在上表中描述的陷阱中发送的 IRIS 特定辅助对象。 Auxiliary Object Name (Number) |Description ---|--- irisDBWriteError (1)| 数据库写入失败的 IRIS 特定错误代码。可能的值为:``、``、``、` `或 ``。 irisApp (2) |一个短文本字符串(最多 `20` 个字符),用于标识生成(或来源)`irisAppAlert` 陷阱的应用程序。 irisAppSeverity (3)|指示 `irisAppAlert` 陷阱问题严重性的代码。代码可以是 `0`(信息)、`1`(警告)、`2`(严重)或 `3`(严重)。 irisApptext (4) |导致 `irisAppAlert` 陷阱的问题、错误或事件的文本字符串描述(最多 `1024` 个字符)。
      文章
      Michael Lei · 六月 8, 2023

      使用 InterSystems 互操作性在TeleGram中使用 Open AI ChatGPT 进行自己的聊天

      嗨社区! 想与您分享我在Telegram中使用GPT创建“我自己的”聊天的练习。 这个应用需要用到 Open Exchange 上的两个组件:@Nikolay.Soloviev 的Telegram Adapter和@Francisco.López1549的IRIS Open-AI 因此,通过此示例,您可以在 Telegram 中使用 ChatGPT 设置自己的聊天。 让我们看看如何让它发挥作用! 前提条件 使用@BotFather 帐户创建一个机器人并获取机器人令牌。然后将机器人添加到电报聊天或频道中并赋予其管理员权限。在https://core.telegram.org/bots/api了解更多信息 在https://platform.openai.com/上打开(如果没有,请创建)一个帐户,并获取您的Open AI API Key和Organization id 。 确保您的 InterSystems IRIS 中安装了 IPM。如果没有,这里有一个要安装的衬垫: USER> s r = ##class ( %Net.HttpRequest ). %New (), r .Server= "pm.community.intersystems.com" , r .SSLConfiguration= "ISC.FeatureTracker.SSL.Config" d r .Get( "/packages/zpm/latest/installer" ), $system .OBJ.LoadStream( r .HttpResponse.Data, "c" ) 或者您可以像这样使用带有 IPM 的社区 docker 图像: 安装 在启用互操作性的命名空间中安装 IPM 包。 USER>zpm“安装 Telegram-gpt” 用法 打开Production 将机器人的 Telegram Token 放入 Telegram business service 和 Telegram Business operation 中: 同时使用您的聊天 GPT API 密钥和组织 ID 初始化 St.OpenAi.BO.Api.Connect 操作: 启动Production。 在Telegram聊天中提出任何问题。您将通过 Chat GPT 获得答案。尽情享受吧! 在可视化追中: 细节 本示例使用 3.5 版本的 Chat GPT Open AI。它可以在模型参数的数据转换规则中更改。
      文章
      Jingwei Wang · 十月 28, 2021

      IRIS 2021 技术文档 First Look 26 InterSystems API 管理器

      html {overflow-x: initial !important;}:root { --bg-color: #ffffff; --text-color: #333333; --select-text-bg-color: #B5D6FC; --select-text-font-color: auto; --monospace: "Lucida Console",Consolas,"Courier",monospace; --title-bar-height: 20px; } .mac-os-11 { --title-bar-height: 28px; } html { font-size: 14px; background-color: var(--bg-color); color: var(--text-color); font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; } body { margin: 0px; padding: 0px; height: auto; inset: 0px; font-size: 1rem; line-height: 1.42857143; overflow-x: hidden; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; tab-size: 4; background-position: inherit; background-repeat: inherit; } iframe { margin: auto; } a.url { word-break: break-all; } a:active, a:hover { outline: 0px; } .in-text-selection, ::selection { text-shadow: none; background: var(--select-text-bg-color); color: var(--select-text-font-color); } #write { margin: 0px auto; height: auto; width: inherit; word-break: normal; word-wrap: break-word; position: relative; white-space: normal; overflow-x: visible; padding-top: 36px; } #write.first-line-indent p { text-indent: 2em; } #write.first-line-indent li p, #write.first-line-indent p * { text-indent: 0px; } #write.first-line-indent li { margin-left: 2em; } .for-image #write { padding-left: 8px; padding-right: 8px; } body.typora-export { padding-left: 30px; padding-right: 30px; } .typora-export .footnote-line, .typora-export li, .typora-export p { white-space: pre-wrap; } .typora-export .task-list-item input { pointer-events: none; } @media screen and (max-width: 500px) { body.typora-export { padding-left: 0px; padding-right: 0px; } #write { padding-left: 20px; padding-right: 20px; } .CodeMirror-sizer { margin-left: 0px !important; } .CodeMirror-gutters { display: none !important; } } #write li > figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max-width: 100%; vertical-align: middle; image-orientation: from-image; } button, input, select, textarea { color: inherit; font-family: inherit; font-size: inherit; font-style: inherit; font-variant-caps: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; } input[type="checkbox"], input[type="radio"] { line-height: normal; padding: 0px; } *, ::after, ::before { box-sizing: border-box; } #write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p, #write pre { width: inherit; } #write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p { position: relative; } p { line-height: inherit; } h1, h2, h3, h4, h5, h6 { break-after: avoid-page; break-inside: avoid; orphans: 4; } p { orphans: 4; } h1 { font-size: 2rem; } h2 { font-size: 1.8rem; } h3 { font-size: 1.6rem; } h4 { font-size: 1.4rem; } h5 { font-size: 1.2rem; } h6 { font-size: 1rem; } .md-math-block, .md-rawblock, h1, h2, h3, h4, h5, h6, p { margin-top: 1rem; margin-bottom: 1rem; } .hidden { display: none; } .md-blockmeta { color: rgb(204, 204, 204); font-weight: 700; font-style: italic; } a { cursor: pointer; } sup.md-footnote { padding: 2px 4px; background-color: rgba(238, 238, 238, 0.7); color: rgb(85, 85, 85); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; cursor: pointer; } sup.md-footnote a, sup.md-footnote a:hover { color: inherit; text-transform: inherit; text-decoration: inherit; } #write input[type="checkbox"] { cursor: pointer; width: inherit; height: inherit; } figure { overflow-x: auto; margin: 1.2em 0px; max-width: calc(100% + 16px); padding: 0px; } figure > table { margin: 0px; } tr { break-inside: avoid; break-after: auto; } thead { display: table-header-group; } table { border-collapse: collapse; border-spacing: 0px; width: 100%; overflow: auto; break-inside: auto; text-align: left; } table.md-table td { min-width: 32px; } .CodeMirror-gutters { border-right-width: 0px; background-color: inherit; } .CodeMirror-linenumber { } .CodeMirror { text-align: left; } .CodeMirror-placeholder { opacity: 0.3; } .CodeMirror pre { padding: 0px 4px; } .CodeMirror-lines { padding: 0px; } div.hr:focus { cursor: none; } #write pre { white-space: pre-wrap; } #write.fences-no-line-wrapping pre { white-space: pre; } #write pre.ty-contain-cm { white-space: normal; } .CodeMirror-gutters { margin-right: 4px; } .md-fences { font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; overflow: visible; white-space: pre; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; position: relative !important; background-position: inherit; background-repeat: inherit; } .md-fences-adv-panel { width: 100%; margin-top: 10px; text-align: center; padding-top: 0px; padding-bottom: 8px; overflow-x: auto; } #write .md-fences.mock-cm { white-space: pre-wrap; } .md-fences.md-fences-with-lineno { padding-left: 0px; } #write.fences-no-line-wrapping .md-fences.mock-cm { white-space: pre; overflow-x: auto; } .md-fences.mock-cm.md-fences-with-lineno { padding-left: 8px; } .CodeMirror-line, twitterwidget { break-inside: avoid; } .footnotes { opacity: 0.8; font-size: 0.9rem; margin-top: 1em; margin-bottom: 1em; } .footnotes + .footnotes { margin-top: 0px; } .md-reset { margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: top; text-decoration: none; text-shadow: none; float: none; position: static; width: auto; height: auto; white-space: nowrap; cursor: inherit; line-height: normal; font-weight: 400; text-align: left; box-sizing: content-box; direction: ltr; background-position: 0px 0px; } li div { padding-top: 0px; } blockquote { margin: 1rem 0px; } li .mathjax-block, li p { margin: 0.5rem 0px; } li blockquote { margin: 1rem 0px; } li { margin: 0px; position: relative; } blockquote > :last-child { margin-bottom: 0px; } blockquote > :first-child, li > :first-child { margin-top: 0px; } .footnotes-area { color: rgb(136, 136, 136); margin-top: 0.714rem; padding-bottom: 0.143rem; white-space: normal; } #write .footnote-line { white-space: pre-wrap; } @media print { body, html { border: 1px solid transparent; height: 99%; break-after: avoid; break-before: avoid; font-variant-ligatures: no-common-ligatures; } #write { margin-top: 0px; padding-top: 0px; border-color: transparent !important; } .typora-export * { -webkit-print-color-adjust: exact; } .typora-export #write { break-after: avoid; } .typora-export #write::after { height: 0px; } .is-mac table { break-inside: avoid; } .typora-export-show-outline .typora-export-sidebar { display: none; } } .footnote-line { margin-top: 0.714em; font-size: 0.7em; } a img, img a { cursor: pointer; } pre.md-meta-block { font-size: 0.8rem; min-height: 0.8rem; white-space: pre-wrap; background-color: rgb(204, 204, 204); display: block; overflow-x: hidden; } p > .md-image:only-child:not(.md-img-error) img, p > img:only-child { display: block; margin: auto; } #write.first-line-indent p > .md-image:only-child:not(.md-img-error) img { left: -2em; position: relative; } p > .md-image:only-child { display: inline-block; width: 100%; } #write .MathJax_Display { margin: 0.8em 0px 0px; } .md-math-block { width: 100%; } .md-math-block:not(:empty)::after { display: none; } .MathJax_ref { fill: currentcolor; } [contenteditable="true"]:active, [contenteditable="true"]:focus, [contenteditable="false"]:active, [contenteditable="false"]:focus { outline: 0px; box-shadow: none; } .md-task-list-item { position: relative; list-style-type: none; } .task-list-item.md-task-list-item { padding-left: 0px; } .md-task-list-item > input { position: absolute; top: 0px; left: 0px; margin-left: -1.2em; margin-top: calc(1em - 10px); border: none; } .math { font-size: 1rem; } .md-toc { min-height: 3.58rem; position: relative; font-size: 0.9rem; border-top-left-radius: 10px; border-top-right-radius: 10px; border-bottom-right-radius: 10px; border-bottom-left-radius: 10px; } .md-toc-content { position: relative; margin-left: 0px; } .md-toc-content::after, .md-toc::after { display: none; } .md-toc-item { display: block; color: rgb(65, 131, 196); } .md-toc-item a { text-decoration: none; } .md-toc-inner:hover { text-decoration: underline; } .md-toc-inner { display: inline-block; cursor: pointer; } .md-toc-h1 .md-toc-inner { margin-left: 0px; font-weight: 700; } .md-toc-h2 .md-toc-inner { margin-left: 2em; } .md-toc-h3 .md-toc-inner { margin-left: 4em; } .md-toc-h4 .md-toc-inner { margin-left: 6em; } .md-toc-h5 .md-toc-inner { margin-left: 8em; } .md-toc-h6 .md-toc-inner { margin-left: 10em; } @media screen and (max-width: 48em) { .md-toc-h3 .md-toc-inner { margin-left: 3.5em; } .md-toc-h4 .md-toc-inner { margin-left: 5em; } .md-toc-h5 .md-toc-inner { margin-left: 6.5em; } .md-toc-h6 .md-toc-inner { margin-left: 8em; } } a.md-toc-inner { font-size: inherit; font-style: inherit; font-weight: inherit; line-height: inherit; } .footnote-line a:not(.reversefootnote) { color: inherit; } .md-attr { display: none; } .md-fn-count::after { content: "."; } code, pre, samp, tt { font-family: var(--monospace); } kbd { margin: 0px 0.1em; padding: 0.1em 0.6em; font-size: 0.8em; color: rgb(36, 39, 41); background-color: rgb(255, 255, 255); border: 1px solid rgb(173, 179, 185); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; box-shadow: rgba(12, 13, 14, 0.2) 0px 1px 0px, rgb(255, 255, 255) 0px 0px 0px 2px inset; white-space: nowrap; vertical-align: middle; } .md-comment { color: rgb(162, 127, 3); opacity: 0.8; font-family: var(--monospace); } code { text-align: left; } a.md-print-anchor { white-space: pre !important; border: none !important; display: inline-block !important; position: absolute !important; width: 1px !important; right: 0px !important; outline: 0px !important; text-shadow: initial !important; background-position: 0px 0px !important; } .md-inline-math .MathJax_SVG .noError { display: none !important; } .html-for-mac .inline-math-svg .MathJax_SVG { vertical-align: 0.2px; } .md-fences-math .MathJax_SVG_Display, .md-math-block .MathJax_SVG_Display { text-align: center; margin: 0px; position: relative; text-indent: 0px; max-width: none; max-height: none; min-height: 0px; min-width: 100%; width: auto; overflow-y: visible; display: block !important; } .MathJax_SVG_Display, .md-inline-math .MathJax_SVG_Display { width: auto; margin: inherit; display: inline-block !important; } .MathJax_SVG .MJX-monospace { font-family: var(--monospace); } .MathJax_SVG .MJX-sans-serif { font-family: sans-serif; } .MathJax_SVG { display: inline; font-style: normal; font-weight: 400; line-height: normal; text-indent: 0px; text-align: left; text-transform: none; letter-spacing: normal; word-spacing: normal; word-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border: 0px; padding: 0px; margin: 0px; zoom: 90%; } #math-inline-preview-content { zoom: 1.1; } .MathJax_SVG * { transition: none; } .MathJax_SVG_Display svg { vertical-align: middle !important; margin-bottom: 0px !important; margin-top: 0px !important; } .os-windows.monocolor-emoji .md-emoji { font-family: "Segoe UI Symbol", sans-serif; } .md-diagram-panel > svg { max-width: 100%; } [lang="flow"] svg, [lang="mermaid"] svg { max-width: 100%; height: auto; } [lang="mermaid"] .node text { font-size: 1rem; } table tr th { border-bottom-width: 0px; } video { max-width: 100%; display: block; margin: 0px auto; } iframe { max-width: 100%; width: 100%; border: none; } .highlight td, .highlight tr { border: 0px; } mark { background-color: rgb(255, 255, 0); color: rgb(0, 0, 0); } .md-html-inline .md-plain, .md-html-inline strong, mark .md-inline-math, mark strong { color: inherit; } .md-expand mark .md-meta { opacity: 0.3 !important; } mark .md-meta { color: rgb(0, 0, 0); } @media print { .typora-export h1, .typora-export h2, .typora-export h3, .typora-export h4, .typora-export h5, .typora-export h6 { break-inside: avoid; } } .md-diagram-panel .messageText { stroke: none !important; } .md-diagram-panel .start-state { fill: var(--node-fill); } .md-diagram-panel .edgeLabel rect { opacity: 1 !important; } .md-require-zoom-fix foreignObject { font-size: var(--mermaid-font-zoom); } .md-fences.md-fences-math { font-size: 1em; } .md-fences-math .MathJax_SVG_Display { margin-top: 8px; cursor: default; } .md-fences-advanced:not(.md-focus) { padding: 0px; white-space: nowrap; border: 0px; } .md-fences-advanced:not(.md-focus) { background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit; background-repeat: inherit; } .typora-export-show-outline .typora-export-content { max-width: 1440px; margin: auto; display: flex; flex-direction: row; } .typora-export-sidebar { width: 300px; font-size: 0.8rem; margin-top: 80px; margin-right: 18px; } .typora-export-show-outline #write { --webkit-flex: 2; flex: 2 1 0%; } .typora-export-sidebar .outline-content { position: fixed; top: 0px; max-height: 100%; overflow: hidden auto; padding-bottom: 30px; padding-top: 60px; width: 300px; } @media screen and (max-width: 1024px) { .typora-export-sidebar, .typora-export-sidebar .outline-content { width: 240px; } } @media screen and (max-width: 800px) { .typora-export-sidebar { display: none; } } .outline-content li, .outline-content ul { margin-left: 0px; margin-right: 0px; padding-left: 0px; padding-right: 0px; list-style: none; } .outline-content ul { margin-top: 0px; margin-bottom: 0px; } .outline-content strong { font-weight: 400; } .outline-expander { width: 1rem; height: 1.428571429rem; position: relative; display: table-cell; vertical-align: middle; cursor: pointer; padding-left: 4px; } .outline-expander::before { content: ''; position: relative; font-family: Ionicons; display: inline-block; font-size: 8px; vertical-align: middle; } .outline-item { padding-top: 3px; padding-bottom: 3px; cursor: pointer; } .outline-expander:hover::before { content: ''; } .outline-h1 > .outline-item { padding-left: 0px; } .outline-h2 > .outline-item { padding-left: 1em; } .outline-h3 > .outline-item { padding-left: 2em; } .outline-h4 > .outline-item { padding-left: 3em; } .outline-h5 > .outline-item { padding-left: 4em; } .outline-h6 > .outline-item { padding-left: 5em; } .outline-label { cursor: pointer; display: table-cell; vertical-align: middle; text-decoration: none; color: inherit; } .outline-label:hover { text-decoration: underline; } .outline-item:hover { border-color: rgb(245, 245, 245); background-color: var(--item-hover-bg-color); } .outline-item:hover { margin-left: -28px; margin-right: -28px; border-left-width: 28px; border-left-style: solid; border-left-color: transparent; border-right-width: 28px; border-right-style: solid; border-right-color: transparent; } .outline-item-single .outline-expander::before, .outline-item-single .outline-expander:hover::before { display: none; } .outline-item-open > .outline-item > .outline-expander::before { content: ''; } .outline-children { display: none; } .info-panel-tab-wrapper { display: none; } .outline-item-open > .outline-children { display: block; } .typora-export .outline-item { padding-top: 1px; padding-bottom: 1px; } .typora-export .outline-item:hover { margin-right: -8px; border-right-width: 8px; border-right-style: solid; border-right-color: transparent; } .typora-export .outline-expander::before { content: "+"; font-family: inherit; top: -1px; } .typora-export .outline-expander:hover::before, .typora-export .outline-item-open > .outline-item > .outline-expander::before { content: '−'; } .typora-export-collapse-outline .outline-children { display: none; } .typora-export-collapse-outline .outline-item-open > .outline-children, .typora-export-no-collapse-outline .outline-children { display: block; } .typora-export-no-collapse-outline .outline-expander::before { content: "" !important; } .typora-export-show-outline .outline-item-active > .outline-item .outline-label { font-weight: 700; } :root { --side-bar-bg-color: #fafafa; --control-text-color: #777; } @include-when-export url(https://fonts.loli.net/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext); /* open-sans-regular - latin-ext_latin */ /* open-sans-italic - latin-ext_latin */ /* open-sans-700 - latin-ext_latin */ /* open-sans-700italic - latin-ext_latin */ html { font-size: 16px; } body { font-family: "Open Sans","Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; color: rgb(51, 51, 51); line-height: 1.6; } #write { max-width: 860px; margin: 0 auto; padding: 30px; padding-bottom: 100px; } @media only screen and (min-width: 1400px) { #write { max-width: 1024px; } } @media only screen and (min-width: 1800px) { #write { max-width: 1200px; } } #write > ul:first-child, #write > ol:first-child{ margin-top: 30px; } a { color: #4183C4; } h1, h2, h3, h4, h5, h6 { position: relative; margin-top: 1rem; margin-bottom: 1rem; font-weight: bold; line-height: 1.4; cursor: text; } h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor { text-decoration: none; } h1 tt, h1 code { font-size: inherit; } h2 tt, h2 code { font-size: inherit; } h3 tt, h3 code { font-size: inherit; } h4 tt, h4 code { font-size: inherit; } h5 tt, h5 code { font-size: inherit; } h6 tt, h6 code { font-size: inherit; } h1 { font-size: 2.25em; line-height: 1.2; border-bottom: 1px solid #eee; } h2 { font-size: 1.75em; line-height: 1.225; border-bottom: 1px solid #eee; } /*@media print { .typora-export h1, .typora-export h2 { border-bottom: none; padding-bottom: initial; } .typora-export h1::after, .typora-export h2::after { content: ""; display: block; height: 100px; margin-top: -96px; border-top: 1px solid #eee; } }*/ h3 { font-size: 1.5em; line-height: 1.43; } h4 { font-size: 1.25em; } h5 { font-size: 1em; } h6 { font-size: 1em; color: #777; } p, blockquote, ul, ol, dl, table{ margin: 0.8em 0; } li>ol, li>ul { margin: 0 0; } hr { height: 2px; padding: 0; margin: 16px 0; background-color: #e7e7e7; border: 0 none; overflow: hidden; box-sizing: content-box; } li p.first { display: inline-block; } ul, ol { padding-left: 30px; } ul:first-child, ol:first-child { margin-top: 0; } ul:last-child, ol:last-child { margin-bottom: 0; } blockquote { border-left: 4px solid #dfe2e5; padding: 0 15px; color: #777777; } blockquote blockquote { padding-right: 0; } table { padding: 0; word-break: initial; } table tr { border: 1px solid #dfe2e5; margin: 0; padding: 0; } table tr:nth-child(2n), thead { background-color: #f8f8f8; } table th { font-weight: bold; border: 1px solid #dfe2e5; border-bottom: 0; margin: 0; padding: 6px 13px; } table td { border: 1px solid #dfe2e5; margin: 0; padding: 6px 13px; } table th:first-child, table td:first-child { margin-top: 0; } table th:last-child, table td:last-child { margin-bottom: 0; } .CodeMirror-lines { padding-left: 4px; } .code-tooltip { box-shadow: 0 1px 1px 0 rgba(0,28,36,.3); border-top: 1px solid #eef2f2; } .md-fences, code, tt { border: 1px solid #e7eaed; background-color: #f8f8f8; border-radius: 3px; padding: 0; padding: 2px 4px 0px 4px; font-size: 0.9em; } code { background-color: #f3f4f4; padding: 0 2px 0 2px; } .md-fences { margin-bottom: 15px; margin-top: 15px; padding-top: 8px; padding-bottom: 6px; } .md-task-list-item > input { margin-left: -1.3em; } @media print { html { font-size: 13px; } table, pre { page-break-inside: avoid; } pre { word-wrap: break-word; } } .md-fences { background-color: #f8f8f8; } #write pre.md-meta-block { padding: 1rem; font-size: 85%; line-height: 1.45; background-color: #f7f7f7; border: 0; border-radius: 3px; color: #777777; margin-top: 0 !important; } .mathjax-block>.code-tooltip { bottom: .375rem; } .md-mathjax-midline { background: #fafafa; } #write>h3.md-focus:before{ left: -1.5625rem; top: .375rem; } #write>h4.md-focus:before{ left: -1.5625rem; top: .285714286rem; } #write>h5.md-focus:before{ left: -1.5625rem; top: .285714286rem; } #write>h6.md-focus:before{ left: -1.5625rem; top: .285714286rem; } .md-image>.md-meta { /*border: 1px solid #ddd;*/ border-radius: 3px; padding: 2px 0px 0px 4px; font-size: 0.9em; color: inherit; } .md-tag { color: #a7a7a7; opacity: 1; } .md-toc { margin-top:20px; padding-bottom:20px; } .sidebar-tabs { border-bottom: none; } #typora-quick-open { border: 1px solid #ddd; background-color: #f8f8f8; } #typora-quick-open-item { background-color: #FAFAFA; border-color: #FEFEFE #e5e5e5 #e5e5e5 #eee; border-style: solid; border-width: 1px; } /** focus mode */ .on-focus-mode blockquote { border-left-color: rgba(85, 85, 85, 0.12); } header, .context-menu, .megamenu-content, footer{ font-family: "Segoe UI", "Arial", sans-serif; } .file-node-content:hover .file-node-icon, .file-node-content:hover .file-node-open-state{ visibility: visible; } .mac-seamless-mode #typora-sidebar { background-color: #fafafa; background-color: var(--side-bar-bg-color); } .md-lang { color: #b4654d; } /*.html-for-mac { --item-hover-bg-color: #E6F0FE; }*/ #md-notification .btn { border: 0; } .dropdown-menu .divider { border-color: #e5e5e5; opacity: 0.4; } .ty-preferences .window-content { background-color: #fafafa; } .ty-preferences .nav-group-item.active { color: white; background: #999; } .menu-item-container a.menu-style-btn { background-color: #f5f8fa; background-image: linear-gradient( 180deg , hsla(0, 0%, 100%, 0.8), hsla(0, 0%, 100%, 0)); } :root {--mermaid-font-zoom:1em ;} @media print { @page {margin: 0 0 0 0;} body.typora-export {padding-left: 0; padding-right: 0;} #write {padding:0;}} 目录 技术概要:InterSystems API 管理器InterSystems API管理器是如何工作的?试一试!在 InterSystems IRIS 中设置 REST API 在 IAM 中为您的 REST API 创建服务在 IAM 中创建路由 从 REST 客户端调用您的 API添加速率限制插件添加您的 REST 规范到 IAM了解有关 InterSystems API Manager 的更多信息 技术概要:InterSystems API 管理器 本文档将向您介绍InterSystems API管理器(InterSystems API Manager ,IAM),解释了它的工作原理,并让您开始在自己的实例上探索它的功能。 InterSystems API管理器是如何工作的? InterSystems API管理器是 InterSystems IRIS®数据平台的一个组件,它允许您利用由 InterSystems IRIS 应用程序暴露或消费的微服务和 API。作为 InterSystems IRIS的 服务器和应用程序之间的 API 网关(gateway),API 管理器使您能够更有效地监视和控制服务器端 API 和客户端应用程序之间的调用流量。 要了解有关 InterSystems API管理器的更多信息,您可以观看这个概述视频。 试一试! InterSystems API管理器(InterSystems API Manager ,IAM)是与 InterSystems IRIS 实例分开安装的。要获得自己的 IAM 安装包,您可以从 InterSystems WRC 软件分发(Software Distribution)网站下载 ,或者联系您的 InterSystems 销售工程师。安装包包括一个脚本(iam-setup),用于设置 IAM 并将它与您的 InterSystems IRIS 实例连接。 这个练习假定您有 InterSystems IRIS 和 IAM 的实例,并且已经运行了安装脚本来连接它们。本练习使用 IAM 2.3 版本进行展示。 在 InterSystems IRIS 中设置 REST API 从位于 https://github.com/intersystems/FirstLook-IAM 的 GitHub 存储库中,将以下内容导入 InterSystems IRIS: /cls/cmAPI 包括使用 API 管理服务生成的三个类文件,以及一个coffeemaker对象定义: impl.cls disp.cls spec.cls coffeemaker.cls 要导入,请打开 InterSystems IRIS 管理门户(Management Portal),并导航到 Classes 页面(System Explorer(系统资源管理器) > Classes(类));如果您不在 USER 命名空间中,请使用左边的选择器来更改为它,如下图所示: 选择上面列出的四个类并点击 Import(导入)。这将 REST API 导入 InterSystems IRIS,同时导入相应的类,应用程序将使用这些类访问存储在数据库中的coffermakers集合。 /gbl/coffeemakers.gof。 通过进入管理门户(Management Portal),并点击 System Explorer(系统资源管理器)> Globals > Import(导入)来导入。查找 coffeemakers.gof。导入到 User.cmAPI.coffeemaker 模式。 接下来,设置一个 Web 应用程序(Web Application),指向您刚刚导入的 REST 类。Web 应用程序层为自定义和安全提供了额外的机会。在管理门户(Management Portal)中,选择 System Administration(系统管理) > Security(安全) > Applications(应用程序)> Web Applications(Web 应用程序)。点击 Create New Web Application(新建Web 应用程序) 并填写以下设置: Name(名称): /rest/coffeemakerapp Namespace(命名空间): USER Enable Application(启用应用程序):选中此复选框 Enable(启用):选择 REST Dispatch Class(分派类): cmAPI.disp 安全设置 - Allowed Authentication Methods(允许的身份认证方法): Unauthenticated ,Password 在 IAM 中为您的 REST API 创建服务 正如您在 IAM 概述视频中所看到的,在 IAM 工作流中,有三个主要组件在发挥作用------消费者(Consumers)、路由(Route)和服务(Service)。IAM 中的服务是为您存在于 InterSystems IRIS 中的 API 创建的。在这种情况下,我们将为您的coffeemaker API 创建一个服务。 您从 WRC 下载的 IAM 包还包括一个脚本(iam-test),用于设置示例服务和路由。如果您运行了这个脚本,您将能够查看 test-iris 服务。 我们将取得类似的结果,使用 IAM 门户添加您的Coffeemakers服务。 iam-setup.sh是用来启动 IAM 的,可以通过输入iam-setup.sh 脚本中指定的门户的 URL 来启动 IAM 管理门户(management portal)。默认情况下,URL 是: http://localhost:8002 选择 default Workspace(默认工作区)。如果默认工作区不可见,而且管理门户(Management Portal)似乎是空的,那么可能是您没有输入 iam-setup.sh 定义的确切 URL。 选择 API Gateway(API 网关) 中的 Services(服务),并选择 New Service(新的服务)。请按以下方式填写表格: Name(名称): 咖啡机服务(CoffeemakerService) 选择 Add using Protocol, Host and Path(添加使用协议、主机和路径) Protocol(协议): http Host(主机):[插入您的 InterSystems IRIS 实例的 IP 地址。为避免 DNS 问题,使用 IP 地址的数字形式。] Path(路径): /rest/coffeemakerapp Port(端口): [插入您的实例的 webserver 端口,默认为 52773,或者如果实例是在容器中,您已经映射到 web 服务器(webserver) 端口的主机端口] 不要选择"查看 6 个高级字段(View 6 Advanced Fields)"。 选择 Create(创建)。 一旦创建了服务,您就可以查看服务,并需要创建路由。 在 IAM 中创建路由 当您在查看服务时,选择 "添加路由(Add a Route)"。请按以下方式填写表格: Sevice(服务):此字段已正确地用服务的十六进制的 ID 初始化。 Name(名称): 可以留空 Protocols(协议):http Hosts(主机): 可以留空 Methods(方法):GET、POST、PUT、DELETE Paths(路径):select(选择) "+添加路径(Add Path)"并输入 /rest/coffeemakerapp Headers(标题): 可以留空 HTTPS Redirect Status Code(HTTPS 重定向状态代码): 426(这是默认值) Tags(标签): 可以留空 不要选择 "查看 4 个高级字段(View 4 Advanced Fields)"。 选择 Create(创建)。 一旦创建了路由,您将通过从 REST 客户端进行简单的 API 调用来测试您的路由和服务。 从 REST 客户端调用您的 API 使用 REST 客户端------可以使用Postman 或来自 Google Chrome 的高级 REST 客户端(Advanced REST Client)------在 InterSystems IRIS 中对您的咖啡机(Coffeemakers) API 进行一个简单的 API 调用。要做到这一点,创建一个请求 URL,其中包括您的 IAM 实例的 IP 地址和端口号,以及您的服务的路径和请求的端点。请务必使用用户名和密码授权您的请求。下面是一个示例;注意,默认情况下,IAM 处理 8000 端口上的代理请求。例如: POST http://localhost:8000/rest/coffeemakerapp/coffeemakers 一旦您成功地进行了调用,您可以导航回您的 IAM 仪表板(Dashboard),查看来自所进行的调用的统计数据和其他信息。从这个仪表板上,您可以看到许多不同的信息集,这些信息将帮助您监控和控制客户端应用程序和 InterSystems IRIS 内的服务之间的流量。 添加速率限制插件 有效地监测您的 API 流量是有益的,但仅限于使用该信息适当地控制和优化流量。IAM 使您能够使用一些不同的插件来提高您控制客户端和 API 之间流量的能力。 在 IAM 管理门户(Management Portal)中,选择 API Gateway(API 网关) 中的 Plugins(插件) ,并选择 New Plugin(新的插件)。在 Traffic Control(流量控制) 类别中,找到 Rate Limiting(速率限制) 插件,并选择 Enable(启用)。 在这个插件的配置屏幕上: 选择 Scoped(范围)。 在 Service(服务) 中选择咖啡机服务(CoffeeMakerService)。 试一试! 其他大部分字段保留它们的默认值,但将 Config.Limit By 设置为服务(Service),将 Config.Minute 设置为 5。 这将限制所有消费者每分钟只能调用 5 次服务中所有路由。 选择 Create(创建)。 您可以通过返回 REST 客户端并进行示例调用来测试这个速率限制插件。客户端超过限制后,它将得到一个 429 返回错误,并带有"超过 API 速率限制"的信息 添加您的 REST 规范到 IAM REST 开发的最佳实践方法是规范优先,因此很可能您已经有了自己的 REST 规范。对于这个练习,您可以使用您从 github 下载 FirstLook-IAM 存储库时,spec 目录下的 swagger_100419.json 文件。您也可以直接从 GitHub 存储库的 spec 文件夹中下载 JSON 规范。 https://github.com/intersystems/FirstLook-IAM/blob/master/spec/swagger_100419.json 注意: 有关记录和管理 REST API 规范的更多信息,请参见 Creating REST Services(《创建 REST 服务》)中的 Discovering and Documenting REST APIs(发现和记录 REST API)。 一旦下载,您就能将您的规范添加到 IAM 中: 从 IAM 管理门户(management portal),选择 Workspaces(工作区) 标签并选择默认工作区。 为咖啡机服务(CoffeemakerService)服务选择 View(查看)。 在 Documents(文档) 区域(面板的底部)选择 Add a document(添加一个文档)到这个服务。 点击下面的文件选择器文本框 Or upload a new spec instead...(或者上传一个新的规范代替...) ,然后选择您下载的 swagger_100419.json 文件。 您现在可以查看咖啡机服务(CoffeemakerService)的 OpenAPI 规范。外部开发者也可以访问这个规范,这允许他们开发对它的 REST 调用。由于 curl 命令没有指定正确的服务,所以 "试一试(Try it Out)"选项将无法工作。 了解有关 InterSystems API管理器 的更多信息 注意: 如果没有设置默认的开发门户(dev portal),选择 Set up Dev Portal(设置开发门户)。如果默认的开发门户(Dev Portal)被禁用,选择 Enable Developer Portal(启用开发门户)。它可能需要几分钟的时间来设置。 了解有关 InterSystems API Manager 的更多信息 InterSystems 提供了一些参考资料来了解有关 IAM 的更多信息: API Manager Introduction(《API Manager 介绍》) (演示) What is InterSystems API管理器?(《什么是 InterSystems API管理器?》)(视频) IAM Guide(《IAM 指南》) (文档) 如果您想了解有关如何开发咖啡机服务(CoffeemakerService) REST 服务的更多详细信息,请参见 《技术概要:在 InterSystems 产品中开发 REST 接口》。
      文章
      Louis Lu · 九月 26, 2021

      IRIS 2021 技术文档 First Look 10 -- InterSystems .Net 网关

      本技术概要( First Look)通过重点概述和一个基础的、实际操作的示例,向您介绍在 InterSystems IRIS®数据平台上使用 .NET 网关(Gateway)的基础知识。您将了解 InterSystems IRIS 如何与 .NET 程序集进行互操作,在这个示例中,您将创建一个 .NET 网关(Gateway),并从 InterSystems IRIS 中的代理类调用基础 DLL。 本文档设计简单;当您把 .NET 网关(Gateway)引入您的生产系统时,您可能需要做一些不同的事情。本文档末尾的参考资料,提供了有关在生产中使用 .NET 网关(Gateway)的详细和完整的信息。 要浏览所有的技术概要(First Look),包括其他可以在免费的云实例或 web 实例上执行的技术概要(First Look),请参见 InterSystems First Looks(InterSystems 技术概要)。 1. 为什么 .NET 网关(Gateway)很重要 InterSystems IRIS Object Gateway for .NET(也称为".NET 网关(Gateway)")为InterSystems IRIS 与 Microsoft .NET Framework 组件进行互操作提供了一种简便的方法。在使用网关(Gateway)导入 .NET DLL 后,您可以实例化一个外部 .NET 对象,InterSystems IRIS通过代理类将其作为的一个本地对象来操作。 每个代理对象(proxy object)都与相应的 .NET 对象通信,使您能够从 InterSystems IRIS 和 ObjectScript 中访问您的 .NET 类和方法。调用任何 InterSystems IRIS 代理方法都会将消息发送给 .NET 网关(Gateway) 工作线程,该线程会找到合适的方法或构造函数调用。调用的结果发送回代理对象,再将结果返回给 InterSystems IRIS 应用程序。 通常,使用 .NET 网关(Gateway)的最佳方法是在您的应用程序中为第三方 DLL 构建一个小型包装器类(a small wrapper class),然后为包装器生成代理类。包装器类只公开您想要的功能,而不是创建大量应用程序可能不需要的代理类。 2. 探索 .NET 网关(Gateway) 在这个实际操作的示例中,您将: 创建一个 DLL,其中包含要从 InterSystems IRIS 调用的示例类 定义一个 .NET 网关(Gateway),并启动服务器进程 创建一个 ObjectScript 类,从 DLL 生成代理类 创建另一个 ObjectScript 类,以连接到网关(Gateway)并通过代理对象操作 DLL 想试试 InterSystems IRIS .NET 开发和互操作性功能的在线视频演示吗?请看.NET QuickStart(.NET 快速入门)! 2.1 用前须知 要运行这个演示,您需要一个运行 Microsoft .NET Framework 4.5 版本 的 Windows 10 系统、Visual Studio,以及一个已安装的 InterSystems IRIS 实例。(有关安装 InterSystems IRIS 的说明,请参见 InterSystems IRIS Basics:Installation [《InterSystems IRIS 基础:安装》]。) 有关配置 Visual Studio 以连接到您的 InterSystems IRIS 实例的说明,请参见 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础: 连接一个 IDE》)中的 InterSystems IRIS Connection Information(InterSystems IRIS 连接信息)和 .Net IDE。 您还将使用InterSystems 的 Studio IDE(一个在 Windows 系统上运行的客户端应用程序)来创建 ObjectScript 代码;更多信息,请参见InterSystems IRIS Basics: Connecting an IDE(《InterSystems IRIS 基础: 连接一个 IDE》)中的 Using Studio(使用 Studio) 和 Studio。 )​​​​​​ 2.2 创建 DLL 使用 Visual Studio,创建一个名为 Person 的类并复制以下 C# 代码。在本例中使用 .NET 4.5。 public class Person { public int age; public String name; //constructor public Person (int startAge, String Name) { age = startAge; name = Name; } public void setAge(int newAge) { age = newAge; } public String getName() { return name; } public int getAge() { return age; } public static void main(String []args) { Person myPerson = new Person (5, "Tom"); Console.Out.WriteLine(myPerson.getName()); Console.Out.WriteLine(myPerson.getAge()); } } 编译 Person 类,并生成一个 Person.dll 文件。注意 DLL 的位置,因为您稍后会需要它。 2.3 创建并启动 .NET 网关 使用 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础: 连接一个 IDE》)中的 InterSystems IRIS Connection Information(InterSystems IRIS 连接信息)描述的 URL,在浏览器中打开您的实例的管理门户(Management Portal)。 导航至 System Administration(系统管理) > Configuration(配置) > Connectivity(连接) > External Language Servers(外部语言服务)。 选择 Create External Language Server(创建外部语言服务)。 输入 Server Name(网关名称)。 在 Server Type (服务类型)中选择 .Net 在 Port(端口)字段中,输入 55000。 对于 .NET Version(.NET 版本),请选择 4.5。 选择 Save(保存)。 在External Language Servers(外部语言服务)页面,找到您刚刚定义的网关(Gateway),并选择 Start(开始) 2.4 生成代理类 使用 Studio, 在实例的 USER 命名空间中创建一个名为 CreateProxyClasses.cls 的新 ObjectScript 类,并粘贴以下代码, 将您的实例的主机标识符替换为 gwyConn.%Connect 中的 server,并用双引号括起来的 Person.dll 文件的完整文件路径替换 YOUR FILEPATH HERE。 Class User.CreateProxyClasses Extends %Persistent { ClassMethod run() { // get a connection to the .NET Gateway set gwyConn = ##class(%Net.Remote.Gateway).%New() set status = gwyConn.%Connect("127.0.0.1", 55000, "USER") if $$$ISERR(status) { write !,"error: "_$system.OBJ.DisplayError(status) quit } // add the DLL to the classpath set classpath = ##class(%ListOfDataTypes).%New() do classpath.Insert("YOUR FILEPATH HERE") set status = gwyConn.%AddToCurrentClassPath(classpath) if $$$ISERR(status) { write !,"error: "_$system.OBJ.DisplayError(status) quit } // create the proxy ObjectScript classes corresponding to the .NET classes in the DLL set status = gwyConn.%Import("Person",,,,1) if $$$ISERR(status) { write !,"error: "_$system.OBJ.DisplayError(status) quit } //close the connection to the .NET Gateway set status = gwyConn.%Disconnect() if $$$ISERR(status) { write !,"error: "_$system.OBJ.DisplayError(status) quit } } } 编译并构建该类。然后使用 InterSystems IRIS Basics:Connecting an IDE(InterSystems IRIS 基础: 连接一个 IDE) 中的 instructions for your instance(对您的实例的说明),在 USER 命名空间中打开 InterSystems 终端(InterSystems Terminal), 并执行以下命令: do ##class(User.CreateProxyClasses).run() 2.5 使用ObjectScript 操作 .NET Object 在 USER 命名空间中创建另一个名为 ManipulateObjects.cls 的 ObjectScript 类,并粘贴以下代码 (注意要将您的实例的主机标识符替换 gwyConn.%Connect 中的 第一个参数): Class User.ManipulateObjects Extends %Persistent { ClassMethod run() { // get a connection to the .NET gateway set gwyConn = ##class(%Net.Remote.Gateway).%New() set status = gwyConn.%Connect("127.0.0.1", 55000, "USER") if $$$ISERR(status) { write !,"error: "_$system.OBJ.DisplayError(status) quit } // manipulate some proxy objects set person = ##class(User.Person).%New(gwyConn,5,"Tom") write !,"Name: "_person.getName() write !,"Age: "_person.getAge() do person.setAge(100) write !,"Age: "_person.getAge() // close the connection to the .NET gateway set status = gwyConn.%Disconnect() if $$$ISERR(status) { write !,"error: "_$system.OBJ.DisplayError(status) quit } } } 编译并构建该类,然后在终端(Terminal)中的 USER 命名空间中执行以下命令: do ##class(User.ManipulateObjects).run() 您应该可以看到以下输出: Name: Tom Age: 5 setting age to 100 Age: 100 现在您已经成功地完成了练习,停止您创建的 .NET 网关(Gateway)。返回到管理门户(Management Portal)中的 External Language Servers(外部语言服务)页面,找到网关(Gateway),并选择 Stop(停止)。 3. 了解更多有关 .NET 网关(Gateway)的信息 从这里,您可以继续探索 .NET 网关(Gateway)和 InterSystems IRIS。请参阅下面的文档和参考资料,了解 .NET、互操作性、应用程序开发等。 Using the Gateway for .NET(使用 .NET 网关) — 了解更多有关 InterSystems IRIS 和 Microsoft .NET Framework 组件之间互操作性的信息。 Skyrocket Your .NET Application Development(Skyrocket Your .NET 应用程序开发) — 这是 InterSystems 关于在 .NET 中作为对象建模和访问数据的演示。 .NET Documentation(.NET 文档) — Microsoft 在 .NET 上的文档,包括架构概念、教程和开发指南。
      文章
      Nicky Zhu · 九月 22, 2021

      IRIS 2021 技术文档 First Look 2--InterSystems IRIS基础知识:安装

      1 安装基础知识:目的 本指南可帮助您成功在桌面或虚拟机上运行一个经授权许可的 InterSystems IRIS®。适用于我们在技术概要 (First Look)操作指南里所提及的技术。我们提供的说明包括64位 Windows 10, Red Hat 企业版Linux7,以及Apple macOS10.13. 注: InterSystems 云管理器(ICM)提供了一种简单、直观的方法来配置云或虚拟基础架构,用户可在该基 础架构上部署所需的 InterSystems IRIS架构以及其他服务。 请勿使用本指南安装生产实例或任何自定义安装配置;如需帮助,请参阅InterSystems Cloud Manager Guide(《InterSystems 云管理器指南》)或Installation Guide(《安装指南》)。 2 用前须知 在开始安装 InterSystems IRIS之前,请确保:• 计算机上的完整管理员权限或sudo权限。• 访问InterSystems IRIS的单文件的可执行安装文件(Windows)或工具包(Linux和macOS)。 • 在IRIS可访问的文件夹下存放有效的许可证密钥文件,通常命名为iris.key。 您正在使用的技术概要(First Look)中对安装有特定要求;例如,可能需要“正常”安全性。在遵循以下说 明之前,请务必查看技术概要中“用前须知”章节。 注: 安装了 InterSystems 的IRIS之后,您可以在InterSystems IRIS Basics: Connecting an IDE (《InterSystems IRIS基础:连接一个IDE》)中,查找介绍如何将一个IDE连接到InterSystems IRIS上的实例过程。 3 在Windows10系统安装 InterSystems IRIS 要在Windows10上安装 InterSystems IRIS: 在Windows资源管理器中,右键单击 InterSystems IRIS安装可执行文件,然后选择“Run as administrator(以管理员身份运行)”。在生成的Windows用户帐户控制对话框中,选择“YES”。 如果出现“Select instance(选择实例)”对话框,请选择“New Instance(新建实例)”。 勾选接受许可协议,然后单击“Next(下一步)”。 在“InterSystems IRIS Instance Name(InterSystems IRIS实例名称)”对话框中为你的实例起 名,InterSystems IRIS实例名称仅可使用字母数字字符和下划线。然后单击“Next(下一步)”。 如果目标文件夹显示可安装,请单击“Next(下一步)”。如不可安装,请单击“Change(更改)”以选 择其他文件夹。请使用计算机上的文件夹,而不是映射的网络驱动器。 在“Setup Type(安装类型)”对话框中,接受默认的Development,然后单击“Next(下一步)”。 在“Initial Security Settings(初始安全设置)”对话框中,选择技术概要(First Look)中所推荐的 安全类型。通常应选用Normal(正常)类型。如未找到推荐的安全类型,请使用Minimal(最小值),然后 单击“Next(下一步)”。 (仅限正常和锁定安全类型)在“Enter Credentials(输入凭据)”对话框中,选择在defined Username account(定义的用户名账号)下运行InterSystems IRIS,确认Windows用户名和域名正确,并输入 Windows密码。然后单击“Next(下一步)”。 (仅限正常和锁定安全类型)在InterSystems IRIS Users configuration(InterSystems IRIS用户配 置)对话框中,输入并再次确认8-32个字符的密码(允许使用字母数字和标点符号)。请注意此密码将在 登录InterSystems IRIS主要管理工具(management tools)时使用。然后单击“Next(下一步)”。 (仅限正常和锁定安全类型)输入CSPSystem Account的密码时(Enter password for CSPSystem account),请输入并再次确认8-32个字符的密码(允许使用字母数字和标点符号)。请记住此密码。然后 单击“Next(下一步)”。 在“Ready to Install the Program(准备安装程序)”对话框中,单击“License(许可证)”,然后选 择许可证密钥文件。然后单击“Install(安装)”,此安装过程需要几分钟时间。 要访问新安装,请右键单击上箭头 4 在Linux系统安装 InterSystems IRIS 在Linux系统上安装 InterSystems IRIS须知: 在Linux中创建一个组,并添加您的用户账号。 提取安装文件。 跳转至安装文件。 运行命令“sudo ./irisinstall”,它将出现一系列提示 如果系统提示您要输入平台的编号,请输入为Red Hat Enterprise Linux列出的编号。 “Enter instance name(输入实例名称)”,请输入用户名。仅使用字母数字字符和下划线。 按Enter键确认名称。 “Enter a destination directory for the new instance(为新实例输入目标目录)”,请输入 InterSystems IRIS系统文件的目录名称,您的计算机上不存在目录,不要使用符号链接 (symlink)。 按Enter确认需要创建的新目录(或使用输入的现有目录)。 “Setup type<1>(安装程序类型<1>)”,按Enter键接受默认安装类型(Development)。 “Initial Security settings(初始安全设置)”,请输入技术概要(First Look)中所推荐的安全 类型的编号,通常应选择Normal(正常)类型。如果没有,请按Enter接受默认值1(Minimal)。 (仅限正常和锁定安全类型)“Which user should be the owner of this instance?(本实例的用户 是?)”请输入您的用户账户名称。 (仅限正常和锁定安全类型)“Please enter the common password for _SYSTEM...(请输入 _SYSTEM...的通用密码)”,输入(然后再次确认)8-32个字符的密码(允许使用字母数字和标点符 号)。请注意此密码,因为您将在登录到InterSystems IRIS主要管理工具(management tools)时使 用此密码。 (仅限正常和锁定安全类型)“Please enter the common password for CSPSystem...(请输入 CSPSystem...的通用密码)”,输入(然后再次确认)8-32个字符的密码(允许使用字母数字和标点 符号)。请记住此密码。 “What group should be allowed to start and stop this instance?(应该允许哪个组启动和停 止此实例?)”请输入您在上面的步骤1中创建的组的名称。 “Do you want to enter a license key(您是否需要输入一个license key?)”输入y,然后输入许 可证密钥的完整路径名(例如, /home/user/iris/iris.key)。 该脚本会显示您在继续之前选择的安装选项。按Enter键选择继续安装。 请注意安装结束时显示的URL:它是管理门户(Management Portal)的URL,也是 InterSystems IRIS的系 统管理用户界面。 要检查新安装实例的状态并查看其他信息,请在Linux命令行下输入“iris list”查看实例列表。 5 在macOS系统安装InterSystems IRIS 要使用bashshell在macOS上安装 InterSystems IRIS: 在macOS中创建一个组,并添加您的用户账户。 提取安装文件。 跳转至安装文件。 运行命令“sudo ./irisinstall”,它将出现一系列提示。 如果系统提示您要输入平台的编号,请输入macOS列出的编号。 “Enter instance name(输入实例名称)”,请输入用户名。仅使用字母数字字符和下划线。 按Enter键确认实例名称。 “Enter a destination directory for the new instance(为新实例输入目标目录)”请输入 InterSystems IRIS系统文件的目录名称,您的计算机上不存在目录,不要使用符号链接 (symlink)。 按Enter确认需要创建的新目录(或使用输入的现有目录)。 “Setup type<1>(安装程序类型<1>)”,按Enter键接受默认安装类型(Development)。 “Initial Security settings(初始安全设置)”,请输入技术概要(First Look)中所推荐的安全 类型的编号。通常应选择Normal(正常)安全类型。如果没有,请按Enter接受默认值1(Minimal)。 (仅限正常和锁定安全)“Which user should be the owner of this instance?(本实例的用户 是?)”请输入您的用户账户名称。 (仅限正常和锁定安全类型)“Please enter the common password for _SYSTEM...(请输入 _SYSTEM...的通用密码)”,输入(然后再次确认)密码(包含字母和数字)。请注意此密码,因为 您将在登录到主要InterSystems IRIS管理工具(management tools)时使用此密码。 (仅限正常和锁定安全类型)“Please enter the common password for CSPSystem...(请输入 CSPSystem...的通用密码)”,输入(然后再次确认)密码(包含字母和数字)。请记住此密码。 “What group should be allowed to start and stop this instance?(应该允许哪个组启动和停 止此实例?)”请输入您在上面的步骤1中创建的组的名称。 “Do you want to enter a license key(您是否需要输入一个license key?)”输入y,然后输入许 可证密钥的完整路径名(例如, /home/user/iris/iris.key)。 该脚本会显示您在继续之前选择的安装选项。按Enter键选择继续安装 请注意安装结束时显示的URL:它是管理门户(Management Portal)的URL,也是 InterSystems IRIS的系统管理用户界面。 要检查新安装实例的状态并查看其他信息,请进入 命令行并输入“iris list”查看实例列表。
      文章
      Louis Lu · 十一月 2, 2021

      IRIS 2021 技术文档 First Look 30 -- 使用 InterSystems 产品进行文本分析

      本技术概览( First Look )介绍了 InterSystems IRIS® 数据平台 支持使用 Natural Language Processing(NLP,自然语言处理 )文本分析的能力,NLP文本分析以各种自然语言对非结构化文本数据进行语义分析。能让您发现有关大量文本文档内容的有用信息,而无需事先了解文本内容。 本技术概览( First Look )介绍了 InterSystems IRIS Natural Language Processing(自然语言处理),并介绍了一些与索引文本数据相关的初始任务,以进行语义文本分析。完成这些任务后,您将对一组文本建立索引并执行分析,以确定这些文本中最常见的实体(entity)、关于这些实体的度量指标、实体之间的各种关联,以及查看实体在源文本的表现形式。这些活动仅设置使用默认设置和功能,以便您熟悉 NLP 文本分析的基础知识。有关Text Analytics(文本分析)的完整文档,请参阅InterSystems IRIS Natural Language Processing (NLP) Guide (《InterSystems IRIS 自然语言处理 (NLP) 指南》)。 处理非结构化文本的一个相关但独立的工具是InterSystems IRIS SQL Search。SQL Search允许您search(搜索)这些相同的实体,以及多个文本中的单个单词、正则表达式(regular expression)和其他结构。本质上,搜索解决方案的前提是您知道自己要寻找的目标。NLP 文本分析旨在帮助您发现内容和内容实体之间的联系,而无需明确要寻找的目标。 要浏览技术概要(First Look)的所有内容,包括可以在InterSystems IRIS的免费评估实例上执行的许多内容 , 请参阅InterSystems First Looks (《InterSystems 技术概要》)。 为什么 NLP 文本分析很重要 企业逐渐累积的越来越多的非结构化文本数据,远远超出了他们阅读或记载这些文本的能力。通常,企业可能对这些文本文档的内容知之甚少。基于纯search(搜索)技术传统的“自上而下”文本分析,对这些文本的内容做出假设,可能会遗漏重要内容。 InterSystems IRIS Natural Language Processing (NLP)可以在预先不了解这些文本的主题的情况下,对这些文本进行文本分析。它通过应用识别语义实体的特定语言规则来实现这项功能。由于这些规则是专门针对语言而非内容,因此 NLP 可以在不使用字典或本体的情况下提供对文本内容的深入分析。 InterSystems IRIS 如何实施 NLP 文本分析 要为 NLP 分析准备文本,您必须将这些文本加载到domain(域)中,然后构建域。基于对这些文本的分析,NLP为该域构建索引, NLP可以使用域快速分析大量文本。文本可以从各种数据位置输入,包括 SQL 表、文本文件、strings(字符串)、globals 和 RSS 数据。 NLP 支持以下功能: Language models(语言模型):识别单词之间的语义关系是专门针对语言的。NLP 包含十种自然语言的语义规则(语言模型),可以分析用该语言编写的任何主题的文本。如果指定的语言不止一种,NLP 通过确定每个文本中的每个句子与指定语言之间的最佳匹配来执行自动语言识别。NLP 分析不需要预先创建或关联字典或本体,尽管您可以通过添加它们来扩展其功能。 Entity analysis(实体分析):一个或多个单词的语义群,被称为实体,NLP对其进行操作。实体被定义为Concepts(包括名词和名词短语)或Relations(包括动词和介词)。通常,要考虑的最相关实体是Concepts,但也可以分析Relations。句子和单词始终泾渭分明。忽略字母大小写。 Path analysis(路径分析):NLP 将Concepts和Relations的连贯序列分组为Paths。一个句子通常由一个单独的 Path 组成。Path 反映了实体之间的联系。 Attributes(属性):NLP 标记语义属性,例如否定,以便您可以区分肯定的文本序列(“结构损坏的证据”)和否定的文本序列(“没有结构损坏的证据”)。 Frequency、Spread 和 Dominance:这些是为实体计算的度量指标。Frequency是实体在一组文本中出现的次数。Spread是包含该实体的文本数。Dominance 是一个更细微的指标,通过将实体重复出现次数相对于每个文本的长度、具有共同单词的其他实体的重复出现次数以及其他因素考虑在内,形成该指标。实体通常按这些指标按降序排列。通过这些指标可以了解文本内容,您能更加深入地分析特定实体。 Similar Entities、 Related Concepts 和 Proximity Profile。给定一个实体,这些功能可以发现其他相关实体。例如,给定一个简短的实体,相似的实体将包括域中包含相同词的其他更长的实体,从而是比种子实体更具体的实体。给定一个实体,相关实体是同一句子中通过单个Relation与指定实体相关联的其他实体。给定一个实体,Proximity 指标度量计算指定实体与其他实体之间在路径内的距离。 Dictionaries(字典):您可以添加可选的字典来识别实体的同义词。 Summarization(摘要):您可以使用 NLP 生成文本摘要,要求摘要按整体文本的一定百分比生成。例如,50% 的摘要将包含原始文本中一半的句子,NLP 会选择那些被计算为与整个源文本最相关的句子。 亲自尝试 NLP 文本分析 使用 InterSystems IRIS 文本分析很容易。这个简单的程序将引导您按基本步骤生成NLP 度量指标。 提供此示例是为了让您初步体验InterSystems IRIS Natural Language Processing。不应将此示例用作开发实际应用程序的基础。如要在真实情况下使用 NLP,您应该充分研究该软件提供的可用选项,然后开发您的应用程序以生成稳健且高效的代码。 用前须知 要使用该程序,您需要一个正在运行的 InterSystems IRIS 实例。您的选择包括多种类型的已授权的和免费的评估实例;该实例不需要在您工作的系统中(尽管它们必须相互具有网络访问权限)。如果您还没有一个可以使用的实例,如何部署每种类型实例的有关信息,请参阅InterSystems IRIS Basics: Connecting an IDE(《INTERSYSTEMS IRIS 基础:连接一个IDE》)中的Deploying InterSystems IRIS(部署 InterSystems IRIS)。 您还需要获取 Aviation.Event SQL 表,该表可在 GitHub 上找到,网址为https://github.com/intersystems/Sam-ples-Aviation。按照First Look: SQL Search with InterSystems Products(《技术概览:使用 InterSystems 产品进行 SQL 搜索》)中的Downloading and Setting up the Sample Files(下载和设置示例文件)提供的说明下载和设置文件 创建域并添加数据位置 所有 NLP 分析都发生在一个域内。将多个文本关联到一个域。然后构建域,创建 NLP 查询使用的索引。 域是在namespace(命名空间)中创建的,例如在上一节中按照First Look: SQL Search with InterSystems Products(《技术概览:使用 InterSystems 产品进行 SQL 搜索》)的过程,创建的SAMPLES命名空间。可以在一个命名空间内创建多个域。可以将一个文本与多个域进行关联。 有多种方法可以创建、填充和构建域。以下示例使用Domain Architect界面。 在浏览器(browser)中为实例打开 Management Portal (管理门户),使用 InterSystems IRIS Basics: Connecting an IDE(《INTERSYSTEMS IRIS 基础:连接一个IDE 》)的URL described for your instance(实例适用的URL)。 导航到 Domain Architect 页面(Analytics > Text Analytics > Domain Architect)。使用Analytics选项之前,可能需要切换到启用分析功能的SAMPLES命名空间。 点击 New (新建)按钮定义域。指定以下域值(按给定的顺序): Domain name:分配给域的名称在当前命名空间必须是唯一的(不仅仅是在其package class(包类)中唯一);域名不区分大小写。本示例指定名称为 MyTest。 Definition class name:域定义 package name (包名)和 class name(类名),用句号分隔。从 Domain name字段按 Tab 键生成默认Definition class name:Samples.MyTest 。 Allow Custom Updates:此复选框允许手动将数据或字典添加到此域。本示例请勿选中此框。 点击 Finish(结束) 按钮来创建域。在屏幕中将显示 Model Elements 选项。 在域内,可以为域定义数据位置和其他模型元素。要添加或修改模型元素,请单击标题之一旁边的扩展三角形。一开始,没有扩展三角形出现。定义一些模型元素后,单击扩展三角形会显示您定义的模型元素。 点击 Data Locations 三角形以在屏幕右侧显示 Details 选项卡。Details选项卡显示五个 Add Data 选项。选择 Add data from table。 此选项允许您指定存储在 SQL 表中的数据。在本例中,我们将指定以下字段: Name:提取的数据文件集的名称。使用默认值:Table_1。 Schema:从下拉列表中选择 Aviation。 Table Name:从下拉列表中选择 Event。 ID Field:从下拉列表中选择 ID。 Data Field:从下拉列表中选择 NarrativeFull。 如果当前域定义有未保存的更改,Domain Architect 页面标题后跟一个星号 (*)。点击 Save (保存)保存更改。 按 Compile(编译) 按钮,编译 Domain。 按 Build 按钮,为源数据构建NLP索引。 分析数据 使用以下过程分析数据: 在 Domain Architect 页面上,选择屏幕右侧的 Tools 选项卡,然后单击 Domain Explorer 按钮。 Domain Explorer 最初显示源文本中最重要概念的列表: frequency选项卡按频率降序显示Top Concepts。每个列出的项目都列示其频度计数(出现次数)和分布计数(包含该概念的源数量)。 例如, pilot概念的重复出现次数为6206,分布计数为1085;student pilot概念的重复出现次数为 319,分布计数为 141。 dominance选项卡按 dominance 计算结果,降序显示Dominant Concepts。 例如,pilot概念拥有 351.6008 的dominance;student pilot概念拥有 49.3625 的dominance。 当您选择上述其中一项概念,将显示该概念的另一个Domain Explorer列表: Similar Entities 列出所选概念以及包含该概念的所有其他概念,每个概念都有其重复出现次数和分布计数。 例如,选择student pilot,Similar Entities 将显示包括student pilot, student pilot certificate, student pilot's logbook, solo student pilot在内的列表。 Related Concepts 列出与所选概念相关的其他概念,以及在上下文语境中该实例的这些概念的重复出现次数和分布技术。 例如,选择student pilot,Related Concepts 将显示包括flight instructor和airplane在内的列表。 Proximity Profile 列出所选概念相邻的其他概念,以及当发现在相同的句子中有与所选概念相同的概念,将计算这些概念的实例的相邻程度。 例如,选择student pilot,Proximity Profile 将列示 airplane的相邻程度为 2702,以及flight instructor的相邻程度为 1662 。 在上述任一列表中的选择一个概念,这些列表将根据该概念进行刷新。或者,您也可以将实体(Concept或Relation)键入到 Domain Explorer Explore 区域并单击 Explore! 按钮。 通过使用这些列表,可以确定源文档中出现哪些概念、它们的重要性以及与它们相关联的其他概念。 Domain Explorer 的下部分允许您查看所选概念在源文本中的显示方式: Sources 选项卡按来源列出包含所选概念的所有句子。该概念被高亮显示,红色文本用于表示涉及该概念的否定。 Paths 选项卡列出了包含所选概念的所有路径。路径文本被突出显示,以显示 NLP 索引:所选概念以橙色高亮显示,路径中的其他概念以蓝色高亮显示,与路径相关的概念(通常是代词)以浅蓝色高亮显示。关系显示为白色。红色文本用于表示涉及该概念的否定。 通过点击 eye 图标,可以显示源的完整文本,所选概念将被高亮显示,并使用红色文本表示否定。 Indexing 切换按钮显示源的完整文本,高亮显示 NLP 索引。因为这是源文本,所以会显示大小写、标点符号和不相关的单词;文本的这些方面没有显示在Paths列表中。 % 选项允许您显示文本摘要。指定一个百分比。文本中的句子总数减少到该百分比。NLP 包含在摘要中的句子由它们对全文的重要性计算确定 您可以添加一个 skiplist 来排除不需要的概念。通常,top concepts(上层概念)列表始于那些非常常见或在几乎没有什么有用信息的概念。这些可能是出现在所有来源中的词或短语(例如“accident report(事故报告)”或“conclusions(结论)”)、一般概念(例如“airplane(飞机)”或“pilot(飞行员)”),或与您所使用数据无关的概念(例如城市列表)。您可以使用 skiplist 避免显示这些概念。Skiplist 仅影响某些查询结果中概念的显示;它对概念的 NLP 索引没有影响。 在 Domain Architect 中单击 Open 按钮并选择 Samples >>,然后是 MyTest 打开现有域 Samples.MyTest。 点击 Skiplists 扩展三角形。将在屏幕右侧的 Details 选项卡显示 Add skiplist 按钮。点击 Add skiplist 以显示 Name 和 Entries 字段。接受 skiplist 的默认名称 (Skiplist_1)。在 Entries 框列示条目(概念),一行一个概念;条目不区分大小写。本例中列出如下概念:pilot(飞行员) student pilot(学生飞行员)、 co-pilot(副驾驶)、 passenger(乘客)、instructor(教官)、flight instructor(飞行教官)、certified flight instructor(认证飞行教官)。 Save(保存)和Compile(编译)域。(不需要使用 Build 功能去添加、修改或删除 skiplists 的域)。 在Domain Explorer中单击 sunglasses 右上角的图标。将显示您可以应用的为该域定义的skiplists的列表。选择Skiplist_1。请注意,Top Concepts 不再列出 skiplists 的概念。 了解有关 NLP 文本分析的更多信息 InterSystems 有其他相关资料可帮助您了解有关 NLP 文本分析的更多信息,包括: InterSystems IRIS Natural Language Processing (NLP) Guide(《InterSystems IRIS自然语言处理 (NLP) 指南》)
      文章
      Hao Ma · 十一月 2, 2021

      IRIS 2021 技术文档 First Look 23 - 使用 InterSystems 分布式缓存扩展用户容量

      本文档将向您介绍 InterSystems IRIS®数据平台如何通过使用应用服务器进行分布式缓存,利用企业缓存协议(Enterprise Cache Protocol,ECP)来扩展用户容量(User Volume)。本指南介绍了如何使用分布式缓存架构进行扩展,并介绍了与部署 InterSystems IRIS 分布式缓存集群相关的一些初始任务。一旦您完成了本指南,您将对分布式缓存集群的工作原理和设置方法有一个基本的了解。这些活动被设计成只使用默认的设置和功能,这样您就可以熟悉该功能的基本原理,而不必处理细节(尽管这些细节在执行实现时可能很重要)。有关使用 InterSystems IRIS 分布式缓存和 ECP 的完整文档,请参见本指南末尾 " For More Information (更多信息)" 部分中的参考资料列表。要浏览所有的技术概要(First Look),包括可以在 InterSystems IRIS 免费的评估实例上执行的那些,请参见 InterSystems First Looks(《InterSystems 技术概要》)。 1 问题:扩展用户容量(User Volume) 当用户通过应用程序连接到您的 InterSystems IRIS 数据库时,他们需要快速、有效地访问数据。无论您的企业是小型、大型,还是介于两者之间,对数据库的大量并发用户请求——用户容量(user volume)——都会在托管数据库的系统上造成性能问题。这可能会影响更多用户,使他们等待更长时间才能收到所需信息。在一个动态业务中,用户容量(User Volume)可能会迅速增长,从而进一步影响性能。特别是,如果很多用户在执行许多不同的查询,这些查询的大小会超过缓存,这意味着,它们不能再存储在内存中,而是需要从磁盘上读取数据。这种低效的过程会导致瓶颈和性能问题。您可以增加系统的内存和缓存大小(垂直扩展),但这种解决方案可能是昂贵的、不灵活的,并最终受限于硬件的最大功能。将用户的工作量分散到多个系统上(水平扩展)是一种更加灵活、高效和可扩展的解决方案。 2 解决方案:分布式缓存(Distributed Caching)为了提高用户访问数据的速度和效率,InterSystems IRIS 可以使用分布式缓存(Distributed Caching)。这种技术允许 InterSystems IRIS 在多个应用服务器(application server)上存储数据库缓存。然后,用户容量(User Volume)可以分布在这些服务器上,从而提高缓存效率。使之成为可能的节点间通信是由 ECP,即企业缓存协议(Enterprise Cache Protocol)启用的。使用分布式缓存(Distributed Caching),您可以让进行类似查询的用户共享一部分缓存,该缓存托管在应用服务器集群中,与托管数据的数据服务器一起。实际数据保留在数据服务器上,但缓存保留在应用服务器上,以加快用户访问。数据服务器负责保持企业中每台应用服务器上的缓存数据是最新的。 分布式缓存是如何工作的? 有了分布式缓存集群,您可以根据需要添加或删除应用服务器,轻松地扩展您的解决方案。所有的应用服务器都会自动维护自己与数据服务器的连接,并在连接中断时尝试恢复连接。您可以在单个集群实例上使用管理门户(Management Portal)配置应用服务器及其相关的数据服务器,或使用 InterSystems 云管理器(InterSystems Cloud Manager,ICM)部署和配置集群。有关 ICM 的更多信息 ,请参见 First Look:ICM(《技术概要:ICM》)和 InterSystems Cloud Manager Guide(《InterSystems 云管理器指南》)。 3 分布式缓存是如何工作的?当您部署一个 InterSystems IRIS 分布式缓存集群时,指定一个实例为数据服务器,指定一个或多个实例为应用服务器。这些实例不需要在相同的操作系统或硬件上运行,它们只需要符合 InterSystems IRIS 系统的要求。• 数据服务器的执行方式与标准的 InterSystems IRIS 服务器一样,在命名空间中托管数据库,并根据请求向其他系统提供数据。• 应用服务器接收来自应用程序的数据请求。当用户打开一个应用程序时,它不是连接到数据服务器,而是连接到应用服务器。用户不会注意到有什么不同。应用服务器从数据服务器获取必要的数据并提供给用户。• 应用服务器将数据存储在自己的缓存中,这样,下次任何用户请求相同的数据时,应用服务器不需要再次联系数据服务器就可以提供。• 数据服务器监控所有的应用服务器,以确保其缓存中的数据是最新的。数据服务器还处理整个系统的数据锁。• 如果应用服务器和数据服务器之间的连接丢失,应用服务器会自动尝试重新连接并恢复任何需要的数据。• 您可以设计您的应用程序,将进行类似查询的用户引导到同一个应用服务器。这样一来,用户可以共享一个包含他们最需要的数据的缓存。例如,在医疗保健设置中,您可能会让临床医生运行一组特定的查询,而前台工作人员使用相同的应用程序和相同的底层数据运行不同的查询;这些用户组可以在不同的应用服务器上分组。再比如,如果集群处理多个应用程序,每个应用程序的用户可以被引导到他们自己的应用服务器上,以获得最大的缓存效率。 4 亲自尝试分布式缓存使用 InterSystems IRIS 建立一个分布式缓存集群很容易。这个简单的程序将引导您完成在几个实例上配置 ECP 的基本步骤。注意: 为了让您体验分布式缓存,而又不至于在细节上陷入困境,我们保持了简单的探索;例如,我们让您尽可能多地使用默认设置。不过,当您把这个功能带到您的生产系统时,您可能需要以不同的方式配置一些设置(例如,安全设置)。本文档末尾提供的参考资料将为您提供更多细节。 亲自尝试分布式缓存4.1 用前须知在这个示例中,您将设置一个InterSystems IRIS 实例作为数据服务器,再设置两个实例作为应用服务器。这意味着您将总共需要三个实例。您对 InterSystems IRIS 的选择包括多种类型的已授权的实例;这些实例不需要由您正在工作的系统托管(尽管它们必须相互有网络访问权限)。关于如何部署每种类型的实例的信息(如果您还没有三个实例可以使用),请参见 InterSystems IRIS Basics: Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中的 Deploying Licensed Instances(部署已授权的实例)。注意:InterSystems IRIS 数据平台(Data Platform)提供了几种自动部署分布式缓存集群的方法,这些集群在部署后可以完全运行;请参见 Scalability Guide(《可扩展性指南》)中的 Deploying a Distributed Cache Cluster Automatically(自动部署分布式缓存集群)。4.2 启用 ECP 服务器 首先,在三个实例上启用 ECP 服务器,如下所示:1. 使用 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中URL described for your instance(为您的实例描述的 URL),在您的浏览器中打开实例的管理门户(Management Portal)。2. 进入 Services(服务器) 页面(System Administration(系统管理) > Security(安全) > Services(服务器))。3. 选择 %服务_ECP。在 Edit Service(编辑服务器)页面上,选择 Service Enabled(已启用的服务器)复选框,然后选择 Save(保存)。您现在已经在系统上启用了 ECP。只需要几个步骤就可以完成对数据服务器和两个应用服务器的设置。4.3 配置数据服务器 在将要成为您的数据服务器的系统上,只需要两个快速步骤就可以完成设置。首先,您需要将允许的应用服务器的数量从默认值增加一个。然后,您将创建一个新的数据库供应用服务器连接。当然,在生产环境中,您已经有一个正在使用的数据库。要完成数据服务器配置:1. 在管理门户(Management Portal)中,进入 ECP Settings(ECP 设置) 页面(System Administration(系统管理) > Configuration(配置) > Connectivity(连接) > ECP Settings(ECP 设置))。2. 在标有 This System as an ECP Data Server(本系统作为 ECP 数据服务器)的部分中,将 Maximum number of application servers(应用服务器的最大数量) 设置为 2。 选择 Save(保存)。3. 重新启动实例。 有关创建数据服务器和设置可用选项的更多细节,请参见 Scalability Guide(《可扩展性指南》)中 "Horizontally Scaling Systems for User Volume with InterSystems Distributed Caching(《使用 InterSystems 分布式缓存为用户容量水平扩展系统》)"一章中的 Preparing the Data Server(准备数据服务器)。要为这个练习创建一个新的数据库:1. 在管理门户(Management Portal)中,进入 Local Databases(本地数据库) 页面(System Administration(系统管理) > Configuration(配置) > System Configuration(系统配置) > Local Databases(本地数据库))。2. 选择 Create New Database(创建新的数据库)。3. 为新数据库输入一个名称。对这个练习来说,称它为 ECP。4. 选择 Next(下一步) ,然后 Finis(完成)。 您已经创建了新数据库,并且您的数据服务器也已经准备好了。 亲自尝试分布式缓存 在接下来的章节中,您将设置两个应用服务器,并配置它们使其能够与数据服务器进行通信。为此,您需要知道数据服务器的超级服务器端口号(superserver port number),如 InterSystems IRIS Basics:Connecting an IDE(《技术概要:连接一个 IDE》)中所述。 4.4 配置应用服务器 接下来,您将把另外两个实例设置为应用服务器。您将配置每个应用服务器以指向数据服务器,并在每个服务器上创建一个新的命名空间,映射到您在数据服务器上创建的数据库。请确保在每个应用服务器上执行以下两个程序。 4.4.1 设置应用服务器1. 登录管理门户(Management Portal),进入 ECP Settings(ECP 设置) 页面(System Administration(系统管理) > Configuration(配置) > Connectivity(连接) > ECP Settings(ECP 设置))。2. 选择 Data Servers(数据服务器) ,然后选择 Add Server(添加服务器)。3. 填写所需信息:• Server Name(服务器名称)——输入一个名称或标签来识别这个服务器。它不需要与实例名称或实例的主机名称相同。• Host DNS Name or IP Address(主机 DNS 名称或 IP 地址)——输入托管您在上一节配置的数据服务器实例所在系统的主机标识符。• IP Port(IP 端口)——输入数据服务器实例的超级服务器端口号(superserver port number)。 4. 选择 Save(保存)。您的数据服务器现在出现在列表中。应用服务器连接到数据服务器,验证连接可能需要一些时间。4.4.2 创建命名空间和远程数据库现在您已经将应用服务器连接到数据服务器,您需要在每个应用服务器上创建一个命名空间。这个命名空间将是应用服务器的本地命名空间,但它不是包含本地数据库,而是映射到远程数据库——也就是您在上一节创建的数据服务器上的 ECP 数据库。1. 在管理门户(Management Portal)中,进入 Namespaces(名称空间) 页面(System Administration(系统管理) > Configuration(配置) > System Configuration(系统配置)> Namespaces(命名空间))。2. 选择 Create New Namespace(创建新的命名空间)。3. 在 Name of the namespace(命名空间名称) 字段中,输入 ECPNS。4. 对于 The default database for Globals in this namespace is a(这个命名空间中的 Globals 的默认数据库是一个),选择 Remote Database(远程数据库)。然后选择 Create New Database...(创建新数据库...) 按钮。 这将打开 Create Remote Database(创建远程数据库)窗口。5. 填写所需信息:• Remote Server(远程服务器)——使用下拉菜单来选择您在前面的程序中给数据服务器的 Server Name(服务器名称)。• Remote Directory(远程目录)——在数据服务器上,选择包含 ECP 数据库的目录。• Database Name(数据库名称)——输入一个数据库的名称。这可以与它在数据服务器(本例中是 ECP)上的名称相同,也可以不同。 6. 选择 Finish(完成)。窗口关闭,您会返回到 New Namespace(新的命名空间) 页面。 您应该看到,您刚刚创建的数据库现在显示在 Select an existing database for Globals(为 Globals 选择一个现有的数据库) 字段中。 亲自尝试分布式缓存 7. 由于这个命名空间中的例程(Routines)的默认数据库是 a(The default database for Routines in this namespace is a),选择 Remote Database(远程数据库)。现在您应该能够从下拉菜单中选择您刚刚创建的新数据库。8. 清除 Enable namespace for interoperability productions(为互操作性产品启用命名空间) 复选框。9. 选择 Save(保存)。现在新的命名空间出现在列表中。 有关创建命名空间及其相关数据库的更多细节,请参见 System Administration Guide(《系统管理指南》)中 "Configuring InterSystems IRIS(《配置 InterSystems IRIS》)"一章中的 "Create/Modify a Namespace(创建/修改命名空间)"。有关背景信息,请参见 Orientation Guide for Server-Side Programming(《服务器端编程指导手册》)中的"Namespaces and Databases(命名空间和数据库)"。您已经完成了! 一旦您在每个应用服务器实例上执行了这两个程序,您就成功地创建了一个集群 ,这个集群有一个数据服务器和两个应用服务器。在下一节中,您将测试这些连接,以确保所有三个实例都能正确地相互通信。 4.5 测试设置 现在您已经启用了 ECP 服务器,并设置了两个应用服务器,其命名空间指向数据服务器上的数据库,现在是时候做一个快速测试了,以确保这三个系统相互之间的通信。为了达到这个目的,您将在一个应用服务器上设置一个简单的 global,然后在第二个应用服务器上读取并改变它。要了解有关 globals 的更多信息,请参见 Using Globals(《使用 Globals》)。1. 在一个应用服务器上,使用 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中为您的实例描述的程序打开 InterSystems 终端(Terminal),并更改到您在上一节创建的命名空间。在这个示例中,命名空间被称为 ECPNS,因此您将执行以下操作:USER>set $namespace="ECPNS" ECPNS> 2. 创建一个 global,只需给它一个值即可: ECPNS> set ^MyGlobal = "My Value" 3. 在另一个应用服务器上,登录到终端(Terminal),并按照上面的描述更改到 ECPNS 命名空间。4. 写入 global 的值: ECPNS> write ^MyGlobal My Value 这表明两个应用服务器正在与数据服务器正常通信。您使用其中一个应用服务器来创建 global,但由于您是在包含远程数据库的命名空间中工作,global 实际上是在数据服务器上创建的。这就是为什么其他应用服务器可以读取它的原因。当然,这只是一个示例,但其机制是相同的,无论您是在终端(Terminal)上手动设置然后读取 global,还是有大量的用户通过十几台应用服务器在同一数据服务器前每秒发行数千个事务。ECP 将确保数据保持同步,并保证所有这些用户与系统交互的事务的一致性。5. 如果您愿意,可以在数据服务器实例上查看 global 作为最后检查。在管理门户(Management Portal)中,进入本地数据库(Local Databases)页面(System Administration(系统管理) > Configuration(配置) > System Configuration(系统配置) > Local Databases(本地数据库))。找到您的应用服务器所指向的数据库,并为该数据库选择 Globals。您应该会看到 MyGlobal 在列表中。 了解有关分布式缓存和 ECP 的更多信息 5 了解有关分布式缓存和 ECP 的更多信息 要了解有关使用 InterSystems IRIS 分布式缓存和 ECP 的更多信息,请参见以下参考资料:• Scalability Guide(《可扩展性指南》)的 "Horizontally Scaling Systems for User Volume with InterSystems Distributed Caching(《使用 InterSystems 分布式缓存为用户容量水平扩展系统》)"章节• Sample Mirroring Architecture and Network Configurations(《镜像架构和网络配置示例》)、Redirecting Application Connections Following Failover or Disaster Recovery(《故障转移或灾难恢复后重定向应用连接》)、Configuring Application Server Connections to a Mirror(《配置应用服务器到镜像的连接》),以及 High Availability Guide(《高可用性指南》)中"Mirroring(《镜像》)"章节中的其他分布式缓存和 ECP 相关章节