lizongbo at 618119.com 工作,生活,Android,前端,Linode,Ubuntu,nginx,java,apache,tomcat,Resin,mina,Hessian,XMPP,RPC

2011年05月5日

从google的json接口获取地理位置信息的Java代码

Filed under: IP,Java,JavaScript — 标签:, , , , , — lizongbo @ 22:55

从google的json接口获取地理位置信息的Java代码

google 提供了公开的接口,通过,这个接口,根据gps或基站信息或wifi热点信息来获取当前位置的地理信息.
gps信息是经纬度,基站信息是基站的cellid等信息,wifi热点信息是wifi的mac地址是热点名字,信号强度等。
因此可以通过java程序获取相应信息,在LBS项目中可以用上:

api接口定义描述在:

http://code.google.com/p/gears/wiki/GeolocationAPI

Java代码如下:

[code]

package com.lizongbo.geo;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;

import com.lizongbo.org.json.JSONArray;
import com.lizongbo.org.json.JSONException;
import com.lizongbo.org.json.JSONObject;

/**
* 从google的json接口获取地理位置信息的代码
*
* @author lizongbo
*
*/
public class GeoTest {

/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
String url = “http://www.google.com/loc/json”;
JSONObject json = new JSONObject();
json.put(“version”, “1.1.0”);
json.put(“host”, “maps.618119.com”);
json.put(“home_mobile_country_code”, 460);// 国家代码
json.put(“home_mobile_network_code”, 0);// 移动运营商代码
json.put(“radio_type”, “gsm”);
json.put(“carrier”, “lizongbo”);
json.put(“request_address”, true);
json.put(“address_language”, “zh_CN”);
JSONArray jsoncells = new JSONArray();
json.put(“cell_towers”, jsoncells);
JSONArray jsonwifis = new JSONArray();
json.put(“wifi_towers”, jsonwifis);
JSONObject jsoncell = new JSONObject();
jsoncell.put(“mobile_country_code”, 460);// 国家代码,mcc
jsoncell.put(“mobile_network_code”, 0);// 移动运营商代码,mnc
jsoncell.put(“location_area_code”, 9364);// 位置区域代码,lac
jsoncell.put(“cell_id”, “3851”);// 移动基站id
// jsoncell.put(“age”, 0);
// jsoncell.put(“signal_strength”, -70);
// jsoncell.put(“timing_advance”, 7777);
jsoncells.put(jsoncell);
JSONObject jsonwifi = new JSONObject();
// jsonwifi.put(“mac_address”, “00-11-22-33-44-55”);
// jsonwifi.put(“signal_strength”, 8);
// jsonwifi.put(“age”, 0);
// jsonwifis.put(jsonwifi);
// jsonwifi = new JSONObject();
jsonwifi.put(“mac_address”, “00-55-44-33-22-11”);//
jsonwifi.put(“ssid”, “TPLINK_618119”);// 无线路由器的名字
jsonwifi.put(“signal_strength”, 8);// 信号强度
jsonwifi.put(“age”, 0);
// jsonwifis.put(jsonwifi);

System.out.println(json.toString());
System.out.println(downloadUrlbyPOST(url, json.toString(), null,
“UTF-8”));

}

public static String downloadUrlbyPOST(String urlStr, String query,
String referer, String encoding) throws Exception {
String line = “”;
StringBuilder sb = new StringBuilder();
HttpURLConnection httpConn = null;
try {
URL url = new URL(urlStr);
System.out.println(urlStr + “?” + query);
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(
“proxy.lizongbo.com”, 8080));
proxy = Proxy.NO_PROXY;
httpConn = (HttpURLConnection) url.openConnection(proxy);
httpConn.setDoInput(true);
httpConn.setDoOutput(true);
httpConn.setRequestMethod(“POST”);
if (referer != null) {
httpConn.setRequestProperty(“Referer”, referer);
}
httpConn.setConnectTimeout(5000);
// httpConn.getOutputStream().write(
// java.net.URLEncoder.encode(query, “UTF-8”).getBytes());
httpConn.getOutputStream().write(query.getBytes());
httpConn.getOutputStream().flush();
httpConn.getOutputStream().close();

BufferedReader in = null;
if (httpConn.getResponseCode() != 200) {
System.err.println(“error:” + httpConn.getResponseMessage());
in = new BufferedReader(new InputStreamReader(httpConn
.getErrorStream(), “UTF-8”));
} else {
in = new BufferedReader(new InputStreamReader(httpConn
.getInputStream(), “UTF-8”));
}
while ((line = in.readLine()) != null) {
sb.append(line).append(‘\n’);
}
// 关闭连接
httpConn.disconnect();
return sb.toString();
} catch (Exception e) {
// 关闭连接
httpConn.disconnect();
System.out.println(e.getMessage());
throw e;
}
}
}

[/code]
运行结果如下:
{“address_language”:”zh_CN”,”wifi_towers”:[],”host”:”maps.618119.com”,”radio_type”:”gsm”,”home_mobile_country_code”:9364,”carrier”:”lizongbo”,”home_mobile_network_code”:460,”cell_towers”:[{“mobile_network_code”:0,”cell_id”:”3851″,”mobile_country_code”:460,”location_area_code”:9364}],”request_address”:true,”version”:”1.1.0″}
http://www.google.com/loc/json?{“address_language”:”zh_CN”,”wifi_towers”:[],”host”:”maps.618119.com”,”radio_type”:”gsm”,”home_mobile_country_code”:9364,”carrier”:”lizongbo”,”home_mobile_network_code”:460,”cell_towers”:[{“mobile_network_code”:0,”cell_id”:”3851″,”mobile_country_code”:460,”location_area_code”:9364}],”request_address”:true,”version”:”1.1.0″}
{“location”:{“latitude”:22.522185,”longitude”:113.925618,”address”:{“country”:”中国”,”country_code”:”CN”,”region”:”广东省”,”city”:”深圳市”,”street”:”滨海大道辅路”},”accuracy”:620.0},”access_token”:”2:618119:lizongbo”}

试了一下把无线路由器的mac地址发到 https://www.google.com/loc/json ,google果然返回很准的定位看来google是把我用手机测试定位的时候就把数据采集分析好了,确实强大。

2010年12月23日

java.net.URL设置代理服务器和自定义Host头绕过DNS解析

Filed under: DNS,IP — 标签:, , , , , , , — lizongbo @ 00:34

在實際工作中,由于办公网络的限制,连接外网访问时需要指定代理,

而访问某些虚拟主机域名的服务器时,并不存在对应的dns解析记录,因此需要手工配置hosts文件来进行映射,非常麻烦。

于是根据java.net.URL的api整理了设置代理服务器和自定义Host头绕过DNS解析的方法:

代码如下:

[code]

public static void main(String[] args) throws IOException {
/**
* 下面这种方法是全局方式的设置 ,不建议使用。 System.setProperty(“proxySet”, “true”);
* System.setProperty(“proxyHost”, “proxy.lizongbo.com”);
* System.setProperty(“proxyPort”, “8080”);
*/
String urlStr = “http://about.me/lizongbo”;
urlStr = “http://about.me/lizongbo”;
HttpURLConnection httpConn = null;
StringBuilder sb = new StringBuilder();
URL url = new URL(urlStr);
String hostName = url.getHost();
// 根据配置自定义url里的ip地址
if (hostName.toLowerCase().endsWith(“.mqq.im”)) {
url = new URL(urlStr.replace(hostName, “127.0.0.1”));
}
System.out.println(url);
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(
“proxy.lizongbo.com”, 8080));
// 只针对当前这个连接使用http代理
httpConn = (HttpURLConnection) url.openConnection(proxy);
httpConn.setRequestMethod(“GET”);
// 手工设置Host头信息以支持虚拟主机,通过这样的方式,可以避免去手工配置/etc/hosts来绕过dns解析的麻烦,尤其是程序经常在不同服务器上运行的时候,非常实用
httpConn.setRequestProperty(“Host”, hostName);
httpConn.setConnectTimeout(5000);
httpConn.connect();
InputStream is = httpConn.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is,
“UTF-8”));
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line).append(‘\n’);
}
// 关闭连接
httpConn.disconnect();
System.out.println(sb);
}

[/code]

2008年01月29日

关于分布式负载均衡的几个设置

Filed under: DNS,JavaScript — 标签:, , , — lizongbo @ 08:38

服务器对外的展现要统一,简洁。
即用户在URL里看到的地址是很方便记忆的。

而对于页面中嵌入的图片,脚本,样式表,视频,音频等文件,则可以放在其它服务器上。

第一层: DNS记录轮询负载均衡
www.google.com为例进行分析
1.首先是将 www.google.com,指定多个cname,根据不同的网络线路请求得到不同的别名

比如在中国得到的别名为:www.l.google.com,
www.l.google.com 的别名为: www-china.l.google.com

www-china.l.google.com再指定多个ip的a记录,
例如 ip 64.233.189.99, 64.233.189.104,64.233.167.147.

99,104,147这三个ip分别实现ip别名绑定,即如果99这个ip挂了,104会自动接管该ip到本机。

通过这样的方式,保证用户最终访问到的ip始终在线。

在cname解析的地方,可以使用多层cname解析,以实现更细粒度的负载均衡并灵活切换。

假设当www-china.l.google.com下整个节点都断网了,则只需要将www.l.google.com指向www-usa.l.google.com这样就可以切换了。

(纯属猜测:指定了cname的域名,则不要再配置a记录,因为a记录的优先级比cname高。)

dns解析过程记录如下:

[code]
E:\>nslookup
DNS request timed out.
timeout was 2 seconds.
*** Can’t find server name for address 192.168.18.1: Timed out
*** Default servers are not available
Default Server:  UnKnown
Address:  192.168.18.1

> server 202.96.128.86
DNS request timed out.
timeout was 2 seconds.
Default Server:  [202.96.128.86]
Address:  202.96.128.86

> server 202.96.128.86
Default Server:  cache-a.guangzhou.gd.cn
Address:  202.96.128.86

> set q=cname
> www.google.com
Server:  cache-a.guangzhou.gd.cn
Address:  202.96.128.86

Non-authoritative answer:
www.google.com  canonical name = www.l.google.com
> www.l.google.com
Server:  cache-a.guangzhou.gd.cn
Address:  202.96.128.86

Non-authoritative answer:
www.l.google.com        canonical name = www-china.l.google.com
> www-china.l.google.com
Server:  cache-a.guangzhou.gd.cn
Address:  202.96.128.86

l.google.com
primary name server = f.l.google.com
responsible mail addr = dns-admin.google.com
serial  = 1331146
refresh = 900 (15 mins)
retry   = 900 (15 mins)
expire  = 1800 (30 mins)
default TTL = 60 (1 min)
> set q=a
> www-china.l.google.com
Server:  cache-a.guangzhou.gd.cn
Address:  202.96.128.86

Non-authoritative answer:
Name:    www-china.l.google.com
Addresses:  64.233.189.99, 64.233.189.104

[/code]

(也可用这个命令查询: dig @202.96.128.86 www.google.com +trace)

第二层,服务端请求分发。

前端的ip得到客户端的请求,并不是在本机进行业务逻辑处理,而是对请求进行初步解析过滤,再分发给其它服务器进行处理,
请求分发规则通常是基于url的,也可根据其它附加条件进行分发,例如GET/POST,user-Agent,remoteAddr,urlhash等。

第三层:客户端分发请求。

通常用于对图片资源的请求进行分发,按找浏览器的默认限制,对同一服务器的并发连接不超过2个,
因此,假设一个网页里要显示40张图片,而这40张图片,如果使用同一个域名的话,及时后台做了请求分发,
而受浏览器的限制,假设一秒中下载两张图,打开这40张图片,也需要20秒,

而在采取客户端分发请求的模式,将图片的链接自动分布的请求到远程多台服务器,那么以同时请求5台为例,则相当于将对网站的并发请求提高了 5倍,
获得了了10个并发请求。
不光是图片资源,其它资源也都可以采取这种模式,url的动态分布,可以在服务端生成html代码的时候完成,
也可以在html的Javascript中预先存放一个可用服务器列表

www.flickr.com为例:

http://farm1.static.flickr.com/
http://farm2.static.flickr.com/
http://farm3.static.flickr.com/
……
http://farmx.static.flickr.com/

Older Posts »

Powered by WordPress