7. GDA配置¶
7.1. 弹簧配置¶
7.1.1. 这个 gda
命名空间¶
7.1.1.1. 在XML文件中使用命名空间¶
要使用中的元素,请执行以下操作 gda
命名空间,则需要通过将以下属性添加到 <beans>
您的Spring配置中的元素:
xmlns:gda="http://www.diamond.ac.uk/schema/gda/gda"
您还需要将这些条目添加到 xsi:schemaLocation
属性:
http://www.diamond.ac.uk/schema/gda/gda http://www.diamond.ac.uk/schema/gda/gda/gda-gda-1.0.xsd
7.1.1.2. 将命名空间添加到Eclipse中的XML目录¶
如果您使用 gda
命名空间,则应将 gda
将命名空间添加到Eclipse XML Catalog,以便Eclipse可以验证包含这些自定义元素的XML文件。要执行此操作,请执行以下操作:
打开Eclipse首选项(Window→首选项)
转到xml→xml目录
单击“添加.”
输入以下详细信息:
位置:单击“工作区.”并选择
uk.ac.gda.core/src/gda/spring/namespaces/gda/gda-gda-1.0.xsd
密钥类型:选择“命名空间名称”
键:回车
http://www.diamond.ac.uk/schema/gda/gda/gda-gda-1.0.xsd
7.1.2. FindableNameSetterPostProcessor
¶
这句话的意思是:
<bean class="gda.spring.FindableNameSetterPostProcessor" />
在Spring XML文件中导致所有 Findable
对象具有其 name
属性设置为与Spring相同 id
。因此,您不需要(除少数特殊情况外):
<property name="name" value="..." />
7.1.3. 从创建属性 java.properties
可获得的¶
使用以下命令:
<context:property-placeholder location="file:${gda.config}/properties/java.properties" />
它允许您在Spring XML文件中使用属性。例如:
<property name="hostname" value="${gda.images.camerahost}" />
要在中制作标记,请执行以下操作 context
命名空间,则需要将以下属性添加到 <beans>
您的Spring配置中的元素:
xmlns:context="http://www.springframework.org/schema/context"
您还需要将这些条目添加到 xsi:schemaLocation
属性:
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
7.1.4. 直接实例化EPICS设备¶
例如:
<bean id="S1_top_motor" class="gda.device.motor.EpicsMotor">
<property name="pvName" value="BL04J-AL-SLITS-01:Y:PLUS" />
</bean>
7.1.5. 使用EPICS接口“在幕后”实例化¶
这是为那些不喜欢在其XML文件中包含PV的人准备的;-)
要使用在EPICS IOC构建过程中生成的Diamond的GDA-EPICS接口文件,
将其放在Spring XML文件中的某个位置(它不需要ID):
<bean class="gda.configuration.epics.EpicsConfiguration">
<constructor-arg value="${gda.config}/xml/epics-interface.xml" />
</bean>
然后执行以下操作:
<bean id="S1_top_motor" class="gda.spring.EpicsMotorFactoryBean">
<property name="deviceName" value="S1.YP" />
</bean>
EpicsMotorFactoryBean
是弹簧吗? factory bean - S1_top_motor
对象实际上将是一个 EpicsMotor
.
除了 EpicsMotorFactoryBean
,还有 EpicsMonitorFactoryBean
和 EpicsPositionerFactoryBean
(他们都需要一个 deviceName
)
7.1.6. 将一个文件导入到另一个文件¶
<import resource="S1.xml" />
实际上, <import>
替换为导入文件的内容。所有的豆子都在同一个春天里 语境 (即不需要复制 PropertyPlaceholderConfigurer
, the FindableNameSetterPostProcessor
等)。
7.1.7. 请使用 ref
属性!¶
而不是这样:
<bean id="s1_bottom" class="gda.device.scannable.ScannableMotor">
<property name="motorName" value="S1_bottom_motor" />
</bean>
您可以执行以下操作:
<bean id="s1_bottom" class="gda.device.scannable.ScannableMotor">
<property name="motor" ref="S1_bottom_motor" />
</bean>
请注意,该属性是 motor
不是 motorName
,并且这使用 ref
属性-该属性将 S1_bottom_motor
把马达装进 s1_bottom
对象(因此 ScannableMotor
不需要使用 Finder
来获得底层的马达-它已经使用Spring连接起来了)。
由于Spring具有此依赖项注入功能,因此不需要使用 Finder
在新的类中,可以使用Spring进行连接。
7.1.8. 通过CORBA使远程对象可用¶
您将在服务器端配置中需要以下内容:
<corba:export namespace="stnBase" />
您需要声明 corba
通过将以下内容放在XML文件的顶部来创建命名空间:
xmlns:corba="http://www.diamond.ac.uk/schema/gda/corba"
并将这些条目添加到 xsi:schemaLocation
属性:
http://www.diamond.ac.uk/schema/gda/corba http://www.diamond.ac.uk/schema/gda/corba/gda-corba-1.0.xsd
由于Spring的限制,属性占位符不能在 namespace
属性时使用 <corba:export />
。因此,举个例子:
<corba:export namespace="${gda.beamline.name}" />
不会奏效的。(属性占位符通常由 PropertyPlaceholderConfigurer
,这是一个 BeanFactoryPostProcessor
在应用程序上下文中对bean定义进行操作的。这个 <corba:export />
元素本身不会转换为bean定义:它使用名称空间值为远程对象添加bean定义。这是不可能的 PropertyPlaceholderConfigurer
要解析中使用的占位符,请执行以下操作 namespace
属性,然后使用该值查找远程对象。)
7.1.9. 从其他对象服务器导入远程对象¶
您的客户端配置中将需要以下内容:
<corba:import namespace="stnBase" />
和一样 <corba:export />
,以使用 corba
命名空间,则需要在XML文件的顶部声明它。
使用的好处是 corba:import
“隐藏”bean被添加到所有远程对象的Spring上下文中,因此您可以在任何 ref="..."
文件中其他位置的属性。
7.1.10. 使用启用基于角色的访问控制 <gda:rbac />
¶
要启用基于角色的访问控制(RBAC),请将以下元素添加到Spring配置中:
<gda:rbac />
您还必须将 gda.accesscontrol.useAccessControl
属性到 true
.
7.1.11. 这个 corba
命名空间¶
如同 gda
命名空间,如果使用 <corba:export>
或 <corba:import>
元素,则应添加 corba
命名空间添加到Eclipse XML目录。要执行此操作,请按照 gda
以上命名空间,但使用下列值:
位置:
uk.ac.gda.core/src/gda/spring/namespaces/corba/gda-corba-1.0.xsd
密钥:
http://www.diamond.ac.uk/schema/gda/corba/gda-corba-1.0.xsd
由于SpringSource工具套件的问题,您可能仍会收到以下警告,可以忽略这些警告:
找不到架构命名空间‘http://www.diamond.ac.uk/schema/gda/corba’‘的元素’corba:export‘的Spring NamespaceHandler
7.1.12. SingletonRegistrationPostProcessor
¶
<bean class="gda.spring.SingletonRegistrationPostProcessor" />
这会将您在Spring上下文中创建的某些对象注册为应用程序范围的单例实例(例如,元数据)。
(默认情况下,Spring XML文件中的对象是单例。在完美世界中,元数据和其他单例可以注入到其他对象中,而不是调用 Whatever.getInstance()
。在实践中很难做到这一点,因为(1)需要单例的对象太多;(2)并非所有这些对象都将在Spring XML文件中定义。在Spring XML文件中定义对象很好,因为这使我们可以完全控制它们的配置,这意味着我们可以用模拟对象交换真实对象。但这意味着我们需要将这些对象注册到某种注册表中。)
7.1.13. 属性编辑器¶
PropertyEditor
(Javadoc) is a standard
Java interface concerned with converting text representations of property values into their 'real' types (among other
things).
在Spring中,它们用于将Spring配置文件中使用的文本值转换为被实例化的bean所需的类型。Spring已经内置了对许多类型的支持,但是通过将其放入Spring配置中:
<import resource="classpath:gda/spring/propertyeditors/registration.xml" />
您还可以设置以下类型的属性:
double[][]
-2D双阵列
类支持的任何其他类型。 PropertyEditor
s列在 GdaPropertyEditorRegistrar
班级。
7.1.14. Spring配置示例¶
钻石I04.1光束线专门使用Spring进行配置。如果您有权访问GDA Subversion存储库,则可以 view the I04.1 configuration 。这两个对象服务器的Spring上下文被拆分为多个XML文件,这些文件都位于 servers/main/live 目录。
7.2. 登录¶
日志记录消息不仅可以由GDA类生成,还可以由第三方库生成,例如 Apache Commons Configuration 。GDA类通常使用 SLF4J 用于日志记录的接口。来自使用Commons日志记录或Log4j的代码的日志条目被重定向到SLF4J中,使用两个 SLF4J bindings : SLF4J上的公共日志记录 和 SLF4J上的Log4j .
GDA使用 Logback 作为SLF4J实现,因此日志记录条目从SLF4J传递到Logback。
下图显示了一些DLS光束线上使用的日志记录配置选项之一-集中式日志记录服务

