首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

IP 地址歸屬地查詢:新浪/淘寶/騰訊 API 對比與高併發優化實戰

     編輯:Java 綜合教學

主流免費 IP 歸屬地 API 對比

服務商介面地址回傳格式頻率限制準確度適用場景
新浪https://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js&ip=JavaScript 變數無明確限制國內較高中小型專案、批次離線解析
淘寶https://ip.taobao.com/service/getIpInfo.phpJSON約 10 QPS/IP高(淘寶大數據)電商/高準確度需求
騰訊https://apis.map.qq.com/ws/location/v1/ipJSON需 Key,免費額度高(騰訊位置服務)正規商業專案、需 HTTPS
ip-api.comhttps://ip-api.com/json/JSON45 req/min 免費全球覆蓋國際化業務

新浪 API 實作範例(同步 HTTP + 正則解析)

public class IpLocationUtil {
    private static final String SINA_API = "https://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js&ip=";

    public static String getLocationBySina(String ip) {
        if (StringUtils.isBlank(ip)) return null;
        try {
            String url = SINA_API + ip;
            String resp = HttpClientUtil.get(url); // 封裝 HttpClient/GetMethod
            // 回傳範例:var remote_ip_info = {"ret":1,"start":"...","end":"...","country":"中國","province":"廣東","city":"廣州","district":"天河","isp":"電信","type":"","desc":""};
            String ret = StringUtils.substringBetween(resp, "\"ret\":", ",");
            if (!"1".equals(ret)) return null;
            String province = decodeUnicode(StringUtils.substringBetween(resp, "\"province\":", ","));
            String city = decodeUnicode(StringUtils.substringBetween(resp, "\"city\":", ","));
            String district = decodeUnicode(StringUtils.substringBetween(resp, "\"district\":", ","));
            String isp = decodeUnicode(StringUtils.substringBetween(resp, "\"isp\":", "}"));
            return province + city + district + isp;
        } catch (Exception e) {
            log.error("IP查詢失敗: {}", ip, e);
            return null;
        }
    }

    // Unicode \uXXXX 解碼
    private static String decodeUnicode(String str) { ... }
}

淘寶 API 實作(POST + JSON 解析)

public String getLocationByTaobao(String ip) {
    String url = "https://ip.taobao.com/service/getIpInfo.php";
    String param = "ip=" + ip;
    String json = HttpClientUtil.post(url, param); // 回傳 JSON 字串
    // {"code":0,"data":{"ip":"...","country":"中國","region":"廣東","city":"廣州","county":"天河","isp":"電信","area_id":"440100"}}
    JSONObject obj = JSON.parseObject(json);
    if (obj.getIntValue("code") != 0) return null;
    JSONObject data = obj.getJSONObject("data");
    return data.getString("country") + data.getString("region") + data.getString("city") + data.getString("county") + data.getString("isp");
}

高併發場景三大優化策略

1. 本地快取(Guava/Caffeine)

// 單機百萬級 IP 去重率極高,快取命中率 > 95%
private static final Cache<String, String> IP_CACHE = Caffeine.newBuilder()
    .maximumSize(100_000)
    .expireAfterWrite(30, TimeUnit.DAYS)
    .build();

public String getLocationCached(String ip) {
    return IP_CACHE.get(ip, k -> fetchFromApi(k)); // 原子獲取或計算
}

2. 批次異步預熱

  • 離線任務:每日從日志提取去重 IP,多執行緒呼叫 API 落庫 ip_location 表。
  • 線上服務:直接查本地資料庫/Redis,毫秒級回應,零外部依賴。

3. 連線池與超時控制

HttpClientBuilder.create()
    .setMaxConnTotal(200)
    .setMaxConnPerRoute(50)
    .setDefaultRequestConfig(RequestConfig.custom()
        .setConnectTimeout(2000)
        .setSocketTimeout(5000)
        .build())
    .build();

實測效能數據(單機 8 核 16G)

方案10 萬 IP 耗時成功率備註
同步逐個呼叫淘寶~2.5 小時60%(頻繁 429/超時)不可用
同步逐個呼叫新浪~10 分鐘95%可接受
本地快取 + 新浪~30 秒(含首次)99%+生產推薦
離線批次入庫 + Redis 查詢離線 5 分鐘 / 線上 1ms100%高併發標配

避坑指南

  1. 內網 IP(10.x, 172.16-31.x, 192.168.x)直接返回「內網」,不呼叫 API。
  2. IPv6:上述免費介面多不支援,需用 ip-api.com 或付費服務。
  3. 編碼陷阱:新浪回傳 JS Unicode,必須 decodeUnicode;淘寶回傳 UTF-8 JSON,直接解析。
  4. 法律合規:免費介面無 SLA,核心業務請採購商業授權(如 ipip.net、MaxMind GeoIP2 離線庫)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved