Tag Archives: AGS Architecture

在Docker的container中授权Portal for ArcGIS失败的解决办法

Docker是一中基于传统的Linux container, Namespaces, Control groups等技术发展而来的开源并且超轻量的虚拟化技术。相比传统的虚拟化技术,Docker省去了hypervisor(如VMWare,Hyper-V等)软件以及guest os两层,节约了相当可观的软硬件资源,但又实现了软硬件资源的完全隔离。所以你几乎可以在Docker的虚拟机实例(叫做container)中做传统虚拟机可以办到的任何事情,唯一的区别就是更快。
这次尝试在Docker的container中安装Portal for ArcGIS 10.3软件,以便更快地分发给其他人来使用。软件的静默安装可以利用类似“./Setup -m silent -l yes -a /path/to/portal.ecp -d /opt/arcgis/portal”的命令来实现,但装完启动Portal服务后,仍然提示需要授权,利用./authorizeSoftware –f portal.ecp授权时报错:

Software authorization failed. Please make sure your authorization file is valid and try again.

检查了ecp文件并没有问题。于是查看authorizeSoftware脚本文件,发现有相应的授权日志文件:
image 查看该日志文件发现,是由于缺少so库引起的:
image 安装相应类库后,再次授权成功。
附上在从docker hub中下载的centos:centos6 image启动的container里,安装Portal for ArcGIS 10.3时需要用到的类库列表:
tar, gettext, libpng-1.2.49-1.el6_2.x86_64, freetype-2.3.11-14.el6_3.1.x86_64, libSM-1.2.1-2.el6.x86_64, libXrender-0.9.8-2.1.el6.x86_64, fontconfig-2.8.0-5.el6.x86_64, libXext-1.3.2-2.1.el6.x86_64

Portal for ArcGIS多机部署并进行内容目录迁移的简要步骤

  以下内容假设你已经成功在单机环境下部署过下述软件。
  目标:在多台机器上分别部署ArcGIS for Server,Portal for ArcGIS,ArcGIS Web Adaptor等软件,达到Portal正常运行,软件角色物理分离,能够投入生产的目的。

  具体环境:4台Windows Server 2008 R2 SP1机器,提前设置fully qualified domain name (FQDN),

  • 192.168.220.182 wa.newnaw.com,可通过外网域名访问到该机器。部署ArcGIS Web Adaptor v10.2.1,配置共享存储\waarcgisserver,供ArcGIS for Server使用(config-store,server directories),配置共享存储\waarcgisportal,供Portal for ArcGIS使用,部署PostgreSQL v9.2.2,供建立SDE Geodatabase,作为ArcGIS for Server的data store使用。注:若硬件资源允许,理论上上述两个共享存储位置及SDE GDB应设置在独立的机器上;
  • 192.168.220.183 portal.esrichinacp.com,内网机器。部署Portal for ArcGIS v10.2.1;
  • 192.168.220.184 ags1.esrichinacp.com,内网机器。部署ArcGIS for Server v10.2.1;
  • 192.168.220.185 ags2.esrichinacp.com,内网机器。部署ArcGIS for Server v10.2.1;

  此次部署四台机器的防火墙均为开启状态。简便起见,也可将183,184,185三台只能内网访问的机器防火墙关闭,免去设置端口例外的麻烦。
image   部署完成后,可在外网通过wa.newnaw.com域名访问Portal for ArcGIS门户网站,并可发布托管服务到hosting server site(184,185集群)上;Portal运行或处理请求过程中,183,184,185的机器ip及域名对最终用户均透明不可见。

  大致步骤:

  1. 在wa机器上安装postgresql 9.2.2;
  2. 在wa机器上建立c:arcgisserver文件夹,创建用户arcgis/arcgis。并共享c:arcgisserver,网络和ntfs权限里均赋予arcgis用户对该文件夹的完全控制权限;
  3. 在ags1,ags2上安装arcgis 10.2.1 for server,系统用户为arcgis/arcgis。ags1,ags2两台机器上防火墙均开启,均添加6080,6443,4000-4004端口为例外;在两台机器上均安装pgsql的64位客户端。注:config-store和directories目录填写时用的都是ip的unc地址,并且加入已有站点时,填的也是ags1的ip:6080;
  4. 给ags站点添加managed database。利用arcmap的gp工具,在wa机器(防火墙开5432端口,修改pg_hba.conf文件重启服务允许任何客户端连接,拷贝st_geometry到lib目录下)上创建sde geodatabase;在ags1,ags2的site的data store中添加该sde作为managed database;
  5. 在访问ags1的site admin界面,将站点的protocol从http only改为http or https;
  6. 在portal机器上安装portal,全部默认设置;portal机器防火墙开7080,7443两个端口;登陆http://portal.esrichinacp.com:7080/arcgis/home/,创建初始管理员;注:目前Portal在安装时只能指定本地路径为工作目录,将工作目录迁移到\waarcgisportal的工作会在以下步骤中完成;
  7. 在wa机器的IIS上,绑定之前申请好的wa.newnaw.com的ssl证书到443端口,安装web adaptor,配置portal机器上的portal。使得portal门户网站可以正常访问,访问地址为http://wa.esrichinacp.com/arcgis/home;
  8. 为了让用户访问地图服务时,不暴露出最终的ags ip地址,所以必须给ags也配置adaptor。在wa机器上给ags站点配置web adaptor;
  9. 访问portal的组织管理,设置federated server和hosting server:
    image image
  10. 测试。发布hosted feature service正常,但在wa机器上访问item页面时请求有错,
    image 是通过wa机器的代理页面无法访问到ags1的6443端口。ags1的6443端口使用的是安装ArcGIS for Server时,内置tomcat自动生成的自签名证书,所以在wa机器上访问该证书并设置为受信任根证书办法机构即可,对于ags2的6443端口证书也做同样操作。再次测试,发布hosted feature service/hosted tiled map service均工作正常。所有请求都是通过wa.esrichinacp.com地址暴露出来的,从请求的url看不到portal,ags1及ags2三台机器的ip与域名;

  至此完成软件部署工作。接下来将之前Portal的内容目录迁移到wa机器的共享路径中,此处我们继续使用以前Portal门户的所有内容。步骤如下:

  • 拷贝之前Portal的工作目录arcgisportal到wa机器上的c:arcgisportal;
  • 在wa和portal机器上都建立本地账户arcgis/arcgis;
  • 共享c:arcgisportal为\waarcgisportal,并赋予arcgis账户共享中读写和本地安全中读写的权限;
  • 在portal机器上停止portal服务,修改服务运行账户为本地arcgis账户(默认的“本地系统账户”无法访问共享路径);
  • 在portal机器上赋予arcgis账户对portal安装目录C:Program FilesArcGISPortal的读写权限;并修改C:Program FilesArcGISPortalframeworketcportal-config.properties文件中一行为(注意是正斜杠“/”):
    dir.data=//wa/portalshared;
  • 在http://wa.esrichinacp.com/arcgis/portaladmin中,将content,db,index,logs,temp5个目录都修改为对应的共享路径,如: \waportalsharedcontent等;
  • 重启portal服务,可直接用原来的账户登录。原先所有用户及其对应内容,Group,共享关系等依然保留;新建item,发现已经存储在新的共享路径了。

  注:内容目录按上述步骤迁移后,所有设置均为原先设置(因为内容目录中包含数据库存储文件,内容未做任何修改)。比如hosting server site原先地址为:http://oldags.xxx.com:6080,在新环境下会失效。所以对于这些设置,以管理员身份登陆后需要修改为新的有效地址。

在startssl.com申请免费的ssl证书并导入IIS进行使用

  如果网站需要提供https加密访问方式,那么必须拥有一个有效的ssl证书来向客户端证明自己的身份。而ssl证书通常由第三方机构签发,有Domain Validation (DV), Organisation Validation (OV) 和 Extended Validation (EV)三种级别,分别对应由低到高的三种认证级别,DV比较宽松,EV最严格。认证方式不同,价格也不同。比如DV级别的证书,StartSSL可免费申请一年GeoTrust是149$每年Godaddy是69.99$每年我国的万网价格是4200¥每年。个人使用当然是StartSSL提供的证书性价比最高,虽然免费,但依然在Chrome,Firefox,IE等主流浏览器的内置受信任根证书颁发机构里面,如果是商业或机构使用,可选择顶级的证书颁发机构(当然不包括万网之流),彰显身份。下面就说明如何在startssl.com上申请免费证书,并部署到IIS上进行使用的步骤。

1. 首先需要在startssl.com上进行注册。该网站采用的是客户端证书认证方式,所以注册的过程就是填写自己的资料,邮件接收验证码,之后获得并在浏览器中安装StartSSL生成的一个客户端证书。这样以后以自己身份登录startssl.com时,就需要从安装了上述步骤证书的浏览器里直接访问startssl.com,而不需要输入用户名密码了。这个身份验证证书丢失后,只能重新注册,所以建议将该证书备份,具体步骤见How do I backup my client certificates。备份好后,可将该证书安装到其他计算机或浏览器,便于登陆startssl.com。

2. 注册之后,若要给某个域名申请证书,需要对域名进行验证,证明你是这个域名的拥有者才行。StartSSL采用的是域名拥有者邮箱验证,所以在Validations Wizard里选择Domain Name Validation,按照向导完成验证即可。

