您好,登錄后才能下訂單哦!
這篇文章主要介紹“java IP歸屬地功能如何實現”,在日常操作中,相信很多人在java IP歸屬地功能如何實現問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”java IP歸屬地功能如何實現”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
大家都知道,我們一般想訪問公網,一般必須具備上網環境,那么我們開通寬帶之后,運營商會給我們分配一個IP地址。一般IP地址我們都是自動分配的。所以我們不知道本機地址是什么?想知道自己的ip公網地址,可以通過百度搜索IP查看自己的ip位置
那么問題來了。百度是怎么知道我的公網IP的?
一般情況,用戶訪問我們的服務網絡拓撲如下:
用戶通過域名或者IP訪問門戶,然后請求到后端服務。這樣的話后端服務就可以通過request.getRemoteAddr();方法獲取用戶的ip。
SpringBoot獲取IP如下:
@RestController public class IpController { @RequestMapping("/getIp") public String hello(HttpServletRequest request) { String ip = request.getRemoteAddr(); System.out.println(ip); return ip; } }
將服務部署到服務端,然后請求該接口,即可獲取IP信息,如下圖:
v
但是為什么我們獲取的IP和百度搜出來的不一樣呢?
打開電腦CMD,輸出ipconfig命令,查看本機的IP地址,發現我們本機地址和程序獲取的地址是一樣的。
其實,網絡也是分內網IP和公網IP的。內網也成局域網。對于像公司,學校這種一般內部建立自己的局域網,對內部的信息進行傳輸時,都是通過內網相互通訊,建立局域網內網通訊節省了公網IP資源,并且通信效率也有很大的提升。當然非局域網內的設備則無法向內網的設備發送信息。
但是機器想要訪問互聯網的資源時,則需要機器擁有外網帶寬,也就是我們所說的分配公網IP,負責也是無法訪問互聯網資源的。
因此,我們把服務部署在同一局域網內,客戶端使用內網進行通信,因此獲取的就是內網IP地址。但訪問百度是需要使用公網訪問,因此百度搜出來的IP就是公網IP地址。
當我們興致勃勃的把IP獲取的功能搞上去之后,發現獲取的IP都是同一個?這是為什么呢?不可能只是一個用戶在訪問呀?查詢IP信息之后發現,原來是我們部署的一臺負載均衡的IP地址。
那么后端服務獲取的地址都是負載均衡如nginx的地址。那么怎么透過負載均衡獲取真實的地址呢?
透明的代理服務器在將客戶端的訪問請求轉發到下一環節的服務器時,會在HTTP的請求頭中添加一條X-Forwarded-For記錄,用于記錄客戶端的IP,格式為X-Forwarded-For:客戶端IP。如果客戶端和服務器之間有多個代理服務器,則X-Forwarded-For記錄使用以下格式記錄客戶端IP和依次經過的代理服務器IP:X-Forwarded-For:客戶端IP, 代理服務器1的IP, 代理服務器2的IP, 代理服務器3的IP, ……。
因此,常見的Web應用服務器可以通過解析X-Forwarded-For記錄獲取客戶端真實IP。
public static String getIp(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } else if (ip.length() > 15) { //多次反向代理后會有多個ip值,第一個ip才是真實ip String[] ips = ip.split(","); for (int index = 0; index < ips.length; index++) { String strIp = ips[index]; ip = strIp; break; } } return ip; }
IP來了,我們怎么解析呢:
IP的解析一般都要借助第三方軟件使用了,第三方一般也分為離線庫和在線庫
離線庫支持的有如:IPIP,使用離線庫的好處是解析效率高,性能好,問題就是IP庫要經常更新。如果大家需要我私信我可以提供給大家比較新版本的ip庫。
在線庫則各大云廠商接口能力都有支持。在線版本的好處是更新即時,問題就是接口查詢性能和使用TPS有要求。
以下演示借助IP庫離線IP解析方式:
借助IP庫就可以幫我們實現ip地址的解析。
public static void main(String[] args) { IpAddrInfo IpAddrInfo = IPAddr.getInstance().putLocInfo("114.103.71.226"); System.out.println(JSONObject.toJSONString(IpAddrInfo)); } public IpAddrInfo putLocInfo(String ip) { IpAddrInfo info = new IpAddrInfo(); if (StringUtils.isNotBlank(ip)) { try { DistrictInfo addrInfo = db.findInfo(ip, "CN"); info.setCity(addrInfo.getCityName()); info.setCountry(addrInfo.getCountryName()); info.setCountryCode(addrInfo.getChinaAdminCode()); info.setIsp(addrInfo.getIsp()); info.setLat(addrInfo.getLatitude()); info.setLon(addrInfo.getLongitude()); info.setProvince(addrInfo.getRegionName()); info.setTimeZone(addrInfo.getTimeZone()); System.out.println(addrInfo.toString()); } catch (IPFormatException e) { e.printStackTrace(); } catch (InvalidDatabaseException e) { e.printStackTrace(); } } return info; }
其實IP的定位解析其實就是一個巨大的位置庫,同時IP數量也是有限制的,因此同一個Ip也可能會分配到不同的區域,因此影響IP解析位置準確率的有幾個方面
1、位置庫不精準,導致解析偏差大或者地區字段確實
2、離線庫更新不及時 并且海外的一般有專門的離線庫去支持,使用同一套離線庫并不一定支持海外IP的解析,所以本次受影響最大的海外網紅門被解析到中國各個地區,被大家認為造假,當然也包括真的有造假。
不過上線了這個功能也是有好處的,至少網絡不是法外之地,大家也要有序的健康的沖浪,拒絕網絡暴力。
到此,關于“java IP歸屬地功能如何實現”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。