查看原文
其他

炫酷,Spring Boot + ECharts 实现用户访问地图可视化(附源码)

顶级架构师后台回复 1024 有特别礼包

来源:toutiao.com/i6845433908494860804/


上一篇:支付系统高可用架构实践


意义


  • 在常见的电商、新闻、社交网站等,合理运用运营成本才能最大化输出自己的产品,其中最常见的功能就有针对不同访问热度的城市制定不同的运营手段,因此我们掌握用户城市分布情况至关重要。


  • pc端与移动端不同,无法依托手机自带的gps定位到用户所在城市,只能通过ip来进行判断所在地理位置。


根据ip获取城市的方式


  • 淘宝、新浪等常年提供根据ip获取城市的接口,但是隔一段时间会出现接口地址更改的情况,也有一定的限流


  • 开源纯真ip库:不断迭代更新ip库内容,一般场景下足以使用,自主可控。(下载qqwry.dat库)


思路


首先需要获取用户请求的ip地址,我们对该方法进行简单封装:

public class IPUtil { 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("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_CLIENT_IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; }}


封装纯真ip的解析工具,根据ip获取请求地址所在城市,github有大量实现版本,我们这里不做赘述,具体代码见文末源码

在公众号后端架构师后台回复“架构整洁”,获取一份惊喜礼包。

//篇幅较长,截取的主要方法,详细在源码地址查看 public IPZone findIP(final String ip) { final long ipNum = toNumericIP(ip); final QIndex idx = searchIndex(ipNum); if (idx == null) { return new IPZone(ip); } return readIP(ip, idx);}

自定义拦截器,对用户的登录请求进行拦截,在此处判断请求ip所在城市,并进行计数。我们这里只是简单逻辑的说明,在生产上时应该用redis来存放计数,并且专门提供一个rest接口来推送当前各城市访问数量情况,再由前端配合,隔一段时间发起一次请求,例如隔一小时请求一次该rest接口,从而进行前端数据的展示。

/** * 登录拦截器 */@Slf4jpublic class MyLoginInterceptor implements HandlerInterceptor { private static final String LOGIN_PATH = "/user/login"; private static Map<String, AtomicInteger> visitCount; private static final QQWry qqWry; static { visitCount = new HashMap<>(31); qqWry = new QQWry(); }
//展示访问数量不是精确指标,如果要做到完全正确需要使用锁,防止计数存在并发问题 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("【MyLoginInterceptor】调用了:{}", request.getRequestURI()); if (request.getRequestURI().equals(LOGIN_PATH)) { String ipAddress = IPUtil.getIpAddress(request); String province = qqWry.findIP(ipAddress).getMainInfo(); if (visitCount.containsKey(province)) { visitCount.put(province,new AtomicInteger(visitCount.get(province).incrementAndGet())); } else { visitCount.put(province,new AtomicInteger()); } } return true; }
@Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}
@Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex){}}

注册自定义的拦截器

@Configurationpublic class WebMvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyLoginInterceptor()); }}

登录controller模拟逻辑,注意:如果想看效果图需要自己写线程用不同的虚拟ip进行访问url,从而达到在不同城市访问接口的效果。

@RestController("user")public class LoginController {
@GetMapping("login") public String login() { //登录逻辑 return "success"; }}


源码获取

扫码下方二维码,后台回复【可视化】即可获取


公众号后台回复 架构 或者 架构整洁 有惊喜礼包!顶级架构师交流群

 「顶级架构师」建立了读者架构师交流群,大家可以添加小编微信进行加群。欢迎有想法、乐于分享的朋友们一起交流学习。

扫描添加好友邀你进架构师群,加我时注明姓名+公司+职位】


版权申明:内容来源网络,版权归原作者所有。如有侵权烦请告知,我们会立即删除并表示歉意。谢谢。

猜你还想看

最新一二线城市知名 IT互联网公司名单出炉!
Spring Boot 整合 Elastricsearch + LogStash + Kibana
阿里技术专家:一文教你高效画出技术架构图
新写了个牛逼的 AOP 日志切面,甩锅更方便了!

: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存