当前位置: 首页 > news >正文

中国商标网商标查询官方网站页面模板怎么添加文章

中国商标网商标查询官方网站,页面模板怎么添加文章,可以免费发帖的网站,招聘网站开发需求分析1、Redis的单/多线程 1.1、单线程 其实直接说Redis什么单线程或者是多线程#xff0c;不太准确#xff0c;在redis的4.0版主之前是单线程#xff0c;然后在之后的版本中redis的渐渐改为多线程。 Redis是单线程主要是指Redis的网络IO和键值对读写是由一个线程来完成的#…1、Redis的单/多线程 1.1、单线程 其实直接说Redis什么单线程或者是多线程不太准确在redis的4.0版主之前是单线程然后在之后的版本中redis的渐渐改为多线程。 Redis是单线程主要是指Redis的网络IO和键值对读写是由一个线程来完成的Redis在处理客户端的请求时包括获取 (socket 读)、解析、执行、内容返回 (socket 写) 等都由一个顺序串行的主线程处理这就是所谓的“单线程”。这也是Redis对外提供键值存储服务的主要流程。 但Redis的其他功能比如持久化RDB、AOF、异步删除、集群数据同步等等其实是由额外的线程执行的。Redis命令工作线程是单线程的但是整个Redis来说是多线程的。 那么问题来Redis之前是单线程为什么还可以做到性能这么的好主要是有四个方面 首先是redis是基于内存的方式Redis 的所有数据都存在内存中因此所有的运算都是内存级别的所以他的性能比较高 其次数据结构简单Redis 的数据结构是专门设计的而这些简单的数据结构的查找和操作的时间大部分复杂度都是 O(1)因此性能比较高 再者多路复用和非阻塞 I/ORedis使用 I/O多路复用功能来监听多个 socket连接客户端这样就可以使用一个线程连接来处理多个请求减少线程切换带来的开销同时也避免了 I/O 阻塞操作 最后避免上下文切换因为是单线程模型因此就避免了不必要的上下文切换和多线程竞争这就省去了多线程切换带来的时间和性能上的消耗而且单线程不会导致死锁问题的发生。 在之前的版本中使用单线程模型是 Redis 的开发和维护更简单因为单线程模型方便开发和调试即使使用单线程模型也并发的处理多客户端的请求主要使用的是IO多路复用和非阻塞IO对于Redis系统来说主要的性能瓶颈是内存或者网络带宽而并非 CPU。 但是随着时代的发展cup也步入多核的时代不改变就会被淘汰当然对于单线程Redis也有一些小问题比如说正常情况下使用 del 指令可以很快的删除数据而当被删除的 key 是一个非常大的对象时例如时包含了成千上万个元素的 hash 集合时那么 del 指令就会造成 Redis 主线程卡顿。 于是在 Redis 4.0 中就新增了多线程的模块当然此版本中的多线程主要是为了解决删除数据效率比较低的问题的。就是让子线程去处理这些问题然后主线程正常的工作。 unlink key 惰性删除 flushdb async 异步清空数据库 flushall async 异步清空所有数据库 1.2、多线程 在Redis6/7中非常受关注的第一个新特性就是多线程。这是因为Redis一直被大家熟知的就是它的单线程架构虽然有些命令操作可以用后台线程或子进程执行比如数据删除、快照生成、AOF重写。但是从网络IO处理到实际的读写命令处理都是由单个线程完成的。 随着网络硬件的性能提升Redis的性能瓶颈有时会出现在网络IO的处理上也就是说单个主线程处理网络请求的速度跟不上底层网络硬件的速度,为了应对这个问题采用多个IO线程来处理网络请求提高网络请求处理的并行度Redis6/7就是采用的这种方法。 但是Redis的多IO线程只是用来处理网络请求的对于读写操作命令Redis仍然使用单线程来处理。这是因为Redis处理请求时网络处理经常是瓶颈通过多个IO线程并行处理网络操作可以提升实例的整体处理性能。而继续使用单线程执行命令操作就不用为了保证Lua脚本、事务的原子性额外开发多线程互斥加锁机制了(不管加锁操作处理)这样一来Redis线程模型实现就简单了 在Redis6.0及7后多线程机制默认是关闭的如果需要使用多线程功能需要在redis.conf中完成两个设置。 四核给两个或者三个、八核的话给6个 io-threads 4 ​ #配置项为yes表示多线程的启用。 io-threads-do-reads no 1.2.1、主线程和io线程的工作方式 阶段一: 服务端和客户端建立Socket连接并分配处理线程 首先主线程负责接收建立连接请求当有客户端请求和实例建立Socket连接时主线程会创建和客户端的连接并把Socket 放入全局等待队列中。紧接着主线程通过轮询方法把Socket连接分配给IO线程。 阶段二:10线程读取并解析请求 主线程一旦把Socket分配给IO线程就会进入阻塞状态等待IO线程完成客户端请求读取和解析。因为有多个IO线程在并行处理所以这个过程很快就可以完成。 阶段三:主线程执行请求操作 等到IO线程解析完请求主线程还是会以单线程的方式执行这些命令操作。 阶段四:10线程回写Socket和主线程清空全局队列 当主线程执行完请求操作后会把需要返回的结果写入缓冲区然后主线程会阻塞等待IO线程把这些结果回写到Socket中并返回给客户端。和I0线程读取和解析请求一样10线程回写Socket时也是有多个线程在并发执行所以回写Socket的速度也很快。等到I0线程回写Socket完毕主线程会清空全局队列等待客户端的后续请求。 1.2.2、五种网络编程中的IO模型 1.2.2.1、Blocking IO 阻塞IO 1.2.2.2、NoneBlocking IO 非阻塞IO 1.2.2.3、IO multiplexing IO多路复用 一种同步的IO模型实现一个线程监视多个文件句柄一旦某个文件句柄就绪就能够通知到对应应用程序进行相应的读写操作没有文件句柄就绪时就会阻塞应用程序从而释放CPU资源。 这里的句柄是指文件描述符FileDescriptor简称句柄或者FD 文件描述符File descriptor是计算机科学中的一个术语是一个用于表述指向文件的引用的抽象化概念。文件描述符在形式上是一个非负整数。实际上它是一个索引值指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时内核向进程返回一个文件描述符。在程序设计中文件描述符这一概念往往只适用于UNIX、Linux这样的操作系统。 网络IO就是指操作系统层面指数据在内核态和用户态之间的读写操作。多路是指多个客户端的连接。复用是指复用一个或者多个线程。简单的说就是一个或一组线程处理多个TCP连接使用单进程就能够实现同时处理多个客户端的连接无需创建或者维护过多的进程/线程。一句话就是一个服务端进程可以同时处理多个套接字描述符。实现IO多路复用的模型有3种可以分select-poll-epoll三个阶段来描述。 将用户socket对应的文件描述符(FileDescriptor)注册进epoll然后epoll帮你监听哪些socket上有消息到达这样就避免了大量的无用操作。此时的socket应该采用非阻塞模式。这样整个过程只在调用select、poll、epoll这些调用的时候才会阻塞收发客户消息是不会阻塞的整个进程或者线程就被充分利用起来这就是事件驱动所谓的reactor反应模式。 在单个线程通过记录跟踪每一个Sockek(I/O流)的状态来同时管理多个I/O流. 一个服务端进程可以同时处理多个套接字描述符。目的是尽量多的提高服务器的吞吐能力。这就是IO多路复用原理有请求就响应没请求不打扰。 1.2.2.4、signal driven IO 信号驱动IO 1.2.2.5、asynchronous IO 异步IO 2、BigKey问题 2.1、keys * /flushdb/flushall key * 这个指令有致命的弊端在实际环境中最好不要使用这个指令没有 offset、limit 参数是要一次性吐出所有满足条件的 key由于 redis 是单线程的其所有操作都是原子的而 keys 算法是遍历算法复杂度是 0(n)如果实例中有千万级以上的 key这个指令就会导致 Redis 服务卡顿所有读写 Redis 的其它的指令都会被延后甚至会超时报错可能会引起缓存雪崩甚至数据库宕机。 对于flushdb和flushall这种删库的操作执行起来可简简单单很刑这些命令的使用的话应该在生产环境中做出一定的限制可以在配置中设置禁用这些危险命令 rename-command keys rename-command flushall rename-command flushdb 经过这样操作后重新执行这些限制的数据那么就会出现报错所以这样设置可以避免生产事故。另外如果真的是一不小心的执行了清空数据库的操作那么这时候如果使用的AOF的持久化操作在没有重启redis主机之前也就是再次重启恢复配置文件可以编辑AOF文件然后删除误操作的命令保存后重启redis也可以恢复数据。 但是除了keys *还可以使用其他什么命令来进行数据的匹配可以使用scan 语法SCAN cursor [MATCH pattern] [COUNT count] cursor 游标 pattern 匹配的模式 count 指定从数据集中返回多少个元素默认值是10 SCAN 命令是一个基于游标的迭代器每次被调用之后 都会向用户返回一个新的游标 用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游标参数 以此来延续之前的迭代过程。 SCAN 返回一个包含两个元素的数组 第一个元素是用于进行下一次迭代的新游标第二个元素则是一个数组 这个数组中包含了所有被迭代的元素。如果新游标返回零表示迭代已结束。 SCAN的遍历顺序 非常特别它不是从第一维数组的第零位一直遍历到末尾而是采用了高位进位加法来遍历。之所以使用这样特殊的方式进行遍历是考虑到字典的扩容和缩容时避免槽位的遍历重复和遗漏。 2.2、多大算BigKey String类型控制在10kb以内 hash、list、set、zset元素的个数不要超过5000个 非字符串的bigkey不要使用del删除使用hscan、sscan、zscan方式渐进式删除同时要注意防止bigkey过期时间自动删除问题(例如一个200万的zset设置1小时过期会触发del操作造成阻塞而且该操作不会出现在慢查询中(latency可查)) 如果key过大会导致内存分布不均匀、集群迁移困难超时删除、网络流量阻塞等问题。 2.3、查找BigKey redis-cli -h 127.0.0.1 -p 6379 -a 111111 --bigkeys # Scanning the entire keyspace to find biggest keys as well as # average sizes per key type. You can use -i 0.1 to sleep 0.1 sec # per 100 SCAN commands (not usually needed). ​ [00.00%] Biggest zset   found so far shop:geo:2 with 5 members [00.00%] Biggest set   found so far follows:1024 with 2 members [00.00%] Biggest string found so far icr:order:2024:01:16 with 1 bytes [00.00%] Biggest set   found so far setmealPicResources with 7 members [00.00%] Biggest zset   found so far shop:geo:1 with 9 members [00.00%] Biggest string found so far seckill:stock:20 with 2 bytes ​ -------- summary ------- ​ Sampled 12 keys in the keyspace! Total key length in bytes is 170 (avg len 14.17) ​ Biggest string found seckill:stock:20 has 2 bytes Biggest   set found setmealPicResources has 7 members Biggest   zset found shop:geo:1 has 9 members ​ 0 lists with 0 items (00.00% of keys, avg size 0.00) 0 hashs with 0 fields (00.00% of keys, avg size 0.00) 2 strings with 3 bytes (16.67% of keys, avg size 1.50) 0 streams with 0 entries (00.00% of keys, avg size 0.00) 5 sets with 14 members (41.67% of keys, avg size 2.80) 5 zsets with 19 members (41.67% of keys, avg size 3.80) 语法MEMORY USAGE key [SAMPLES count] MEMORY USAGE 命令给出一个 key 和它的值在 RAM 中所占用的字节数返回的结果是 key 的值以及为管理该 key 分配的内存总字节数对于嵌套数据类型可以使用选项 SAIIPLES其中 count 表示抽样的元素个数默认值为 5。当需要抽样所有元素时使用 SAJPLES O 。 Windows connected!MEMORY USAGE redis:category: 3270 2.4、BigKey的删除 string类型 一般使用del如果过于庞大的话使用unlink hash类型 渐进式删除使用hscan每次获取少量field-value再使用hdel删除每个field list类型 使用ltrim渐进式逐步删除直到全部删除完成 set类型 使用sscan每次获取部分元素再使用srem命令删除每个元素 zset类型 使用zscan每次获取部分元素再使用ZREMRANGEBYRANK命令删除每个元素 当然使用非阻塞性的删除也是必要的这种方式可以优化redis的删除效率可以在配置文件中设置 lazyfree-lazy-server-del no改为yes replica-lazy-flush no改为yes ​ lazyfree-lazy-user-del no改为yes 3、缓存双写一致性 3.1、数据的更新策略 3.1.1、先更新数据库后更新缓存 例子先更新mysql的某商品的库存当前商品的库存是100更新为99个。先更新mysql修改为99成功然后更新redis。此时假设异常出现更新redis失败了这导致mysql里面的库存是99而redis里面的还是100 。上述发生会让数据库里面和缓存redis里面数据不一致读到redis脏数据 例子【先更新数据库再更新缓存】A、B两个线程发起调用 【正常逻辑】 1 A update mysql 100 2 A update redis 100 3 B update mysql 80 4 B update redis 80 【异常逻辑】多线程环境下A、B两个线程有快有慢有前有后有并行 1 A update mysql 100 3 B update mysql 80 4 B update redis 80 2 A update redis 100 最终结果mysql和redis数据不一致o(╥﹏╥)omysql80,redis100 3.1.2、先更新缓存后更新数据库 例子【先更新缓存再更新数据库】A、B两个线程发起调用 【正常逻辑】 1 A update redis 100 2 A update mysql 100 3 B update redis 80 4 B update mysql 80 【异常逻辑】多线程环境下A、B两个线程有快有慢有并行 A update redis 100 B update redis 80 B update mysql 80 A update mysql 100 ----mysql100,redis80 3.1.3、先删除缓存再更新数据库 例子 1、 A线程先成功删除了redis里面的数据然后去更新mysql此时mysql正在更新中还没有结束。比如网络延时B突然出现要来读取缓存数据。 2 、此时redis里面的数据是空的B线程来读取先去读redis里数据(已经被A线程delete掉了)此处出来2个问题 2.1 B从mysql获得了旧值B线程发现redis里没有(缓存缺失)马上去mysql里面读取从数据库里面读取来的是旧值。 2.2 B会把获得的旧值写回redis获得旧值数据后返回前台并回写进redis(刚被A线程删除的旧数据有极大可能又被写回了)。 3、A线程更新完mysql发现redis里面的缓存是脏数据A线程直接懵逼了o(╥﹏╥)o 两个并发操作一个是更新操作另一个是查询操作A删除缓存后B查询操作没有命中缓存B先把老数据读出来后放到缓存中然后A更新操作更新了数据库。于是在缓存中的数据还是老的数据导致缓存中的数据是脏的而且还一直这样脏下去了。 解决方法 采用延迟双删的策略上面的问题就是A线程执行删除后然后到数据库中更新缓存但是这时候由于并发操作来啦一个线程B那么这时候首先执行读取redsi但是缓存中没有数据然后回到数据库中查询数据但是A还没有更新完毕数那么此时B读取的数据还是之前的数据然后由于回写机制那么B会把读取到的数据写回redis到头来A只更新了数据库中的数据但是对于redis中的数据是无效更新。 延时双删是指在A线程执行完删除Redis缓存后到数据库中更新数据在数据更换新完毕之后将线程睡一会睡一会的目的是为了避免此时有其他的线程读mysql中的数据后回写到redis中当睡眠完成之后A线程再次执行一次删除缓存的操作。 其实这种方式在高并发的环境中也不是100%的有效而且对于睡眠的设置也不太好掌握。当然也可以改变一种方式让其二次删除可以将随眠转换为开一个子线程来处理删除缓存的操作。 3.1.4、先更新数据库再删除缓存 例子A更新数据库中的数据然后删除缓存中的数据这是理想的情况但是对于假如缓存删除失败或者来不及导致请求再次访问redis时缓存命中读取到的是缓存旧值。 3.2、canal canal [kənæl]译意为水道/管道/沟渠主要用途是基于 MySQL数据库增量日志解析提供增量数据订阅和消费。https://github.com/alibaba/canal/releases/tag/canal-1.1.6 数据库镜像 数据库实时备份 索引构建和实时维护拆分异构索引倒排索引 业务cache刷新 带业逻辑的增量数据处理 3.2.1、传统的mysql主从复制 MySQL的主从复制将经过如下步骤 1、当 master 主服务器上的数据发生改变时则将其改变写入二进制事件日志文件中 2、salve 从服务器会在一定时间间隔内对 master 主服务器上的二进制日志进行探测探测其是否发生过改变offset偏移量 如果探测到 master 主服务器的二进制事件日志发生了改变则开始一个 I/O Thread 请求 master 二进制事件日志 3、同时 master 主服务器为每个 I/O Thread 启动一个dump Thread用于向其发送二进制事件日志 4、slave 从服务器将接收到的二进制事件日志保存至自己本地的中继日志文件中 5、salve 从服务器将启动 SQL Thread 从中继日志中读取二进制日志在本地重放使得其数据和主服务器保持一致 6、最后 I/O Thread 和 SQL Thread 将进入睡眠状态等待下一次被唤醒 3.2.2、canal工作原理 工作原理 canal 模拟 MySQL slave 的交互协议伪装自己为 MysQL slave向 MySQL master 发送 dump 协议。 MySQL master 收到 dump 请求开始推送 binary log 给 slave (即 canal) canal 解析 binary log 对象(原始为 byte 流) 3.2.3、mysql配置 [mysqld] log-binmysql-bin #开启 ​ binlogbinlog-formatROW #选择 ROW 模式 ​ server_id1   #配置MySQL replaction需要定义不要和canal的 slaveId重复 ROW模式 除了记录sql语句之外还会记录每个字段的变化情况能够清楚的记录每行数据的变化历史但会占用较多的空间。STATEMENT模式只记录了sql语句但是没有记录上下文信息在进行数据恢复的时候可能会导致数据的丢失情况MIX模式比较灵活的记录理论上说当遇到了表结构变更的时候就会记录为statement模式。当遇到了数据更新或 授权canal连接mysql账号 DROP USER IF EXISTS canal%; CREATE USER canal% IDENTIFIED BY canal;   GRANT ALL PRIVILEGES ON *.* TO canal% IDENTIFIED BY canal;   FLUSH PRIVILEGES;SELECT * FROM mysql.user; 3.2.4、canal安装配置 首先将下载好的文件上传到Linux系统中然后在指定的目录下解压 tar -zxvf canal.deployer-1.1.7.tar.gz 修改配置文件 cd conf/example vim instance.properties ​ #修改主机的mysql地址 canal.instance.master.address192.168.200.66:3306 canal.instance.master.journal.name canal.instance.master.position canal.instance.master.timestamp canal.instance.master.gtid ​ ​ #连的的canal用户名和密码 canal.instance.dbUsernamecanal canal.instance.dbPasswordcanal canal.instance.connectionCharset UTF-8 # enable druid Decrypt database password canal.instance.enableDruidfalse 启动 #切换到bin目录下 ./startup.sh 查看日志 切换到日志文件夹 ​ cat canal.log ​ cat example.log ​ 4、特殊数据结构的应用 4.1、数据统计的类型 4.1.1、聚合统计 统计多个集合元素的聚合的结果实际上就是使用集合的交并差的运算规则来进行数据的统计。 4.1.2、排序统计 统计评论列表排行榜的应用话可以使用zsetzset的数据结构有序不重复 4.1.3、二值统计 使用bitmap可以解决类似每日签到以及上班打卡的业务。使用bitmap可以节省数据的存储空间优化存储结构。 4.1.4、基数统计 统计一个集合中不重复的元素的个数而且这种统计结果不存储只用做统计 4.2、hyperloglog 4.2.1、行话 UV unique visitor独立访客一般为客户端的IP需要去重考虑 PV Page View页面浏览量不用去重 DAU Daily Active User 日活跃用户量登录或者使用某一个产品的用户数去除重复的用户 MAU Monthly Active User 月活跃用户量 很多计数类场景比如 每日注册 IP 数、每日访问 IP 数、页面实时访问数 PV、访问用户数 UV等。因为主要的目标高效、巨量地进行计数所以对存储的数据的内容并不太关心。也就是说它只能用于统计巨量数量不太涉及具体的统计对象的内容和精准性。 统计单日一个页面的访问量(PV)单次访问就算一次。统计单日一个页面的用户访问量(UV)即按照用户为维度计算单个用户一天内多次访问也只算一次。多个key的合并统计某个门户网站的所有模块的PV聚合统计就是整个网站的总PV。 4.2.2、使用 HyperLogLog就是一种概率算法的实现通过牺牲准确率来换取空间对于不要求绝对准确率的场景下可以使用因为概率算法不直接存储数据本身 通过一定的概率统计方法预估基数值同时保证误差在一定范围内由于又不储存数据故此可以大大节约内存。只是进行不重复的基数统计不是集合也不保存数据只记录数量而不是具体内容。 import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; ​ import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.util.Random; import java.util.concurrent.TimeUnit; ​ /*** auther zzyy* create 2021-05-02 18:16*/ Service Slf4j public class HyperLogLogService {Resourceprivate RedisTemplate redisTemplate; ​/*** 模拟后台有用户点击首页每个用户来自不同ip地址*/PostConstructpublic void init(){log.info(------模拟后台有用户点击首页每个用户来自不同ip地址);new Thread(() - {String ip null;for (int i 1; i 200; i) {Random r new Random();ip r.nextInt(256) . r.nextInt(256) . r.nextInt(256) . r.nextInt(256); ​Long hll redisTemplate.opsForHyperLogLog().add(hll, ip);log.info(ip{},该ip地址访问首页的次数{},ip,hll);//暂停几秒钟线程try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }}},t1).start();} ​ } ​ ​ ​ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; ​ import javax.annotation.Resource; ​ /*** auther zzyy* create 2021-05-02 18:16*/ Api(description 淘宝亿级UV的Redis统计方案) RestController Slf4j public class HyperLogLogController {Resourceprivate RedisTemplate redisTemplate; ​ApiOperation(获得IP去重后的首页访问量)RequestMapping(value /uv,method RequestMethod.GET)public long uv(){//pfcountreturn redisTemplate.opsForHyperLogLog().size(hll);} ​ } 4.3、GEO 4.3.1、经纬度 经纬度 经度与纬度的合称组成一个坐标系统。又称为地理坐标系统它是一种利用三度空间的球面来定义地球上的空间的球面坐标系统能够标示地球上的任何一个位置。 经线和纬线 是人们为了在地球上确定位置和方向的在地球仪和地图上画出来的地面上并线和经线相垂直的线叫做纬线(纬线指示东西方向)。纬线是一条条长度不等的圆圈。最长的纬线就是赤道。 因为经线指示南北方向所以经线又叫子午线。 国际上规定把通过英国格林尼治天文台原址的经线叫做0°所以经线也叫本初子午线。在地球上经线指示南北方向纬线指示东西方向。东西半球分界线东经160° 西经20° 经度和维度 经度(longitude)东经为正数西经为负数。东西经 纬度(latitude)北纬为正数南纬为负数。南北纬 4.3.2、使用 import com.atguigu.redis7.service.GeoService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.data.geo.*; import org.springframework.data.redis.connection.RedisGeoCommands; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; ​ import javax.annotation.Resource; import java.util.HashMap; import java.util.List; import java.util.Map; ​ /*** auther zzyy* create 2022-12-25 12:12*/ Api(tags 美团地图位置附近的酒店推送GEO) RestController Slf4j public class GeoController {Resourceprivate GeoService geoService; ​ApiOperation(添加坐标geoadd)RequestMapping(value /geoadd,method RequestMethod.GET)public String geoAdd(){return geoService.geoAdd();} ​ApiOperation(获取经纬度坐标geopos)RequestMapping(value /geopos,method RequestMethod.GET)public Point position(String member){return geoService.position(member);} ​ApiOperation(获取经纬度生成的base32编码值geohash)RequestMapping(value /geohash,method RequestMethod.GET)public String hash(String member){return geoService.hash(member);} ​ApiOperation(获取两个给定位置之间的距离)RequestMapping(value /geodist,method RequestMethod.GET)public Distance distance(String member1, String member2){return geoService.distance(member1,member2);} ​ApiOperation(通过经度纬度查找北京王府井附近的)RequestMapping(value /georadius,method RequestMethod.GET)public GeoResults radiusByxy(){return geoService.radiusByxy();} ​ApiOperation(通过地方查找附近,本例写死天安门作为地址)RequestMapping(value /georadiusByMember,method RequestMethod.GET)public GeoResults radiusByMember(){return geoService.radiusByMember();} ​ } ​ ​ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.geo.Distance; import org.springframework.data.geo.GeoResults; import org.springframework.data.geo.Metrics; import org.springframework.data.geo.Point; import org.springframework.data.geo.Circle; import org.springframework.data.redis.connection.RedisGeoCommands; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; ​ import java.util.HashMap; import java.util.List; import java.util.Map; ​ /*** auther zzyy* create 2022-12-25 12:11*/ Service Slf4j public class GeoService {public static final String CITY city; ​Autowiredprivate RedisTemplate redisTemplate; ​public String geoAdd(){MapString, Point map new HashMap();map.put(天安门,new Point(116.403963,39.915119));map.put(故宫,new Point(116.403414 ,39.924091));map.put(长城 ,new Point(116.024067,40.362639)); ​redisTemplate.opsForGeo().add(CITY,map); ​return map.toString();} ​public Point position(String member) {//获取经纬度坐标ListPoint list this.redisTemplate.opsForGeo().position(CITY,member);return list.get(0);} ​ ​public String hash(String member) {//geohash算法生成的base32编码值ListString list this.redisTemplate.opsForGeo().hash(CITY,member);return list.get(0);} ​ ​public Distance distance(String member1, String member2) {//获取两个给定位置之间的距离Distance distance this.redisTemplate.opsForGeo().distance(CITY,member1,member2, RedisGeoCommands.DistanceUnit.KILOMETERS);return distance;} ​public GeoResults radiusByxy() {//通过经度纬度查找附近的,北京王府井位置116.418017,39.914402Circle circle new Circle(116.418017, 39.914402, Metrics.KILOMETERS.getMultiplier());//返回50条RedisGeoCommands.GeoRadiusCommandArgs args RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().includeCoordinates().sortAscending().limit(50);GeoResultsRedisGeoCommands.GeoLocationString geoResults this.redisTemplate.opsForGeo().radius(CITY,circle, args);return geoResults;} ​public GeoResults radiusByMember() {//通过地方查找附近String member天安门;//返回50条RedisGeoCommands.GeoRadiusCommandArgs args RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().includeCoordinates().sortAscending().limit(50);//半径10公里内Distance distancenew Distance(10, Metrics.KILOMETERS);GeoResultsRedisGeoCommands.GeoLocationString geoResults this.redisTemplate.opsForGeo().radius(CITY,member, distance,args);return geoResults;} } 4.4、BitMap 由0和1组成的二进制位的bit数组可用于日活跃统计连续的签到打卡等等
http://www.pierceye.com/news/617117/

