许多组织使用单独的开发、过渡和生产环境维护其网站的质量。ArcGIS Server 所处的环境具有以下行为:
- 开发 - 沙盒 ArcGIS Server 站点,可在其中自由测试应用程序和服务。通常,开发站点在小型计算机上使用 ArcGIS Server 的 Esri 开发者网络 (EDN) 许可运行。在开发站点中验证更改后,更改将应用到过渡站点。.
- 过渡 - 此 ArcGIS Server 站点为生产站点的克隆站点。在此级别测试将决定在生产站点应用更改或拒绝更改并等待开发站点的新迭代。过渡站点不用于开发,仅用于性能和功能测试。Esri 为 ArcGIS Server 用户提供的过渡许可比生产许可便宜。
- 生产 - 实际支持业务工作流的站点,实际用户访问的站点。此站点上无任何开发或测试操作发生。只有通过过渡站点中的测试详查的更改才会应用于生产站点。
在理想情况下,开发、过渡和生产环境使用不同的数据库和基础架构。每个组织都有如何在站点间测试和批准更改的特有规则。
在站点间移动更改可能面临逻辑挑战。本帮助主题将提供模式和脚本,引导您完成整个过程。
配置每种环境
在每种环境中,都需要安装 ArcGIS Server,创建站点并配置安全性、服务器对象扩展 (SOE) 以及其他设置。尽管可以使用示例:通过两个文本文件创建用户和角色等脚本,但在手动执行时,大部分任务也都可以更快完成。.
首先运行开发站点,然后创建过渡站点,最后创建生产站点。
部署服务
在多种环境中部署服务的关键是向 ArcGIS Server 正确注册文件夹和数据库并使用服务定义 (SD) 进行发布。
向 ArcGIS Server 注册文件夹和数据库
向 ArcGIS Server 注册文件夹或数据库时,请提供发布者的数据路径和服务器的路径。
- 发布者的路径是计算机中将用于创建 SD 文件的数据路径。在开发、过渡和生产服务器上注册项目时,发布者的路径始终相同。
- 服务器的路径是服务器上的数据路径。在开发、过渡和生产服务器上注册项目时,此路径可能不同。
如果要注册多个文件夹或数据库,可以考虑使用脚本。示例:注册文本文件中列出的文件夹和数据库使用 ArcPy AddDataStoreItem 函数注册文本文件中提供的文件夹和数据库列表。您需要针对每种环境修改文本文件。
发布服务
在多种环境中部署服务时使用 SD 文件。SD 文件获取发布服务所需的信息并将其打包为一个便携式文件。虽然可以将 GIS 数据打包到 SD 文件中,但将数据预加载到每种环境中并使用副本保持同步将更加轻松容易。
创建中性连接 SD 文件(在保存服务定义 向导中选择无可用连接选项),这样,便可在任意服务器上灵活发布文件。在发布 SD 文件时,ArcGIS Server 将自动更正写入 SD 的路径,以便使用您的服务器路径。因此,必须认真注册数据才能在多种环境中部署同一 SD 文件。
发布服务任务非常适合脚本。示例:发布文本文件中列出的服务定义将读取文本文件并发布其中的所有 SD 文件。脚本使用 ArcPy 函数 Upload Service Definition 发布每个 SD 文件。
从 SD 文件部署服务后,需要启用这些服务所需的任何扩展模块。可以手动或通过脚本完成此操作。
可以脚本化的另一任务是应用权限。示例:通过文本文件应用权限使用 ArcGIS REST API 按照文本文件的说明应用不同服务的权限。
更新服务
有时,您可能想要更新服务以便使用新属性或反映源文档中的更改,例如 ArcMap 文档 (MXD) 中的一组永久符号编辑内容。在多种环境中更新服务的建议方法:保存新的 SD 文件,删除此服务,然后发布更新的 SD 文件。
采用此方法时,上文的发布脚本示例也可以更新服务。只需修改输入文件,使其只包含您想要更新的服务。如果找到现有服务,此脚本会在更新 SD 文件前删除此服务。
采用这种方法更新服务后,需要重新启用此服务使用的所有 SOE。
您也可以使用 ArcGIS REST API 中的编辑服务操作将服务属性(而非地图或源文档)更新脚本化。
保持数据同步
请确保数据在多种环境间同步。地理数据库复制可帮你解决这一问题。此外,您还可以采用新数据集完全替换旧数据集。例如,您可以删除文件地理数据库并采用更新的文件地理数据库替换它。
如果你决定完全替换表或文件地理数据库,请牢记 ArcGIS Server 服务默认锁定基础数据集的方案。如果方案已经锁定,则必须停止服务才能替换数据。出于谨慎原因,您可以针对地图服务禁用方案锁定,但不能针对其他服务类型禁用方案锁定。
更新应用程序
要在开发、过渡和生产环境间移动应用程序,您可以将应用程序文件从一个站点复制到另一个站点,然后更新代码中的所有 Web 服务 URL,使它们指向新站点。使用配置文件定义服务的 URL。
以下脚本可以帮您更新代码中的 URL。代码将在您提供的文件夹中递归查找所含文件,在这些文件中搜索 http://myDevServer/arcgis 等特殊字符串,然后采用过渡或生产站点的位置(例如 http://myProdServer/arcgis)替换这些字符串。
在启动此脚本前,应对原始应用程序文件进行备份。另请注意,此脚本允许您指定待处理文本文件的扩展名,例如 ArcGIS API for JavaScript 文件的 .js 和 .html 扩展名。
使用此脚本替换 URL 之后,可将应用程序文件复制到工作流中的下一服务器(过渡或生产服务器)。
import os
import sys
import shutil
import traceback
def dirEntries(dir_name, subdir, *args):
'''Return a list of file names found in directory 'dir_name'
If 'subdir' is True, recursively access subdirectories under 'dir_name'.
Additional arguments, if any, are file extensions to match filenames. Matched
file names are added to the list.
If there are no additional arguments, all files found in the directory are
added to the list.
Example usage: fileList = dirEntries(r'H:\TEMP', False, 'txt', 'py')
Only files with 'txt' and 'py' extensions will be added to the list.
Example usage: fileList = dirEntries(r'H:\TEMP', True)
All files and all the files in subdirectories under H:\TEMP will be added
to the list.
'''
fileList = []
for file in os.listdir(dir_name):
dirfile = os.path.join(dir_name, file)
if os.path.isfile(dirfile):
if not args:
fileList.append(dirfile)
else:
if os.path.splitext(dirfile)[1][1:] in args:
fileList.append(dirfile)
# recursively access file names in subdirectories
elif os.path.isdir(dirfile) and subdir:
print "Accessing directory:", dirfile
fileList.extend(dirEntries(dirfile, subdir, *args))
return fileList
def updateString(infileName, srchString,rplString):
bakFileName = os.path.splitext(infileName)[0] + ".bak"
if not os.path.exists(bakFileName):
# copy the original file
shutil.copy(infileName, bakFileName)
# Open the backup (= original) file to read
inFileHndl = open(bakFileName,"r")
outFileHndl = open(infileName,"w")
for line in inFileHndl:
if line.find(searchString) > 0:
line = line.replace(searchString, replaceString)
outFileHndl.write(line)
outFileHndl.close()
inFileHndl.close()
# remove the backup (=original content file)
os.remove(bakFileName)
if __name__ == '__main__':
try:
inFolder = r"C:\inetpub\wwwroot\viewer" # path to search
searchString = "http://mydevserver" # string to find
replaceString = "http://mystgserver" # string - replace searchString with replaceString
fList = dirEntries(inFolder, True, 'xml')
for f in fList:
updateString(f, searchString, replaceString)
print '\n\n\n' + 'Process Complete'
except:
# Return any python specific errors as well as any errors from the geoprocessor
#
tb = sys.exc_info()[2]
tbinfo = traceback.format_tb(tb)[0]
pymsg = "PYTHON ERRORS:\nTraceback Info:\n" + tbinfo + "\nError Info:\n " + \
str(sys.exc_type)+ ": " + str(sys.exc_value) + "\n"
print '\n\n\n' + pymsg