首页 > 自考资讯 > 高考百科

全网上线 IP 归属地功能,一文教你如何实现?ip地址归属精确位置查询

小条 2024-09-23

细心的朋友可能已经发现,抖音、知乎、快手、小红书等平台都推出了“网络用户显示IP功能”。国际用户将看到国家,国内用户将看到省份。无法关闭项目并强制显示位置。

作为一个网友,你可能只是看看节目,但作为一个勤奋的程序员,你应该看看这个功能是如何实现的。今天的文章我们将讲解这个功能是如何实现的。

1获取用户 IP 地址

HttpServletRequest 获取 IP

首先,让我们看看如何在Java 中获取IP 区域。有两个主要步骤。

通过HttpServletRequest对象获取用户的“IP”地址通过IP地址获取对应的州和城市】首先用户的每个Request请求都包含请求的IP地址,所以这里获取IP地址写一个工具类来您可以通过在请求头中添加来截取请求中的IP,从而获取IP 地址。

/** * 网络工具类* * @author a href='https://github.com/liyupi'程序员的鱼皮/a * @from a href='https://yupi.icu'编程导航知识星球/a */public class NetUtils {/** * 获取客户端IP地址* * @param request * @return */public static String getIpAddress(HttpServletRequest request) { String ip=request.getHeader('x-forwarded-for') if (ip==null | | ip.length()==0 || 'unknown'.equalsIgnoreCase(ip)) { ip=request.getHeader('代理客户端IP') } if (ip==null || ip.length( )==0 | | 'unknown'.equalsIgnoreCase(ip)) { ip=request.getHeader('WL-Proxy-Client-IP') } if (ip==null || ip.length() | | 'unknown'.equalsIgnoreCase(ip )) { ip=request.getRemoteAddr(); if (ip.equals('127.0.0.1')) { //根据网卡获取本机配置的IP InetAddress inet=null try { inet=InetAddress. getLocalHost(); } catch (Exception e) { e.printStackTrace(); } if (inet !=null) { ip=inet.getHostAddress() } } //对于多个代理,第一个IP是真实的IP客户。多个IP按照“,”进行划分。 if (ip !=null ip.length() 15) { if (ip.indexOf(',') 0) { ip=ip.substring(0, ip.indexOf(',')); } } //本地access if ('localhost'.equalsIgnoreCase(ip) || '127.0.0.1'.equalsIgnoreCase(ip) || ' 0:0:0:0:0:0:0:1'.equalsIgnoreCase(ip)){ //根据网卡InetAddress获取I在本机配置的IP会。 try { inet=InetAddress.getLocalHost() } catch (UnknownHo) stException e ) { e.printStackTrace(); } } //如果没有找到IP,则返回127.0.0.1,可以做一些具体处理,但不考虑//if (ip==null) { //return '127.0.0.1'; //} return ip; } /** * 获取MAC 地址*/public static String getMacAddress() throws Exception { //获取MAC 地址byte[] macAddressBytes=NetworkInterface.getByInetAddress(InetAddress.getLocalHost()).getHardwareAddress(); //以下代码获取MAC 地址。该地址被组装到StringStringBuilder 中。 sb=new StringBuilder(); for (int i=0; i macAddressBytes.length; i++) { if (i !=0) { sb.append('-') } //mac[i ]0xFF 转换为a正整数String s=Integer.toHexString(macAddressBytes[i]0xFF);==1 ? 0 + s : s); } return sb.toString( ).trim().toUpperCase (); 1010

2获取用户的 IP 地址属地

通过该方法,可以从请求头中获取IP地址所属的州和城市。在这里您可以使用各种IP地址查询库进行查询。要测试的库是:

淘宝IP地址数据库:ip.taabao.com/

818d20dd75cc4a1bbe3c003926ff0896~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1727653551&x-signature=RWXM6NllCDGMyjYtXe20cLI%2B6rs%3D 然而,淘宝IP地址查询库于2022年3月31日下线。这里已经不能用了,我们得另想办法。

c8e34f9604b64673ae53b6cad290efb2~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1727653551&x-signature=k88uxTQ%2FjWut9rK862fMxmvgtyA%3D这里,我们截取之前淘宝分配IP地址的源码,一起看一下。

正如您在这里看到的,日志文件中有很多由于用户问题而超过最大qps 的请求。

这种方法已经传播,但是放弃求知之路可以吗?绝对不可能。这里我们介绍Ip2region,一种获取IP地址位置的新方法,它是今天文章的主角。

淘宝库获取用户 IP 地址属地

这是我们在上一篇文章中看到的Gthub开源项目,Ip2region开源项目。

地址是:https://github.com/lionsoul2014/ip2region

该开源库已更新至V2版本,成为强大的离线IP地址定位库和IP定位数据管理框架,为多种主流编程语言提供XDB数据。我想说客户端实现非常容易使用。今天的文章主要讨论V2版本。如果您想查看1.0版本的内容,请访问Github。

Ip2region 介绍

3Ip2region 详解

数据由多个知名IP聚合至地名查询提供商,官方测试后准确度比传统良性IP定位更准确。

ip2region 的数据来自开放API 或来自以下服务提供商的数据(每秒升级程序请求2-4 次):比例为:

80%,淘宝IP地址数据库,ip.taabao.com/%5C10%,GeoIP,geoip.com/%5C2%,无罪IP数据库,www.cz88.net/%5C

高达 99.9 % 的查询准确率

Ip2region V2.0 特性

xdb支持数亿个IP数据段行。默认地区信息固定格式:国家|地区|省|城市|ISP。默认区域信息为0。

区域信息支持完全定制。例如,您可以添加根据您所在区域的特定业务需求定制的数据,例如GPS 信息/国际本地区号/邮政编码。这意味着您可以使用ip2region 来管理您自己的IP 位置数据。

1、IP 数据管理框架

xdb 格式生成器自动删除重复数据并压缩某些数据。生成的ip2region.xdb 数据库随着数据变得更加详细而逐渐增长。

2、数据去重和压缩

单次查询响应时间在10 微秒范围内,即使对于完全基于xdb 文件的查询也是如此。可以通过两种方式启用内存加速查询:

vIndex Index Cache:使用固定的512KiB内存空间来缓存向量索引数据,减少一次IO磁盘操作,平均查询效率稳定在10~20微秒之间。整个xdb 文件缓存:将整个xdb 文件加载到内存中。内存占用与xdb文件大小相同,保持微秒级的查询效率。

3、极速查询响应

已有客户端:Java、C#、php、C、Python、Node.js、PHP 扩展(PHP 5 和PHP 7)等。主要有:

d99c10e674b34cb68059fa9feb7df910~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1727653551&x-signature=29JFiR4EELm7XFjv8rti6BilsHo%3D

多语言以及查询客户端的支持

下面是Java 实现的简单演示。这里我们采用开发中常用的Maven实现方式。

Ip2region xdb Java 查询客户端实现

由于项目是使用Spring构建的,因此您可以选择在此处部署Spring starter。

依赖groupIdcom.github.hiwepy/groupId artifactIdip2region-spring-boot-starter/artifactId version2.0.1.RELEASE/version/dependency 依赖groupIdorg.lionsoul/groupId artifactIdip2region/artifactId version2.7.0/version/dependency 引入Maven 依赖然后,安装为接下来。有几种方法可以实现这一目标:

1. 引入 Maven 仓库

import org.lionsoul.ip2region.xdb.Searcher;import java.io.*;import java.util.concurrent.TimeUnit;public class SearcherTest { public static void main(String[] args) { //1. 创建searcher object String dbPath='ip2region.xdb 文件路径'; try { searcher=Searcher.newWithFileOnly(dbPath) } catch (IOException e) { System.out.printf(' 无法使用`%s 创建搜索器`: %s\n', dbPath, e) } //2. 查询尝试{ String ip='1.2.3.4'; String area=searcher.search(ip) ); toMicros((long) (System.nanoTime() - sTime)); System.out.printf('{region: %s, ioCount: %d, take: %d s}\n',region, searcher.getIOCount( ),cost ); } catch (Exception e) { System.out.printf('failed to search(%s): %s\n', ip, e) } //3. 注意:如果同时使用,每个线程必须创建单独的搜索器对象供自己使用。 }}

2. 实现方式 1:【基于文件查询】

您可以从xdb 文件预加载VectorIndex 数据并将其全局缓存。每次创建Searcher对象时使用全局VectorIndex缓存,可以减少固定IO操作,加快查询速度,减少IO。压力。

import org.lionsoul.ip2region.xdb.Searcher;import java.io.*;import java.util.concurrent.TimeUnit;public class SearcherTest { public static void main(String[] args) { String dbPath='ip2region.xdb 文件path'; //1. 从dbPath 预加载VectorIndex 缓存,并将检索到的数据用作全局变量以供以后重复使用。 byte[] vIndex; try { vIndex=Searcher.loadVectorIndexFromFile(dbPath); catch (Exception e) { System.out.printf('%s': 无法从%s'\n' 加载向量索引, dbPath, e ) ; return; } //2. 使用全局vIndex 创建带有VectorIndex 缓存的查询对象。 Searcher searcher; try { searcher=Searcher.newWithVectorIndex(dbPath, vIndex); } catch (Exception e) { System.out.printf(无法在'%s`: %s'\ n' 上创建矢量索引缓存搜索器, dbPath, e); } //3. 查询尝试{ String ip='1.2.3.4'; String area=searcher.search(ip); (long) (System.nanoTime() - sTime)) ; printf('{region: %s, ioCount: %d, Take: %d s}\n', zone, searcher.getIOCount(), cost); } catch (Exception e) { System.out.printf( '搜索失败( %s): %s\n', ip, e); } //注意:每个线程必须创建一个单独的Searcher 对象。它们都共享全局系统vIndex 缓存。您还可以将整个ip2region.xdb 数据预加载到内存中,并根据此数据创建查询对象,以实现完全基于文件的查询,类似于之前的内存搜索。

import org.lionsoul.ip2region.xdb.Searcher;import java.io.*;import java.util.concurrent.TimeUnit;public class SearcherTest { public static void main(String[] args) { String dbPath='ip2region.xdb 文件path'; //1. 将整个xdb 从dbPath 加载到内存中。 byte[] cBuff; try { cBuff=Searcher.loadContentFromFile(dbPath); } catch (Exception e) { System.out.printf('%s': 无法从%s'\n', dbPath, e 加载内容; return; } //2. 使用上面的cBuff 创建一个完全基于内存的查询对象。 Searcher searcher; try { searcher=Searcher.newWithBuffer(cBuff); } catch (Exception e) { System.out.printf('缓存的searcher: %s\n', e); //3.Query try { String ip=' 1.2.3.4'; 长sTime=System.nanoTime(); 字符串区域=searcher.search(ip); 长成本=TimeUnit.NANOSECONDS.toMicros((long) (System.nanoTime() -) sTime)); out.printf('{region: %s, ioCount: %d, take: %d s}\n', Region, searcher.getIOCount(), cost);printf('搜索失败(%s): %s \n ', ip, e); } //注意:对于并发使用,跨xdb 数据缓存创建的查询对象可以安全地并发使用。这意味着该搜索器对象可以是用于跨线程访问的全局对象。 }}

3. 实现方式 2:【缓存VectorIndex索引】

使用Maven 编译测试程序。

# cd binding/java/mvn 到Java绑定根目录运行编译包,在当前目录的target目录下会得到ip2region-{version}.jar的包文件。

您可以使用

4. 实现方式 3:「缓存整个 xdb 数据」

java -jar ip2region-{version}.jar 搜索命令测试您的查询。

java git:(v2.0_xdb) java -jar target/ip2region-2.6.0.jar searchjava -jar ip2region-{version}.jar search [命令选项]options: --db string ip2region 二进制xdb 文件路径--cache-policy string缓存策略: File/vectorIndex/content 示例:使用默认的data/ip2region.xdb 文件进行查询测试。

java git:(v2.0_xdb) java -jar target/ip2region-2.6.0.jar search --db=././data/ip2region.xdbip2region xdb 搜索器测试程序,cachePolicy: VectorIndextype 'quit' 退出ip2region 1.2.3.4 {region: United States|0|Washington|0|Google, ioCount: 7, take: 82 s}ip2region 输入运行查询测试的IP。您还可以将缓存策略设置为file/vectorIndex/content 并测试三个不同的查询。缓存实现。

5. 编译测试程序

java -jar ip2region-{version}.jar bench 命令允许您执行基准测试,同时确保xdb 文件没有错误。评估查询性能。

java git:(v2.0_xdb) java -jar target/ip2region-2.6.0.jar benchjava -jar ip2region-{version}.jar bench [命令选项]options: --db string ip2region 二进制xdb 文件路径--src string 源ip文本文件路径--cache-policy string 缓存策略: File/vectorIndex/content 示例:使用默认data/ip2region.xdb 和data/ip.merge.txt 文件进行基准测试:

java git:(v2.0_xdb) java -jar target/ip2region-2.6.0.jar bench --db=././data/ip2region.xdb --src=././data/ip.merge .txtBench已完成,{cachePolicy: VectorIndex,total: 3417955,Take: 8s,cost: 2 s/op} 您可以通过将每个缓存策略设置为file/vectorIndex/content来测试三种不同缓存实现的有效性。

@Note:请注意,bench中使用的src文件必须生成与xdb文件对应的相同源文件。

版权声明:本文转载于网络,版权归作者所有。如有侵权,请联系本站编辑删除。

猜你喜欢

  • 全网上线 IP 归属地功能,一文教你如何实现?ip地址归属精确位置查询

    全网上线 IP 归属地功能,一文教你如何实现?ip地址归属精确位置查询

    细心的朋友们可能已经发现了,先在抖音、知乎、快手、小红书等这些平台已经上线了“网络用户显示 IP 的

    来源:中国自考网 2024-09-23
  • 杭州师范大学考研什么时侯′出复试通知

    杭州师范大学考研什么时侯′出复试通知

    今天小编整理了杭州师范大学考研什么时侯′出复试通知相关信息,希望在这方面能够更好帮助到大家。本文目录一览:1、杭州师范大学考研什么时

    来源:中国自考网 2024-09-23
  • 高考刚刚过本科线,应该怎么选择?

    高考刚刚过本科线,应该怎么选择?

    今天小编整理了高考刚刚过本科线,应该怎么选择?相关内容,希望能帮助到大家,一起来看下吧。本文目录一览:1、高考刚刚过本科线,应该怎么选择?2、

    来源:中国自考网 2024-09-23
  • 3+证书可以考什么大专院校

    3+证书可以考什么大专院校

    今天小编整理了3+证书可以考什么大专院校相关信息,希望在这方面能够更好帮助到大家。 金华职业技术学院 ,它在浙江省里面是非常知名的

    来源:中国自考网 2024-09-23
  • 上海海洋大学有什么专业

    上海海洋大学有什么专业

    最近经常有小伙伴私信询问上海海洋大学有什么专业相关的问题,今天,小编整理了以下内容,希望可以对大家有所帮助。 上海海洋大学招生专业有:

    来源:中国自考网 2024-09-23
  • 宜春学院广播电视编导专业怎么样

    宜春学院广播电视编导专业怎么样

    宜春学院广播电视编导专业怎么样很多朋友对这方面很关心,整理了相关文章,供大家参考,一起来看一下吧! 北京师范大学珠海分校 、成都文理学院

    来源:中国自考网 2024-09-23
  • 高一学画画还来得及吗

    高一学画画还来得及吗

    高一学画画还来得及吗相关内容,小编在这里做了整理,希望能对大家有所帮助,关于高一学画画还来得及吗信息,一起来了解一下吧!本文目录一览:1、高

    来源:中国自考网 2024-09-23
  • 太原好的中专技校有哪些?

    太原好的中专技校有哪些?

    小编给大家带来了太原好的中专技校有哪些?相关文章,一起来看一下吧。 你问的是太原中职学生资助卡怎么办吧。学校向本地建设银行提供受助学

    来源:中国自考网 2024-09-23
  • 名牌中职学校排名榜最新 烟台中职学校排名

    名牌中职学校排名榜最新 烟台中职学校排名

    最近经常有小伙伴私信询问名牌中职学校排名榜最新 烟台中职学校排名相关的问题,今天,小编整理了以下内容,希望可以对大家有所帮助。 重庆中

    来源:中国自考网 2024-09-23
  • 本人是医学院的学生,本科,不准备考研,想毕业后去中专卫校当老师,不知道需要具备什么条件?

    本人是医学院的学生,本科,不准备考研,想毕业后去中专卫校当老师,不知道需要具备什么条件?

    最近经常有小伙伴私信询问本人是医学院的学生,本科,不准备考研,想毕业后去中专卫校当老师,不知道需要具备什么条件?相关的问题,今天,小编整理了以

    来源:中国自考网 2024-09-23