访问控制的影响
受控环境的一个关键特征是,对环境的访问受到策略的控制。一般来说,一个环境越接近生产,它的策略就越严格。为了说明这一点,表2展示了表1的环境,但列出了一些可能存在的访问限制:
功能测试 |
开发人员运行供应脚本。 开发人员拆除环境。 操作人员和开发人员都可以执行运行时管理和监控工具。 开发人员修改供应和部署脚本。 开发人员运行部署脚本部署新的应用程序版本。 开发人员开始和/或中止测试。 |
系统测试 |
部署团队运行供应脚本。 部署团队拆除环境。 操作人员可以执行运行时管理工具。 操作人员和开发人员可以执行运行时监控工具。 部署团队可以修改供应和部署脚本。 部署团队运行脚本部署新的应用程序版本。 测试团队开始和/或终止测试。 |
性能测试 |
部署团队运行供应脚本。 部署团队拆除环境。 操作人员可以执行运行时管理工具。 操作人员和开发人员可以执行运行时监控工具。 部署团队可以修改供应和部署脚本。 部署团队运行脚本部署新的应用程序版本。 测试团队开始和/或终止测试。 |
用户验收测试 |
部署团队运行供应脚本。 部署团队拆除环境。 操作人员可以执行运行时管理工具和监控工具。 部署团队修改供应和部署脚本。 部署团队运行脚本部署新的应用程序版本。 用户代表开始测试。 |
表2:说明测试环境策略
当然,该表的内容非常简单。一个成功的项目能使各个团队在多个方面通力合作。例如,在性能测试环境中可以使用管理工具调试系统。尽管该职责分配给了操作人员,但在实际操作中,该工作应该与系统架构师、应用程序设计师以及平台专家一起完成。尽管使用合作方法可以讨论更改并对其达成一致,但实际操作中任何特定任务都必须根据策略执行。
自动推进脚本
我们已经讨论了使用脚本代替向导供应环境,以及脚本如何实现自动化。现在开始讨论BEA WebLogic Platform自动供应的参与者。同时我将提供一些脚本示例供那些以前没有研究过脚本环境构建的人员参考。
用于BEA WebLogic Platform的脚本语言和工具
正如本文所述,自动化使用脚本工具配置环境。另一种方法是使用虚拟供应,但这种方法不常用。虚拟可以作为脚本的替代方法,能够提供高速供应,将来的文章中我们将讨论这个主题。
供应的鸟瞰图不仅要包括WebLogic域配置,而且要包括许多其他系统组件的配置,例如:
网络基础架构
防火墙
操作系统补丁
硬件负载平衡器
内容切换
数据库管理
内容管理系统
安全服务集成
后端系统连通性
我们没有足够的篇幅讨论所有以上组件的端对端安装和配置,因此我故意限制了WebLogic Platform的翻译,将一小部分扩展转入Web服务器和数据库服务器。这些扩展用于说明如何使用类似的技术以及共享相同的供应数据(可用时)来供应其他相关的系统组件。相关组件之间的共享供应数据可以减少许多可能出现的供应错误。
许多脚本工具都可用于自动化,本文不打算比较这些工具。既然我们一直在讨论WebLogic Platform的供应,我假定使用WLST作为主要的脚本工具。WLST是一个命令行工具,使用Jython脚本语言,Jython本身是Python脚本语言的Java绑定。
在WebLogic Platform 8.1中,WLST有两个版本。离线版(就叫WLST)用于构建WebLogic域内容,而另一个在线版(称为WLSTOnline)用于监控和更改运行域的配置。在WebLogic Platform 9中,单个WLST工具(叫做WLST)能够以离线和在线模式运行。为了更清楚的说明,我们将讨论用这两者模式使用WLS。如果您使用的是WebLogic Platform 8.1,则意味着您要使用WLST(离线模式)和WLSTOnline (在线模式)。
在离线模式中,WLST提供与域配置向导等效的脚本。与向导一样,它基于域模版构建一个域,然后使用脚本自定义域。BEA提供许多WLST可以使用的通用模版。WLST可以使用自定义模版构建新域,这些新域类似构建模版的域。在离线模式下,WLST构建并向文件库写入一个域目录结构。供应受控环境时,由于防火墙和其他访问控制的原因,可能无法直接向域服务器所在的机器写入域目录。下文中我们将讨论如何调整访问控制。
在线模式的WLST类似于WebLogic域控制台Web应用程序的等效脚本形式。除了可以监控其运行状态外,它还能检查和修改活动域的配置。运行在线模式时,WLST不依赖模版,因为它总是对现有的活动域进行操作。在线WLST使用JMX与管理服务器(以及受管服务器,但通常不能是在供应期间)进行通信。这与离线模式有明显的区别,WLST在离线模式只编写目录层次。JMX的访问控制可能限制了JMX接口访问管理服务器的方式,供应脚本必须针对这种约束做出调整。
编写适应性强的脚本
自动供应最关键的优点在于:您可以使用一个环境的供应脚本作用原型用于其他环境。要实现这一点,编写供应脚本时应该注意使脚本的行为与特定的环境需求相适应。要真正实现适应性强的脚本,您需要一个完善的脚本语言。幸运的是,Jython和Python非常适合这种情况。
如果您使用 WLST,应该使用Jython语言编写供应脚本。当您启动WLST并执行其脚本时,您实际上运行的是WLST工具中嵌入的Jython解释器。您也可以启动Jython解释器并将WLST加载到其中,以在Jython脚本中执行WLST命令。使用任何一种方法都可以发挥Jython语言的全部能力。
下面是一个摘自环境供应脚本(WLST离线脚本)的片段: weblogic_listen_port=int(profile['managed.server.listen.port']) hostnames=profile['managed.server.hosts'] managed_server_count=len(hostnames) foridxinrange(managed_server_count): listen_address=hostnames[idx] interface_address=listen_address managedServer=create(managedServerName,'Server') managedServer.setInterfaceAddress(interface_address) managedServer.setListenAddress(interface_address) managedServer.setListenPort(weblogic_listen_port)
我没有展示它是如何创建的,但对象profile属于Python语言,它包含定义每个要供应的特定环境变量的键值对。这些值可以从一个或多个外部属性文件加载,也可以使用开始导入的Jython脚本设置。下面是一个Jython导入文件的等效示例: defgetProfile(): env={} env['managed.server.listen.port']=7001 env['managed.server.hosts']= ["hostname_1","hostname_2","hostname_3"] returnenv
如果这在名为environment.py的Jython文件中,那么可以使用以下两行初始化profile对象: importenvironment profile=environment.getProfile()
注意如何使用Jython功能减少所需条目的数量。没有必要明确定义环境中受管服务器的数量:这可以从managed.server.hosts元素的内容中获得。
我展示的只是一个非常简单的示例,但它说明了一些重要的适应性技术:
供应脚本中导入了供应的变化方面。在本例中,它们从属性文件加载,但也可以通过单独的Jython脚本导入。
脚本可以扩缩,不需要更改即可用于配置一个或多个受管服务器。
脚本采用必需的模式,这些模式对于所有环境相同的。在本例中,模式是所有受管服务器使用的接口地址都与侦听接口相同,并且它们都使用相同的侦听端口。此外,受管服务器的唯一服务器名称的形式为<basename><index>,其中<basename>是所有服务器的共同点。示例中,<basename>是使用键值managedServerNameRoot从 dictionary元素中获得的,索引的值从1开始。这种配置模式在大型环境中很常见。
现在,假设上述受管服务器始终是群集的一部分。配置群集时,您需要设置群集地址。群集地址可以设置为DNS名称,也可以是以逗号分隔的服务器IP地址和端口号所组成的列表。经验告诉我们,只有后期阶段的测试环境才配置DNS服务器。让我们向代码片段中加入一些次要的内容(并添加Jython导入): importenvironment profile=environment.getProfile() weblogic_listen_port=int(profile['managed.server.listen.port']) hostnames=profile['managed.server.hosts'] managed_server_count=len(hostnames) cluster_list='' foridxinrange(managed_server_count): listen_address=hostnames[idx] interface_address=listen_address managedServer=create(managedServerName,'Server') managedServer.setInterfaceAddress(interface_address) managedServer.setListenAddress(interface_address) managedServer.setListenPort(weblogic_listen_port) cluster_list= cluster_list+listen_address+":"+str(weblogic_listen_port) if'cluster.dns.name'inprofile: cluster.setClusterAddress(profile['cluster.dns.name']) else: cluster.setClusterAddress(cluster_list)
在这个修改过的代码片段中,您积累了一个以逗号分隔的服务侦听地址和端口所组成的列表。如果在配置文件中提供了DNS名称(本例没有),则可以使用其作为群集地址,但默认情况下使用积累的地址和端口列表。
端对端供应:共享配置数据
在大部分测试环境中,供应的不仅仅是WebLogic域。例如,Apache Web服务器可以用于群集中受管服务器的静态HTTP目录或者平衡其HTTP请求的负载。供应脚本中也可以实现其他此类环境组件的配置。下面是一个environment.py的扩展版,包括了一个用于Apache Web服务器的配置值: defgetProfile(): env={} env['managed.server.listen.port']=7001 env['managed.server.hosts']= ["hostname_1","hostname_2","hostname_3"] env['apache.listen.port']=8080 returnenv
要实现这一点,您需要向供应脚本添加几行代码(新增行添加到片段的最后面): importenvironment profile=environment.getProfile() weblogic_listen_port=int(profile['managed.server.listen.port']) hostnames=profile['managed.server.hosts'] managed_server_count=len(hostnames) cluster_list='' foridxinrange(managed_server_count): listen_address=hostnames[idx] interface_address=listen_address managedServer=create(managedServerName,'Server') managedServer.setInterfaceAddress(interface_address) managedServer.setListenAddress(interface_address) cluster_list= cluster_list+listen_address+":"+str(weblogic_listen_port) if'cluster.dns.name'inprofile: cluster.setClusterAddress(profile['cluster.dns.name']) else: cluster.setClusterAddress(cluster_list) f=open('weblogic.conf','w') f.write(' ') f.write('WebLogicCluster') f.write(cluster_list) f.write(' ') f.write('MatchExpression*.jsp ') f.write(' ') f.close() f=None f=open('httpd.conf','w') f.write('Listen=') f.write(str(profile['apache.listen.port'])) f.write(' ') f.write('LoadModuleweblogic_modulemodules/mod_wl_20.so ') f.write(' ') f.write('Includeconf/weblogic.conf ') f.write(' ') f.close()
最后面的行创建两个文件:httpd.conf和weblogic.conf,分别用于配置Apache Web服务器和WebLogic插件。下面是httpd.conf形式的输出内容: Listen=8080 LoadModuleweblogic_module=modules/mod_wl_20.so Includeconf/weblogic.conf
下面是从environment.py生成的weblogic.conf: WebLogicClusterhostname_1:7001,hostname_2:7001,hostname_3:7001MatchExpression*.jsp
httpd.conf的配置使用键值 apache.listen.port,该键值从我们的environment.py文件中获得。但是要注意,插件的配置使用配置 WebLogic群集本身产生的副产品所累积的数据。WebLogic域配置数据曾经用于配置另一个相关的组件。这种配置数据的共享可以避免互相依赖的组件配置之间的不一致性。
注意,这是使用的技术(即直接使用Jython编写配置)并不是很恰当,只有在配置文件很小的时候才适合这样做。实际操作中,包括Apache Web服务器文件在内的许多配置文件都很大,不能简单的这样处理。在这种情况下,最好使用Jython输出带有配置值的属性文件,然后使用 Ant导入该属性文件,并根据配置文件模式执行标记替换。从WLST脚本中使用Ant很简单:安装了 WebLogic Platform 8.1和9.x的情况下,BEA包含一个运行Ant的Jython脚本。
不要使用过多的参数
编写适应性强的脚本的价值在于可以用于多个环境。但是,您不应该使用过多的参数。不要为不会随环境改变的属性和值创建参数,即使您的脚本会设置默认值。不必要的参数会使脚本更加复杂,使其变得更加难以理解。记住,您正试图创建的是可重用的脚本,可以在您进行其他项目之后仍然能被他人使用。每一个不必要的参数都会给您的继承者带来潜在的问题:“为什么所有环境采用相同值时要设置这个变量呢?我是不是哪里搞错了?”记住,您的继承者很可能有您的电子邮件地址和电话号码,会追问您可能早已不记得的事情!
结束语
BEA WebLogic Platform安装带来了三个功能强大的脚本工具:WLST、Jython和Ant。这些脚本工具可以用来构建强大的、适应性强的、可维护的供应和部署脚本,这些脚本可用于所有项目需要的环境来确保您的应用程序能够满足其需求。脚本不仅可以增强环境构建间的统一性,而且可以减少工作量,真是一举两得。
(编辑:aniston)
|