• ArcGIS Server 优化


    名词解释及翻译: 
    Instances (In Use/Running) : 
    实例的使用状态。 In Use 代表正在使用中的实例数。 Running 代表已经创建的实例数。 
    Minimum number of instances : 最小实例个数。 
    Maximum number of instances : 最大实例个数。 
    The maximum time a client will wait to get a service : 客户端等待获取服务的最大时间。

    首先,简单介绍一下 ArcGIS 池化与非池化服务的原理。 ArcGIS ADF 框架在使用池化服务时,只是在程序需要的时候在实例池中获取一个实例,此时 In Use 加 1 。使用完毕后立即释放回实例池(注意是释放而不是关闭),等待下一次被再次重用,此时 In Use 减 1 。这就是为什么池化实例一经创建就不会减少的原因。这中间并没有创建以及关闭实例的过程(Running 的数目不变),因此池化服务相对于非池化服务而言使用效率是很高的。

                                                     图1

          而在使用非池化服务时,则是在浏览器会话开始时创建一个实例,此时 In Use 与 Running 各加 1 。而在浏览器会话结束后关闭实例,此时 In Use 与 Running 各减 1 。因此,非池化服务在长时间闲置的情况下实例数( Running )会减少,而池化服务只会释放回实例池,而不会真正减少实例数。

                                                      图2

    那么是否池化服务的实例数( Running )就不会增加了呢?当然不是了,只不过在一般情况下你先后打开两次地图是无法增加实例个数的。那么什么时候才会增加呢?答案就是在并发的情况下才会增加实例数。 
    通常情况下啊,如果我们先后打开两次地图。在第一次打开地图,并获取地图的时候, ADF 会从实例池获取一个实例,此时 In Use 加 1 ,等到地图在浏览器中显示完成后, ADF 马上释放实例回实例池,此时 In Use 减 1 。由于池化服务的高性能,从获取实例到释放实例通常只需要 1 秒左右。因此在大多数时候当我们去看池化服务的 In Use 时总是显示为 0 。而非池化服务就不同了,只要在你会话有效期内 In Use 总是不为 0 的。接下来,当我们第二次打开地图的时候,由于之前使用过的实例已经被释放回实例池了,因此在第二次获取实例的时候 ADF 又重用了之前的实例。所以新的实例并不需要被创建( Running 不变),只需要重用即可。 
    但是在并发的情况下就不同了。如果同时有两个或多个请求打开地图,当实例池中实例数( Running )不够时, ArcGIS 才会创建一个新的实例,此时 In Use 与 Running 各加 1 。 
    讲了那么多,现在来讲讲如何优化吧! 
    1. 针对池化服务实例数只能增加无法减少的情况进行优化 
    通常在设置池化服务时,都有 Minimum number of instances 和 Maximum number of instances 两 个设置项。 ESRI 的建议是前者设置为 1 而后者设置为系统的最大并发数。但我不认为只是最好的设置方式。如果最大实例数设置为系统的最大并发数,或许可以解决问题。但是由于池化服务实例数只增不 减的特性,一旦某一时刻并发达到最大值,则实例池中的实例数同时也会达到这一个最大值。但是系统的并发量并不总是维持在最大并发量,大多时候都是远远小于 最大并发值。因此这会导致大量闲置的实例。同时,由于最小实例数设置为 1 ,则每次当实例不够用时 ArcGIS 都需要反复创建实例,这对性能以及客户体验的影响是很大的。 
    因此,我的建议是把最小值与最大值设为同样的值,并且该值小于系统最大并发数。至于该值该如何设置需要通过多次测试以达到最佳性能为宜。同时,要适当增大 The maximum time a client will wait to get a service 的值。该值的意思就是当并发数大于最大实例数时,系统等待多久以重用被释放回实例池的实例。 
    2.
    针对非池化服务的实例无法及时关闭的情况进行优化 
    非池化服务在长时间闲置的情况下会自动关闭。但是这里究竟需要闲置多久才关闭。我没有找到相应的说明。总之默认情况下的结果是我们所不能接受的。这就需要我们自己动手了。具体的做法可以有很多,这里我就讲一下原理: 
    在地图初始化之后,把实例的相关信息发送到服务器端保存起来。然后在客户端通过 Ajax 每过一定时间就发送一个实例保持的信号,服务器端单独开一个线程来检查信号。由于 Ajax 是客户端代码,依赖于浏览器执行。因此如果一个实例对应的信号在 3 个周期之后仍旧没有发送到服务器端。则认为相应的浏览器页面已经被关闭,此时可手动关闭该实例。 
    3. 针对一个应用混合多个地图服务的情况进行优化 
    在项目实际应用中,单一的地图服务通常是不够用的。以下图为例,下图所示系统共使用 4 个地图服务,四个地图服务以如下顺序叠加产生地图:

                                         图3

    多个地图服务叠加生成地图,这虽然带来一定得灵活性,但这是以牺牲性能为代价换来的,在一般的应用中,性能往往是我们更关注的。那么有没有方法可以鱼和熊掌兼得呢?正规的方法是不行的,那只有用非正规的方法。 
    在介绍我的方法前,先来了解一下 ArcGIS 的缓存。 ArcGIS 的缓存分两种,一种是融合所有图层的缓存生成方式,我称之为融合模式。另一种是将各图层分离单独生成多个图层缓存的方式,我称之为多层模式。融合模式的好 处是速度快,但是缺点也同样明显——无法动态更新图片,因此所有涉及到得添加,删除或者显示 / 隐藏图层都无法在融合模式上表现出来。多层模式可以选择需要制作缓存的图层。在显示地图的时候,通过把各个已生成缓存的图层的图片和动态绘制的未生成缓存 的图层的要素相叠加,生成一张图片。此模式在已生成缓存的图层和未生成缓存的图层都不多的情况下,性能较好。反之,则性能很差。 
    下面就开始介绍我的方法: 
    1)
    首先把图 1 中地图服务 2 和地图服务 4 以融合模式分别生成缓存。 
    2) 新建一个 MXD 文件,把地图服务 1 所涉及的图层全都加入该 MXD 的图层列表。 
    3) 在 MXD 中随意加入一个图层到图层列表的最底端,选择图层状态为可视,并且不设置任何显示级别。 
    4) 把地图服务 3 所涉及的图层全部加入 MXD 图层列表的最低端。 
    5) 重复步骤 3 。 
    6) 以该 MXD 建立地图服务 5 ,并以多层模式生成步骤 3 以及步骤 5 中两个图层的缓存。 
    7)
    找到 ArcGIS 缓存存放目录。该目录下共有三个地图服务所生成的缓存,分别以地图服务 2 、地图服务 4 以及地图服务 5 的名称命名。打开地图服务 5 的缓存目录,找到以步骤 3 中图层名称命名的文件夹,把在步骤 1 中生成的地图服务 2 的缓存拷贝、覆盖到该目录。 
    8)
    同上,找到以步骤 5 中图层名称命名的文件夹,把在步骤 1 中生成的地图服务 4 的缓存拷贝、覆盖到该目录。 
    至此,混合了融合模式和多层模式的地图缓存就算建立完成了。打开地图查看一下效果是不是和原来的一样!上面的方法从原理上还是多层模式的缓存机制,只不过 采用之前生成的融合后的缓存图片替换了单一图层的缓存图片。而 ArcGIS 并不知道图片已经被替换,仍旧会按照预定的方式把缓存叠加到最终生成的地图中去,这正好被我们利用。使用此方法生成的地图服务理论上的性能至少不会差于多 个地图服务混合的方式,但究竟性能如何还有待实践证明。

    名词解释及翻译: 
    Instances (In Use/Running) : 
    实例的使用状态。 In Use 代表正在使用中的实例数。 Running 代表已经创建的实例数。 
    Minimum number of instances : 最小实例个数。 
    Maximum number of instances : 最大实例个数。 
    The maximum time a client will wait to get a service : 客户端等待获取服务的最大时间。

    首先,简单介绍一下 ArcGIS 池化与非池化服务的原理。 ArcGIS ADF 框架在使用池化服务时,只是在程序需要的时候在实例池中获取一个实例,此时 In Use 加 1 。使用完毕后立即释放回实例池(注意是释放而不是关闭),等待下一次被再次重用,此时 In Use 减 1 。这就是为什么池化实例一经创建就不会减少的原因。这中间并没有创建以及关闭实例的过程(Running 的数目不变),因此池化服务相对于非池化服务而言使用效率是很高的。

                                                     图1

          而在使用非池化服务时,则是在浏览器会话开始时创建一个实例,此时 In Use 与 Running 各加 1 。而在浏览器会话结束后关闭实例,此时 In Use 与 Running 各减 1 。因此,非池化服务在长时间闲置的情况下实例数( Running )会减少,而池化服务只会释放回实例池,而不会真正减少实例数。

                                                      图2

    那么是否池化服务的实例数( Running )就不会增加了呢?当然不是了,只不过在一般情况下你先后打开两次地图是无法增加实例个数的。那么什么时候才会增加呢?答案就是在并发的情况下才会增加实例数。 
    通常情况下啊,如果我们先后打开两次地图。在第一次打开地图,并获取地图的时候, ADF 会从实例池获取一个实例,此时 In Use 加 1 ,等到地图在浏览器中显示完成后, ADF 马上释放实例回实例池,此时 In Use 减 1 。由于池化服务的高性能,从获取实例到释放实例通常只需要 1 秒左右。因此在大多数时候当我们去看池化服务的 In Use 时总是显示为 0 。而非池化服务就不同了,只要在你会话有效期内 In Use 总是不为 0 的。接下来,当我们第二次打开地图的时候,由于之前使用过的实例已经被释放回实例池了,因此在第二次获取实例的时候 ADF 又重用了之前的实例。所以新的实例并不需要被创建( Running 不变),只需要重用即可。 
    但是在并发的情况下就不同了。如果同时有两个或多个请求打开地图,当实例池中实例数( Running )不够时, ArcGIS 才会创建一个新的实例,此时 In Use 与 Running 各加 1 。 
    讲了那么多,现在来讲讲如何优化吧! 
    1. 针对池化服务实例数只能增加无法减少的情况进行优化 
    通常在设置池化服务时,都有 Minimum number of instances 和 Maximum number of instances 两 个设置项。 ESRI 的建议是前者设置为 1 而后者设置为系统的最大并发数。但我不认为只是最好的设置方式。如果最大实例数设置为系统的最大并发数,或许可以解决问题。但是由于池化服务实例数只增不 减的特性,一旦某一时刻并发达到最大值,则实例池中的实例数同时也会达到这一个最大值。但是系统的并发量并不总是维持在最大并发量,大多时候都是远远小于 最大并发值。因此这会导致大量闲置的实例。同时,由于最小实例数设置为 1 ,则每次当实例不够用时 ArcGIS 都需要反复创建实例,这对性能以及客户体验的影响是很大的。 
    因此,我的建议是把最小值与最大值设为同样的值,并且该值小于系统最大并发数。至于该值该如何设置需要通过多次测试以达到最佳性能为宜。同时,要适当增大 The maximum time a client will wait to get a service 的值。该值的意思就是当并发数大于最大实例数时,系统等待多久以重用被释放回实例池的实例。 
    2.
    针对非池化服务的实例无法及时关闭的情况进行优化 
    非池化服务在长时间闲置的情况下会自动关闭。但是这里究竟需要闲置多久才关闭。我没有找到相应的说明。总之默认情况下的结果是我们所不能接受的。这就需要我们自己动手了。具体的做法可以有很多,这里我就讲一下原理: 
    在地图初始化之后,把实例的相关信息发送到服务器端保存起来。然后在客户端通过 Ajax 每过一定时间就发送一个实例保持的信号,服务器端单独开一个线程来检查信号。由于 Ajax 是客户端代码,依赖于浏览器执行。因此如果一个实例对应的信号在 3 个周期之后仍旧没有发送到服务器端。则认为相应的浏览器页面已经被关闭,此时可手动关闭该实例。 
    3. 针对一个应用混合多个地图服务的情况进行优化 
    在项目实际应用中,单一的地图服务通常是不够用的。以下图为例,下图所示系统共使用 4 个地图服务,四个地图服务以如下顺序叠加产生地图:

                                         图3

    多个地图服务叠加生成地图,这虽然带来一定得灵活性,但这是以牺牲性能为代价换来的,在一般的应用中,性能往往是我们更关注的。那么有没有方法可以鱼和熊掌兼得呢?正规的方法是不行的,那只有用非正规的方法。 
    在介绍我的方法前,先来了解一下 ArcGIS 的缓存。 ArcGIS 的缓存分两种,一种是融合所有图层的缓存生成方式,我称之为融合模式。另一种是将各图层分离单独生成多个图层缓存的方式,我称之为多层模式。融合模式的好 处是速度快,但是缺点也同样明显——无法动态更新图片,因此所有涉及到得添加,删除或者显示 / 隐藏图层都无法在融合模式上表现出来。多层模式可以选择需要制作缓存的图层。在显示地图的时候,通过把各个已生成缓存的图层的图片和动态绘制的未生成缓存 的图层的要素相叠加,生成一张图片。此模式在已生成缓存的图层和未生成缓存的图层都不多的情况下,性能较好。反之,则性能很差。 
    下面就开始介绍我的方法: 
    1)
    首先把图 1 中地图服务 2 和地图服务 4 以融合模式分别生成缓存。 
    2) 新建一个 MXD 文件,把地图服务 1 所涉及的图层全都加入该 MXD 的图层列表。 
    3) 在 MXD 中随意加入一个图层到图层列表的最底端,选择图层状态为可视,并且不设置任何显示级别。 
    4) 把地图服务 3 所涉及的图层全部加入 MXD 图层列表的最低端。 
    5) 重复步骤 3 。 
    6) 以该 MXD 建立地图服务 5 ,并以多层模式生成步骤 3 以及步骤 5 中两个图层的缓存。 
    7)
    找到 ArcGIS 缓存存放目录。该目录下共有三个地图服务所生成的缓存,分别以地图服务 2 、地图服务 4 以及地图服务 5 的名称命名。打开地图服务 5 的缓存目录,找到以步骤 3 中图层名称命名的文件夹,把在步骤 1 中生成的地图服务 2 的缓存拷贝、覆盖到该目录。 
    8)
    同上,找到以步骤 5 中图层名称命名的文件夹,把在步骤 1 中生成的地图服务 4 的缓存拷贝、覆盖到该目录。 
    至此,混合了融合模式和多层模式的地图缓存就算建立完成了。打开地图查看一下效果是不是和原来的一样!上面的方法从原理上还是多层模式的缓存机制,只不过 采用之前生成的融合后的缓存图片替换了单一图层的缓存图片。而 ArcGIS 并不知道图片已经被替换,仍旧会按照预定的方式把缓存叠加到最终生成的地图中去,这正好被我们利用。使用此方法生成的地图服务理论上的性能至少不会差于多 个地图服务混合的方式,但究竟性能如何还有待实践证明。


  • 相关阅读:
    一年后重翻javascript
    针对thinkphp 5框架存储过程bug而重写的存储过程的扩展类
    移动应用端的支付宝支付php开发流程
    android studio 开发中启动android项目报错sdk版本不一致解决方案
    正则表达式(一)
    linux下memcached安装以及启动
    linux如何添加服务为系统服务快速启动或关闭
    js或者jquery直接下载网页上的图片代码
    onethink多图上传
    php+redis实现多台服务器内网存储session并读取
  • 原文地址:https://www.cnblogs.com/merray/p/2511206.html
Copyright © 2020-2023  润新知