7.2.1. 日志服务器配置¶
GDA提供了一个实用程序- gda.util.LogServer
-用于集中记录来自服务器和客户端上运行的其对象的消息,如上图所示。您需要使用四个属性配置日志服务器:
财产 |
描述 |
---|---|
|
日志服务器侦听的端口 |
|
日志服务器的日志记录配置文件,例如LogServer.xml |
|
要存储GDA日志文件(例如gda.log)的目录 |
|
日志查看器侦听的端口,即日志服务器将消息转发到的端口 |
虽然前两个属性是LogServer类所需且必不可少的,但后两个属性是可选的,仅在LogServer.xml文件中用于指定日志目的地。
LogServer.xml为日志服务器上的中央日志记录服务定义日志记录目的地(附加器)、记录器级别筛选器和文件日志记录规则。
7.2.2. GDA对象日志记录配置¶
GDA对象是系统中日志消息的来源。虽然可以配置不同于服务器对象的客户端对象日志记录,但这里我们描述了客户端和服务器都将其日志记录消息发送到中央日志服务器的情况,如上图所示。
在这种情况下,客户端和服务器共享在例如LoggingConfiguration.xml或logBack.xml中定义的相同日志记录配置。需要设置四个属性(上面已经定义了一个):
财产 |
描述 |
---|---|
|
将所有消息发送到的远程端口,即日志服务器的侦听端口 |
|
运行日志服务器的远程主机。 |
|
GDA客户端对象的日志记录配置文件 |
|
GDA服务器对象的日志记录配置文件 |
xml将Log Server定义为日志目的地,并为消息源的GDA对象中使用的所有/特定记录器设置所需的记录器级别过滤器。
系统中有两个日志记录配置文件属性的原因是历史的,因为我们过去配置客户端的方式与配置服务器的方式不同。在我们这里讨论的情况下,最后两个属性指向相同的LoggingConfiguration.xml文件。
7.2.3. 日志查看器配置¶
GDA还提供了一个简单的日志查看器实用程序- gda.util.LogPanel
用于查看从中央日志服务器接收的日志记录消息。它通过属性指定的端口上的套接字连接到日志服务器 gda.logPanel.logging.port
。此属性是启动日志面板查看器所必需的。
财产 |
描述 |
---|---|
|
日志查看器侦听的端口,即日志服务器将消息转发到的端口 |
|
此日志查看器的日志记录配置文件,例如LogPanel.xml。 |
通过LogPanel.xml,您可以进一步配置显示端GDA对象中使用的所有/特定记录器的消息显示级别。
7.2.4. 默认服务器端日志记录配置¶
服务器端日志记录配置用于对象服务器和事件服务器。
GDA有一个默认的服务器端日志记录配置文件,位于 uk.ac.gda.core
文件中的插件 src/gda/util/logging/configurations/server-default.xml
。它目前仅用于为GDA中使用的某些第三方库指定日志过滤器。
特定GDA配置的服务器端日志记录配置文件可以使用 gda.server.logging.xml
财产。将首先应用默认的服务器端配置,然后应用自定义配置。
7.2.5. 默认客户端日志记录配置¶
GDA有一个默认的客户端日志记录配置文件,位于 uk.ac.gda.core
文件中的插件 src/gda/util/logging/configurations/client-default.xml
它目前仅用于为GDA中使用的某些第三方库指定日志过滤器。
特定GDA配置的客户端日志记录配置文件可以使用 gda.client.logging.xml
财产。将首先应用默认客户端配置,然后应用自定义配置。
7.2.6. 在登录配置文件中使用属性占位符¶
您可以创建在中定义的属性 java.properties
可在Logback配置文件中使用,方法是将以下元素添加到文件顶部(在 <configuration>
元素):
<property file="${gda.config}/properties/java.properties" />
(使用 ${{gda.config}}
在这里工作是因为 gda.config
是系统属性。)
然后,您可以在文件中的其他位置使用属性占位符。例如:
<appender name="SOCKET" class="ch.qos.logback.classic.net.SocketAppender">
<RemoteHost>${gda.logserver.host}</RemoteHost>
<Port>${gda.logserver.port}</Port>
...
</appender>
请注意,日志记录系统不会读取属性文件中提供的include语句。要处理多个属性文件,请添加多个 <property .../>
元素。
7.3. 记录Jython终端输出¶
可以将服务器配置为将发送到客户端的Jython终端的所有文本记录到当前data/access目录中的一个文件中。为此,应该在Spring中创建一个RedirectableFileLogger,并提供一个跟踪data/access目录的ObservablePathProvider。当文件位置更改时,将在最后一个文件中留下一个注释,将读者引导到新文件,并在新文件中记录一个注释,指明日志是从哪里传输过来的。然后,可以在JythonTerminal观察到的相同观测对象上使用适配器。
例如,假设已经创建了一个JythonServer(始终命名为‘command_server’),请尝试执行以下操作以获取JythonServerFacade引用::
<bean id="jython_server_facade" class="gda.jython.JythonServerFacade">
<constructor-arg ref="command_server" />
</bean>
然后执行以下操作来构建典型的记录器:
<bean id="terminal_logger" class="gda.jython.logger.RedirectableFileLogger">
<constructor-arg ref="terminallog_path_provider" />
</bean>
<bean class="gda.jython.logger.OutputTerminalAdapter">
<constructor-arg ref="jython_server_facade" />
<constructor-arg ref="terminal_logger"/>
</bean>
<bean class="gda.jython.logger.InputTerminalAdapter">
<constructor-arg ref="command_server" />
<constructor-arg ref="terminal_logger"/>
</bean>
<bean class="gda.jython.logger.ScanDataPointAdapter">
<constructor-arg ref="jython_server_facade" />
<constructor-arg ref="terminal_logger"/>
</bean>
<bean class="gda.jython.logger.BatonChangedAdapter">
<constructor-arg ref="jython_server_facade" />
<constructor-arg ref="terminal_logger"/>
</bean>
何处 terminallog_path_provider
Bean可能是一个哑元::
<bean id="terminallog_path_provider" class="gda.data.SimpleObservablePathProvider">
<property name="path" value="${gda.data.scan.datawriter.datadir}/gdaterminal.log" />
<property name="local" value="true" />
</bean>
或跟踪服务器的访问元数据::
<bean id="terminallog_path_provider" class="gda.data.ObservablePathConstructor">
<property name="template" value="${gda.data.scan.datawriter.datadir}/gdaterminal.log" />
<property name="gdaMetadata" ref="GDAMetadata" />
<property name="local" value="true" />
</bean>
注: gda.data.ObservablePathConstructor
不支持Java属性,仅支持特定于GDA的模板。也就是说,它不会正确解释诸如 ${{gda.data.scan.datawriter.datadir}}
。相反,您必须将此属性的值放在上面的Spring配置中,例如 /dls/i21/data/$year$/$visit$/spool/gdaterminal.log
.
注: InputTerminalAdapter
接收键入的命令 all 客户端终端(通过命令服务器)。
7.4. Java属性和自定义GDA¶
要在整个代码库中共享的属性作为名称-值对存储在 java.properties
文件位于 config/properties
文件夹。这是定制GDA行为的常用方式。
当以与Spring或Logback XML文件相同的方式定义Java属性时,可以使用变量插值。
以下是可能需要定制的主要Java属性。然而,还有更多。
假定在运行服务器进程时由-D标志设置的Java属性:
财产 |
描述 |
---|---|
|
GDA安装的插件目录。假定要素目录和第三方目录处于同一级别 |
|
配置目录的位置。假定此目录具有标准子结构。 |
|
顶级数据目录。实际写入数据文件的子目录由 |
请注意,RCP客户端还将依赖于 gda.config
和 gda.data
变量在其 .ini
文件。
在运行GDA Java进程时必须由-D标志设置的属性(第三方软件要求);这些标志由Python启动脚本自动添加:
财产 |
描述 |
---|---|
|
|
|
用于连接到EPICS PV的JCA库属性文件。 |
最有可能进行自定义的属性:
财产 |
描述 |
---|---|
|
任何日志记录进程的全局读写目录。请注意,如上所述,主日志记录系统有其自己的配置文件。 |
|
要写入数据文件的目录。可以将其设置为动态的,方法是使用 |
|
扫描写入的数据格式 |
|
其中为RCP客户端创建工作区。如果要允许多个RCP客户端,则需要使用变量插值。 |
使用读取GDA属性文件 Commons Configuration 。有关属性文件格式的更多信息,请参阅 Properties files 公共配置部分 User's Guide .
属性文件可以包含另一个属性文件,方法是使用 include
指令。有关更多信息,请参阅 Includes 用户指南中的部分。
7.5. 元数据¶
7.5.1. ICAT¶
ICAT子系统与数据库(RDBMS或XML文件)对话,该数据库将用户ID映射到光束线和实验。它用于找出启动每个客户端的用户属于哪些实验,因此在该客户端的命令下收集的扫描应该将任何数据写入哪些位置。
如果未使用ICAT,则数据始终写入由 gda.data.scan.datawriter.datadir
Java属性。
不同ICAT系统的一些示例:
要始终写入同一数据目录,请执行以下操作:
gda.data = /scratch/data
gda.data.scan.datawriter.datadir = ${gda.data}
不使用ICAT,但要在每个不同的实验中更改数据目录,请执行以下操作:
gda.data = /scratch/data
gda.data.metadata.icat.type = gda.data.metadata.icat.NullIcat
gda.data.scan.datawriter.datadir = ${gda.data}/$visit$
# change this for every experiment:
gda.defVisit = myVisit
要使用ICAT根据谁正在运行接力棒(控制光束线)的GDA客户端来动态更改输出目录,请执行以下操作:
gda.data = /scratch/data
gda.data.scan.datawriter.datadir = ${gda.data}/$year$/$visit$
gda.data.metadata.icat.type = gda.data.metadata.icat.DLSIcat
gda.data.metadata.icat.url = jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(HOST=${oracle.host})(PROTOCOL=tcp)(PORT=${oracle.port}))(CONNECT_DATA=(SID=xe)))
gda.data.metadata.icat.shift_tolerance = 1440
gda.data.metadata.dlsicat.user = icatusername
gda.data.metadata.dlsicat.password = icatpassword
这个 DLSIcat
类提供到ICAT数据库的连接。类中有一个备用类。 uk.ac.gda.core
已调用插件 XMLIcat
它使用XML文件作为数据库。这主要用于单元测试或非现场演示,但如果其他设施将数据库转储为该格式,也可以使用它。
在戴蒙德,其中的剧本 /dls_sw/dasc/bin/iKittenScripts
可用于诊断ICAT的问题。例如:
getCurrentVisit
将显示当前访问的ID(如果有)。getFedIdsForCurrentVisit
将显示当前访问的用户详细信息。getDetailsOfVisit
将显示有关特定访问的信息。
7.6. 基于角色的访问控制¶
7.6.1. 概念¶
RBAC系统背后的想法不是为系统提供铁一般的安全性,而是防止用户在错误的时间意外操作硬件,这可能会破坏他们的实验。例如防止用户移动已经调谐的光学设备或在不同分支之间共享的硬件。
7.6.1.1. 设备保护¶
可以为每台设备(等级扩展设备)分配一个保护级别(默认值为1),并为每个用户分配一个授权级别(默认值为1,但可以将其配置为不同的值)。当表示设备的对象的某些方法被调用时,则将用户的授权与保护级别进行比较;如果授权等于或大于保护级别,则调用该方法,否则抛出gda.jython.accesscontrol.AccessDeniedException。
GDA开发人员不必在他们的设备类中编写任何特殊代码来实现此访问逻辑。但是,如果类或接口中有一个方法需要保护(例如,Motor.moveTo()),那么在Java源代码中,您应该使用标记注释该方法:
@!MethodAccessProtected(isProtected=true)
RBAC系统将使用反射搜索源代码以查找此类注释。
其想法是,某些方法将始终检查保护,而某些方法将始终被调用,而不管用户的授权如何(例如,所有用户都可以询问任何电机的位置,但可能只能控制某些电机)。
7.6.1.2. 客户授权¶
当启动GDA客户端时,用户id要么从操作系统获取,要么可能输入不同的用户id和密码。如果输入了不同的详细信息,则会根据已配置的任何授权者(钻石的单点登录LDAP系统)对它们进行身份验证。
登录信息通过InterfaceProvider类从客户端传递到命令服务器(Jython Server)。客户端向命令服务器进行唯一注册,以便可以识别每个命令的来源。然后,命令服务器通过将客户端使用的FedID与该光束线上的XML数据库进行比较来确定该客户端的授权级别。如果FedID列在XML中,则使用存储的授权级别,否则给客户端提供默认值。
有一个工具(gda.jython.authiser.EditPermission)可供开发人员或光束线科学家用来设置和更改授权级别。建议在XML中仅列出具有提升授权的用户或光束线员工。
7.6.1.3. 接力棒¶
在实现RBAC系统的光束线上,如果光束线可能有多个客户端在运行,则可以选择使用指挥棒来确定哪个客户端控制该光束线。手持指挥棒的客户端根据其授权级别控制光束线,而其他客户端无论其授权级别如何,都不能操作任何硬件的受保护方法。
接力棒持有者可以释放接力棒,这样任何客户都可以拿起接力棒,也可以将接力棒交给特定的客户。
如果接力棒持有者的授权级别较低,客户也可以从接力棒持有者手中接过接力棒。
有一个GUI面板,其中列出了光束线上的所有客户端,并具有释放/拿起/传递接力棒的控件。
7.6.2. 配置选项¶
7.6.2.1. Java属性¶
要打开RBAC,请将以下元素添加到Spring配置中:
<gda:rbac />
并设置以下java属性:
gda.accesscontrol.useAccessControl = true
要打开指挥棒控件(如果将其设置为true,则必须在Swing UI中使用BatonPanel,默认情况下,它将在SWT UI中可用):
gda.accesscontrol.useBatonControl = true
要设置默认授权级别(默认值为1),请执行以下操作:
gda.accesscontrol.defaultAuthorisationLevel = 1
要设置员工的默认授权级别(默认值为2),请执行以下操作:
gda.accesscontrol.defaultStaffAuthorisationLevel = 2
对于服务器开始自动拿起接力棒后的第一个客户端:
gda.accesscontrol.firstClientTakesBaton = true
告诉服务器使用哪个类进行授权(该类必须实现gda.jython.authiser.gda.jython.Authiser,这主要是为了区分用户和员工):
gda.gui.AcquisitionGUI.authorisationMethod = gda.jython.authoriser.LdapAuthoriser
常见的实现是FileAuthoriser-事实上,提供的LDAPAuthoriser实现使用FileAuthoriser来提供本地覆盖。FileAuthoriser使用XML文件,它在${gda.user.permissions.dir}中查找该文件(如果没有定义第一个属性,则在${gda.config}/xml/中查找)。两者具有相同的格式,即:
<user_permissions>
<user_id>N</user_id>
</user_permissions>
其中,user_id标识特定用户,N是数字权限级别。文件user_permissions.xml中的条目指示存在的用户及其设备权限。
告诉服务器使用哪个类进行身份验证(实现gda.jython.Authenticator.Authenticator接口。如果未定义,则不会出现登录屏幕,并且将使用操作系统身份验证-建议这样做):
gda.gui.AcquisitionGUI.authenticationMethod = gda.jython.authenticator.LdapAuthenticator
(对于Diamond,我们现在使用LDAP,因为cclrc LDAP服务器也可用于区分员工和用户帐户)
7.6.2.2. XML文件¶
要将特定帐户标识为人员,应该在配置中放置一个XML文件,该文件列出LDAP服务器之外的所有人员(非用户)帐户。
这是xml/beamlinestaff.xml,示例配置中有此文件的副本。
RBAC系统中员工和用户之间的不同之处在于,员工获得不同的默认权限级别,如果在ICAT系统中找不到该用户ID的访问,则使用默认访问(由java.property定义)。如果非员工帐户在ICAT系统中没有关联的访问,则UI将不会启动。
7.6.2.3. XML标记¶
在对象服务器XML文件中的设备和DOF上:
<protectionLevel>1</protectionLevel>
保护级别必须大于0!
在客户端XML文件中(仅限Swing UI):
<!BatonPanel>
<name>Baton Control</name>
</BatonPanel>
7.6.3. 如何在钻石上的光束线上设置RBAC¶
按照上面列出的方式设置Java属性。
为每个要控制访问的硬件向服务器和客户端XML配置文件添加适当的标记。
添加
beamlinestaff.xml
文件添加到您的配置中,以列出哪些帐户应被视为员工如果要授予某些用户高于用户默认级别的权限,请运行该工具为该光束线构建授权数据库:
java -Dgda.root=/dls/ixx/software/gda -Dgda.config=/dls/ixx/software/gda/config -Dgda.propertiesFiles=/dls/ixx/software/gda/config/properties/java.properties gda.jython.authoriser.EditPermissions
重新启动GDA!
7.7. 新配置布局¶
从GDA8.10开始,支持简化的启动机制,允许在使用 gda
发射器。
参数 |
默认设置 |
目的 |
---|---|---|
|
|
用于区分不同类型的GDA对象服务器或客户端 |
|
|
允许配置的不同变体;例如,连接到真实硬件的“实时”模式,或使用虚拟设备的“虚拟”模式 |
要允许使用这些参数,配置必须使用新的目录布局。以下所有目录必须位于配置目录的顶层:
号码簿 |
目的 |
---|---|
|
包含与客户端相关的XML配置文件 |
|
包含 |
|
包含 |
|
包含与服务器相关的XML配置文件 |
然后将自动确定以下设置,并且在运行时不需要指定这些设置 gda
启动器:
设置 |
价值 |
---|---|
属性文件 |
|
JacORB配置目录 |
|
JCA配置文件 |
|
服务器XML文件 |
|
客户端XML文件 |
|
关于新布局的注释:
这个
properties
目录必须包含每种模式的子目录(例如dummy
和live
);每个子目录必须包含java.properties
文件。这个
jacorb
目录必须包含每种模式的子目录;每个子目录必须包含etc
JacORB所需的目录(依次包含jacorb.properties
)这个
jca
目录必须包含每种模式的子目录;每个子目录必须包含JCALibrary.properties
文件。中必须存在的唯一文件
servers
和clients
子目录为<profile>/<mode>/server.xml
和<profile>/<mode>/client.xml
分别为。其他文件可以放在下面的任何级别servers
和clients
根据需要。
7.7.1. 对象服务器启动文件¶
启动对象服务器或创建objectServerImpl的任何客户端或服务器都将创建启动文件。如果使用带有配置文件名称的新配置布局,则此文件的名称不同。
<xmlfile>
是用于启动客户端或服务器的XML文件的基本名称(不含路径或后缀<initialisationCompleteFolder>
在Java属性中定义gda.objectserver.initialisationCompleteFolder
,它指定创建此文件的位置。
布局格式 |
启动文件名 |
---|---|
旧的 |
|
配置文件的新功能 |
|
7.8. 内存配置¶
在GDA的最新版本中,默认的Java内存选项已不足以满足RCP GDA客户端的可靠操作。在此期间, gdaclient
脚本在 example-config
设置通用堆的起始大小和最大大小:
-Xms256m
-Xmx1024m
它不设置单独的起始值或最大值 永久发电 堆大小:
-XX:PermSize=128m
-XX:MaxPermSize=256m
如果没有至少一个 -XX:MaxPermSize
选项,比示例更复杂的RCP GDA客户端可能很快就会耗尽 PermGen 空间和坠毁,几乎没有留下为什么它会坠毁的证据。
7.8.1. JVM选项¶
有四个主要选项可以控制JVM垃圾收集器的行为:
参数和默认设置 |
目的 |
---|---|
|
永久生成堆的默认起始大小。 |
|
永久生成堆的默认最大大小。 |
|
JVM堆的默认起始大小。 |
|
JVM堆的默认最大大小。 |
此外,还有一些选项可以帮助监视JVM垃圾收集器并更改其行为。
参数 |
目的 |
---|---|
|
请求JVM打印每个垃圾收集的详细信息。 |
|
导致打印附加信息。 |
|
将在每个集合的开始处添加时间戳 |
|
打印有关每个垃圾收集的更多信息。 |
|
JVM忽略的请求 |
|
使用不同的GC机制 |
7.8.2. JVM默认值¶
可以使用以下命令查看当前的系统默认值:
$ java -server -XX:+PrintFlagsFinal -version 2>&1 | grep -i -E 'heapsize|permsize'
uintx AdaptivePermSizeWeight = 20 {product}
uintx ErgoHeapSizeLimit = 0 {product}
uintx InitialHeapSize := 66328512 {product}
uintx LargePageHeapSizeThreshold = 134217728 {product}
uintx MaxHeapSize := 1063256064 {product}
uintx MaxPermSize = 67108864 {pd product}
uintx PermSize = 16777216 {pd product}
如果我们添加建议的内存配置选项,我们可以看到这些选项具有的效果:
$ java -server -Xms256m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=256m \
> -XX:+PrintFlagsFinal -version 2>&1 | grep -i -E 'heapsize|permsize'
uintx AdaptivePermSizeWeight = 20 {product}
uintx ErgoHeapSizeLimit = 0 {product}
uintx InitialHeapSize := 268435456 {product}
uintx LargePageHeapSizeThreshold = 134217728 {product}
uintx MaxHeapSize := 1073741824 {product}
uintx MaxPermSize := 268435456 {pd product}
uintx PermSize := 134217728 {pd product}
注意:如果以上命令没有输出或输出减少,请尝试添加参数:
-XX:+UnlockDiagnosticVMOptions
7.8.3. 优化起始值和最大值¶
JVM允许您指定不同的起始值和最大值,以便优化应用程序中的内存使用。
选项 -Xms256m -Xmx1024m
请说:
首先为该应用程序的堆分配256MB的内存,但是如果应用程序需要的话,允许堆增长到1 GB。
如果应用程序所需的内存增加到256MB以上,那么JVM将从操作系统请求更多内存并调整应用程序堆的大小。如果应用程序所需的内存增加到1 GB以上,则最终应用程序将崩溃,并显示 java.lang.OutOfMemoryError
例外。
遗憾的是,每次JVM增加堆的大小时,都需要时间来管理扩展。如果gda客户端在启动过程中分配了400MB的内存,它将从256MB开始,当它超过这个大小时会增加一个小挡路,当它超过这个新的限制时会再增加一点,并不断增加大小,直到它不再需要增加堆为止。这些堆扩展中的每一个都会增加启动GDA客户端的时间。
要获得最佳结果,最好使用 jvisualvm
要分析GDA客户端通常需要多少内存,然后添加更多内存以供将来扩展。
例如,如果客户端仅分配400MB用于启动,在几次基本扫描后上升到480MB,但在密集使用期间上升到1.6 GB,则 -Xms512m -Xmx2g
可能是个不错的起点。
同样的道理也适用于 永久发电 空间。
例如,如果 jvisualvm
显示客户端在使用Scan透视图启动时使用60MB,在打开PyDev脚本透视图后上升到90MB,并在长时间会话期间达到150MB的峰值,然后 --XX:PermSize=96m -XX:MaxPermSize=192m
可能就足够了。
7.8.4. 内存不足异常¶
大多数内存不足异常都是JVM耗尽通用堆空间的简单问题,通常可以通过增加 -Xmx
价值。
当堆空间用完时,错误形式为:
java.lang.OutOfMemoryError: Java heap space
不过,其他内存不足异常比较模糊。
在java6中,垃圾回收器将生成内存不足异常。 如果总时间的98%以上花在垃圾收集上,而回收的堆不到2% 。这可能表示您在已经内存受限的JVM中创建了过多的临时对象。只需给JVM更多的堆空间就可以解决这个问题,但这也可能表明存在其他问题。
当垃圾收集接管您的应用程序时,错误形式为:
java.lang.OutOfMemoryError: GC overhead limit exceeded
当你用完的时候 PermGen 空格中,错误可能发生在随机线程中,因此表单的任何错误:
java.lang.OutOfMemoryError: PermGen space
是一种迹象,表明 -XX:MaxPermSize=
可能需要增加。
由于MaxPermSize太低而导致的错误示例,记录在 gda_output
日志文件为:
Logging exception:
java.lang.OutOfMemoryError: PermGen space
Exception in thread "jReality ToolSystem EventQueue" java.lang.OutOfMemoryError: PermGen space
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: PermGen space
最后,在32位RHEL机器上,当您将permgen空间和堆的总容量增加到2.6 GB左右时,似乎也会出现问题。
在一次测试中,使用 -Xmx2048m -XX:MaxPermSize=768m
,则JVM拒绝加载客户端。这可以通过以下命令显示:
$ java -Xmx2048m -XX:MaxPermSize=768m -version
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.
用 -Xmx2048m -XX:MaxPermSize=640m
,JVM允许加载RCP GDA客户端,但是在300到1000秒内,客户端将崩溃,并在Java运行时出现致命错误:
# A fatal error has been detected by the Java Runtime Environment:
#
# java.lang.OutOfMemoryError: requested 32756 bytes for ChunkPool::allocate. Out of swap space?
#
# Internal Error (allocation.cpp:166), pid=6265, tid=69073808
# Error: ChunkPool::allocate
#
# JRE version: 6.0_24-b07
# Java VM: Java HotSpot(TM) Client VM (19.1-b02 mixed mode linux-x86 )
# An error report file with more information is saved as:
# /home/gfn74536/hs_err_pid6265.log
这是一个内部错误,而不是异常,因此无法捕获或处理,而且似乎是JIT编译器本身内存不足,即使有足够的堆和PermGen空间也是如此。
尚未研究Windows 32位JVM和Windows或Linux 64位JVM的限制。
7.8.5. 由于垃圾收集而暂停¶
如果您的GDA客户端经常出现明显的暂停,您可能需要尝试添加以下选项:
-verbose:gc
这将记录每次垃圾收集前后堆的详细信息,以及收集所用的时间。由于JVM同时执行这两种功能 少数的 和 full 对于集合,有些只需要很短的时间就可以完成,而另一些则可能需要几秒钟才能完成。
可以使用更多选项来在每次垃圾收集时提供更多信息。
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
虽然使用 System.gc()
不鼓励调用,GDA软件的某些部分仍在使用它。作为 System.gc()
强制立即显式完全垃圾回收,则每次调用都可能导致RCP GDA客户端暂停一秒以上。
如果显式垃圾收集导致了问题,您可以指示JVM忽略对 System.gc()
通过使用选项:
-XX:DisableExplicitGC
另一种选择 1 在Java 6中引入,似乎提供了介于完全显式垃圾收集和无垃圾收集之间的折中方案:
-XX:+ExplicitGCInvokesConcurrent
此选项使用 并发标记扫描收集器 其目的是使垃圾收集引起的暂停保持较短时间。这还没有经过测试,但可能值得研究一下禁用显式垃圾收集和启用它是否都会导致问题。