发出来时候总是没有,故分两段发续上文:
(3)导出为jar包,放到SuperMap iServerJava 6R安装目录下\webapps\iserver\WEB-INF\lib下即可。
(4)找到SuperMap iServerJava 6R安装目录下\webapps\iserver\WEB-INF\config\services.xml文件,然后在相应模块添加Component及接口配置,具体可以参考SuperMap iServerJava 6R相关配置管理模块。
component配置
配置Component <component class="com.zhangwei.Extend.InWithComponent" interfaceNames="inWith" name="InWithCom" providers="ugcDataProvider-World"></component>
配置interface <interface class="com.zhangwei.Extend.ISWithInServlet" name="inWith"></interface>
2、使用apache的测试工具ab测试url如下:扩展测试url:http://172.16.2.23:8090/iserver/services/InWithCom/inWith?in={"resultSetting":{"returnEdgeFeatures":true,"returnEdgeGeometry":true,"returnEdgeIDs":true,"returnNodeFeatures":true,"returnNodeGeometry":true,"returnNodeIDs":true,"returnPathGuides":true,"returnRoutes":true},"turnWeightField":"TurnCost","weightFieldName":"length"}测试命令:测试命令 ab -n 10000 -c 100 http://172.16.2.23:8090/iserver/services/InWithCom/inWith?in={"resultSetting":{"returnEdgeFeatures":true,"returnEdgeGeometry":true,"returnEdgeIDs":true,"returnNodeFeatures":true,"returnNodeGeometry":true,"returnNodeIDs":true,"returnPathGuides":true,"returnRoutes":true},"turnWeightField":"TurnCost","weightFieldName":"length"}测试结果:测试结果C:\Program Files\Apache Software Foundation\Apache2.2\bin>ab -n 10000 -c 100 http://172.16.2.23:8090/is
WithCom/inWith?in={"resultSetting":{"returnEdgeFeatures":true,"returnEdgeGeometry":true,"returnEdgeIDs"
Features":true,"returnNodeGeometry":true,"returnNodeIDs":true,"returnPathGuides":true,"returnRoutes":tr
eld":"TurnCost","weightFieldName":"length"}
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 172.16.2.23 (be patient)
Server Software: Apache-Coyote/1.1
Server Hostname: 172.16.2.23
Server Port: 8090
Document Path: /iserver/services/InWithCom/inWith?in={resultSetting:{returnEdgeFeatures:true,r
:true,returnEdgeIDs:true,returnNodeFeatures:true,returnNodeGeometry:true,returnNodeIDs:true,returnPathG
Routes:true},turnWeightField:TurnCost,weightFieldName:length}
Document Length: 15116 bytes
//并发粒度为100个,即每次发送100个请求
Concurrency Level: 100
Time taken for tests: 2.606 seconds //测试总耗时
Complete requests: 173 //完成请求数数
Failed requests: 1 //失败的请求数
(Connect: 0, Receive: 0, Length: 1, Exceptions: 0)
Write errors: 0
Total transferred: 2654717 bytes //传输数据总量
HTML transferred: 2630183 bytes //传输的html数据总量
Requests per second: 66.77 [#/sec] (mean) //平均每秒处理事务数量,即请求个数。
Time per request: 1497.787 [ms] (mean) //平均事务请求时间,即每次请求耗费时间
Time per request: 14.978 [ms] (mean, across all concurrent requests) //每个请求实际运行时间的平均值
Transfer rate: 1006.20 [Kbytes/sec] received //平均每秒网络上的流量,可以帮助排除是否存在网络流量过大导致响应时间延长的问题
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.5 0 2
Processing: 20 647 742.2 276 2543
Waiting: 20 647 742.2 276 2543
Total: 20 647 742.2 276 2544
//下面的内容为整个场景中所有请求的响应情况
Percentage of the requests served within a certain time (ms)
50% 313
66% 872
75% 1217
80% 1472
90% 2119
95% 2279
98% 118
99% 29
100% 539 (longest request)
3、测试结果分析
初次接触ab工具,分析参数大多从网上抄袭,多多见谅。从分析结果上来看每秒处理大概66个左右,请求耗费时间也挺长,但是在10000访问,100并发情况下访问效率尚可,有进一步优化空间如:
(1)component层为测试数据准备方便进行两次查询,查询出点和面几何对象,更为实际的接口应该是点传参数传过来,而面对象可能查询获取或者也直接传过来,更好的情况是直传参传到后台,这样虽然提高了传输数据量但是减少了查询时间,可以调高的效率应该很高,另外用户交互过程中可能涉及情况不同,所以直接进行传参可能效率更高,交互性更好些,当然需要根据情况综合考虑。
(2)参数传递此处直接封装死到代码中,可能会有效率上的损耗。
(3)可以考虑多个servlet来处理,这样更符合tomcat容器的处理servlet的特点,但是此处未考虑,后续再加。
上面是一次针对自己封装的接口测试,并不能代表SuperMap iServerJava 6R真实请求处理并发量。
今天突然给了个任务让测试点在面内算法,然后通过SuperMap iServerJava 6R发布出来并测试并发访问性能。好久没结果Java突然有点乱,胡子眉毛一把抓,不过思路总算清晰起来了,记录下来以备后需查找吧。
测试总体思路
1、扩展领域开发开出点在面内REST接口。
(1)扩展Component。
扩展Component
(2)扩展服务接口,由于是测试,此处不用Restlet或者JAX-RS,此处为了模拟数据传输对服务器影响,所以直接加了参数解析及返回结果,其实只是测试之用。
扩展接口
上篇文章讨论了Java调用 SuperMap iServer Java6R的REST API 比较直接,直接自己拼URL,比较费劲,今天发现SuperMap iServer Java6R的SP1版中提供了RestMapProvider 等接口,意味着可以直接调用 iServer-all的 jar包即可。
准备:
1、启动iServer 6R服务。
代码:
使用RestMapProvider
得到输出结果:
http://localhost:8090/iserver/services/maps/rest/maps/%E4%B8%96%E7%95%8C%E5%9C%B0%E5%9B%BE/image.png?viewer=%7B%22leftTop%22%3A%7B%22y%22%3A0%2C%22x%22%3A0%7D%2C%22rightBottom%22%3A%7B%22y%22%3A512%2C%22x%22%3A512%7D%7D&cacheEnabled=false&rectifyType=BYCENTERANDMAPSCALE&clipRegion=%7B%22center%22%3Anull%2C%22id%22%3A0%2C%22style%22%3Anull%2C%22parts%22%3Anull%2C%22points%22%3Anull%2C%22type%22%3A%22REGION%22%7D&clipRegionEnabled=false&customEntireBoundsEnabled=false&angle=0.0&antialias=true&colorMode=DEFAULT&dynamicProjection=false&markerAngleFixed=false&maxVisibleTextSize=1000.0&maxVisibleVertex=3600000&minVisibleTextSize=0.3&overlapDisplayed=true&paintBackground=true&textAngleFixed=false&textOrientationFixed=false¢er=%7B%22y%22%3A27.5734580668%2C%22x%22%3A96.1736997712%7D&scale=2.563206512274041E-8&layersID=tu45quuz_fc28ec230a514c45a2217b8db661b191&imageFormat=PNG&noLayers=true&transparent=false输入浏览测试,得到效果图如下
此处简单使用了RestMapProvider接口,后续再对程序进行升级扩展,做出一个C/S小系统。
今天客户问起预缓存生成需要多少时间、多上张图片,上次计算缓存张数已经是去年的事情了,时间较久就翻了翻以前的记录和研发的同事记录如下,以供后续参考吧。
计算前需要准备的内容:
1、DPI,一般普通PC的DPI为72-96,此处考虑Deskpro出预缓存时候设置出图与设备无关,所以直接通过CustomMapRatioX及CustomMapRatioY值计算了,DPI = CustomMapRatioX * 25.4(一般CustomMapRatioX = CustomMapRatioY,CustomMapRatioX值可以参考Deskpro安装目录/bin/supermap.ini文件中值) 。
2、地图范围,即左右及上下距离,此处参考Deskpro 出预缓存索引范围如下图
得出上下距离:如图得出 7612.6676397641 米
左右距离:如上图得出 8910.4536856326 米
3、图片大小 一般 为256或者512像素。
4、英寸 = 2.54 厘米
5、地球赤道长度 = 40073700 米
6、比例尺。
计算思路如下:
1、推算出每张图片的实际地理距离 ((512 像素 / DPI) * 2.54 * 比例尺) / 100 。
2、如果数据单位是米,则上下左右距离 / 每张图片的实际地理距离 ----取整后 相乘即可。
3、如果数据单位是度,则根据 (地球赤道长度 / 360 ) * 上下 (左右)实际地理距离,此处实际上要考虑高纬度及低纬度的区别,由于此处是估算,所以暂且考虑相同。
注意:此处由于是切图,所以计算出左右 应该切的地图张数后 +1 或者 +2即可。
例子:
长春地图:
参数值:图片大小 512像素,上下 (7612.6676397641 )、左右(8910.4536856326 ) ,比例尺1000,DPI = 3.5 * 25.4 = 88.9
即值为上下切的图块 数目为 = 7612.6676397641 / ((( 512 / 88.9 ) * 2.54 * 1000 ) / 100) = 53 + 1
左右的图块 数目为 = 8910.4536856326 / ((( 512 / 88.9 ) * 2.54 * 1000 ) / 100) = 61 + 1
图块个数为 = 上下图块数目 * 左右图块数目 = 54 * 62 = 3348 可以参考和Deskpro计算相同。
中国地图:
参数值:图片大小 512 像素 ,上下(49.724654913)、左右(61.5884246827),比例尺 1000000,DPI = 88.9
每度代表的 地理长度 = 40073700 / 360
上下切块数目 = ((40073700 / 360 )*49.724654913) / ((( 512 / 88.9 ) * 2.54 * 1000000 ) / 100) = 38 + 1
左右切块数目 = ((40073700 / 360 )*61.5884246827) / ((( 512 / 88.9 ) * 2.54 * 1000000 ) / 100) = 47 + 1
图块个数为 = 上下图块数目 * 左右图块数目 = 48 * 39 = 1872,如下图所示
总结:上面粗略的估计了地图的缓存切块的个数,由于SuperMap Deskpro中地图是以比例尺,而不是空间分辨率来表达地图的,所以会涉及到DPI的相关计算,相关概念可以参考WIKI百科。
最近总是碰到有人问Java如何访问SuperMap iServerJava6R的服务,由于目前SuperMap iServerJava6R不支持RMI访问访问,所以考虑使用Java直接访问REST的API。
环境准备:
1、开发工具 MyEclipse,服务器iServerJava6R
2、HttpComponents及Org.json类库,第一个http协议的开源Java客户端工具库,org.json是Json库,这两个都在iServerJava6R依赖库中,直接调用即可。如下图为所用类库,可以直接在iServerJava6R安装目录下\webapps\iserver\WEB-INF\lib找到:
3、iServerJava6R的REST API的文档
开发思路:
1、根据REST API构造参数类。
2、调用HttpComponents发送请求,解析结果
3、展现结果,一般使用地图
实现一个简单的吧,就调用distance,量算距离,上代码吧:
1、参数类,distance接口需要两个参数一个是Point2D数组,另外一个是一个枚举单位,我一般习惯使用以米为单位,所以直接用单位METER了。
参数类
2、发送请求与解析,这里distance接口是一个get请求,所以构造调用HttpComponents的HttpGet对象,代码如下:
请求发出与解析
备注:这个地方比较纠结,我第一用HttpComponents碰到比较多的问题列举如下阅读时候可以参考一下:
(1)url可以直接获取,即http://localhost:8090/iserver/services/map-world/rest/maps/世界地图/distance.rjson,但是不能直接用,因为需要对中文进行编码,而且不能直接调用URLEncoder直接对这个url整体进行编码,此处我图简单直接对 世界地图 进行编码为:/%E4%B8%96%E7%95%8C%E5%9C%B0%E5%9B%BE,所以url为http://localhost:8090/iserver/services/map-world/rest/maps/%E4%B8%96%E7%95%8C%E5%9C%B0%E5%9B%BE/distance.rjson,可以逐段解析url进行编码。
(2)、如果直接用org.json类库中JSONArray构造解析Point2D数组,解析结果不太对,所以我直接构造一个toJSONArray来对Point2D数组进行处理。
(3)、默认浏览器对url进行编码处理时候使用的是utf-8编码,而且iServerJava6R对请求返回结果的编码为utf-8。
3、结果展示,此处偷懒了直接调用println函数输出。
长度为1570277.6641936298 METER
上面只是一个简单的思路介绍,也许对高手很简单,但是毕竟初次学习,记录下来以备后查吧。
最近碰到这样的问题地图切换而要保持地图中心点及比例尺不变,而且不同地图的图片格式也不同,解决过程颇费周章,写出来供大家分享吧。
其实问题的起源挺简单的,由于Google地图的大行其道,配置两幅地图影像及矢量地图是一般WebGIS工程中常见到的方案,好处当然是显而易见,影像直观,矢量精细。所以作为一个WebGIS开发基础平台,SuperMap IS.NET急切需要支持这种需求。
从SuperMap IS.NET 5.3.6开始支持两种切换地图模式,在MapControl初始化参数中switchMapMode来设置,文档解释如下:
1. 每次切换地图时以当前地图范围的中心点和比例尺为地图显示视窗的中心点和比例尺,该模式为默认模式,值为0。
2. 每次切换地图时以上一幅地图的地图范围的中心点和比例尺为地图显示视窗的中心点和比例尺,即保持上一幅地图的中心点和比例尺,值为1。该模式主要被采用于基于同一幅地图但在不同领域有不同应用(其数据不同)的场景,如基于同一幅世界地图的林业领域数据和气象领域数据。
但是上述参数也有个限制,那就是图片格式,一般情况下影像的出图格式为jpg,矢量的推荐png,这样切换地图时候如果地图做了预缓存就没法做修改了,而且switchMapMode也有限制只能用于AjaxScripts开发模式,AjaxControl开发模式就没法设置了,根据反复测试及研究服务器相关参数找到解决方案如下:
1、使用地图服务管理工具发布地图之后设置添加如下地图图中地图名字根据自己工作空间设置,1500及1501都是地图名字。
图1
2、设置每副地图的格式相关设置,如图2
图2
设置1500地图的图片格式为png,其他设置在默认地图设置选项中已经设置,可以不用管了。1501地图设置同上。
3、修改SuperMap.IS.Utility.js文件中的_CreateMapControl函数的params.imageFormat = imageFormat;代码为params.imageFormat = "png52";png52为一个错误或者不支持的图片格式,此处给了个不存在的格式png52。注意此处修改了系统类库,所以建议升级工程时候注意下。
4、工程初始化MapControl时候设置的图片格式为一个地图默认需要的即可,或者不用填写。
5、然后调用
此代码保持了地图的中心点及比例尺,当然可以随意设置比例尺中心点。
至此该需求已经给出基本方案,当然现在只能满足AjaxControl及AjaxScripts开发模式,至于MapControl开发模式,后台代码直接修改即可。不用这么破费周章了。iClient for 6R for silverlight等富客户端的话服务端每个地图都只是相当于客户端的一个图层,而且图层都有设置请求的图片格式,所以天然满足此需求,不用解释了。
最近一个同事测试SuperMap iServer Java 6R性能,问及集群配置及进程内集群的概念,就索性自己配置测试一下,算是SuperMap iServer Java 6R集群研究的第二篇吧。
还是从概念了解起,原理如下:在 SuperMap iServer 中,服务提供者提供的 GIS 功能通过服务组件封装成粗粒度的模块,然后发布为不同类型的服务。即服务请求到达服务组件后,是由服务组件寻找对应的服务提供者,由服务提供者最终处理的。
SuperMap iServer 进程内集群是指将进程内提供同种 GIS 功能的服务提供者组成逻辑意义上的集群,从而提高服务器单机环境下高并发访问时的效率。
例如将 World.sxwu 工作空间发布为 GIS 服务,想提高单服务器环境下,该 GIS 服务高并发访问时的效率,可以在服务提供者层使用 World.sxwu 工作空间构建两个服务提供者,如 ugcMapProvider-World 和 ugcMapProvider-World1,然后将以上两个服务提供者同时供服务组件使用并发布为 GIS 服务,该 GIS 服务处理高并发访问时,就比普通的 GIS 服务具有更高的稳定性和效率(此处说明下,UDB的数据源也可以配置为多个Provider)。
注意,不同数据来源的服务提供者只要提供了相同的 GIS 功能,也可以组成进程内集群。例如 wmsMapProvider-World 是由远程 WMS 服务构建的服务提供者,它提供了跟 ugcMapProvider-World 同样的 GIS 功能,那么就可以把 wmsMapProvider-World 也加入进程内集群,从而进一步提升高并发访问时 GIS 服务的稳定性和效率。另外,服务提供者也可以和服务提供者集合组成进程内集群,前提是服务提供者与服务提供者集合中的某个服务提供者具有相同的 GIS 功能。
图1
前面讨论了进程内集群的相关注意事项,下面配置为一个测试环境,即如何配置进程内集群并且测试使用上了集群。
1、打开服务管理器,添加多个(这里以两个为例)具有相同 GIS 功能的地图服务提供者,如 map1和map2,配置参考下图2及3。配置服务提供者map1
配置服务提供者map2如下图3
图3
2、配置完成之后配置一个服务组件,配置效果图4
图4
3、配置完成之后可以直接浏览服务实例mapcon/rest,则随意照一张地图浏览,即可如下图5
图5
点击silverlight浏览可以出图。
此时有两个方案可以看到是否使用上了集群
a)使用Httpwatch这些请求跟踪工具,可以看到下图6可以看到有图片是从http://localhost:8090/iserver/output/cache下取出的,也有从http://localhost:8090/iserver/outputC/cache下取出。
b)可以直接浏览图片生成目录,看到两个目录下均有图片,而且图片生成时间一致。
进程内集群总算是简单配置完成,实际部署还需要综合考虑性能与部署情况,上面部署方式加大了服务组件层请求并发数压力,所有请求都要经过组件层,如果把图片服务器分出来就最好了,而且图片位于两个目录下还是一个目录下性能最优需要性能测试来验证吧,另外从请求返回结果来看,所有返回图片请求均分从两个图片服务器出来,看来服务提供者只是简单的进行了均分吧。另外后续部署考虑缓存存放位置也是一个值得考虑的地方。上面是个简单的进程内集群的介绍及测试方案,望大家指正。











