Terry.Li-彬

虚其心,可解天下之问;专其心,可治天下之学;静其心,可悟天下之理;恒其心,可成天下之业。

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  143 随笔 :: 344 文章 :: 130 评论 :: 0 Trackbacks
一.功能介绍  

通过传入的IP地址,返回IP所在的地理位置。如传入“58.16.209.19”,返回“贵州省六盘水市 ”。 

返回的地理位置又分为3种精确度,程序可以按照自身需要选择。三种精确度分别为:地区(省直辖市级),城市(地市级),详细位置。例如对于“58.16.209.19”,三种精度的值为: 

Java代码 
  1. 地区:贵州     
  2. 城市:贵州省六盘水市    
  3. 详细地址:六枝特区腾龙网吧  

二.3行代码实现地域查询 

Java代码 
  1. //第1行,获取IP反查服务(JSP中写的)  
  2. IPLocationService ipService = (IPLocationService) GuzzWebApplicationContextUtil.getGuzzContext(session.getServletContext()).getService("IPService") ;  
  3.   
  4. //第2行,执行查询。findLocation方法传入要查询的IP地址。  
  5. LocationResult result = (LocationResult) ipService.findLocation("58.16.209.19").get() ;  
  6.   
  7. //第3行,按照精确度要求,读取地理位置  
  8. System.out.println("城市:" + result.cityName) ;  

三.性能如何? 

上面的第1步需要获取IP反查服务,此服务有3个实现客户端,一个为远程方法调用(phprpc协议实现,类似hessian的一个协议),一个是socket长连接,一个nio。 

针对这两种实现,在内网下进行性能测试。测试方法:单线程,串行执行查询请求。查询IP:59.66.106.0,返回地理位置:清华大学。 

性能测试结果: 

PHPRPC实现:执行1000次查询,耗时1339ms。 

Socket实现:执行1000次查询,耗时84ms;执行10000次查询,耗时843ms。 

NIO socket实现:执行1000次查询,耗时115ms;执行10000次查询,耗时1247ms。 

Socket长连接模式为连接池实现,可以配置多个socket并行计算。对于绝大部分的应用,应该都能满足要求。PHPRPC为短连接,每次查询都建立一个http连接进行查询。 

四.如何配置到我的系统中? 

上面的IP反查为guzz的服务,因此需要应用程序首先将guzz框架配置进去。Guzz框架不具有应用侵入性,不会影响现有系统运转。配置方法:http://code.google.com/p/guzz/wiki/TutorialConfig 

Guzz框架整合完毕后,只需要将IP反查服务在guzz中声明即可。声明包含3步(以socket的IP服务为例): 

1. 将IP反查的实现jar包放到项目lib中。Jar包在附件中,包含源代码。 

2. 在guzz.xml中增加此服务: 
Xml代码 
  1. <service name="IPService" configName="fundIPServiceSocketClient" class="org.guzz.service.dir.impl.socket.IPLocationServiceSocketClientImpl" />  

3. 配置服务参数(guzz的properties文件): 
Properties代码 
  1. [fundIPServiceSocketClient]  
  2. pool.maxActive=5  
  3. host=services.guzz.org  
  4. port=11546  

参数中包含连接池大小,服务地址和端口。 

配置完服务以后,就可以按照上一节的方式进行IP反查了。如附件中的示例jsp实现。 

五.LocationResult介绍 

执行查询时,返回的是LocationResult对象,此对象有一些方法和变量按照不同精确度和用途存储地理信息。LocationResult介绍: 
Java代码 
  1.       
  2. public class LocationResult implements Serializable {  
  3.       
  4.     /**如:对于国外地区,值为“海外”;对于cityName中不包含省市信息的,如“清华大学”,值为地区名称,如“北京”*/  
  5.     public String cityMarker ;  
  6.   
  7.     /**查询地市级名称,如:贵州省六盘水市*/  
  8.     public String cityName ;  
  9.       
  10.     /**详细地址,如:六枝特区腾龙网吧*/  
  11.     public String detailLocation ;  
  12.       
  13.     /**地区名称,精确到省;对于国外,统一为:海外*/  
  14.     public String areaName ;  
  15.       
  16.     /** 
  17.      * 返回标记后的城市名称。此名称用于进行程序内的城市匹配,不用于对网友显示。 
  18.      */  
  19.     public String getMarkedCityName(){  
  20.         if(cityMarker == null){  
  21.             return cityName ;   
  22.         }else{  
  23.             return cityMarker + cityName ;  
  24.         }  
  25.     }  
  26.       
  27.     public String toString(){  
  28.         StringBuilder sb = new StringBuilder() ;  
  29.         sb.append("cityMarker:").append(cityMarker)  
  30.           .append("cityName:").append(cityName)  
  31.           .append("detailLocation:").append(detailLocation)  
  32.           .append("areaName:").append(areaName) ;  
  33.           
  34.         return sb.toString() ;  
  35.     }  
  36.       
  37.     }  

六.我的查询请求不多,如何配置phprpc方式的查询(不需要保持socket连接池)? 

第1步:在系统中配置phprpc框架。详细请参看:http://phprpc.org 

第2步:将刚才guzz.xml中IPService服务换成PHPRPC实现: 
Java代码 
  1. <service name="IPService" configName="fundIPServiceClient" class="org.guzz.service.dir.impl.IPLocationServiceClientImpl" />  

第3步:配置服务参数(properties文件): 
Properties代码 
  1. [fundIPServiceClient]  
  2. rpc.protocol=phprpc  
  3. rpc.serviceURL=http://services.guzz.org/service/IPService  

七.其他: 

1. JDK1.6+。如果使用JDK1.5,将源代码在1.5下编译即可。 

2. 没看明白如何配置服务? 看这里:http://code.google.com/p/guzz/wiki/TutorialService 

3. IP反查可不可以异步执行? 可以。ipService.findLocation(ip)返回的就是异步接口,在需要的时候调用get()即可;异步方法也支持超时,调用getOrCancel(5L, TimeUnit.SECONDS)可以让接口最多等待5秒,随后超时返回null。如果服务端故障,ipService.findLocation(ip)返回null。 

4. 为什么会返回null? 没有查询到就返回null,null也很有用,如网易评论中的“火星网友”。 

5. 支持spring IOC吗? 支持。如果使用spring,IPService可以通过spring bean配置并进行注入。这样只需要2行代码即可。 

posted on 2010-11-17 22:29 礼物 阅读(479) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。

网站导航: