服務地址和接口已經更改,新的使用手冊在:http://www.guzzservices.com/2010/man_ip_service/
一.功能介紹
通過傳入的IP地址,返回IP所在的地理位置。如傳入“58.16.209.19”,返回“貴州省六盤水市 ”。
返回的地理位置又分為3種精確度,程序可以按照自身需要選擇。三種精確度分別為:地區(qū)(省直轄市級),城市(地市級),詳細位置。例如對于“58.16.209.19”,三種精度的值為:
- 地區(qū):貴州
- 城市:貴州省六盤水市
- 詳細地址:六枝特區(qū)騰龍網吧
二.3行代碼實現地域查詢
-
- IPLocationService ipService = (IPLocationService) GuzzWebApplicationContextUtil.getGuzzContext(session.getServletContext()).getService("IPService") ;
-
-
- LocationResult result = (LocationResult) ipService.findLocation("58.16.209.19").get() ;
-
-
- System.out.println("城市:" + result.cityName) ;
三.性能如何?
上面的第1步需要獲取IP反查服務,此服務有3個實現客戶端,一個為遠程方法調用(phprpc協議實現,類似hessian的一個協議),一個是socket長連接,一個nio。
針對這兩種實現,在內網下進行性能測試。測試方法:單線程,串行執(zhí)行查詢請求。查詢IP:59.66.106.0,返回地理位置:清華大學。
性能測試結果:
PHPRPC實現:執(zhí)行1000次查詢,耗時1339ms。
Socket實現:執(zhí)行1000次查詢,耗時84ms;執(zhí)行10000次查詢,耗時843ms。
NIO socket實現:執(zhí)行1000次查詢,耗時115ms;執(zhí)行10000次查詢,耗時1247ms。
Socket長連接模式為連接池實現,可以配置多個socket并行計算。對于絕大部分的應用,應該都能滿足要求。PHPRPC為短連接,每次查詢都建立一個http連接進行查詢。
四.如何配置到我的系統(tǒng)中?
上面的IP反查為guzz的服務,因此需要應用程序首先將guzz框架配置進去。Guzz框架不具有應用侵入性,不會影響現有系統(tǒng)運轉。配置方法:http://code.google.com/p/guzz/wiki/TutorialConfig
Guzz框架整合完畢后,只需要將IP反查服務在guzz中聲明即可。聲明包含3步(以socket的IP服務為例):
1. 將IP反查的實現jar包放到項目lib中。Jar包在附件中,包含源代碼。
2. 在guzz.xml中增加此服務:
- <service name="IPService" configName="fundIPServiceSocketClient" class="org.guzz.service.dir.impl.socket.IPLocationServiceSocketClientImpl" />
3. 配置服務參數(guzz的properties文件):
- [fundIPServiceSocketClient]
- pool.maxActive=5
- host=services.guzz.org
- port=11546
參數中包含連接池大小,服務地址和端口。
配置完服務以后,就可以按照上一節(jié)的方式進行IP反查了。如附件中的示例jsp實現。
五.LocationResult介紹
執(zhí)行查詢時,返回的是LocationResult對象,此對象有一些方法和變量按照不同精確度和用途存儲地理信息。LocationResult介紹:
-
- public class LocationResult implements Serializable {
-
-
- public String cityMarker ;
-
-
- public String cityName ;
-
-
- public String detailLocation ;
-
-
- public String areaName ;
-
-
-
-
- public String getMarkedCityName(){
- if(cityMarker == null){
- return cityName ;
- }else{
- return cityMarker + cityName ;
- }
- }
-
- public String toString(){
- StringBuilder sb = new StringBuilder() ;
- sb.append("cityMarker:").append(cityMarker)
- .append("cityName:").append(cityName)
- .append("detailLocation:").append(detailLocation)
- .append("areaName:").append(areaName) ;
-
- return sb.toString() ;
- }
-
- }
六.我的查詢請求不多,如何配置phprpc方式的查詢(不需要保持socket連接池)?
第1步:在系統(tǒng)中配置phprpc框架。詳細請參看:http://phprpc.org
第2步:將剛才guzz.xml中IPService服務換成PHPRPC實現:
- <service name="IPService" configName="fundIPServiceClient" class="org.guzz.service.dir.impl.IPLocationServiceClientImpl" />
第3步:配置服務參數(properties文件):
- [fundIPServiceClient]
- rpc.protocol=phprpc
- 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反查可不可以異步執(zhí)行? 可以。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行代碼即可。
附件下載地址:http://dl.javaeye.com/topics/download/08c5a323-0c58-3fd7-a2ca-07a4dd9aa199