搜索​​​​

清除过滤器
文章
Hao Ma · 四月 19, 2022

Linux系统IRIS安装总结

本文档只是给您一个大致的概念,方便您了解IRIS安装的方方面面。并非官方安装手册或者安装建议。生产环境的安装请仔细研究并参照[IRIS官方的安装文档](https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=AB_install#AB_install_Linux) ### 操作系统的选择 IRIS支持多种Linux系统。详细的列表请参见各个版本的支持列表,比如这个是最新的[2021IRIS的支持列表](https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=ISP_technologies#ISP_platforms_server)。需要注意的是, CentOS只支持作为测试系统, 并不支持生产系统的安装。 官方文档是以Redhat为主介绍的IRIS安装, 这是IRIS在生产环境中最常用的Linux系统之一。另一个Ubantu, InterSystems提供的docker版本是安装在Ubantu上的。 我自己测试的时候喜欢使用CentOS, 所以后面有具体安装步骤中,使用的CentOS上的记录。 ### 服务器的配置 对于生产系统,安装前需要一个硬件配置方案,这个方案通常是您的项目的实施部门根据用户需求提供的。 对于测试系统,只有一个最小的磁盘的要求:1.5G。无论是实体服务器, 虚拟服务器,或者docker container,根据您要测试的内容, 一切以方便为准。如果不做性能测试,我个人经常使用的CentOS虚拟机是2核CPU, 2G或4G内存,没有运行不流畅的问题。 ### 磁盘分区 标准的Linux磁盘分区并不适合IRIS的生产运行。哪怕要创建一个尽量接近生产的测试环境,建议您安装软件前要有一个完整的磁盘分区规划。在官方文档中,创建IRIS服务器分区有以下原则: 1. **IRIS程序,客户的数据库,首选Journal,备选Journal应该是分开标准分区或者逻辑盘存储的。所以至少要4个分区/逻辑盘**。 您也可能会喜欢再给backup文件和其他的比如IRIS使用的web文件添加更多的逻辑盘。 2. 文件系统方面,IRIS程序,客户的数据库推荐使用xfs文件格式,**journal盘推荐ext4格式**。( 经过专家确认,这个推荐不属于强烈推荐,更不是强制要求。大多数情况下使用xfs格式没问题。只是在大项目中,比如当您的Journal盘需要分配1TB的空间,特别是使用ECP服务器的情况下, ext4会因为更低的延时带来相对好的性能表现) 以下是一个测试系统中的分区配置,仅仅是示意。 ```sh [root@MyCentOS7 ~]# cat /etc/fstab /dev/mapper/centos_hmscentos7-root / xfs defaults 0 0 UUID=1d1b46a2-d66d-4346-8709-e70854088b11 /boot xfs defaults 0 0 /dev/mapper/vg_iris-isc_data /isc/data xfs defaults 0 0 /dev/mapper/vg_iris-isc_iris /isc/iris xfs defaults 0 0 UUID=c9ce6576-b469-4c74-8867-fe5b5060ad62 /isc/j1 ext4 defaults 1 2 UUID=0be8a20a-b76c-4a17-9018-ecea1964b73b /isc/j2 ext4 defaults 1 2 /dev/mapper/centos_hmscentos7-swap swap swap defaults 0 0 [root@hmsCentOS7 ~]# ``` 这是一个生产环境的配置实例, 其中/isc/iris是iris安装路径:下面放系统的文件,系统使用的数据库,以及和系统工作相关的文件等等,通常分配100-200G。其他的逻辑盘按客户需要分配。SWAP, /boot, /home, /var等等的配置按Linux的推荐及客户的方案配置。 | **Mount Point** | **VG** | **LV** | Size | **File System** | **Mount Options** | | :-------------- | :------ | :-------- | :--- | --------------- | :---------------- | | /isc/iris | vg_iris | lv_iris | 200G | XFS | 默认, nobarrier | | /isc/db | vg_iris | lv_irisdb | 1TB | XFS | 默认, nobarrier | | /isc/jrnpri | | | 500G | EXT4 | 默认 | | /isc/jrnsec | | | 500G | EXT4 | 默认 | 在上面的方案中, iris系统自带的数据库IRISTEMP是放在/isc/iris下的。 IRISTEMP正常情况下不会很大,但如果应用的设计很特别,或者出了什么问题,分配了200G大小的/isc/iris可能不足够。如果生产环境发现IRISTEMP有过大的风险,您可能需要单独给IRISTEMP分配一个逻辑盘。 ###优化服务器内存配置 以下的对服务器内存的设置可以提高IRIS的性能。 **使用HugePage内存** IRIS会自动使用系统配置的HugePage, 这会提高IRIS的内存使用效率。在线文档有这么一句: **在超大页内存中可用的内存数量应大于待分配的共享内存总数;否则,将不会使用超大页内存**。 因为 内存数据的总数是为Global, Routine, Lock等分配的内存的和。可以简单的从IRIS启动的日志message.log里看到。 比如下面IRIS被分配了8913M的总内存: ```sh 12/24/21-16:28:58:490 (14080) 0 [Generic.Event] Allocated 8913MB shared memory: 8003MB global buffers, 300MB routine buffers ``` 另外,因为操作系统自身的进程不会使用HugePage内存, 您也不能把内存都设置成HugePage。所以设置为**比IRIS需要的多一点就好**。 我们来看看配置HugePage的一个简单例子 ```bash # 查看服务器物理内存 [root@hmsCentOS7 ~]# cat /proc/meminfo | grep MemTotal MemTotal: 995676 kB #查看HugePage配置 [root@hmsCentOS7 ~]# cat /proc/meminfo | grep Huge AnonHugePages: 67584 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB # 修改配置,分配256个2M的HugePage [root@hmsCentOS7 ~]# vi /etc/sysctl.conf [root@hmsCentOS7 ~]# cat /etc/sysctl.conf | grep -v ^# vm.nr_hugepages=256 #load新配置 [root@hmsCentOS7 ~]# sysctl -p vm.nr_hugepages = 256 [root@hmsCentOS7 ~] [root@hmsCentOS7 ~]# cat /proc/meminfo | grep Huge AnonHugePages: 6144 kB HugePages_Total: 256 HugePages_Free: 256 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB [root@hmsCentOS7 ~]# ``` 如果此时您启动IRIS, 会出现“Allocated xxxxMB shared memory using Huge Pages"的日志记录,而且能在/proc/meminfo里看到HugePage的占用情况。 **禁用THP(Transparent Huge Pages)** InterSystems建议在IRIS服务器禁用THP。RedHat或者CentOS是默认打开的: ```SH [root@hmsCentOS7 ~]# cat /sys/kernel/mm/transparent_hugepage/enabled [always] madvise never [root@hmsCentOS7 ~]# ``` 禁用THP您需要修改/etc/default/grub中的GRUB_CMDLINE_LINUX记录,添加“transparent_hugepage=never“ ```sh # 修改文件 [root@hmsCentOS7 ~]# cat /etc/default/grub | grep GRUB_CMDLINE GRUB_CMDLINE_LINUX="crashkernel=auto spectre_v2=retpoline rd.lvm.lv=centos_hmscentos7/root rd.lvm.lv=centos_hmscentos7/swap rhgb quiet transparent_hugepage=never" # regenerate grub2配置 [root@hmsCentOS7 ~]# grub2-mkconfig -o /boot/grub2/grub.cfg Generating grub configuration file ... Found linux image: /boot/vmlinuz-3.10.0-1160.el7.x86_64 Found initrd image: /boot/initramfs-3.10.0-1160.el7.x86_64.img Found linux image: /boot/vmlinuz-0-rescue-bd06ad08438443f5a959cb7c0c264e89 Found initrd image: /boot/initramfs-0-rescue-bd06ad08438443f5a959cb7c0c264e89.img done #重启 [root@hmsCentOS7 ~]shutdown -r now # 确认配置成功 [root@hmsCentOS7 ~]# cat /sys/kernel/mm/transparent_hugepage/enabled always madvise [never] [root@hmsCentOS7 ~]# ``` > [Redhat文档:配置THP](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/performance_tuning_guide/sect-red_hat_enterprise_linux-performance_tuning_guide-configuring_transparent_huge_pages) **Dirty Page Cleanup** 在一个大内存(比如大于8G)的Linux系统中,以下参数的修改会提高大量flat-files的写性能,比如大量的文件拷贝或者IRIS backup。 - dirty-background_ratio: InterSystems建议设置为5 - dirty_ratio: InterSystems建议设置为10 您需要修改/etc/sysctl.conf文件, 添加这两行: ```sh vm.dirty_background_ratio=5 vm.dirty_ratio=10 ``` ###配置NTP服务 各个数据库服务直接以及数据库服务器和应用服务,Web服务,打印服务等等之间要求精准的时间同步。客户可以自己选择采用chornyd或者ntpd来配置NTP。而且, 每个IRIS服务器推荐配置至少2个NTP Server地址。 有关配置NTP的方法请参考相关文档。 比如:[Redhat文档: CONFIGURING NTP USING THE CHRONY SUITE](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/ch-configuring_ntp_using_the_chrony_suite#sect-differences_between_ntpd_and_chronyd) ### 安装Web Server (optional) IRIS提供Web服务需要单独安装的Web服务器。在Linux系统,IRIS支持Apache Web Server和Nginx。 生产环境中, 推荐将Web Server和IRIS安装在不同的硬件服务器上。但是, **如果是要将Web服务器和IRIS安装在同一台服务器,那么最好最好先装好Web Server, 再安装IRIS。** 在执行IRIS的安装脚本时,会提示用户是否需要连接那么先装Apache Web Server和Nginx是正确的顺序, 这样安装IRIS的时候可以将IRIS的Web服务组件,IRIS_WebGateway安装到Apache Web Server的安装目录,并生成相应的配置文件。 ```sh # 修改httpd状态的常用命令 systemctl start httpd.service #启动apache systemctl stop httpd.service #停止apache systemctl restart httpd.service #重启apache #设置开机启动 sudo systemctl enable httpd.service #设置开机启动 ``` > 如果启动httpd显示错误“httpd: Could not reliably determine the server's fully qualified domain name”,您需要修改httpd.conf文件, 添加ServerName, 比如设为ServerName localhost:80 **到这里, 您已经基本完成了安装IRIS的准备工作,下面是IRIS的安装步骤。** ### 加载IRIS安装软件 ```sh # 解压安装文件 [root@hmsCentOS7 ~]# mkdir /tmp/iriskit [root@hmsCentOS7 ~]# chmod og+rx /tmp/iriskit [root@hmsCentOS7 ~]# umask 022 [root@hmsCentOS7 ~]# gunzip -c IRIS-2022.1.0.140.0-lnxrh7x64.tar.gz | (cd /tmp/iriskit; tar xf -) [root@hmsCentOS7 iriskit]# cd /tmp/iriskit/IRIS-2022.1.0.140.0-lnxrh7x64/ [root@hmsCentOS7 IRIS-2022.1.0.140.0-lnxrh7x64]# ls LICENSE NOTICE cplatname dist docs irisinstall irisinstall_client irisinstall_silent kitlist lgpl.txt package tools ``` > tar -zxvf *.tar.gz是centos上常用的解压命令。上面使用的gunzip来着文档,据说是更通用,适合无法用tar来操作.gz文件的linux系统环境。 ###安装依赖的软件包 建议执行IRIS安装脚本前先检查需要的软件包。 ```sh # 查看安装需要的软件包 [root@hmsCentOS7 IRIS-2022.1.0.140.0-lnxrh7x64]# ./irisinstall --prechecker Your system type is 'Red Hat Enterprise Linux (x64)'. Checking Requirements ... Requirement for openssl version 1.0.2 is satisfied. Requirement for zlib version 1.2.7 is satisfied. [root@hmsCentOS7 IRIS-2022.1.0.140.0-lnxrh7x64]# ``` 除此以外,以下软件包是按情况可选的: - snmpd: 如果您需要使用SNMP来监控IRIS - jre或者jdk : 如果您需要IRIS服务器使用JDBC连接其他数据库 - unixODBC: 如果您需要IRIS服务器使用ODBC连接其他数据库 - policycoreutils-python, policycoreutils-devel, settroubleshoot-server : 如果您需要使用SELinux管理IRIS文件的读写。 它们只是IRIS工作时需要的软件包,IRIS的安装并不依赖或者检查它们。 ###创建iris用户 安装iris需要root用户或者拥有root权限的sudoer。然而,按照Linux的常规做法,出于安全的考虑,IRIS的管理和运行应该拥有自己的用户和用户组。在安装过程中, 您会被要求提供以下的内容: - What user should be the owner of this instance? - What group should be allowed to start and stop? "owner of instance"和“group to start and stop"可以是一个用户和它的用户组。比如您创建了一个irisowner的用户, 它默认的用户组irisowner可以作为“group start to stop"。当然您也可以专门创建一个用户组, 比如irisadmin, 将您的管理员tom, jerry, mickey等等加入irisadmin。 在标准的安装步骤下, 用户组irisowner和用户组irisadmin权限相同, 因此最简单的方式就是使用irisowner用户和irisowner用户组。 ```sh # 创建iris owner useradd irisowner # 创建您的管理员团队 [root@hmsCentOS7 mail]# useradd -N tom [root@hmsCentOS7 mail]# useradd -N jerry [root@hmsCentOS7 mail]# useradd -N iscbackup [root@hmsCentOS7 mail]# gpasswd irisowner -a tom Adding user tom to group irisowner [root@hmsCentOS7 mail]# gpasswd irisowner -a jerry Adding user jerry to group irisowner [root@hmsCentOS7 mail]# gpasswd irisowner -a iscbackup Adding user iscbackup to group irisowner [root@hmsCentOS7 mail]# cat /etc/group | grep irisowner irisowner:x:1000:tom,jerry,iscbackup [root@hmsCentOS7 mail]# ``` *如果需要,您可以把tom, jerry等用户加入sudoer列表。* **实际上, 在后面安装脚本的执行过程中, 还有2个重要的用户被创建出来, 他们是:** - **irisusr**: 所有iris进程使用这个user运行。它还用来访问数据库和journal。在一个安全的系统里,irisusr组里就只有一个用户irisusr, 也不要添加其他的user。 - **iscagent**: 用于运行镜像使用的iscagent进程 IRIS用户和管理员不要动这两个用户。 ###执行IRIS安装脚本 安装脚本会设置user, group,和安装后文件的权限,您需要在按照前检查umask, 确认设置为022。 **执行标准的安装流程** ```bash # 开始安装步骤 [root@hmsCentOS7 iriskit]# cd /tmp/iriskit/IRIS-2022.1.0.140.0-lnxrh7x64/ [root@hmsCentOS7 IRIS-2022.1.0.140.0-lnxrh7x64]# ls LICENSE NOTICE cplatname dist docs irisinstall irisinstall_client irisinstall_silent kitlist lgpl.txt package tools [root@hmsCentOS7 IRIS-2022.1.0.140.0-lnxrh7x64]# ./irisinstall Your system type is 'Red Hat Enterprise Linux (x64)'. Currently defined instances: Enter instance name: iris Do you want to create InterSystems IRIS instance 'iris' ? Enter a destination directory for the new instance. Directory: /isc/iris ------------------------------------------------------------------ NOTE: Users should not attempt to access InterSystems IRIS while the installation is in progress. ------------------------------------------------------------------ Select installation type. 1) Development - Install InterSystems IRIS server and all language bindings 2) Server only - Install InterSystems IRIS server 3) Custom Setup type ? 1 How restrictive do you want the initial Security settings to be? "Minimal" is the least restrictive, "Locked Down" is the most secure. 1) Minimal 2) Normal 3) Locked Down Initial Security settings ? 2 What user should be the owner of this instance? irisowner An InterSystems IRIS account will also be created for user irisowner. Install will create the following InterSystems IRIS accounts for you: _SYSTEM, Admin, SuperUser, irisowner and CSPSystem. Please enter the common password for _SYSTEM, Admin, SuperUser and irisowner: Re-enter the password to confirm it: Please enter the password for CSPSystem: Re-enter the password to confirm it: What group should be allowed to start and stop this instance? irisowner Do you want to install IRIS Unicode support ? InterSystems IRIS did not detect a license key file Do you want to enter a license key ? Please review the installation options: ------------------------------------------------------------------ Instance name: iris Destination directory: /isc/iris InterSystems IRIS version to install: 2022.1.0.140.0 Installation type: Development Unicode support: Y Initial Security settings: Normal User who owns instance: irisowner Group allowed to start and stop instance: irisowner Effective group for InterSystems IRIS processes: irisusr Effective user for InterSystems IRIS SuperServer: irisusr SuperServer port: 1972 WebServer port: 52773 JDBC Gateway port: 53773 Web Gateway: using built-in web server Not installing IntegratedML ------------------------------------------------------------------ Confirm InterSystems IRIS installation ? Starting installation Starting up InterSystems IRIS for loading... ../bin/irisinstall -s . -B -c c -C /isc/iris/iris.cpf*iris -W 1 -g2 Starting Control Process Allocated 238MB shared memory 32MB global buffers, 80MB routine buffers Creating a WIJ file to hold 32 megabytes of data IRIS startup successful. locale: Cannot set LC_CTYPE to default locale: No such file or directory locale: Cannot set LC_ALL to default locale: No such file or directory System locale setting is 'en_US.UTF-8' This copy of InterSystems IRIS has been licensed for use exclusively by: Local license key file not found. Copyright (c) 1986-2022 by InterSystems Corporation Any other use is a violation of your license agreement ^^/isc/iris/mgr/> ^^/isc/iris/mgr/> Start of IRIS initialization Loading system routines Updating system TEMP and LOCALDATA databases Installing National Language support Setting IRISTEMP default collation to IRIS standard (5) Loading system classes Updating Security database Loading system source code Building system indices Updating Audit database Updating Journal directory Updating User database Updating Interoperability databases Scheduling inventory scan IRIS initialization complete See the iboot.log file for a record of the installation. Starting up InterSystems IRIS... Once this completes, users may access InterSystems IRIS Starting IRIS Using 'iris.cpf' configuration file Starting Control Process Global buffer setting requires attention. Auto-selected 25% of total memory. Allocated 463MB shared memory 243MB global buffers, 80MB routine buffers Creating a WIJ file to hold 99 megabytes of data This copy of InterSystems IRIS has been licensed for use exclusively by: Local license key file not found. Copyright (c) 1986-2022 by InterSystems Corporation Any other use is a violation of your license agreement 1 alert(s) during startup. See messages.log for details. You can point your browser to http://hmsCentOS7:52773/csp/sys/UtilHome.csp to access the management portal. Installation completed successfully [root@hmsCentOS7 IRIS-2022.1.0.140.0-lnxrh7x64]# ``` **执行customer安装IRIS+WebGateway** 如果要在本机安装WebGateway, 需要在执行安装脚本的过程中,当被问到:“Select installation type.”时选择Customer, 而不是Development。这样后面就脚本将在Web Server上加载IRIS专用的动态连接库,并创建和Web Server连接的IRIS Web网关。 在此之前, 您还需要配置安装semanage来保证可以配置SELinux。安装脚本会检查,如果没有发现semanag, 会提示您停止继续安装。 ```sh # 安装semanage, 确认命令可以工作。省略输出 [root@hmsCentOS7 ~]# yum install policycoreutils-devel [root@hmsCentOS7 ~]# yum instll setroubleshoot-server [root@hmsCentOS7 ~]# yum install setroubleshoot-server [root@hmsCentOS7 ~]# semanage -h ... [root@hmsCentOS7 ~]# ``` 假设你已经创建了一个/isc/iris2的目录,然后就可以安装了。注意下面使用的superserver和web端口是51773和52774。这是默认的第2个IRIS实例的端口号,您也可以输入其他端口号或者在安装后在维护页面修改这些端口。 ```sh [root@hmsCentOS7 IRIS-2022.1.0.140.0-lnxrh7x64]# ./irisinstall Your system type is 'Red Hat Enterprise Linux (x64)'. Currently defined instances: IRIS instance 'IRIS' directory: /isc/iris versionid: 2022.1.0.140.0 datadir: /isc/iris conf file: iris.cpf (SuperServer port = 1972, WebServer = 52773) status: down, last used Fri Apr 8 13:32:47 2022 product: InterSystems IRIS Enter instance name: iris2 Do you want to create InterSystems IRIS instance 'iris2' ? Enter a destination directory for the new instance. Directory: /isc/iris2 ------------------------------------------------------------------ NOTE: Users should not attempt to access InterSystems IRIS while the installation is in progress. ------------------------------------------------------------------ Select installation type. 1) Development - Install InterSystems IRIS server and all language bindings 2) Server only - Install InterSystems IRIS server 3) Custom Setup type ? 3 How restrictive do you want the initial Security settings to be? "Minimal" is the least restrictive, "Locked Down" is the most secure. 1) Minimal 2) Normal 3) Locked Down Initial Security settings ? 2 What user should be the owner of this instance? irisowner An InterSystems IRIS account will also be created for user irisowner. Install will create the following InterSystems IRIS accounts for you: _SYSTEM, Admin, SuperUser, irisowner and CSPSystem. Please enter the common password for _SYSTEM, Admin, SuperUser and irisowner: Re-enter the password to confirm it: Please enter the password for CSPSystem: Re-enter the password to confirm it: What group should be allowed to start and stop this instance? irisowner Do you want to configure additional security options ? Do you want to install IRIS Unicode support ? Enter the SuperServer port number : Enter the WebServer port number : Do you want to configure the Web Gateway to use an existing web server ? yes Specify the WebServer type. Choose "None" if you want to configure your WebServer manually. 1) Apache 2) None WebServer type ? 1 Enter user name used by Apache server to run its worker processes : Please enter location of Apache configuration file [/etc/httpd/conf/httpd.conf]: // /etc/httpd/conf.d/isc.conf Please enter location of Apache executable file : Apache version 2.4 is detected. Apache httpd server will be restarted during the install. Please enter destination directory for Web Gateway files [/opt/webgateway]: InterSystems IRIS did not detect a license key file Do you want to enter a license key ? Do you want to install IntegratedML (this feature requires additional 1166MB of disk space) ? Please review the installation options: ------------------------------------------------------------------ Instance name: iris2 Destination directory: /isc/iris2 InterSystems IRIS version to install: 2022.1.0.140.0 Installation type: Custom Unicode support: Y Initial Security settings: Normal User who owns instance: irisowner Group allowed to start and stop instance: irisowner Effective group for InterSystems IRIS processes: irisusr Effective user for InterSystems IRIS SuperServer: irisusr SuperServer port: 51773 WebServer port: 52774 JDBC Gateway port: 53773 Web Gateway: installed into /opt/webgateway Apache web server will be configured for Web Gateway Not installing IntegratedML ------------------------------------------------------------------ Confirm InterSystems IRIS installation ? yes Starting installation Updating Apache configuration file ... - /etc/httpd/conf/httpd.conf Starting up InterSystems IRIS for loading... ../bin/irisinstall -s . -B -c c -C /isc/iris2/iris.cpf*iris2 -W 1 -g2 Starting Control Process Allocated 238MB shared memory 32MB global buffers, 80MB routine buffers Creating a WIJ file to hold 32 megabytes of data IRIS startup successful. locale: Cannot set LC_CTYPE to default locale: No such file or directory locale: Cannot set LC_ALL to default locale: No such file or directory System locale setting is 'en_US.UTF-8' This copy of InterSystems IRIS has been licensed for use exclusively by: Local license key file not found. Copyright (c) 1986-2022 by InterSystems Corporation Any other use is a violation of your license agreement ^^/isc/iris2/mgr/> ^^/isc/iris2/mgr/> Start of IRIS initialization Loading system routines Updating system TEMP and LOCALDATA databases Installing National Language support Setting IRISTEMP default collation to IRIS standard (5) Loading system classes Updating Security database Loading system source code Building system indices Updating Audit database Updating Journal directory Updating User database Updating Interoperability databases Scheduling inventory scan IRIS initialization complete See the iboot.log file for a record of the installation. Starting up InterSystems IRIS... Once this completes, users may access InterSystems IRIS Starting IRIS2 Using 'iris.cpf' configuration file Starting Control Process Global buffer setting requires attention. Auto-selected 25% of total memory. Allocated 463MB shared memory 243MB global buffers, 80MB routine buffers Creating a WIJ file to hold 99 megabytes of data This copy of InterSystems IRIS has been licensed for use exclusively by: Local license key file not found. Copyright (c) 1986-2022 by InterSystems Corporation Any other use is a violation of your license agreement 1 alert(s) during startup. See messages.log for details. You can point your browser to http://hmsCentOS7:52774/csp/sys/UtilHome.csp to access the management portal. Installation completed successfully [root@hmsCentOS7 IRIS-2022.1.0.140.0-lnxrh7x64]# ``` 上面步骤中当提示:”Please enter location of Apache configuration file [/etc/httpd/conf/httpd.conf]: “ 的时候我使用了默认选项/etc/httpd/conf/httpd.conf, IRIS安装脚本回修改httpd.conf文件, 加入连接IRIS的配置。这里更好的做法是先在/etc/httpd/conf.d里创建一个单独的配置文件,比如isc.conf, 在回答上面的提示是输入**/etc/httpd/conf.d/isc.conf**。很遗憾您需要自己手工先创建这个文件,安装脚本不回替您创建。 ### 安装后的检查 **检查安装日志** 查看上面的安装日志,确认没有错误发生。 **查看新创建的用户irisusr和iscagent** ```sh [root@hmsCentOS7 ~]# id irisusr uid=1001(irisusr) gid=1001(irisusr) groups=1001(irisusr) [root@hmsCentOS7 ~]# id iscagent uid=1002(iscagent) gid=1002(iscagent) groups=1002(iscagent) [root@hmsCentOS7 ~]# ``` **查看文件系统权限** ```sh [root@hmsCentOS7 ~]# ls -l /isc total 8 drwxr-xr-x. 2 root root 6 Apr 1 23:57 data drwxrwxr-x. 14 irisowner irisusr 4096 Apr 6 14:28 iris drwxr-xr-x. 3 root root 1024 Apr 1 23:57 jrnpri drwxr-xr-x. 3 root root 1024 Apr 1 23:57 jrnsec [root@hmsCentOS7 ~]# ls -l /isc/iris total 112 -r--r--r--. 1 irisowner irisusr 11358 Apr 6 14:28 LICENSE -r--r--r--. 1 irisowner irisusr 534 Apr 6 14:28 NOTICE -rwxr-xr-x. 1 irisowner irisusr 4497 Mar 7 15:20 ODBCinstall drwxrwxr-x. 2 irisowner irisusr 26 Apr 6 14:27 SNMP -rwxrw-r--. 1 irisusr irisusr 9703 Apr 6 14:28 _LastGood_.cpf drwxr-xr-x. 2 root irisowner 8192 Apr 6 14:28 bin drwxrwxr-x. 7 irisowner irisusr 106 Apr 6 14:27 csp drwxr-xr-x. 17 irisowner irisusr 214 Apr 6 14:28 dev drwxrwxr-x. 3 irisowner irisusr 20 Apr 6 14:28 devuser drwxr-xr-x. 3 root root 21 Apr 6 14:28 dist drwxr-xr-x. 5 irisowner irisusr 156 Apr 6 14:28 docs drwxr-xr-x. 5 irisowner irisusr 68 Apr 6 14:28 fop drwxrwxr-x. 5 irisowner irisusr 41 Apr 6 14:27 httpd -rw-rw-r--. 1 root root 9557 Apr 6 14:28 install.cpf -rw-rw-r--. 1 irisowner irisusr 9732 Apr 6 14:28 iris.cpf -rwxr-xr-x. 1 irisowner irisusr 9557 Apr 6 14:28 iris.cpf_20220406 -r-xr-x---. 4 irisowner irisowner 909 Apr 6 14:28 irisforce -r-xr-x---. 4 irisowner irisowner 909 Apr 6 14:28 irisstart -r-xr-x---. 4 irisowner irisowner 909 Apr 6 14:28 irisstop -r--r--r--. 1 irisowner irisusr 7639 Apr 6 14:28 lgpl.txt drwxr-xr-x. 6 irisowner irisusr 80 Apr 6 14:28 lib drwxrwxr-x. 13 irisowner irisusr 4096 Apr 6 14:28 mgr -rw-------. 1 root root 3299 Apr 6 14:28 parameters.isc drwxr-xr-x. 2 irisowner irisusr 237 Apr 6 14:27 patrol [root@hmsCentOS7 ~]# ls -l /isc/iris/mgr total 163952 -rw-r-----. 1 irisowner irisusr 62914560 Apr 6 14:31 IRIS.DAT -rw-rw----. 1 irisowner irisusr 104857600 Apr 6 14:36 IRIS.WIJ drwxr-xr-x. 2 irisowner irisusr 4096 Apr 6 14:28 Locale -rwxrw-r--. 1 irisusr irisusr 66 Apr 6 14:28 SystemMonitor.log drwxrwxr-x. 2 irisusr irisusr 6 Apr 6 14:28 Temp -rwxrw-r--. 1 irisusr irisusr 134 Apr 6 14:28 alerts.log -rwxrw-r--. 1 irisusr irisusr 13759 Apr 6 14:28 ensinstall.log drwxrwxr-x. 3 irisowner irisusr 36 Apr 6 14:28 enslib -rwxr-xr-x. 1 irisowner irisusr 38319 Apr 6 14:28 iboot.log -rwxrwxrwx. 1 irisowner irisusr 0 Apr 6 14:28 ilock -rw-rw----. 1 irisowner irisusr 10 Apr 6 14:28 iris.ids -rw-rw----. 1 irisowner irisusr 30 Apr 6 14:28 iris.lck -rw-rw-rw-. 1 irisowner irisusr 2 Apr 6 14:28 iris.shid -rw-rw-r--. 1 irisowner irisusr 5 Apr 6 14:28 iris.use drwxrwxr-x. 3 irisowner irisusr 52 Apr 6 14:28 irisaudit drwxrwxr-x. 3 irisowner irisusr 36 Apr 6 14:28 irislib drwxrwxr-x. 3 irisowner irisusr 52 Apr 6 14:28 irislocaldata -rw-rw----. 1 irisowner irisusr 933 Apr 6 14:28 irisodbc.ini drwxrwxr-x. 3 irisowner irisusr 52 Apr 6 14:28 iristemp drwxrwxr-x. 2 irisowner irisusr 42 Apr 6 14:28 journal -rw-rw----. 1 irisowner irisusr 211 Apr 6 14:28 journal.log -rw-rw-r--. 1 irisowner irisusr 14146 Apr 6 14:28 messages.log drwxrwxr-x. 2 irisowner irisusr 6 Apr 6 14:27 python -rw-rw-rw-. 1 irisowner irisusr 55 Apr 6 14:28 startup.last drwxrwxr-x. 2 irisowner irisusr 6 Apr 6 14:28 stream drwxrwxr-x. 3 irisowner irisusr 52 Apr 6 14:28 user [root@hmsCentOS7 ~]# ``` **修改文件系统权限** 将/isc/data, /isc/jrnpri, /isc/jrnsec文件系统的user和group,以及权限修改到下面的样子 ```sh [root@hmsCentOS7 ~]# chown irisowner:irisusr /isc/data /isc/jrnpri /isc/jrnsec [root@hmsCentOS7 ~]# chmod 775 /isc/data /isc/jrnpri /isc/jrnsec [root@hmsCentOS7 ~]# ls -l /isc total 8 drwxrwxr-x. 2 irisowner irisusr 6 Apr 1 23:57 data drwxrwxr-x. 14 irisowner irisusr 4096 Apr 6 14:28 iris drwxrwxr-x. 3 irisowner irisusr 1024 Apr 1 23:57 jrnpri drwxrwxr-x. 3 irisowner irisusr 1024 Apr 1 23:57 jrnsec [root@hmsCentOS7 ~]# ``` **打开防火墙IRIS的TCP端口** IRIS系统使用以下TCP端口: - superserver port: 默认是1972 - web port: 默认是52773 - mirror port: 默认是2188 - license server port: 默认是4001, (很少使用) ```sh [root@hmsCentOS7 iris]# firewall-cmd --permanent --add-port=1972/tcp success [root@hmsCentOS7 iris]# firewall-cmd --permanent --add-port=52773/tcp success [root@hmsCentOS7 iris]# firewall-cmd --permanent --add-port=2188/tcp success [root@hmsCentOS7 iris]# firewall-cmd --list-port 1972/tcp 2188/tcp 52773/tcp [root@hmsCentOS7 iris]# firewall-cmd --reload success [root@hmsCentOS7 iris]# ``` **访问系统管理界面** 通过SMP(System Management Portal)的url, 您可以访问IRIS。 http://host-ipaddr:52773/csp/sys/UtilHome.csp 用户名使用superuser, 密码为您安装创建的密码。 **激活IRIS License** 到管理界面的“系统 > 软件许可颁发 > 软件许可授权码”,加载在本机保存的IRIS许可。 注意弹出窗口的文件选项默认是.key文件。所以您上传文件到Linux服务器前最好把文件改为iris.key。另外,文件和文件夹一定要可以被irisowner访问。如果放在/root文件夹,或者不运行other用户访问,您要么在选文件的窗口无法找到这个文件,要么无法成功激活。 **创建数据库** 到 "系统 > 配置 > 本地数据库"创建数据库。查看在/isc/data里的文件夹和权限。举例:创建demo数据库到/isc/data/demo: ```sh [root@hmsCentOS7 isc]# ls -Rl /isc/data /isc/data: total 0 drwxrwxr-x. 3 irisusr irisusr 52 Apr 6 15:37 demo /isc/data/demo: total 1028 -rw-rw----. 1 irisusr irisusr 1048576 Apr 6 15:38 IRIS.DAT -rw-rw----. 1 irisowner irisusr 30 Apr 6 15:37 iris.lck drwxrwxr-x. 2 irisusr irisusr 6 Apr 6 15:37 stream /isc/data/demo/stream: total 0 [root@hmsCentOS7 isc]# ``` **设置Journal文件夹** 到“系统 > 配置 > Journal 设置”设置journal的主备路径到/isc/jrnprm和/isc/jrnsec。 查看两个路径里的文件权限是660(rw-rw----) ```sh [root@hmsCentOS7 opt]# ls -l /isc/jrnpri total 272 -rw-rw----. 1 irisowner irisusr 262144 Apr 6 15:29 20220406.002 -rw-rw----. 1 irisowner irisusr 30 Apr 6 15:29 iris.lck drwx------. 2 irisowner irisusr 12288 Apr 1 23:57 lost+found [root@hmsCentOS7 opt]# ls -l /isc/jrnsec total 15 -rw-rw----. 1 irisowner irisusr 30 Apr 6 15:29 iris.lck drwx------. 2 irisowner irisusr 12288 Apr 1 23:57 lost+found [root@hmsCentOS7 opt]# ``` **启动ISCAgent** 如果需要配置镜像,服务器需要人工启动ISCAgent ```bash # 启动iscagent服务 systemctl start ISCAgent.service # 设置iscagent systemctl enable ISCAgent.service ``` **SELinux配置**(Optional) 如果您上面执行的是“**执行customer安装以安装WebGateway**”,那么这里您需要配置SELinux。 SELinux会限制httpd对系统其它文件的访问权限,比如说//usr/sbin/httpd无法访问IRIS的WebGateway, 它工作在/opt/webgateway/bin目录。你需要做以下几步来保证SELinux不再限制对IRIS文件的访问: - 允许httpd读写WebGateway文件 ```sh # httpd_sys_content_t – set on directories that Apache is allowed access to, # httpd_sys_rw_content_t – set on directories that Apache is allowed read/write access # httpd_sys_script_exec_t – used for directories that contain executable scripts. [root@hmsCentOS7 conf]# ls -Z /opt/webgateway/conf -rw-------. apache root unconfined_u:object_r:httpd_sys_content_t:s0 CSP.ini -rw-------. apache root unconfined_u:object_r:httpd_sys_content_t:s0 CSPRT.ini [root@hmsCentOS7 conf]# semanage fcontext -a -t httpd_sys_rw_content_t /opt/webgateway/conf/CSP.ini [root@hmsCentOS7 conf]# restorecon -v /opt/webgateway/conf/CSP.ini restorecon reset /opt/webgateway/conf/CSP.ini context unconfined_u:object_r:httpd_sys_content_t:s0->unconfined_u:object_r:httpd_sys_rw_content_t:s0 [root@hmsCentOS7 conf]# semanage fcontext -a -t httpd_sys_rw_content_t /opt/webgateway/conf/CSPRT.ini [root@hmsCentOS7 conf]# restorecon -v /opt/webgateway/conf/CSPRT.ini restorecon reset /opt/webgateway/conf/CSPRT.ini context unconfined_u:object_r:httpd_sys_content_t:s0->unconfined_u:object_r:httpd_sys_rw_content_t:s0 [root@hmsCentOS7 conf]# ls -Z -rw-------. apache root unconfined_u:object_r:httpd_sys_rw_content_t:s0 CSP.ini -rw-------. apache root unconfined_u:object_r:httpd_sys_rw_content_t:s0 CSPRT.ini [root@hmsCentOS7 conf]# [root@hmsCentOS7 webgateway]# semanage fcontext -a -t httpd_sys_rw_content_t /opt/webgateway/logs/CSP.log [root@hmsCentOS7 webgateway]# restorecon -v /opt/webgateway/logs/CSP.log restorecon reset /opt/webgateway/logs/CSP.log context unconfined_u:object_r:httpd_sys_content_t:s0->unconfined_u:object_r:httpd_sys_rw_content_t:s0 [root@hmsCentOS7 webgateway]# ``` - 允许httpd读写IRIS的Web Application文件,假设文件目录是/isc/web, -R是recursively ```sh semanage fcontext -a -t httpd_sys_rw_content_t "/isc/web(/.*)?" restorecon -Rv /isc/web/ ``` - 运行httpd到IRIS的连接, (最新版本也许不需要手工配置了) ```sh # 默认的superserver端口为1972, 上面的iris2使用的是51773 [root@hmsCentOS7 ~]# semanage port -a -t http_port_t -p tcp 51773 ValueError: Port tcp/51773 already defined [root@hmsCentOS7 ~]# semanage port -a -t http_port_t -p tcp 1972 [root@hmsCentOS7 ~]# semanage port -l | grep http_port http_port_t tcp 1972, 51773, 80, 81, 443, 488, 8008, 8009, 8443, 9000 pegasus_http_port_t tcp 5988 [root@hmsCentOS7 ~]# setsebool -P httpd_can_network_connect 1 [root@hmsCentOS7 ~]# ``` 到这里, 您的IRIS安装过程已经结束了。后面的实施工作可能包括: - IRIS配置 - 镜像配置 - WebGateway配置 我会在其他文章中介绍上述内容。 另外, 请注意重启(reboot)在安装过程中十分重要: 通常的情况是,至少有一些配置在第一次重启时并不存在。这可能包括被挂载的卷、/etc/fstab中的错误、启动时不启动的服务、在没有重载服务的情况下进行的配置修改等等。 一旦你认为服务器已经完成,并验证所有的配置都符合预期,而且应用程序仍在工作,那么重新启动服务器是非常明智的。如果不这样做,也不测试集群(例如,一次重启一个节点),可能意味着在第一次重启或HA事件中出现灾难。 *The End*
问题
Weiwei Yang · 一月 25, 2021

docker deploy

生产环境要使用80端口访问服务器,采用直接部署程序的方式,是在Linux服务器上同时部署HealthConnect和Apache。类似的现在想要使用Docker技术,在一台服务器上部署了HealthConnect和Apache容器,该如何配置http.conf文件,使80端口的请求转到HealthConnect上呢?如果这种方式不可行,有没有其他方法呢? 你好, 请参考在Openexchange中发布的例子:Example of InterSystems IRIS with external Apache and WebGateway( https://openexchange.intersystems.com/package/iris-webgateway-example)
问题
Wang li · 三月 30, 2021

HealthShare如何实现socket接口开发

大家好,我想咨询下如何实现用HealthShare开发socket的接口,例如开发socket对外的BS,以及socket调用的BO 您好,InterSystem的产品家族都支持直接使用Socket,借助UDP或TCPIP与第三方通信,参考 TCP:https://docs.intersystems.com/irisforhealthlatest/csp/docbook/Doc.View.cls?KEY=GIOD_tcp UDP:https://docs.intersystems.com/irisforhealthlatest/csp/docbook/DocBook.UI.Page.cls?KEY=GIOD_udp 如果是使用BS或者BO的话,则可以使用IRIS提供的多种适配器按需开发获得,参考 https://docs.intersystems.com/irisforhealthlatest/csp/docbook/Doc.View.cls?KEY=PAGE_interop_protocols 好的,谢谢
文章
姚 鑫 · 七月 8, 2021

第三十一章 检查命名空间和类

# 第三十一章 检查命名空间和类 类`%XML.Namespaces`提供了两个类方法,可用于检查XML命名空间及其包含的类: ## GetNextClass() ```java classmethod GetNextClass(namespace As %String, class As %String) as %String ``` 返回给定`XML`命名空间中给定类之后的下一个类(按字母顺序)。当没有更多的类时,此方法返回`NULL`。 ## GetNextNamespace() ```java classmethod GetNextNamespace(namespace As %String) as %String ``` 返回给定命名空间之后的下一个命名空间(按字母顺序)。当没有更多的命名空间时,此方法返回`NULL`。 在这两种情况下,只考虑当前的InterSystems IRIS命名空间。此外,映射的类也会被忽略。 例如,以下方法列出当前InterSystems IRIS命名空间的XML命名空间及其类: ```java ClassMethod WriteNamespacesAndClasses() { Set ns="" Set ns=##class(%XML.Namespaces).GetNextNamespace(ns) While ns '="" { Write !, "The namespace ",ns, " contains these classes:" Set cls="" Set cls=##class(%XML.Namespaces).GetNextClass(ns,cls) While cls '="" { Write !, " ",cls Set cls=##class(%XML.Namespaces).GetNextClass(ns,cls) } Set ns=##class(%XML.Namespaces).GetNextNamespace(ns) } } ``` 在终端中执行时,此方法会生成如下所示的输出: ```java The namespace http://www.address.org contains these classes: ElRef.NS.Address GXML.AddressNS MyApp4.Obj.Address MyAppNS.AddressNS Obj.Attr.Address Obj.Ns.Address Obj.Ns.AddressClass The namespace http://www.doctor.com contains these classes: GXML.DoctorNS The namespace http://www.one.org contains these classes: GXML.AddressNSOne GXML.DoctorNSOne GXML.PersonNSOne ... ```
文章
Jingwei Wang · 三月 24, 2022

创建REST 服务

REST是一种架构风格,而不是一种格式。尽管REST经常使用HTTP来传输消息,使用JSON来传递数据,但你也可以用XML或纯文本来传递数据。REST利用了现有的网络标准,如HTTP、URL、XML和JSON。 虽然它可以使用XML来描述数据,但它更常使用JSON,这是一个轻量级的数据封装器。 InterSystems REST服务 InterSystems REST服务由以下组件组成: 规范类(%REST.Spec的一个子类):这个类包含了REST服务的OpenAPI 2.0规范(Swagger)。InterSystems支持几个扩展属性,你可以在规范中使用。 调度类(%CSP.REST的一个子类):这个类负责接收HTTP请求并在实现类中调用合适的方法。 实现类(%REST.Impl的子类):这个类定义了实现REST调用的方法。 Web应用程序:它通过InterSystems Web Gateway提供对REST服务的访问。 使用API 管理工具创建REST服务 - 基于 OpenAPI 2.0规范 /api/mgmnt/ 可以使用/api/mgmnt服务来创建、更新和删除REST服务。 使用/api/mgmnt创建 .disp .impl 和 .spec 类 使用http://localhost:52773/api/mgmnt/v2/namespace/myapp 注意: 命名空间必须已经存在,myapp可以自己定义,使用POST。 生成成功消息: { "msg": "New application myapp created" } 创建Web应用程序 名字:/csp/namespace 分派类:myapp.disp 应用角色: %DB_%DEFAULT 补全实现类中的方法 使用^%REST Routine创建REST服务 - 基于 OpenAPI 2.0规范 do ^%REST 使用%REST.API类创建REST服务 - 基于 OpenAPI 2.0规范 可以用它来发现服务器上的REST服务,为这些REST服务生成OpenAPI 2.0规范,并在服务器上创建、更新、或删除REST服务。 使用%REST.API 创建 .disp .impl 和 .spec 类 set file="c:/temp/swagger.json" set obj = ##class(%DynamicAbstractObject).%FromJSON(file) do ##class(%REST.API).CreateApplication("petstore",.obj,,.new,.error) //examine error and decide how to proceed... ... 创建Web应用程序 名字:/csp/namespace 分派类:myapp.disp 应用角色: %DB_%DEFAULT 补全实现类中的方法 基于%CSP.REST 手动创建REST 服务 - 不需要定义OpenAPI 2.0规范 创建REST 分派类,继承 %CSP.REST 类 定义URL map Class REST.Interface.RestHandler Extends %CSP.REST { ​ Parameter CONTENTTYPE = "application/json"; ​ Parameter CONVERTINPUTSTREAM = 1; ​ Parameter CHARSET = "utf-8"; ​ XData UrlMap { <Routes> <Map Prefix="/coffee/sales" Forward="MyLib.coffee.SalesREST"/> <Map Prefix="/coffee/repairs" Forward="MyLib.coffee.RepairsREST"/> <Map Prefix="/coffee" Forward="MyLib.coffee.MiscREST"/> </Routes> } } ​ 创建REST 服务类,继承 %CSP.REST 类 REST 服务类URL map 定义,例如MyLib.coffee.SalesREST类中URL map定义REST 服务类 Class MyLib.coffee.SalesREST Extends %CSP.REST { ​ Parameter HandleCorsRequest = 1; ​ XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ] { <Routes> <Route Url="/request" Method="GET" Call="Request" /> <Route Url="/request" Method="POST" Call="Request" /> </Routes> } ​ /// 根据文档号,输出其HTML格式 /// pDocNo:文档编号 ClassMethod Request() As %Status { #dim tSC As %Status = $$$OK #dim e As %Exception.AbstractException Try { Set tSC = ##class(REST.Util).GetSales(pName) W tSC } Catch (e) { Set tSC=e.AsStatus() } Return tSC } } ​ 创建Web应用程序 名字:/csp/namespace 或其他名字 分派类:REST.Interface.RestHandler 应用角色: %DB_%DEFAULT
文章
姚 鑫 · 一月 18, 2023

第四十九章 使用 ^SystemPerformance 监视性能 - 复制配置文件

# 第四十九章 使用 ^SystemPerformance 监视性能 - 复制配置文件 # 复制配置文件 可以使用以下 `API` 命令将现有配置文件复制到具有不同名称的文件: ```java set rc=$$copyprofile^SystemPerformance("sourceprofilename","targetprofilename") ``` 必须指定: - `sourceprofilename` - 现有配置文件的名称 - `targetprofilename` - 要创建的配置文件的名称。这必须用双引号引起来。 如果成功,该函数返回 `1`。如果不成功,它返回一个 `0` 后跟一个 `carat` 和任何错误的原因。 其中 `sourceprofilename` 是现有配置文件的名称,`targetprofilename` 必须是唯一的并且不能包含空格或空白字符。 例如,要复制 `2minrun` 配置文件,请输入以下内容: ```java set rc=$$copyprofile^SystemPerformance("2minrun","5minrun") ``` 下次运行 `^SystemPerformance` 实用程序时,配置文件列表包括以下配置文件名称和说明: ```java 2minrun A 2-minute run sampling every 30 seconds 5minrun A 2-minute run sampling every 30 seconds ``` 现在可以按照本指南这一部分的编辑配置文件中的说明编辑新配置文件。 # 删除配置文件 可以使用以下 `API` 命令删除现有配置文件(预定义的“测试”配置文件除外): ```java set rc=$$delprofile^SystemPerformance("profilename") ``` - `profilename` - 要删除的配置文件的名称。这必须用双引号引起来。 如果成功,该函数返回 `1`。如果不成功,它返回一个 `0` 后跟一个 `carat` 和任何错误的原因。 例如,要删除 `2minrun` 配置文件,请输入以下内容: ```java set rc=$$delprofile^SystemPerformance("2minrun") ``` 下次运行 `^SystemPerformance` 实用程序时,配置文件列表不包括 `2minrun` 配置文件。 # ^SystemPerformance Utility 创建的性能报告 `^SystemPerformance` 实用程序生成特定于平台的报告,如本章所述。该报告分为几个部分,如下面的清单所示: ```java Configuration IRISTEST3 on machine testsystem Customer: InterSystems Development License : 123456 InterSystems IRIS Version String: InterSystems IRIS for Windows (x86-32) 2018.1 (Build 508) Fri Jan 26 2018 17:51:22 EDT -------------------------------------------------------------- Profile Profile run "test" started at 10:07 on Jun 01 2016. Run over 10 intervals of 30 seconds. -------------------------------------------------------------- license Product=Enterprise License Type=Concurrent User Server=Multi Platform=Heterogeneous Licensed Users=1000 Licensed CPUs=16 . . . -------------------------------------------------------------- End of InterSystems IRIS Performance Data Report ``` 本节中的表格描述了每个特定于平台的报告的部分。这些部分在每个表中按字母顺序列出,以帮助您更轻松地找到特定部分。仅收集一次的数据标有星号 (`*`)。其余数据是在整个配置文件运行过程中收集的。 注意:在以下所有表格中,标有 `*` 的数据每次运行收集一次。
文章
Jingwei Wang · 七月 25, 2022

ESB和注册中心概述

本章介绍了使用InterSystems IRIS作为企业服务总线,描述了InterSystems IRIS ESB架构,并提供了部署ESB的概述。 企业服务总线的概念 企业服务总线(ESB)提供了一个单点来访问和管理具有SOAP、REST或其他网络API的应用程序。ESB提供了以下功能。 提供一个中心来发现和访问服务。 将应用程序与服务隔离开来,允许你在一个地方改变服务的描述,而不需要更新所有依赖它的应用程序。例如,你可以改变服务器的地址,甚至服务的API,并在ESB中处理这些变化。这为你的应用程序提供了协议独立性。如果一个应用程序是使用SOAP API开发的,但一个新的服务用REST API提供了额外的功能,ESB可以使新的REST服务作为REST和SOAP API可用,允许你添加新服务的功能,同时保持对现有应用程序的兼容性。 提供一种机制来组织和跟踪企业使用的应用程序以及这些应用程序之间的依赖关系。。 ESB架构 InterSystems IRIS ESB架构有以下组成部分。 将传入的请求与服务器连接起来的路由机制。这是由具有专门业务服务(BS)和业务操作(BO)的 production实现的,也可以选择业务流程(BP)。 公共服务注册中心--这个服务注册中心可以通过ESB公共REST API被ESB客户访问。开发人员使用它来获取有关通过 ESB 可用的服务的信息。 外部服务注册中心--这个服务注册中心只能在ESB production中访问。它向ESB业务主机提供端点信息。 SAML令牌验证服务。 ESB production和服务注册处都应该被定义在一个专门用于ESB的命名空间中。 注意:InterSystems建议在一个InterSystems IRIS实例上只运行一个ESB production。 在其最简单的形式中,ESB由透传服务、透传操作和服务注册表组成。下面说明了一个简单的ESB的架构。 通常,应用程序开发人员使用网页或应用程序来查询 ESB 服务注册表,以了解可用的服务并获得提供对底层服务的访问的透传业务服务的 URL。这个查询和服务发现过程是在开发者创建客户端应用程序时进行的。一旦开发者拥有了访问服务所需的URL、文档和其它信息,客户端应用程序就不需要为了调用服务而访问服务注册表。在某些环境中,客户端应用程序可能会对公共API进行运行时调用,以确保注册表项在上次访问后没有被修改。 客户机应用程序调用透传服务。透传服务将消息发送到在其目标设置中指定的透传操作。透传操作被配置为在外部服务注册表中查找端点URL。然后,它使用该端点URL调用外部服务。外部服务将响应返回给透传操作,后者将响应指向透传服务。透传服务反过来将响应返回给客户端应用程序。 除了透传服务和操作外,你还可以定义更复杂的服务、操作和业务流程,以增加一些功能,例如,根据呼叫的内容,将呼叫从一个传入的服务路由到多个外部服务。这允许ESB提供一个单一外部服务所不能提供的服务。客户端应用程序与实现扩展服务所需的外部服务隔绝。 修改用于服务的参数或协议。如果一组应用程序是使用一种服务开发的,但后来有了具有不同 API 的高级服务,与其修改每个应用程序,不如在 ESB 中进行转换。客户端应用程序与从一个外部服务转换到另一个服务所需的变化隔绝。直接在ESB上实现服务。如果没有符合需求的外部服务,可以使用ObjectScript在ESB上实现一个。 但是,将这些更复杂的服务添加到 ESB 上有一个效率成本。这些复杂服务的额外处理成本减缓了ESB处理请求的时间,降低了吞吐量。对于需要非常高吞吐量的ESB系统,你可以通过消除持久化消息来减少处理请求的开销。持久性消息是指从透传服务发送到透传操作的对象,以及由操作返回给服务的对象。这些对象被存储在InterSystems IRIS数据库中。这些持久性的消息在跟踪和报告ESB处理的调用以及排除任何问题时非常有用。但创建这些对象需要资源,对于吞吐量非常高的系统,这些对象所需的存储量可能非常大。为了维护系统,你必须经常清除这些信息。你可以抑制对持久化消息的使用,以获得效率,但代价是降低灵活性。更多信息请参见 "在通过式服务和操作中抑制持久化消息"。 注意:如果你正在运行HealthShare产品,HealthShare服务注册表与InterSystems IRIS服务注册表不同。HealthShare服务注册表提供了与InterSystems IRIS外部服务注册表类似的功能。在大多数情况下,你应该继续使用HealthShare服务注册表,而不是使用InterSystems IRIS外部服务注册表。 配置ESB 下面包含安装和配置InterSystems IRIS的几个配置程序: 创建一个具有互操作性的命名空间,以包含ESB production和服务注册。 配置Web网关。 创建外部服务注册表条目,定义ESB所使用的外部服务的端点。 创建 ESB production,添加提供服务的业务服务和业务操作,并启动该 production。 创建通过管理门户和公共 REST API 访问公共服务注册中心所需的角色和用户。 创建将业务服务提供给客户所需的Web应用程序。 创建公共服务注册表条目,描述通过ESB访问的服务。
公告
Claire Zheng · 一月 23, 2022

欢迎中文社区新版主@黎卫东

亲爱的社区开发者们, 我很高兴地向大家介绍一位我们的新版主@黎卫东(Weidong Li)。 @黎卫东(Weidong Li)目前担任上海嘉会国际医院集成平台经理一职 以下是@黎卫东(Weidong Li)的一些自我介绍: – 我从加入嘉会之后开始了解 InterSystems 的技术以及集成平台开发。接触并使用了 InterSystems早期的Caché版本,Cube, Ensemble 并升级到了基于 Iris 的 Health Connect 平台,并深度了解这些版本的一些特性以及基于 Health Connect 打造高效的集成平台。 – 本人有超过16年的医疗信息化经验,熟悉 IHE/DICOM/HL V2/V3,有着丰富的领域知识。曾先后就职于 INFINITT,AGFA, Carestream 等主流的 HIT 公司,设计并开发过多种医疗信息系统及设计的信息集成。在目前医院,带领一个小型的团队,基于 Health Connect,从0开始设计了整个集成平台的底层架构,整体业务流程,开发流程,开发规范,发布部署规范,第三方系统接入,运维部署,运维监控以及安全体系,打造了一个安全、高效、高可用的业务中台,连接了临床、非临床、Iot、智慧医院等多个应用场景。 – InterSystems 平台是一个非常优秀的集成平台,借助该技术,给我们业务带来了非常大的便于。我也希望这么优秀的技术,能给更多的兄弟单位和合作伙伴创造价值。我也希望能够在社区与大家一起交流,分享自己的一些实践经验;同时也希望借助这个平台,向大家学习一些优秀的实践。我们一起成长,共同进步! 热烈欢迎! 感谢@黎卫东(Weidong Li),期待您成为一名优秀的新版主! 👏 Welcome @Weidong.Li ! 热烈欢迎黎老师!
文章
姚 鑫 · 七月 14, 2021

第三章 处理文件和目录名

# 第三章 处理文件和目录名 `%Library.File`类提供了几个可用于处理文件名和目录名的类方法。在大多数情况下,文件和目录不需要存在即可使用这些方法。 ## 获取文件名和目录名 `%Library.File`类提供可用于获取部分文件名和目录名的类方法。 在给定完整路径名的情况下,使用`GetDirectory()`和`GetFilename()`分别获取目录和短文件名。对于此方法,不允许使用部分目录名。 ```java DHC-APP>set filename = "e:\temp\config.txt" DHC-APP>write ##class(%File).GetDirectory(filename) E:\temp\ DHC-APP>write ##class(%File).GetFilename(filename) config.txt ``` 在给定文件名的情况下,使用`CanonicalFilename()`从根目录获取完整路径: ```java DHC-APP>set filename = "cache.dat" DHC-APP>write ##class(%File).CanonicalFilename(filename) e:\dthealth\db\dthis\data\cache.dat DHC-APP>write ##class(%File).CanonicalFilename("foo.dat") ``` 如果文件无法打开,`CanonicalFilename()`方法将返回空字符串。 给定一个目录名,使用`ComputeFullDBDir()`构造目录名的规范形式。 ```java DHC-APP>write ##class(%File).ComputeFullDBDir("foodirectory") C:\InterSystems\Cache\mgr\foodirectory\ ``` 在给定目录名的情况下,使用`GetDirectoryLength()`和`GetDirectoryPiess()`分别获取目录中的片断数和特定片断的片断数。片断可以用斜杠(`/`)或反斜杠(`\`)分隔,具体取决于操作系统。 ```java DHC-APP>set dir = "e:\temp" DHC-APP>write ##class(%File).GetDirectoryLength(dir) 2 DHC-APP>write ##class(%File).GetDirectoryPiece(dir,1) E: ``` 在给定文件名或目录名的情况下,使用`ParentDirectoryName()`获取父目录。 ```java DHC-APP>set dir = "stream" DHC-APP>write ##class(%File).ParentDirectoryName(dir) E:\DtHealth\db\dthis\data\ ```` ## 规范化文件名和目录名 `%Library.File`类提供返回规范化文件名和目录名的类方法(遵循运行服务器的操作系统的命名规则)。当通过将名称片段附加到现有名称来创建新的文件名和目录名时,这些选项非常有用。 给定一个文件名,`NormalizeFilename()`返回规范化的文件名. 给定目录名,`NormalizeDirectory()`返回规范化的目录名。 这些方法返回适合在底层操作系统上使用的规范化名称,并将尝试标准化斜杠(`/`)或反斜杠(`\`)路径分隔符。 Windows示例: ```java DHC-APP>write ##class(%File).NormalizeDirectory("stream") E:\DtHealth\db\dthis\data\stream\ DHC-APP>write ##class(%File).NormalizeFilename("c:\temp//config.txt") C:\temp\config.txt ``` UNIX示例: ```java USER>set filename = "/tmp//samples/myfile.txt" USER>write ##class(%File).NormalizeFilename(filename) /tmp/samples/myfile.txt USER>write ##class(%File).NormalizeDirectory("stream") /InterSystems/IRIS/mgr/user/stream/ ``` 在调用这些方法之一以规范化相对于指定目录的目录名或文件名时,请添加第二个参数。该目录必须存在。 Windows示例: ```java DHC-APP>write ##class(%File).NormalizeFilename("config.txt", "e:\temp") E:\temp\config.txt DHC-APP>write ##class(%File).NormalizeDirectory("stream", "") E:\DtHealth\db\dthis\data\stream\ ``` Unix示例: ```java USER>write ##class(%File).NormalizeFilename("myfile.txt", "/tmp/samples") /tmp/samples/myfile.txt USER>write ##class(%File).NormalizeDirectory("stream", "") /InterSystems/IRIS/mgr/user/stream/ ``` `SubDirectoryName()`方法类似于`NormalizeDirectory()`的双参数形式,只是参数的顺序相反。此外,该目录不需要存在。在第三个参数中传递1以添加尾部分隔符,或者传递0以省略它(默认值)。 Windows示例: ```java DHC-APP>write ##class(%File).SubDirectoryName("C:\foobar", "samples") C:\foobar\samples DHC-APP>write ##class(%File).SubDirectoryName("", "stream", 1) E:\DtHealth\db\dthis\data\stream\ ``` Unix示例: ```java USER>write ##class(%File).SubDirectoryName("/foobar", "samples") /foobar/samples USER>write ##class(%File).SubDirectoryName("", "stream", 1) /InterSystems/IRIS/mgr/user/stream/ ``` ## 用空格处理文件和目录名 对于包含空格的文件名和目录名,请使用`NormalizeFilenameWithSpaces()`,它会根据主机平台处理路径名中的空格。与规格化文件名()和规格化目录()不同,此方法只接受一个参数,不能相对于另一个目录规格化文件或目录名,也不能相对于默认目录规格化部分文件或目录名。 在Windows系统上,如果路径名包含空格,并且文件或目录不存在,则该方法返回用双引号括起来的路径名。如果路径名包含空格,并且文件或目录确实存在,则该方法返回路径名的简短形式。如果路径名不包含空格,该方法将原封不动地返回路径名。 ```java DHC-APP>write ##class(%File).NormalizeFilenameWithSpaces("C:\temp\nonexistant folder") "C:\temp\nonexistant folder" DHC-APP>write ##class(%File).NormalizeFilenameWithSpaces("C:\temp\existant folder") "C:\temp\existant folder" DHC-APP>write ##class(%File).NormalizeFilenameWithSpaces("iris.dat") iris.dat DHC-APP>write ##class(%File).NormalizeFilenameWithSpaces("cache.dat") cache.dat ``` 在Unix系统上,如果路径名包含空格,该方法将返回用双引号括起来的路径名。如果路径名不包含空格,该方法将原封不动地返回路径名。 ```java USER>write ##class(%File).NormalizeFilenameWithSpaces("/InterSystems/my directory") "/InterSystems/my directory" USER>write ##class(%File).NormalizeFilenameWithSpaces("iris.dat") iris.dat ``` ## 构建和解构文件和目录名 `%Library.File`类提供的类方法允许从路径数组构造文件名,或将文件名解构为路径数组。 给定一个路径数组,`Construct()`组装路径并返回文件名。构造的文件名适合服务器平台。在没有参数的情况下调用此方法会返回默认目录。 给定一个文件名,`Deconstruct()`分解文件名并返回一个路径数组。阵列的内容适合服务器平台。 下面的Windows示例将数组目录传递给`Construction()`。最后一个数组位置中的空字符串表示返回的文件名应以`a \`结尾。 ```java USER>zwrite dirs dirs=4 dirs(1)="C:" dirs(2)="Temp" dirs(3)="samples" dirs(4)="" USER>write ##class(%File).Construct(dirs...) C:\Temp\samples\ ``` 下面的Unix示例在不带参数的情况下调用`Construction()`。该方法返回默认目录。 ```java USER>set default = ##class(%File).Construct() USER>write default /InterSystems/IRIS/mgr/user ``` 下面的Unix示例调用`Deconstruct()`,它获取变量default中的路径并将它们存储在数组`defaultdir`中。 ```java USER>do ##class(%File).Deconstruct(default, .defaultdir) USER>zwrite defaultdir defaultdir=4 defaultdir(1)="InterSystems" defaultdir(2)="IRIS" defaultdir(3)="mgr" defaultdir(4)="user" ``` ## 获取System Manager目录 使用`ManagerDirectory()`方法获取`installdir/mgr`目录的完全限定名称。例如: ```java DHC-APP>write ##class(%File).ManagerDirectory() C:\InterSystems\Cache\mgr\ ```
文章
姚 鑫 · 三月 4, 2021

第三章 SQL语言元素(二)

# 第三章 SQL语言元素(二) # 算术运算符和函数 InterSystems SQL支持以下算术运算符: - `+` 加法操作符。 例如,`17+7 = 24`。 - `–` 减法运算符。 例如,`17-7等于10`。 注意,这些字符中的一对是InterSystems SQL注释指示器。 因此,要指定两个或多个减法操作符或负号,必须使用空格或圆括号。 例如,`17- -7或17-(-7)等于24`。 运算符 | 描述 ---|--- `+` | 加法操作符。 `–` | 减法运算符。例如,`17-7等于10`。注意,这些字符中的一对是InterSystems SQL注释指示器。因此,要指定两个或多个减法操作符或负号,必须使用空格或圆括号。 `*` |乘法运算符。例如,`17*7等于119`。 `/` | 除法操作符。例如:`17/7 = 2.428571428571428571`。 `\` | 整数除法运算符。例如,`17\7等于2`。 `#` | 模运算符。例如,`17 #7等于3`。注意,因为#字符也是一个有效的标识符字符,要将它用作模运算符,应该指定它与操作数之间用前后空格分隔 `E` | 求幂(科学记数法)运算符。可以是大写或小写。例如:`7E3 = 7000`。指数过大会导致`SQLCODE -7`“指数超出范围”错误。例如1E309、7E308。 `()`| 分组操作符。用于嵌套算术运算。除非使用了圆括号,否则在InterSystems SQL中算术操作的执行顺序是严格的从左到右的顺序。例如,`17+7*2等于48`,但`17+(7 * 2)等于31`。 `||` | 连接运算符。例如,`17||7等于177`。 算术运算是对标准形式的数字进行的。 ## 产生的数据类型 当对两个具有不同数据类型的数值执行算术运算时,结果数据类型确定如下: 对于加法(`+`),减法(`-`),整数除法(`\`),和取模(`#`): 描述 |NUMERIC| INTEGER| TINYINT| SMALLINT| BIGINT| DOUBLE ---|---|---|---|---|---|--- NUMERIC| NUMERIC| NUMERIC| NUMERIC |NUMERIC| NUMERIC |DOUBLE INTEGER |NUMERIC| BIGINT |BIGINT| BIGINT| BIGINT| DOUBLE TINYINT |NUMERIC| BIGINT| SMALLINT| INTEGER |BIGINT| DOUBLE SMALLINT| NUMERIC |BIGINT| INTEGER| INTEGER |BIGINT| DOUBLE BIGINT| NUMERIC| BIGINT| BIGINT| BIGINT| BIGINT| DOUBLE DOUBLE| DOUBLE| DOUBLE| DOUBLE| DOUBLE |DOUBLE |DOUBLE 对于乘法(`*`)或除法(`/`): 描述 |NUMERIC| INTEGER| TINYINT| SMALLINT| BIGINT| DOUBLE ---|---|---|---|---|---|--- NUMERIC| NUMERIC| NUMERIC| NUMERIC| NUMERIC| NUMERIC| DOUBLE INTEGER| NUMERIC| NUMERIC| NUMERIC| NUMERIC| NUMERIC| DOUBLE TINYINT| NUMERIC| NUMERIC| NUMERIC| NUMERIC| NUMERIC| DOUBLE SMALLINT| NUMERIC| NUMERIC| NUMERIC| NUMERIC| NUMERIC| DOUBLE BIGINT| NUMERIC| NUMERIC| NUMERIC| NUMERIC| NUMERIC| DOUBLE DOUBLE| DOUBLE| DOUBLE| DOUBLE| DOUBLE| DOUBLE |DOUBLE 连接任意数据类型的两个数字将产生VARCHAR字符串。 在动态SQL中,可以使用SQL列元数据来确定结果集字段的数据类型。 ## 运算符优先级 SQL-92标准在操作符优先级方面不精确; 关于这个问题的假设在不同的SQL实现中有所不同。 InterSystems SQL可以配置为支持任意一种优先级: - 在InterSystems IRIS 2019.1及其后续版本中,InterSystems SQL默认支持算术运算符的ANSI优先级。 这是一个系统范围的配置设置。 当配置ANSI优先级时,`"*"`、`"\"`、`"/"`和`"#"`操作符的优先级高于`"+"`、`"-"`和`"||"`操作符。 优先级高的操作符在优先级低的操作符之前执行。 因此,`3+3*5 = 18`。 如果需要,可以使用括号覆盖优先级。 因此,`(3+3)*5 = 30`。 在安装InterSystems IRIS 2019.1时,支持默认的ANSI优先级; 升级InterSystems IRIS 2018.1到InterSystems IRIS 2019.1时,操作符优先级仍然配置为InterSystems IRIS 2018.1 default:严格从左到右的顺序。 - 在InterSystems IRIS 2018.1中,InterSystems SQL默认不提供算术运算符的优先级。 默认情况下,InterSystems SQL严格按照从左到右的顺序执行算术表达式,没有操作符优先级。 这与ObjectScript中使用的约定相同。 因此,`3+3*5 = 30`。 可以使用括号来强制要求的优先级。 因此,`3+(3*5)= 18`。 谨慎的开发人员应该使用圆括号来明确地表达他们的意图。 **可以使用`$SYSTEM.SQL.SetANSIPrecedence()`方法在系统范围内配置任意一种SQL操作符优先级。 `1 = ANSI优先`; `0 =严格从左到右的计算`。** 要确定当前设置,调用`$SYSTEM.SQL.CurrentSettings()`。 更改此SQL选项将立即在系统范围内生效。 更改此选项将导致在系统范围内清除所有缓存的查询。 更改SQL优先级对ObjectScript没有影响。 ObjectScript总是严格遵循从左到右的算术运算符执行。 ## 精度和等级 数字结果的精度(数字中存在的最大数字数)为: - 使用以下算法确定加减:`resultprecision=max(scale1, scale2)+ max(precision1-scale1, precision2-scale2)+1`。 当计算结果精度大于36时,将精度值设置为36。 - 乘法使用以下算法确定:`resultprecision=min(36, precision1+precision2+1)`。 - 除法(value1 / value2)通过以下算法确定:`resultprecision=min(36, precision1-scale1 +scale2+max(6, scale1+precision2+1))`。 以下数字结果的比例(最大小数位数): - 加法或减法使用以下算法确定:`resultscale=max(scale1, scale2)`。 - 乘法使用如下算法确定:`resultscale=min(17, scale1+scale2)`。 - 除法(value1 / value2)通过如下算法确定:`resultscale=min(17, max(6, scale1+precision2+1))`。 ## 算术和三角函数 InterSystems SQL支持以下算术函数: 代码 | 描述 ---|--- ABS |返回数字表达式的绝对值。 CEILING|返回大于或等于数字表达式的最小整数。 EXP| 返回数值表达式的对数指数(以e为底)值。 FLOOR| 返回小于或等于数字表达式的最大整数。 GREATEST| 从逗号分隔的数字列表中返回最大的数字。 ISNUMERIC| 返回一个布尔码,指定表达式是否为有效数字。 LEAST| 从逗号分隔的数字列表中返回最小的数字。 LOG|返回数字表达式的自然对数(以e为基数)值。 LOG10| 返回数字表达式的以10为基数的日志值。 MOD| 返回除法运算的模值(余数)。与#操作符相同。 PI| 返回数值常量pi。 POWER| 返回数值表达式的指定幂的值 ROUND| 返回四舍五入(或截断)到指定数字数目的数字表达式。 SIGN|返回数值代码,指定数值表达式的计算结果是正、零还是负。 SQRT| 返回数值表达式的平方根。 SQUARE| 返回数值表达式的平方。 TRUNCATE|返回截断为指定数字数目的数字表达式。 InterSystems SQL支持下列三角函数。 代码 | 描述 ---|--- ACOS| 返回数值表达式的反余弦值。 ASIN| 返回数字表达式的反正弦值。 ATAN| 返回数值表达式的正切。 COS |返回数值表达式的余弦值。 COT |返回数值表达式的余切。 SIN |返回数值表达式的正弦值。 TAN |返回数值表达式的切线。 DEGREES| 将弧度转换为角度。 RADIANS |将角度转换为弧度。 # 关系运算符 条件表达式的计算结果为布尔值。条件表达式可以使用以下关系运算符: 代码 | 描述 ---|--- `=`| 等于运算符。 `!=` ``|不等于运算符。这两种句法形式在功能上是相同的。 ``| 大于运算符。 `=`| 大于或等于运算符。 比较表格字段值时,这些相等运算符将使用字段的默认排序规则。 InterSystems IRIS默认值不区分大小写。比较两个文字时,比较区分大小写。 比较浮点数时,应避免使用等号运算符(等于或不等于)。浮点数(数据类型为`%Library.Decimal`和`%Library.Double`类)存储为二进制值,而不是固定精度的数字。在转换过程中,舍入运算可能会导致两个浮点数不完全相等,这些浮点数旨在表示相同的数字。使用小于/大于测试来确定两个浮点数是否“相同”至所需的精度。 ## 包含并跟随运算符 InterSystems SQL还支持“包含”和“跟随”比较运算符: - `[` 包含运算符。返回包含操作数的所有值,包括等于该操作数的值。该运算符使用`EXACT`(区分大小写)排序规则。取反是`NOT [`。 - `Contains`运算符确定一个值是否包含指定的字符或字符串。区分大小写。 - `%STARTWITH`谓词条件确定值是否以指定的字符或字符串开头。它不区分大小写。 - InterSystems SQL搜索可用于确定值是否包含指定的单词或短语。 SQL Search执行上下文感知匹配。它不区分大小写。 - `]` 跟随运算符。返回排序规则序列中跟随操作数的所有值。排除操作数值本身。该运算符使用字段的默认排序规则。 InterSystems IRIS默认值不区分大小写。反之则不是`]`。 例如,`SELECT Age FROM MyTable,其中Age] 88`返回89或更大的值,但也返回9,因为在排序序列中9在88之后。 `SELECT Age FROM MyTable WHERE Age > 88`返回89以上; 它不会返回9。 字符串操作数,如`' ABC '`,排序在任何包含附加字符的字符串(如`' ABCA '`)之前; 因此,要从`[`操作符或`>`操作符中排除操作数字符串,必须指定整个字符串。 `Name ] ‘Smith,John’ `包含 `‘Smith,John’` 不包含 `‘Smith,John P.’` # 逻辑运算符 SQL逻辑运算符用于评估为True或False的条件表达式中。这些条件表达式在`SELECT`语句`WHERE`和`HAVING`子句,`CASE`语句`WHEN`子句,`JOIN`语句`ON`子句和`CREATE TRIGGER`语句`WHEN`子句中使用。 ## 非一元运算符 可以使用`NOT`一元逻辑运算符来指定条件的逻辑逆,如以下示例所示: ```sql SELECT Name,Age FROM Sample.Person WHERE NOT Age>21 ORDER BY Age ``` ```sql SELECT Name,Age FROM Sample.Person WHERE NOT Name %STARTSWITH('A') ORDER BY Name ``` 可以将`NOT`运算符放在条件之前(如上所示)。或者,不能将`NOT`放在单字符运算符之前;例如,`NOT =65 ORDER BY Age ``` ```sql SELECT Name,Age FROM Sample.Person WHERE Age>20 & Age=40 & (Age # 2)=0 ! Age>=65 ORDER BY Age ``` 可以使用括号将逻辑运算符分组。这将建立分组级别;评估从最低的分组级别到最高的分组级别进行。在下面的第一个示例中,“与”条件仅应用于第二个“或”条件。它返回来自MA的任何年龄的人,以及来自NY的小于25岁的人: ```sql SELECT Name,Age,Home_State FROM Sample.Person WHERE Home_State='MA' OR Home_State='NY' AND Age < 25 ORDER BY Age ``` 使用括号对条件进行分组会得出不同的结果。以下示例返回来自MA或NY的年龄小于25的人员: ```sql SELECT Name,Age,Home_State FROM Sample.Person WHERE (Home_State='MA' OR Home_State='NY') AND Age < 25 ORDER BY Age ``` - SQL执行使用短路逻辑。如果条件失败,将不会测试其余的`AND`条件。如果条件成功,则将不会测试其余的`OR`条件。 - 但是,由于SQL优化了`WHERE`子句执行,因此无法预测并且不应该依赖多个条件(在同一分组级别)的执行顺序。 # 注释 InterSystems SQL支持单行注释和多行注释。注释文本可以包含任何字符或字符串,当然,指示注释结尾的字符除外。 注意:使用嵌入式SQL标记语法`(&sql(...))` 对SQL注释的内容强加了限制。如果使用标记语法,则SQL代码中的注释可能不包含字符序列“)``”。 可以使用`preparse()`方法返回去除注释的SQL DML语句。 `preparse()`方法还用`?`替换每个查询参数。字符并返回这些参数的`%List`结构。以下示例中的`preparse()`方法返回查询的解析版本,除去单行和多行注释以及空格: ```sql /// d ##class(PHA.TEST.SQL).Null5() ClassMethod Null5() { SET myq=4 SET myq(1)="SELECT TOP ? Name /* first name */, Age " SET myq(2)=" FROM Sample.MyTable -- this is the FROM clause" SET myq(3)=" WHERE /* various conditions " SET myq(4)="apply */ Name='Fred' AND Age > 21 -- end of query" DO ##class(%SQL.Statement).preparse(.myq,.stripped,.args) WRITE stripped,! WRITE $LISTTOSTRING(args) } ``` ```sql DHC-APP>d ##class(PHA.TEST.SQL).Null5() SELECT TOP ? Name , Age FROM Sample . MyTable WHERE Name = ? AND Age > ? ?,?,c,Fred,c,21 ``` ## 单行注释 单行注释由两个连字符前缀指定。注释可以在单独的行上,也可以与SQL代码显示在同一行上。当注释在同一行上跟随SQL代码时,至少一个空格必须将代码与双连字符注释运算符分隔开。注释可以包含任何字符,包括连字符,星号和斜杠。注释继续到该行的末尾。 下面的示例包含多个单行注释: ```sql -- This is a simple SQL query -- containing -- (double hyphen) comments SELECT TOP 10 Name,Age, -- Two columns selected Home_State -- A third column FROM Sample.Person -- Table name -- Other clauses follow WHERE Age > 20 AND -- Comment within a clause Age < 40 ORDER BY Age, -- Comment within a clause Home_State -- End of query ``` ## 多行注释 多行注释由`/ * 开头定界符和 * /`结束定界符指定。注释可以出现在一个或多个单独的行上,或者可以与SQL代码在同一行上开始或结束。注释定界符应与SQL代码分隔至少一个空格。注释可以包含任何字符,包括连字符,星号和斜杠,但* /字符对显然是例外。 下面的示例包含多个多行注释: ```sql /* This is a simple SQL query. */ SELECT TOP 10 Name,Age /* Two fields selected */ FROM Sample.Person /* Other clauses could appear here */ ORDER BY Age /* End of query */ ``` 当注释掉嵌入式SQL代码时,请始终在`&sql`指令之前或括号内开始注释。下面的示例正确注释掉了两个嵌入式SQL代码块: ```sql SET a="default name",b="default age" WRITE "(not) Invoking Embedded SQL",! /*&sql(SELECT Name INTO :a FROM Sample.Person) */ WRITE "The name is ",a,! WRITE "Invoking Embedded SQL (as a no-op)",! &sql(/* SELECT Age INTO :b FROM Sample.Person */) WRITE "The age is ",b ``` ## SQL代码保留为注释 嵌入式SQL语句可以保留为例程的.INT代码版本中的注释。这是通过设置`$SYSTEM.SQL.SetRetainSQL()`方法完成的。若要确定当前设置,请调用`$ SYSTEM.SQL.CurrentSettings()`,它将显示“将SQL保留为注释”设置。默认值为1(“是”)。 将此选项设置为“是”以将SQL语句保留为例程的.INT代码版本中的注释。将此选项设置为“是”还会在注释文本中列出SQL语句使用的所有非%变量。这些列出的变量也应该在ObjectScript过程的PUBLIC变量列表中列出,并使用NEW命令重新初始化。 有用 欢迎来投票:) 讲的很细,非常有帮助! 非常不错的学习资料,十分感谢! 技术博主👍
文章
姚 鑫 · 五月 8, 2021

第三章 使用多维存储(全局变量)(四)

# 第三章 使用多维存储(全局变量)(四) # 管理事务 InterSystems IRIS提供了使用全局变量实现完整事务处理所需的基本操作。 InterSystems IRIS对象和SQL自动利用这些特性。 如果直接将事务性数据写入全局变量,则可以使用这些操作。 事务命令是`TSTART`,它定义事务的开始; `TCOMMIT`,它提交当前事务; 和`TROLLBACK`,它将中止当前事务,并撤消自事务开始以来对全局变量所做的任何更改。 例如,下面的ObjectScript代码定义了事务的开始,设置了一些全局变量节点,然后根据`ok`的值提交或回滚事务: ```java /// w ##class(PHA.TEST.Global).GlobalTro(0) ClassMethod GlobalTro(ok) { TSTART Set ^Data(1) = "Apple1" Set ^Data(2) = "Berry1" If (ok) { TCOMMIT } Else { TROLLBACK } zw ^Data q "" } ``` TSTART在InterSystems IRIS日志文件中写入事务开始标记。 这定义了事务的起始边界。 在上面的示例中,如果变量`ok`为`true`(非零),则`TCOMMIT`命令标记事务成功结束,并将事务完成标记写入日志文件。 如果`ok`为`false(0)`,那么`TROLLBACK`命令将撤消自事务开始以来进行的每一个`set`或`kill`操作。 在这种情况下,`^Data(1)`和`^Data(2)`被恢复到原来的值。 **注意,在事务成功完成时,不会写入任何数据。 这是因为事务期间对数据库的所有修改都是在事务过程中正常执行的。 只有在回滚的情况下,数据库中的数据才会受到影响。 这意味着本例中的事务具有有限的隔离性; 也就是说,其他进程可以在事务提交之前看到修改后的全局值。 这通常被称为未提交的读取。 这是好是坏取决于应用程序的需求; 在许多情况下,这是完全合理的行为。 如果应用程序需要更高级别的隔离,则可以通过使用锁来实现。 这将在下一节中进行描述。** ## 锁和事务 要创建隔离事务-也就是说,为了防止其他进程在提交事务之前看到修改的数据-需要使用锁。在ObjectScript中,可以通过`lock`命令直接获取和释放锁定。锁按照约定工作;对于给定的数据结构(如用于持久对象),所有需要锁的代码都使用相同的逻辑锁引用(即,锁命令使用相同的地址)。 在事务中,锁有一个特殊的行为; 在事务过程中获取的任何锁在事务结束之前都不会被释放。 要了解为什么会这样,请考虑典型事务执行的操作: 1. 使用`TSTART`启动事务。 2. 获取要修改的一个或多个节点上的锁。这通常被称为“写”锁。 3. 修改一个或多个节点。 4. 释放锁(或多个锁)。因为我们处于事务中,所以这些锁在此时实际上不会被释放。 5. 使用`TCOMMIT`提交事务。此时,上一步中释放的所有锁实际上都已释放。 如果另一个进程想要查看此事务中涉及的节点,并且不想看到未提交的修改,则它只需在从节点读取数据之前测试锁(称为“读”锁)。因为写锁定一直保持到事务结束,所以在事务完成(提交或回滚)之前,读取进程看不到数据。 大多数数据库管理系统使用类似的机制来提供事务隔离。InterSystems IRIS的独特之处在于它让开发人员可以使用这种机制。这使得有可能为新的应用程序类型创建自定义数据库结构,同时仍然支持事务。当然,可以简单地使用InterSystems IRIS对象或SQL来管理数据,并让事务得到自动管理。 ## 对TSTART的嵌套调用 InterSystems IRIS维护一个特殊的系统变量`$TLEVEL`,该变量跟踪`TSTART`命令被调用的次数。`$TLEVEL`从值`0`开始;每次调用`TSTART`时,`$TLEVEL`的值递增`1`,而每次调用`TCOMMIT`时,`$TLEVEL`的值递减`1`。如果调用`TCOMMIT`导致将`$TLEVEL`设置回`0`,则事务结束(以`COMMIT`结束)。 调用`TROLLBACK`命令总是终止当前事务,并将`$TLEVEL`设置回`0`,而不管`$TLEVEL`的值是多少。 此行为使应用程序能够将事务包装在本身包含事务的代码(如对象方法)周围。例如,持久对象提供的`%Save`方法始终将其操作作为事务执行。通过显式调用`TSTART`和`TCOMMIT`,可以创建包含几个对象保存操作的更大事务: ```java TSTART Set sc = object1.%Save() If ($$$ISOK(sc)) { // 第一次保存有效,执行第二次保存 Set sc = object2.%Save() } If ($$$ISERR(sc)) { // 其中一个保存失败,正在回滚 TROLLBACK } Else { // 提交 TCOMMIT } ``` # 管理并发性 设置或检索单个全局变量节点的操作是原子的;它可以保证始终成功并获得一致的结果。对于多个节点上的操作或控制事务隔离,InterSystems IRIS提供获取和释放锁的功能。 锁由IRIS锁管理器管理。在ObjectScript中,可以通过`lock`命令直接获取和释放锁定。(InterSystems IRIS对象和SQL根据需要自动获取和释放锁)。 # 检查最新的全局变量引用 **最新的全局变量引用记录在ObjectScript `$ZREFERENCE`特殊变量中。`$ZREFERENCE`包含最新的全局引用,包括下标和扩展全局引用(如果指定)。请注意,`$ZREFERENCE`既不指示全局引用是否成功,也不指示指定的全局是否存在。InterSystems IRIS只记录最近指定的全局引用。** ## 裸全球变量引用 在带下标的全局引用之后,InterSystems IRIS会将裸指示符设置为该全局名称和下标级别。然后,可以使用裸全局引用(省略全局名称和更高级别的下标)对相同的全局变量和下标级别进行后续引用。这简化了在相同(或更低)下标级别对相同全局变量的重复引用。 在裸引用中指定较低的下标级别会将裸指示符重置为该下标级别。因此,在使用裸全局变量引用时,始终使用由最新全局引用建立的下标级别。 裸指示符值记录在`$ZREFERENCE`特殊变量中。裸露指示符被初始化为空字符串。在未设置裸指示器的情况下尝试裸全局引用会导致`` 错误。更改命名空间会重新初始化裸体指示符。可以通过将`$ZREFERENCE`设置为空字符串(`“”`)来重新初始化裸指示符。 在下面的示例中,第一个引用中指定了带下标的GLOBAL `^Produce(“fruit”,1)`。InterSystems IRIS将此全局变量名称和下标保存在裸体指示符中,以便后续的裸体全局引用可以省略全局名称`“Production”`和更高下标级别的`“Fruit”`。当`^(3,1)`裸引用达到更低的下标级别时,此新的下标级别将成为任何后续裸全局变引用的假设。 ```java /// w ##class(PHA.TEST.Global).GlobalNake() ClassMethod GlobalNake() { SET ^Produce("fruit",1)="Apples" /* 完整的全局变量引用 */ SET ^(2)="Oranges" /* 裸全局变量全局引用 */ SET ^(3)="Pears" /* 假设下标级别为2 */ SET ^(3,1)="Bartlett pears" /* 转到下标级别3 */ SET ^(2)="Anjou pears" /* 假设下标级别为3 */ WRITE "latest global reference is: ",$ZREFERENCE,! ZWRITE ^Produce KILL ^Produce q "" } ``` ```java DHC-APP>w ##class(PHA.TEST.Global).GlobalNake() latest global reference is: ^Produce("fruit",3,2) ^Produce("fruit",1)="Apples" ^Produce("fruit",2)="Oranges" ^Produce("fruit",3)="Pears" ^Produce("fruit",3,1)="Bartlett pears" ^Produce("fruit",3,2)="Anjou pears" ``` 除了极少数例外,每个全局变量变引用(全引用或裸引用)都会设置裸指示器。`$ZREFERENCE`特殊变量包含最新全局变引用的完整全局名称和下标,即使这是一个裸全局引用。`ZWRITE`命令还显示每个全局的完整全局名称和下标,无论它是否使用裸引用设置。 应谨慎使用裸全局变量引用,因为InterSystems IRIS在不总是明显的情况下设置裸指示器,包括以下情况: - 完整全局变量引用最初设置裸露指示符,随后的完整全局引用或裸露全局引用会更改裸露指示符,即使全局引用不成功。例如,试图写入不存在的全局变量的值会设置裸指示符。 - 无论InterSystems IRIS如何计算后置条件,引用下标全局的后置条件命令都会设置裸指示符。 - 引用下标全局变量的可选函数参数可能设置或不设置裸指示符,具体取决于IRIS是否计算所有参数。例如,`$get`的第二个参数总是设置裸指示符,即使它包含的默认值没有使用。InterSystems IRIS按从左到右的顺序计算参数,因此最后一个参数可能会重置由第一个参数设置的裸指示符。 - 回滚事务的`TROLLBACK`命令不会将裸指示符回滚到事务开始时的值。 如果完整全局变量引用包含扩展全局变量引用,则后续的裸全局变量引用将采用相同的扩展全局引用;不必将扩展引用指定为裸全局引用的一部分。
问题
Botai Zhang · 四月 13, 2021

编码格式转换

在使用过程中,碰到对接一些国内编码例如:GBK2312等系列的编码格式,碰到这类情况,应该如何处理?各位有没有好的解决方式?期待解答交流! 如果需要在InterSystems IRIS中对不同的编码的数据进行转换,可以使用函数$ZCVT。 例如将变量tStr的unicode值转换为GB2312: s tOutput=$ZCVT(tStr,"O","GB2312") 感谢回复!这种方式尝试过,但是,$ZCVT并不支持GB2312。 用GB18030,它向后兼容GB2312
公告
Michael Lei · 六月 22, 2022

CloudStudio - 一个纯浏览器的代码编辑器

Hi 社区, 这是海外工程师做的一个纯浏览器的代码编辑器CloudStudio. 欢迎大家下载试用: GitHub 下载: https://github.com/SeanConnelly/CloudStudio InterSystems 应用市场下载:https://openexchange.intersystems.com/package/CloudStudio 到Discord 讨论区:https://discord.gg/ZnvdMywsjP Docker 支持与在线Demo: 要求 已安装 git 和 Docker desktop . 安装 Clone/git 把 repo 导入任何本地目录 git https://github.com/rcemper/Dataset-OEX-reviews.git 启动IRIS容器: docker-compose up -d --build 如何测试 http://localhost:42773/cloudstudio/CloudStudio.Index.cls 或使用在线Demo Demo 视频:https://www.youtube.com/watch?v=Am6QAvrPPPg
公告
Claire Zheng · 十一月 22, 2021

参与Gartner Peer Insights同业评审,赢取价值$25的礼品卡

亲爱的社区开发者们,大家好! 现在参与Gartner Peer Insight同业评审对我们的产品做出评价,可获得价值 $25 美元的礼品卡。评论观点需中立客观(InterSystems员工不允许参加)并被Gartner审核通过。点击此处开始: https://gtnr.it/3ulVX4K 。 对流程不熟悉的同学,可以参考一下我们此前发布的一篇旧贴。 调研仅花费您很少时间,欢迎大家积极参与! 活动已经截止了。。。
公告
Claire Zheng · 三月 11, 2021

欢迎中文社区新版主@姚鑫

亲爱的社区开发者们, 我很高兴地向大家介绍一位我们的新版主@姚鑫 @姚鑫是东华医为的一名开发工程师。 以下是@姚鑫的自我介绍: 大家好,我非常热衷于与开发者们分享我的技术经验。作为一名移动端全栈开发工程师,我发表了《Caché 23种设计模式》《Caché 算法与数据结构》《Caché 从入门到精通》《疯狂 Caché》《Caché 命令大全》《Caché 函数大全》《Caché 变量大全》《Caché SQL 必知必会》等一系列文章集。 在CSDN(中国最大的开发者社区之一),我被认证为博客专家,CSDN优秀讲师。 在掘金网这个帮助开发者成长的知名社区,获得了2020年掘金十大年度人气作者称号。 我很荣幸能够加入InterSystems开发者社区(中文版)并参与到社区管理、运营中,希望可以同使用InterSystems技术的开发者更好地交流、共同成长。 感谢@姚鑫,恭喜你成为新版主! 感谢@姚鑫!期待更多大作! 欢迎新版主@姚鑫 欢迎新版主@姚鑫期待将来分享更多关于IRIS数据平台的经验