3. 接下来就是给通过验证的域名申请ssl证书。在Certificates Wizard中选择Web Server SSL/TLS Certificate,然后会进入创建私钥(Generate Private Key)步骤。
image   由于SSL/TLS采用的是非对称加密,所以必须私钥和公钥配合才能建立正确的安全连接。私钥由服务器端持有,保密,私有;公钥包含在客户端访问https网站时看到的证书内,公开,当客户端访问时即获得之。公钥和私钥正确配对后方可建立安全连接。填入对私钥文件保护的10位以上密码,继续,
image   即可得到一段加密文本,将该文本保存为.key的文件,比如privatekey.key,作为私钥保存好。这里你也可以预先利用openssl工具或IIS向导来生成包含自己额外信息,并且包含私钥的证书申请(.csr文件),这样就可以跳过Generate Private Key这步了。之后选择要为哪个域名创建证书,并且输入一个子域名,最终申请的证书会作用在这个子域名上。
image   StartSSL的免费证书只能给一个子域名用,若想为多个子域名申请证书或申请通配符形式的证书,则需要掏钱购买他们提供的class2级证书了。继续下一步,确认之后,可以得到一段文本,该文本便是StartSSL颁发给你网站的经过签名的证书,将其另存为.crt文件,比如ssl.crt(此证书即是网站客户端访问https连接时能够得到的文件,实质是包含了公钥,服务器名称,CA认证签名及其他信息的文件)。此外在该界面上最好根据提示,保存下来一个中间(intermediate)证书文件sub.class1.server.ca.pem,有的地方可能会用到。
  到此,我们得到了一个privatekey.key的私钥文件,一个ssl.crt的证书文件(包含公钥),一个sub.class1.server.ca.pem中间证书文件。在给自己的网站配置ssl.crt公有证书文件之前,我们还需生成两个在其他地方可能会用到的文件。第一个是经过解密的私钥文件(decrypted private key),比如在Nginx部署证书时需要用到。此步骤可通过openssl工具或startssl.com网站提供的Toolbox–>Decrypt Private Key工具完成,将结果保存为decryptedprivatekey.key。第二个是PKCS#12存档文件(*.pfx或*.p12),实质是包含了.crt证书文件所有内容,私钥以及加密信息的文件,而在IIS中部署时就需要用到此文件。可利用startssl.com网站提供的Toolbox–>Create PKCS#12 (PFX) File工具,传入私钥文件privatekey.key及证书文件ssl.crt后,生成之,保存为pfxarchive.p12。
4. 在域名所对应的计算机上部署该证书,此处以IIS为例。操作过程很简单,在IIS根节点的服务器证书功能中,右键,导入,根据向导输入刚才得到的pfxarchive.p12文件即可,
image   最后,在IIS网站绑定中,指定443端口使用我们导入的证书即可。
image   这样,在以https访问此网站时,就能够看到我们申请的证书了。
image
参考文章:

ArcGIS 10.1 for Server机器判断本机是否已经加入site的依据

  在一台机器上安装ArcGIS 10.1 for Server后,它还无法立即工作,必须将其加入site(的cluster)之中才行。首次登录manager时,也会询问创建新的site还是加入已有的site;如果已经加入site,登录manager则会显示该site的管理目录。那么机器自身是如何判断出自己是否已经加入site了呢?
  依据就在于Program FilesArcGISServerframeworketc目录下的两个xml文件,config-store-connection.xml和machine-config.xml。加入site时会在本机创建这两个文件,退出site时会删除之。前者记录site的公用信息,后者记录本机在site中的信息,具体内容大家可以自己查看。
  登录manager时会读取这两个文件,如果找不到,则认为自己没有加入site,会询问创建新site还是加入已有site;如果有这两个文件,会首先访问site的config-store目录验证其内容,合法的情况下就打开site管理目录。 如果在一台机器关机时,从site中将其删除,开机后会根据config-store-connection.xml内容去site的config-store目录中验证,发现自己已经被从site中移除后,会自己删除本机的这两个xml文件。
  此外,如果你的机器已经加入了site A,但现在需要临时加入site B去做一些工作,就不用在admin api去删除site A了,只需将上述两个xml文件先转移到别的地方,然后登录manager,选择加入site B即可;之前site A的config-store内容可以保留,以便将先前挪走的两个xml文件复原后(需要重启ArcGIS Server服务),登录manager即可直接返回site A。

