当前位置: 首页 > 后端技术 > Java

一位新的技术总监来了,让我做一个知识产权领域的功能,.不接受就去做吧!

时间:2023-04-01 15:43:55 Java

作者:ThinkingKeep\链接:https://juejin.cn/post/711895...细心的朋友应该发现,最近在新浪微博、今日头条、腾讯、抖音、知乎、快手、小红书之后等各大平台相继推出“网络用户IP地址显示功能”。海外用户显示国家,国内用户显示省份。此显示无法关闭,归属是强制性的。作为一个技术人,那个!如何实现这个功能?接下来说说Java中如何获取IP领地,主要分为以下几个步骤:通过HttpServletRequest对象获取用户的IP地址。通过IP地址获取对应的省市。首先,你需要写一个IP来获取它。Tools,因为每次用户发出Request时,都会携带请求的IP地址放在请求头中。通过该方法,可以从请求头中获取用户的IP地址。目前我在做的项目中,也是获取IP地址归属地省市需要,使用:淘宝IP库地址:ip.taobao.com/原请求源码如下:可以看日志文件中,下面有大量requestovermaxqpsforuserquestion,给大家介绍一下今天的主角,我在逛Github的时候发现的:最新版本已经更新到v2.0,ip2regionv2.0是一个离线IP地址定位库和IP定位数据管理框架,查询效率10微秒提供多种主流编程语言的xdb数据生成和查询客户端实现。99.9%准确率:数据聚合了一些知名IP的数据给地名查询提供商。这些是他们的官方准确率。经过测试,确实比经典的纯IP定位准确。多查询客户端支持集成的客户端包括:java、C#、php、c、python、nodejs、php扩展(php5和php7)、golang、rust、lua、lua_c、nginx。绑定说明开发状态二进制查询耗时B树查询耗时内存查询耗时cANSCc绑定完成0.0xms0.0xms0.00xmsc#c#绑定完成0.xms0.xms0.1xmsgolangolang绑定完成0.xms0.xms0.1xmsjavajava绑定完成0.xms0.xms0.1xmslualua实现绑定完成0.xms0.xms0.xmslua_clua的c扩展完成0.0xms0.0xms0.00xmsnginxnginxc扩展完成0.0xms0.0xms0.00xmsnodejsnodejs完成0.xms0.xms0.1xmsphpphp实现绑定完成0.xms0.1xms0.1xmsphp5_extphp5的c扩展完成0.0xms0.0xms0.00xmsphp7_extphp7的c扩展已完成0.0ms0.0xms0.00xmspythonpythonbindng已完成0.xms0.xms0.x毫秒rust绑定已完成0.x毫秒0.x毫秒0.x毫秒Ip2regionV2.0特性1.标准化数据格式每个ip数据段的区域信息都有固定的格式:country|region|province|city|ISP,只有国内的大部分数据是精确到城市的,其他国家的部分数据只能定位到国内,前后选项都是0。2.数据去重和压缩xdb格式生成程序会自动去重压缩部分数据,默认所有IP数据,生成的ip2region.xdb数据库为11MiB,随着数据的详细程度增加,数据库的大小会逐渐增大。3、极快的查询响应即使是完全基于xdb文件的查询,单次查询的响应时间也在十微秒级别。可以通过以下两种方式启用内存加速查询:vIndex索引缓存:使用固定的512KiB内存空间缓存向量索引数据,减少一次IO磁盘操作,平均查询效率稳定在10-20微秒之间。xdb整个文件缓存:将整个xdb文件加载到内存中,内存占用等于xdb文件大小,无磁盘IO操作,保持微秒级的查询效率。4.极速查询响应v2.0格式的xdb支持亿级IP数据段行,区域信息也可以完全自定义,例如:您可以根据区域特定业务需求添加数据,例如:GPS信息/国际统一地理信息代码/邮政编码等。即可以使用ip2region来管理自己的IP位置数据。ip2regionxdbjava查询客户端实现使用方法引入maven仓库:org.lionsoulip2region2.6.4完全基于文件查询importorg.lionsoul.ip2region.xdb.Searcher;importjava.io.*;importjava.util.concurrent.TimeUnit;publicclassSearcherTest{publicstaticvoidmain(String[]args){//1.创建搜索器对象StringdbPath="ip2region.xdb文件路径";搜索器searcher=null;尝试{searcher=Searcher.newWithFileOnly(dbPath);}catch(IOExceptione){System.out.printf("无法使用`%s`创建搜索器:%s\n",dbPath,e);返回;}//2.查询try{Stringip="1.2.3.4";长sTime=System.nanoTime();Stringregion=searcher.search(ip);长成本=TimeUnit.NANOSECONDS.toMicros((long)(System.nanoTime()-sTime));System.out.printf("{region:%s,ioCount:%d,take:%dμs}\n",region,searcher.getIOCount(),cost);}catch(Exceptione){System.out.printf("搜索失败(%s):%s\n",ip,e);}//3.注意:为了并发使用,每个线程需要创建一个独立的searcher对象,使用}}单独缓存VectorIndex索引。我们可以预先从xdb文件中加载VectorIndex数据,然后全局缓存。每次创建Searcher对象时使用全局VectorIndex缓存可以减少固定的IO操作,从而加快查询速度。降低IO压力。importorg.lionsoul.ip2region.xdb.Searcher;importjava.io.*;importjava.util.concurrent.TimeUnit;publicclassSearcherTest{publicstaticvoidmain(String[]args){StringdbPath="ip2region.xdb文件小路”;//1.从dbPath中预加载VectorIndex缓存,将获取到的数据作为全局变量,供后续重复使用。字节[]vIndex;尝试{vIndex=Searcher.loadVectorIndexFromFile(dbPath);}catch(Exceptione){System.out.printf("无法从`%s`加载向量索引:%s\n",dbPath,e);返回;}//2.使用全局vIndex创建带有VectorIndex缓存的查询对象。搜索者搜索者;try{searcher=Searcher.newWithVectorIndex(dbPath,vIndex);}catch(Exceptione){System.out.printf("无法使用`%s`创建vectorIndex缓存搜索器:%s\n",dbPath,e);返回;}//3.查询try{Stringip="1.2.3.4";长sTime=System.nanoTime();Stringregion=searcher.search(ip);longcost=TimeUnit.NANOSECONDS.toMicros((long)(System.nanoTime()-sTime));System.out.printf("{region:%s,ioCount:%d,take:%dμs}\n",region,searcher.getIOCount(),cost);}catch(Exceptione){System.out.printf("搜索失败(%s):%s\n",ip,e);}//注意:每个线程都需要创建一个独立的Searcher对象,但是都共享全局的机构vIndex缓存。}}缓存整个xdb数据我们也可以将整个ip2region.xdb数据预加载到内存中,然后根据这个数据创建查询对象,实现完全基于文件的查询,类似于前面的内存搜索。importorg.lionsoul.ip2region.xdb.Searcher;importjava.io.*;importjava.util.concurrent.TimeUnit;publicclassSearcherTest{publicstaticvoidmain(String[]args){StringdbPath="ip2region.xdb文件小路”;//1.将整个xdb从dbPath加载到内存中。字节[]cBuff;尝试{cBuff=Searcher.loadContentFromFile(dbPath);}catch(Exceptione){System.out.printf("无法从`%s`加载内容:%s\n",dbPath,e);返回;}//2.使用上面的cBuff创建一个基于内存的查询对象。搜索者搜索者;尝试{searcher=Searcher.newWithBuffer(cBuff);}catch(Exceptione){System.out.printf("无法创建内容缓存搜索器:%s\n",e);返回;}//3、查询try{Stringip="1.2.3.4";长sTime=System.nanoTime();Stringregion=searcher.search(ip);longcost=TimeUnit.NANOSECONDS.toMicros((long)(System.nanoTime()-sTime));System.out.printf("{region:%s,ioCount:%d,take:%dμs}\n",region,searcher.getIOCount(),cost);}catch(Exceptione){System.out.printf("搜索失败(%s):%s\n",ip,e);}//注意:对于并发使用,用整个xdb数据缓存创建的query对象是可以安全并发使用的,也就是你可以把这个searcher对象做成全局对象进行跨线程访问。}}在IDEA中,做一个完全基于ip领地文件查询的测试。如果是国内就显示省份,如果是国外就只显示国家。可以使用下图所示的方法进一步封装,获取IP域的信息。下面是官网命令给出的运行jar方式的测试demo。可以理解为通过maven编译测试程序来编译测试程序。#cd到java绑定的根目录cdbinding/java/mvncompilepackage则在当前目录的target目录下会得到一个ip2region-{version}.jar的包文件。查询测试可以通过java-jarip2region-{version}.jar搜索命令进行测试:?javagit:(v2.0_xdb)?java-jartarget/ip2region-2.6.0.jarsearchjava-jarip2region-{version}。jarsearch[commandoptions]options:--dbstringip2regionbinaryxdbfilepath--cache-policystring缓存策略:file/vectorIndex/content例如:使用默认的data/ip2region.xdb文件进行查询测试:?javagit:(v2.0_xdb)?java-jartarget/ip2region-2.6.0.jarsearch--db=../../data/ip2region.xdbip2regionxdbsearcher测试程序,cachePolicy:vectorIndextype'quit'toexitip2region>>1.2.3.4{region:USA|0|Washington|0|Google,ioCount:7,take:82μs}ip2region>>输入ip进行查询测试,或者分别设置cache-policy为file/vectorIndex/content测试查询三种不同缓存实现的效果。可以通过java-jarip2region-{version}.jarbench命令进行bench测试,一方面保证xdb文件没有错误,另一方面评估查询性能:?javagit:(v2.0_xdb)?java-jartarget/ip2region-2.6.0.jarbenchjava-jarip2region-{version}.jarbench[commandoptions]options:--dbstringip2region二进制xdb文件路径--srcstring源ip文本文件路径--cache-policy字符串缓存策略:file/vectorIndex/content例如:使用默认的data/ip2region.xdb和data/ip.merge.txt文件进行bench测试:?javagit:(v2.0_xdb)?java-jartarget/ip2region-2.6.0.jarbench--db=../../data/ip2region.xdb--src=../../data/ip.merge.txtBenchfinished,{cachePolicy:vectorIndex,total:3417955,tok:8s,cost:2μs/op}你可以通过将缓存策略分别设置为file/vectorIndex/content来测试三种不同缓存实现的效果。@注意:注意如果bench使用的src文件生成的源文件与对应的xdb文件相同。到这里就完成了用户IP领地的获取。对于本文介绍的v2.0版本,感兴趣的朋友可以登录门的github地址了解v1.0版本。如果觉得有用,欢迎收藏+点赞。如果遇到任何问题,欢迎留言讨论近期热点文章推荐:1.1,000+Java面试题及答案(2022最新版)2.世界之最!Java协程来了。..3.SpringBoot2.x教程,太全面了!4.不要用爆破爆满画面,试试装饰者模式,这才是优雅的方式!!5.《Java开发手册(嵩山版)》最新发布,赶快下载吧!感觉不错,别忘了点赞+转发!