redis实现“附近的人”
最近在做一款交友软件的APP,现在有一个功能需要实现搜索附近的人。后来发现用redis 的GEO功能实现非常简单。
先说一下设计思路,每个用户在登陆的时候都会添加一下经纬度,这个是APP端获取的,然后设置一下这个经纬度到mysql数据库中,最后把经纬度同步到redis数据库中。我们先来了解一下 redis GEO功能。
我们在用到redis的geo功能时候一定要把版本设置到3.2版本以上,3.2版本以上才有这些方法。
核心的用到的pom配置
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.2.0</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.4.2</version></dependency>
核心方法
geoadd:增加某个地理位置的坐标。
geopos:获取某个地理位置的坐标。
geodist:获取两个地理位置的距离。
georadius:根据给定地理位置坐标获取指定范围内的地理位置集合。
georadiusbymember:根据给定地理位置获取指定范围内的地理位置集合。
geohash:获取某个地理位置的geohash值。
具体实现代码:
实体类:
package com.example.demo.entity;import lombok.Data;/*** @author XuYangWei* @Description:* @Date 2021/7/21 11:41*/
@Data
public class Coordinate {double latitude;double longitude;String key;
}
工具包:
package com.example.demo.utils;import com.example.demo.entity.Coordinate;
import redis.clients.jedis.*;
import redis.clients.jedis.params.GeoRadiusParam;import java.util.List;public class RedisUtil {private static JedisPool jedisPool = null;// Redis服务器IP private static String ADDR = "127.0.0.1";// Redis的端口号 private static int PORT = 6379;// 访问密码
// private static String AUTH = "";/** * 初始化Redis连接池 */ static { try { JedisPoolConfig config = new JedisPoolConfig();// 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true config.setBlockWhenExhausted(true); // 设置的逐出策略类名, 默认DefaultEvictionPolicy(当连接超过最大空闲时间,或连接数超过最大空闲连接数) config.setEvictionPolicyClassName("org.apache.commons.pool2.impl.DefaultEvictionPolicy"); // 是否启用pool的jmx管理功能, 默认true config.setJmxEnabled(true); // 最大空闲连接数, 默认8个 控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。 config.setMaxIdle(8); // 最大连接数, 默认8个 config.setMaxTotal(200); // 表示当borrow(引入)一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛出JedisConnectionException; config.setMaxWaitMillis(1000 * 100); // 在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的; config.setTestOnBorrow(true); jedisPool = new JedisPool(config, ADDR, PORT, 3000);} catch (Exception e) { e.printStackTrace(); } } /** * 获取Jedis实例 * * @return */ public synchronized static Jedis getJedis() { try { if (jedisPool != null) { Jedis resource = jedisPool.getResource(); return resource; } else { return null; } } catch (Exception e) { e.printStackTrace(); return null; } } /** * 释放jedis资源 * * @param jedis */ public static void close(final Jedis jedis) { if (jedis != null) { jedis.close(); } } /** * 添加坐标 * key 经度 维度 距离 * return m 表示单位为米*/ public static Long addReo(Coordinate coordinate) { Jedis jedis = null; try { jedis = jedisPool.getResource(); //第一个参数可以理解为表名 return jedis.geoadd("test",coordinate.getLongitude(),coordinate.getLatitude(),coordinate.getKey()); } catch (Exception e) { System.out.println(e.getMessage()); } finally { if (null != jedis) jedis.close(); } return null; } /** * 查询附近人 * key 经度 维度 距离 * return GeoRadiusResponse*/ public static List<GeoRadiusResponse> geoQuery(Coordinate coordinate) {Jedis jedis = null; try { jedis = jedisPool.getResource(); //200F GeoUnit.KM表示km return jedis.georadius("test",coordinate.getLongitude(),coordinate.getLatitude(),200F, GeoUnit.KM, GeoRadiusParam.geoRadiusParam().withDist());} catch (Exception e) { System.out.println(e.getMessage()); } finally { if (null != jedis) jedis.close(); } return null; }}
测试方法:
package com.example.demo;import com.example.demo.entity.Coordinate;
import com.example.demo.utils.RedisUtil;
import redis.clients.jedis.GeoRadiusResponse;
import redis.clients.jedis.Jedis;import java.util.List;import static com.example.demo.utils.RedisUtil.addReo;
import static com.example.demo.utils.RedisUtil.geoQuery;/*** @author XuYangWei* @Description:* @Date 2021/7/21 11:48*/
public class TestRedis {public static void main(String[] args) {Jedis jedis = RedisUtil.getJedis();java.text.DecimalFormat df = new java.text.DecimalFormat("#.######");//保留六位小数//添加经纬度Coordinate coordinate = new Coordinate();coordinate.setLatitude(31.244803); //维度coordinate.setLongitude(121.483671); //经度coordinate.setKey("1"); //可以作为用户表的id//添加经纬度Coordinate coordinate1 = new Coordinate();coordinate1.setLatitude(31.245321); //维度coordinate1.setLongitude(121.485015); //经度coordinate1.setKey("2"); //可以作为用户表的id//添加经纬度Coordinate coordinate2 = new Coordinate();coordinate2.setLatitude(31.245456); //维度coordinate2.setLongitude(121.485285); //经度coordinate2.setKey("3"); //可以作为用户表的idaddReo(coordinate);addReo(coordinate1);addReo(coordinate2);//添加经纬度coordinate.setLatitude(31.244803); //维度coordinate.setLongitude(121.483671); //经度coordinate.setKey("1"); //用户表的id 以当前用户作为查询条件,查询他周围的人数List<GeoRadiusResponse> list = geoQuery(coordinate);for (GeoRadiusResponse geo : list) {System.out.println(geo.getMemberByString()); //主键 有主键了个人信息就很简单了System.out.println(df.format(geo.getDistance())); //距离多少米}RedisUtil.close(jedis);}
}
打印效果:
redis实现“附近的人”相关推荐
- Spring boot基于redis实现附近的人(附源码下载)
此文章是针对去年写的Java基于Redis实现"附近的人 进行业务优化! 核心源码 public class NearbyPO {@NotNull(message = "id值不能 ...
- SpringBoot + Redis:模拟 10w 人的秒杀抢单!
欢迎关注方志朋的博客,回复"666"获面试宝典 作者:神牛003 来源:cnblogs.com/wangrudong003/p/10627539.html 本篇内容主要讲解的是re ...
- Spring Boot + Redis:模拟 10w 人的秒杀抢单!
作者 | 神牛003 来源 | www.cnblogs.com/wangrudong003/p/10627539.html 本篇内容主要讲解的是redis分布式锁,这个在各大厂面试几乎都是必备的,下面 ...
- 使用redis实现5万人同服的“相位技术”
魔兽世界和EVE服务器能够同时支持5万人在线的技术肯定让很多人流口水吧.今天我用redis来模拟实现"相位技术".所谓"相位技术"就是将服务器分为多个并行的空间 ...
- Java基于Redis实现附近的人(内附源码)
前几天收到一个新的需求,需要实现类似"附近的人"的功能:根据自己当前的定位,获取距离范围内的所有任务地点.刚看到这个需求时有点懵逼,第一想到的就是要利用地球的半径公式去计算距离,也 ...
- 使用Redis实现附近的人及打车服务
面向LBS应用的GEO数据类型 各种社交软件里面都有附件的人的需求,在该应用中,我们查询附近 1 公里的食客,同时只需查询出 20 个即可. 这都依赖基于位置信息服务(Location-Based S ...
- Java基于Redis实现“附近的人”(含源码下载)
"附近的人"在社交类APP已成为标配的功能,Low一点的实现方式可以把坐标存至关系型数据库,通过计算的坐标点距离实现,这种计算可行但计算速度远不及内存操作级别的NoSql数据库. ...
- 【Redis】实现附近人功能
01 Redis的Geo 最近在写实现附近人的这个功能,在网上找了很多方案,但是都不尽人意.最后发现了redis已经实现了这个功能.支持存储地理位置信息来实现附近位置,摇一摇这类依赖于地理位置信息的功 ...
- 如何用 Redis 查询 “附近的人” ?
点击关注公众号:互联网架构师,后台回复 2T获取2TB学习资源! 上一篇:Alibaba开源内网高并发编程手册.pdf 来源:juejin.cn/post/6844903966061363207 作者 ...
- 如何使用 Redis 实现 “附近的人” 这个功能?
点击关注公众号,实用技术文章及时了解 作者简介 万汨,饿了么资深开发工程师.iOS,Go,Java均有涉猎.目前主攻大数据开发.喜欢骑行.爬山. 前言:针对"附近的人"这一位置服务 ...
最新文章
- SQLserver数据库操作帮助类SqlHelper
- ORACLE开发:创建与管理表空间和数据文件1
- gcc 4.4.2 安装
- python单例_Python - 单例模式(Singleton)
- linux-三个文件-用户文件-组文件-密码文件
- RSA加密算法的简单案例
- Java案例:Swing摇奖器
- 【java】Java 8 - 移除Permgen 使用元空间
- Echart.js的趋势图入门与实例
- Java NIO 和 IO的区别
- 计算机网络知识汇总(超详细整理)
- 萌新分享打印当前目录下的所有文件和打印出里面java文件的代码
- 供应链金融与区块链01——论文阅读
- 计算机软件公司用ps是,[计算机软件及应用]ps婚纱.doc
- Java聊天室——一对一模式
- 细致的网站开发流程是怎样的?
- Android 11 Audio框架探索之AudioTracK(二)
- 群体遗传,进化分析利器Popgene分享给大家
- 《AutoCAD .NET开发指南2012版》翻译整理已完成,欢迎大家下载!
- 不太吸引人的成就系统