ArcGIS 10.1 for Server中Web Adaptor的工作原理

  ArcGIS 10.1 for Server的安装目录中,都会内置一个tomcat(Program FilesArcGISServerframeworkruntimetomcat),无需单独的Web Server即可发布各种GIS服务(对于熟悉.NET的朋友来说,更省去单独安装和配置IIS的步骤);AGS应用程序的端口号也由之前版本的80(ArcGIS Server for .NET)和8099/8399(ArcGIS Server for Java)统一到了6080上,比如http://localhost:6080/arcgis/rest/serviceshttp://localhost:6080/arcgis/manager等。但对于内置的这个tomcat,我们并不能进行过多的操作,如果需要部署Web应用或通过别的端口来访问ArcGIS for Server的服务,这时就需要用到新的组件:Web Adaptor了。
  Web Adaptor实际上是安装在Web Server机器上的一个Web应用程序,负责将Web Server接收到的GIS请求转发到ArcGIS Server site内的GIS Server机器上去。通过Adaptor这个桥梁,我们就能使ArcGIS for Server利用到企业级Web Server的诸多优势。根据安装帮助中的解释,安装Web Adaptor后主要有以下好处:

  • 将单独的企业级Web Server集成到ArcGIS for Server的部署架构中来。可以将利用ArcGIS for Server服务的Web应用部署到Web Server上去;可以为site内所有的GIS Server提供不含有6080端口及arcgis等字样的统一访问入口点;
  • 可阻止最终用户通过Web Adaptor的访问地址连接到ArcGIS for Server的相关管理程序。比如用户如果得知了类似6080端口的GIS服务访问地址,就可通过固定的url地址访问到Manger,Admin api等涉及到整个站点操作的内置应用。而Web Adaptor给我们提供了选项,可禁止用户通过Web Adaptor暴露出的GIS服务地址访问到这些管理应用。

  此外,相对于site内的多台GIS Server机器,Web Adaptor还可以再次(除了Web Server集群外)起到负载均衡的作用,这在大并发量的情况下会比较有效。假设一个site内有n台GIS Server,它们所能处理的最大并发请求是1w个;根据ArcGIS for Server中p2p的实时通信架构,当我们将1w个并发请求发送到任一GIS Server的tomcat上时,GIS Server之间会自动以轮询(默认设置)的方式处理这些请求,GIS Server们完全可以及时响应;但1w个Web请求会首先使接收请求的这个tomcat过载,产生瓶颈。如果有了Web Adaptor,当这1w个请求到达Web Server(集群)时,Adaptor会将这些请求轮询发送到每个可用的GIS Server去,这样每个tomcat就只需支持1w/n个并发即可,可最大限度利用硬件资源。
  以IIS中的Web Adaptor为例(经过Java高手验证WebLogic和WebSphere的Adaptor工作过程与此是完全一致的),看看反编译后的代码。通过查看inetpubwwwrootarcgisWeb.config文件得知,IIS中的Web Adaptor主要的工作过程都集中在ESRI.ArcGIS.WebAdaptor.dll(在GAC目录中)里。这个dll里首先找到两个类:
image  一个Node就对应一个GIS Server机器,_healthy标记该机器的可用状态;NodeManager是所有Node的管理类。Web Adaptor启动时,会调用WebAdaptorConfig.GetMachines()方法,此方法会向http://siteip:port/arcgis/admin/machines发送get请求,获取site内所有GIS Server机器的列表,然后利用UpdateNodeList方法保存在NodeManager类中,并写入WebAdaptor.config文件。
  此外,最重要的是一个叫AGSHandler的类,它实现了IHttpHandler接口:
image  发送到Web Server的GIS请求都会由其中的ProcessRequest方法进行处理。前面说过Web Adaptor是以轮询方式转发请求的,而_currentNodeIndex便记录了请求转发目标GIS Server的在Nodes列表中的索引:
image  Web Adaptor接收到发到Web Server的GIS请求后,首先会读取初始化时保存的WebAdaptor.config配置文件并查看里面存储的GIS Server机器列表,如果读取失败或者机器个数为0,都会响应500的错误。如1所示;接下来会利用try里的TransferRequest方法将请求转发到具体的GIS Server(的tomcat)上去,如果转发的这个机器没有响应,则会在catch中将此机器利用MarkUnHealthy方法标记为不可用;而不论当前节点是否成功接收请求,TransferRequest方法中都会将_currentNodeIndex节点加一,保证下一个请求发送到下一台GIS Server上去,以实现轮询请求的事实:
image image  最后来看看Web Adaptor是如何根据配置文件的间隔时间去追询标记为下线机器的状态,在机器上线后又将它们加回可用机器列表的:
imageimageimage  可以看出,Web Adaptor检测到没有响应的机器后,除了标记其为不可用,也会同时启动一个定时器,此定时器逝去配置文件中的检测下线机器状态时间间隔(分钟)后,会立即将这台机器重新标记为可用,而不会去检测它事实上是否可用。判断机器是否真正可用的过程还是通过前面TransferRequest方法来完成的,即直接向其转发请求,如正常响应,证明其已经在线;如不能正常响应,则再次标记其不可用,重新启动定时器进入下一个轮回…
  大家可以想一想,整个过程是否有不合理的地方呢?

解读ArcGIS Runtime SDKs

  本文试图解读新的ArcGIS Runtime SDKs及其本质,与ArcGIS移动SDK,for iOS/Windows Phone/Android,之间的关系,以及这三种移动SDK后续发展的一些猜想。
  ArcGIS Runtime SDKs是随ArcGIS 10.1 beta一起发布的一套横跨桌面和移动端的,跨平台,轻量级的GIS开发SDK的总称。