相关文章:

  • 兰州北山生态建设局网站今天重大新闻2021
  • 民权网站建设用别人服务器做网站
  • 周口网站建设 网站制作 网络推广wordpress4.0安装教程
  • 长治市建设局网站自己做网站的优势
  • 网站管理与维护的优势php 做视频网站
  • 建设部网站业绩补录商河 网站建设
  • 网站页面设计考虑要素建站知识
  • 打电话叫人做网站城阳网站制作
  • 网页制作素材网站推荐软件开发属于什么专业类别
  • 淘宝做基础销量怎么网站中国十大培训机构影视后期
  • 网站平台是怎么做财务的兴盛优选购物平台下载
  • 网站备案是给什么进行备案seo如何优化关键词上首页
  • 怎么用qq邮箱做网站做网站一般注册哪几类商标
  • 建设银行网站未响应海外网网址
  • 安防监控网站模板忻州市建设厅网站首页
  • 建网站需要什么条件网站运行费用预算
  • 网站建设打广告网站翻页代码
  • 自己怎么免费做网站平面设计师赚钱吗
  • 南宁建站模板源码公众号开发用什么技术
  • 北京自助建站软件软件外包公司的优势和劣势
  • 网页 代码怎么做网站建设规划展览馆网站的优势
  • 山西省建设主管部门网站单位网站建设意义
  • 怎么建设自己收费网站电影网站建设费用
  • 黑龙江建设网一体化平台seo网站关键词优化价格
  • 西宁做网站公司电话找公司网站建设
  • 有哪些企业可以做招聘的网站机械网站开发方案
  • 九江专业网站建设定制千库网免费素材图库
  • wordpress云建站太仓网站建设网站推广
  • 辽宁网站推广的目的西安企业做网站多少钱
  • 重庆微信网站建设网站平台网站怎么做