用户显示 IP 归属地

477 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

用户显示 IP 归属地

公司的 APP 目前也上线了用户IP地址显示的功能,和其他各家也都大差不差。

显示位置:

  • 个人中心
  • 发表评论时
个人中心

在请求个人信息接口时,通过 IP 地址获取其归属地,并返回前端。实时获取。不保存数据库。

发表评论

在发表评论后,显示该用户的归属地。需要随着评论信息一起保存到数据库中。保存 IP 地址以及归属地。

对于历史数据,因为没有记录,则不进行展示,目前其他 APP 也是如此,比如小红书。

ip2region

使用

采用 mica-ip2region 来实现,它是在 ip2region 基础上又封装了一层,使用更加简便。

参考 gitee.com/lionsoul/ip…

gitee.com/ylh23y/mica…

juejin.cn/post/700538…

实现过程比较简单,代码在 Github 上地址如下:

github.com/SanJingYe88…

IPV6 支持

ip2region 本身是不支持 IPV6 的,而且作者本人也说因为时间原因,不会去实现了,所以需要自己去改造。

参考:blog.csdn.net/u013668852/…

github.com/amazingWu/i…

IP 地址的存储

IP地址如何存储在 MySQL 中,可能首先想到的是 varchar 格式存储,这种方式也是可以的,但不是最好的一种方案。

高性能MySQL 第3版中如下写到:

使用 varchar 类型存储需要 15 个字节,但是使用 int 类型进行存储,只需要 4 个字节。那为什么是 int 类型呢?因为一个 int 型的数据占 4 个字节,每个字节 8 位,其范围就是 0~255(2^8-1),而 ipv4 地址可以分成 4 段,每段的范围是 0~255,巧了么不是,刚刚好能存下,所以将其稍微转换一下,就能巧妙的将 IP地址 用最小的空间存在了数据库中了。

MySQL 中提供了互相转换的方法如下:

-- IP 地址  ->  int 类型
SELECT INET_ATON('192.168.1.13');     //3232235789
SELECT INET_ATON('12.148.14.131');    //211029635
SELECT INET_ATON('255.255.255.255');  //4294967295 

-- int 类型  ->  IP 地址
SELECT INET_NTOA(3232235789);        //192.168.1.13
SELECT INET_NTOA(3232232222);        //192.167.243.30
SELECT INET_NTOA(9999999999);        //NULL, 无法转换为 IP 的返回 null
SELECT INET_NTOA(0);                 //0.0.0.0
  • 如果 IP 地址获取不到, 数据库中直接保存为 0 即可.

假设有一张用户表如下:

-- 查询用户的上次登录 IP 地址
SELECT u.name, INET_NTOA(u.last_login_ip) last_login_ip
FROM tb_user AS u

-- 插入一条数据
INSERT INTO tb_user(id,last_login_ip) 
VALUES (null, INET_ATON('10.153.25.141'));

\