image

  从上图中我们可以看出,ArcGIS Runtime SDKs家族包括了以下内容:

  • ArcGIS Runtime SDK for Android
  • ArcGIS Runtime SDK for iOS
  • ArcGIS Runtime SDK for Windows Phone
  • ArcGIS Runtime SDK for Windows Mobile
  • ArcGIS Runtime SDK for Java
  • ArcGIS Runtime SDK for Qt
  • ArcGIS Rutnime SDK for WPF

  之所以说ArcGIS Runtime SDKs横跨桌面和移动端,是因为它既包含了iOS/Windows Phone/Android等移动平台的开发SDK,也包含了可以开发传统桌面程序(C/S程序)的WPF、Java、QT等SDK;而后三种SDK则可开发出Windows和Linux平台下的具有丰富交互效果和良好体验的应用程序。其实ArcGIS Runtime还包括了一些现成的应用程序,比如iOS/Windows Phone/Android各自市场上都能下载到的“ArcGIS”程序,ArcGIS Mobile中的“ArcGIS”程序等。
  说起轻量级,首先要看看ArcGIS 10.1产品架构的一些变化。

image

  ArcGIS 10.1中,产品的划分更加明确和简单。主要分为四个部分,桌面GIS(传统的ArcMap,ArcGlobe等),ServerGIS(全新架构的ArcGIS Server),轻量级GIS(ArcGIS Explorer,Runtime SDKs及其对应的应用程序)和ArcGIS Online。前三部分都是围绕ArcGIS Online这个云GIS平台的,在不同程度上都与ArcGIS Online有交互,或可将数据直接部署上去,或作为它的客户端(云+端)。而轻量级GIS就是为了能够在任何地点,任何平台,任何设备上访问云平台提供的GIS能力。
  ArcGIS Runtime SDKs正是在这种背景下诞生的。其实它也分为狭义和广义上的两种解释。狭义的ArcGIS Runtime SDK是指桌面上的WPF,Java和Qt,它们的消息早在半年前就已经流出。它们的出现,是为了逐步替代强大而相对臃肿的ArcGIS Engine这个产品。做过Engine开发的朋友都知道,即使是最简单的显示地图的需求,理论上都必须在客户机上安装ArcGIS Engine Runtime这个运行时(注意不是ArcGIS Runtime),安装包通常400m左右。而利用新的ArcGIS Runtime SDK for WPF/Java/Qt开发出的程序,完全是绿色程序,不需要在客户机上安装任何部件(.Net Framework和JRE不计)即可运行,因为所有的依赖库直接和程序拷贝在一起即可。如果你喜欢ArcGIS Runtime SDK开发的程序的部署过程——拷贝到u盘里/插入目标计算机/运行,那么你一定也喜欢它的卸载过程——关闭程序/拔掉u盘。
  广义上的ArcGIS Runtime SDKs是上述列表中,诸多SDKs的统称。除了包含狭义的ArcGIS Runtime SDK,可以看到加入了移动端部分:ArcGIS Runtime SDK for iOS/Windows Phone/Android/Windows Mobile,而它们其实是新瓶装旧酒,分别对应以前的ArcGIS SDK for iOS/Windows Phone/Android和ArcGIS Mobile,只是换了产品名称而已。为什么会换名称?为什么还有ArcGIS Mobile这个“另类”的东西?这得从ArcGIS Runtime SDK的功能说起。
  做过ArcGIS Web API(ArcGIS API for Javascript/Flex/Silverlight)开发的朋友,应该可以很快理解狭义Runtime这个产品的所有功能。目前ArcGIS Runtime的功能与ArcGIS Web API,ArcGIS移动API(iOS/Windows Phone/Android)基本相同,都是基于ArcGIS REST API的。比如地图服务(动态/缓存)的加载,GraphicsLayer/FeatureLayer,基于FeatureService的数据编辑,Identify/Find/Query操作,GeometryService,Geoprocessing Service的调用等。它们的开发思路和代码编写几乎是一样的,比如ArcGIS API for Silverlight和目前的ArcGIS Runtime SDK for WPF,如出一辙(后者的前身就是ArcGIS API for WPF)。但狭义上的ArcGIS Runtime SDK与ArcGIS Web API不同之处在于,前者可以加载本地数据,包括Map Package/Tile Package/Locator Package/Geoprocessing Package。Map Package是包括.mxd文档和所有引用数据在内的压缩包,其余类似。最早的Package是9.3.1产品中的LayerPackage,它不仅包含了.lyr图层配置信息,还打包了图层所引用的实际数据。早期的ArcGIS Online平台允许用户上传LayerPackage以便分享,现在看来,直到此时Runtime产品的出现才将Package的概念发扬光大,并且为以后的所谓云GIS提供了更多的数据共享途径。对本地数据的读取是否破坏了基于ArcGIS REST API的框架呢?其实没有。ArcGIS API for WPF/Java/QT中,都内置了一个c++写的Web Server,读取本地数据后,会自动发布成这个Web Server上的REST服务来供Runtime SDK使用,所以一切功能,还是由REST API提供的。收起题外话,ArcGIS Runtime SDK的框架,是针对轻量级GIS产品(不包括ArcGIS Web API)的,它拥有统一的编程模型,可以用一致的开发思路,做出C/S,及移动端应用(Web API开发出B/S应用),为开发人员提供了极大的便利。这也是为什么将它们统称为ArcGIS Runtime SDKs的原因。
  在来说说ArcGIS Runtime for Windows Mobile(原来的ArcGIS Mobile)这个产品。之所以将它也归为ArcGIS Runtime SDK,是不无道理的。使用过ArcGIS Mobile的朋友一定知道,它的一个核心理念就是将数据划分为Basemap Layer和Operational Layer。前者是指起可视化参考作用的数据,一般是栅格底图或地图服务切片;后者是包含矢量信息在内的业务数据。ArcGIS Runtime中所涉及到Package,恰好与之对应。Tile Package对应Basemap Layer,Map Package对应Operational Layer。可以说,ArcGIS Mobile的设计理念,在整个ArcGIS Runtime产品家族中,得到了很好的延续。其实ArcGIS Mobile是个十分优秀的产品……
  到此,新的三个移动SDK(iOS/Windows Phone/Android)也归为ArcGIS Runtime SDKs的原因也就明了了,主要原因是都基于REST API的框架。另外基本可以肯定,它们都会使用相同的数据模型,即各种Package。由此不难推断,以后iOS/Windows Phone/Android平台上移动SDK的离线功能,也会依赖于Tile Package和Map Package。上周刚刚发布的ArcGIS API for iOS 2.1(以后要叫ArcGIS Runtime SDK for iOS)版本中,已经印证了这种猜测——加入了对Tile Package的支持,实现了原生的底图数据离线功能。其它两个移动平台的离线功能,敬请期待。
  由iPad这个产品引发的变革已经展开,移动设备数量正在爆炸性的增长,桌面设备和移动设备之间的概念会越来越模糊。Windows 8的发布预示着微软已经做出了改变,它即可以运行在桌面电脑上,也可以运行在平板设备中。有人说Windows 8的意义对于微软不亚于当年的Windows 95,我同意这个观点。Esri也做出了积极的改变,新的产品体系,新的产品命名,新的ArcGIS Runtime。

ArcGIS Server 10中的切图/缓存机制深入

  两年前我写过一篇关于ArcGIS地图切图/缓存原理的文章,《ArcGIS Server的切图原理深入》,里面以tiling scheme为主,讲了缓存图片的存储结构以及相关坐标的计算。那时还是ArcGIS 9.3版本,现在ArcGIS 10已经推出快一年多了,地图缓存/切图方面有了很大改进,比如增加了compact缓存格式,增加了import/export map server cache工具,增加了mixed图片模式等。这次就在上篇文章的基础上,以ArcGIS 10为例,看看其中地图切图/缓存制作的工作机制。
  注:本文旨在深入了解ArcGIS目前切图(即制作地图服务的缓存)的机制,以帮助工作中有需要的朋友们提高工作效率,因为切图,尤其是大比例尺,耗时耗资源,实在是一件伤不起的工作。这里已经假设你知道了如何为缓存地图服务配置地图如何检查发布地图服务的地图文档的性能,开始动手前务必进行小范围、全比例尺切图试验等等注意事项,如否,请查阅相关资料。

supertile和bundle

  要深入了解ArcGIS在切图时的工作机制,有两个概念必须明白,就是supertile和bundle。
  假设一个tile(切片)的大小是256*256,在切图时如果按照这个大小直接exportmap,开启了动态标注的地图服务上线图层和面图层就会有很多重复的标注。因为exportmap时,每个tile都会包含一个要素的标注,如果一个要素横跨了多个tile(这在大比例尺下基本是肯定的),那么这些tile上就会出现相同的标注,exportmap时并不知道相邻的tile上已经有了该要素的标注。

image

  为了解决这个问题,ArcGIS在切图时引入了supertile的概念,开启抗锯齿时supertile大小为2048*2048,反之为4096*4096。真正切图时会首先exportmap出一个supertile,然后将它们分割成指定大小的tile。对于每个要素,每个supertile中只包含一次标注,这样保证一个superfile大小的范围内不会出现重复标注。事实上在绘制supertile时,会尽可能多地包含周围的标注,所以在每个supertile的边界周围仍会有重复标注。解决重复标注的根本办法就是使用annotation,而不是label。
  ArcGIS 10中推出了新的compact缓存格式,将原来离散的每个tile图片(exploded格式),保存成连续的二进制文件(.bundle),每个.bundle文件最多可存储128*128个tile。相比以前成千上万的tile文件,这样做有明显的好处:易于缓存迁移,减少占用磁盘空间,减少硬盘i/o等,esri在任何时候都推荐使用compact格式来创建缓存,除非你需要自己读取每个tile(技术上来说这点可以不成立)。ArcGIS 10在切图时,也采用了bundle的概念:对于每一级比例尺,首先从tiling scheme origin开始,将切图范围分成若干个bundle,每个bundle覆盖的范围是128*128个tile大小。比如在1:4096比例尺时,如果tile大小是256*256,DPI为96,那么每个bundle范围的大小是:((4096*2.54/96)/100/1000*256*128)^2=1261.086平方千米。之后,有且仅有(这么做是为了避免多个进程同时读写一个磁盘文件)一个服务实例/一个arcsoc.exe进程(如果是high isolated)来负责此bundle范围的切图,先输出supertile,然后再切成tile。即使选择了exploded缓存格式,ArcGIS 10中也会采用这种机制来切图。

image

  9.3.1及以前版本中,每个服务实例工作的单位是supertile。即一个arcsoc.exe负责生成一个supertile,然后切成tile,再继续生成下一个supertile……相比supertile这种处理单位来说,采用bundle作为处理单位的ArcGIS 10中的服务实例可以将更多精力投入到连续切图中去,而不是频繁切换自己负责的范围。在大比例尺切图中,这种新机制能很大程度上减少切图时间;但在小比例尺切图中,这种新机制有可能反而增加切图时间。因为小比例尺时可能全图范围只有不到一个bundle范围大小,这样只会有一个服务实例来切图,其他实例都处于空闲状态,而9.3.1及以前版本中,所有服务实例都会“蜂拥而上”。

image

网格切图和按featureclass范围切图

  有过大比例尺范围切图经验的朋友肯定会知道,一般切图策略是:小比例尺全图直接切,较小比例尺可能按照某个featureclass范围来切,而大比例尺一般是按照包含网格(grid)的featureclass范围来切。以我国全范围切图为例,小比例尺时全图切没有问题,大比例尺时如果仍然全图范围(包络矩形)切的话,会将周边其他的国家也包含进来,这并不需要的额外工作量在大比例尺时会是一场噩梦。

image

  而之所以不仅要按指定featureclass范围切图,而且featureclass里要包含网格的原因在于,便于细化和跟踪切图进度。切图工具会给你指定的featureclass创建一个新的Cached字段,将已经切好的feature标记为YES,以便在选择Recreate Empty Cache时避免重复切图,从而可以将切图工作分为多次来进行,或者以便在切图失败后排查原因,继续切图工作。
  在指定featureclass范围切图时,是顺序处理该featureclass中的所有feature的。所有的服务实例会首先集体处理一个feature范围,切出该feature范围内所有要求的比例尺级别的结果。此时ArcGIS Server会重启该服务。然后所有服务实例再去切下一个feature范围……所以与每个feature边界相交的supertile可能会被创建两次或多次(多个feature的相交处),这也是为什么在使用featureclass切图前,需要分别对它进行GeneralizeAggregateDissolve的原因。

image

  结合之前bundle的机制我们知道,如果一个feature范围恰好只包含一个bundle,那么就杯具了,因为对该feature切图时,只会有一个服务实例进行工作(一个bundle同时由且仅由一个服务实例处理),其他服务实例全部处于空闲状态。因此,比较理想的情况是,每个feature至少包含比服务实例数更多的bundle时,才能充分利用硬件资源来对其切图。
  这就会引出一个问题,就是如何来确定某个比例尺下一个bundle的大小,从而生成这样的featureclass呢?ArcGIS 10中,给我们提供了一个新的GP工具Map Server Cache Tiling Scheme To Polygons,利用它,我们可以针对某个地图服务,生成每个需要切图比例尺下所有的supertile,进而得到以每个supertile为一个feature的featureclass。以全国地图为例,在1:288,895比例尺(ArcGIS Online Tiling Scheme的第12级)下生成的supertile是这样的:

image

  我们需要的是某个比例尺下bundle的范围,如何根据supertile来确定bundle的大小呢?在N级比例尺时,一个supertile是16*16个tile,第N+1级比例尺时,该supertile会覆盖32*32个tile,第N+2级比例尺时,覆盖64*64个tile,第N+3级比例尺时,这个第N级的supertile会覆盖128*128个tile,眼熟吧,这正是一个bundle的大小。由于supertile和bundle都是从tiling scheme origin往右下角算起的,因此第N级一个supertile的范围正是第N+3级一个bundle的范围。由此如果我们要生成第15级的bundle网格,只需要用Map Server Cache Tiling Scheme To Polygons工具生成第12级supertile的网格即可,如上图。
  以此为例,我们来说明如何有效进行大比例尺切图的问题。假设我们需要对1:36,111(ArcGIS Online Tiling Scheme的第15级)这个比例尺进行切图,我们首先生成该范围的bundle网格,恰好是第12级的supertile网格,如上图。为了简便起见,我们只取其中8个feature来做说明,地图服务的最大实例数是4个(机器是单cpu,4核)。如果每个feature恰好是一个bundle,那么一个feature只能被一个arcsoc.exe处理,而其他3个服务实例均处在空闲状态(占用内存最少的那个arcsoc.exe是用来清空工作目录的,与具体服务无关):

image

  而我们对这个featureclass做一个处理,将4个feature(恰好是一个bundle)合并成一个feature(bundle cluster),这样每个feature就恰好包含了4个bundle,如此我们所开启的4个服务实例就可全速工作了,发挥了机器的最大性能:

image

  ps:Map Server Cache Tiling Scheme To Polygons工具生成的supertile是从tiling scheme origin开始计算的,而不是地图服务的fullextent左上角,因此利用它生成的supertile合并出来的bundle是最合理的,恰好与理想的bundle分界处一致。因此在大比例尺下利用featureclass切图时,应当利用Map Server Cache Tiling Scheme To Polygons来生成网格,而不是fishnet工具。在ArcGIS 10.1中,将会推出新的GP工具,会根据cpu核数来生成合理的包含bundle cluster大小feature的featureclass。
  其他方面还有一些问题,比如切图时最大服务实例数设置多少为好(一般是cpu核数+1),即使所有实例全部工作cpu占用率依然低于90%(有可能是内存不足)等问题,与切图机制无关,就不在此讨论了。
  总之,切图是一个技术活,要求还比较高,需要考虑的问题很多。如果你只把它当一项体力活来看的话,只能说明认识还不够全面,那就不能怪ArcGIS Server不好。毕竟,人家ArcGIS Online全球的19级缓存都7*24小时上线两年了,还有什么理由说产品不好呢?

任务管理器中arcsom.exe和arcsoc.exe的个数问题

        安装了ArcGIS Server的机器,当打开任务管理器的时候,会看到里面有arcsom.exe和arcsoc.exe进程,但它们的数量具体是如何决定的呢?以下的分析仅针对单机配置的情况(假定所有部件都安装在一台机器上),对于分布式的安装,可以此类推。
        GIS Server是由一个SOM(Server Object Manager)和若干个SOC(Server Object Container)机器组成。SOM会在机器里以arcgissom账户启动一个ArcSOM.exe的进程,这个进程负责管理(启动和停止)其他SOC进程(ArcSOC.exe),SOC进程虽然是由SOM启动,但是以arcgissoc账户运行的。arcsom.exe启动时,会自动启动两个arcsoc.exe,一个用于记录AGS的日志,一个用于清空特定的工作目录。这两个arcsoc.exe在任务管理器中可以根据所占用的内存数与其他arcsoc.exe区分开来,如图,占用内存较少的两个arcsoc.exe便是由SOM进程自动启动的,而其他的arcsoc.exe则是由具体service启动的。

        插入一些概念。用户请求一个service时,是和该service的一个instance打交道。service有pooled和non pooled两种。对于pooled service来说,一个用户(或者应用程序)请求该服务时,会随机获得一个该服务已经创建的instance的引用,由该instance对请求做出响应;请求完成后,用户会立即释放该instance的引用,使其返回假想的instance pool中,用户发出另一个请求,重复上面的过程。如果是non pooled service,用户第一次发出请求时,也会随机获得该service已经创建的一个instance引用,但请求处理完成后,该用户继续持有对该instance的引用,直到用户断开与服务器的连接(结束程序),该instance会被销毁,然后SOM会创建一个新的instance来维持数量。对于pooled service,又有low isolation和high isolation两种。high isolation是指service的每个instance都会独占一个进程(arcsoc.exe),low isolation则是指一个进程内可保有多个(默认是8哥,最多可达256个)instance(就是所谓的多线程)。low isolation的好处是可以启动相对少的arcsoc.exe来维持同样数量的instance,节约服务器的内存资源;但如果一个arcsoc.exe崩溃,那么里面的所有instance都会被销毁,即使用户正在使用它们。high isolation的优缺点则与之相反。一般来说,对于pooled service使用high isolation设置。non pooled service的instance总是独占一个进程(同high isolation)。另外可以指定一个服务的最小和最大instance数目,服务启动时会自动创建最小数目的instance等待调用;当创建的instance数目达到最大数量时,所有的请求都会进入等待队列。
        至此,可以来分析一个具体的案例了。现在机器上总共有2个服务:
World:pooled,low isolation(8 instance per process),min-instance:9, max-instance:16 ,随机启动
China: non pooled ,min-instance:2, max-instance:4,手动启动。
        开机,SOM启动一个arcsom.exe,随后启动两个arcsoc.exe;World服务启动,创建9个instance,其中8个instance公用一个arcsoc.exe,剩下一个instance启动另外一个arcsoc.exe。此时机器中共有1个arcsom.exe,4个arcsoc.exe。此时手动启动China服务,创建2个instance,每个instance会启动一个arcsoc.exe。此时,机器中共有1个arcsom.exe,6个arcsoc.exe。
        观察统计可知,最小instance数量为1的服务启动时间平均在17秒左右(cpu:Intel T7200)。可以看出,对于经常不用的服务,我们可以将它设置成手动启动,一来节约内存,二来加快机器启动速度。