目前是 toB 项目,有些文件生产耗时比较久,生成的时候设置了锁,使用了 Redis,如果在生成阶段,应用停止,这些 key 会导致没有删除。目前有两种想法,1.需要应用关闭清理的 key ,在设置的使用同时也设置到一个统一的 Redis Set 中,在最后应用关闭的时候使用实现 DisposableBean 的 destroy 删除这些 key;2.可能就是把所有的前缀放到集合,通过 SCAN 方法,获取到也是 DisposableBean 的 destroy ;清理都是通过钩子函数去做 @PreDestroy 或者使用 ApplicationListener
1
KongLiu 2024-07-01 10:17:03 +08:00
我们 redis 都是要设置过期时间的,让他自然过期
|
2
kingbill 2024-07-01 10:17:16 +08:00
Lifecycle 接口?
|
![]() |
3
635925926 2024-07-01 10:18:04 +08:00
设置过期时间
|
![]() |
4
lsk569937453 2024-07-01 10:19:17 +08:00
设置锁的时候加一个过期时间啊。看你的描述是用的 java ,我记得有封装好的方法在 getlock 的时候默认加超时时间,还有看门狗机制。
|
![]() |
5
BBCCBB 2024-07-01 10:19:23 +08:00
看 redisson lock
|
![]() |
6
Goooooos 2024-07-01 10:19:42 +08:00
心跳机制,key 设置 N 秒过期。
应用[1,N)秒定时刷新 key 的有效期。 |
![]() |
7
BBCCBB 2024-07-01 10:19:43 +08:00
只设置过期时间也不行, 还要续约.
|
8
billbur 2024-07-01 10:21:25 +08:00
设置过期时间,java 的话有很多,有个叫 redisson 的可以直接用,不用自己实现锁
|
9
Plutooo 2024-07-01 10:23:42 +08:00
直接引入 redisson 好了,设置好过期时间
|
11
yangyaofei 2024-07-01 11:41:28 +08:00 ![]() 为啥非要关闭的时候清空呢, 在启动的时候清空不也一样么, 还好实现
|
![]() |
12
nitouge OP @yangyaofei 通过 ContextRefreshedEvent 时间去清理吗
|
![]() |
13
nitouge OP @billbur 项目没引入 redisson ,新的项目中引入了,是不是可以时间不设置或者设置不那么长,通过续期解决,即使应用关闭了,到了过期时间也就删除了
|
![]() |
16
BBCCBB 2024-07-01 15:35:27 +08:00
... 你们应用重启的时候做了优雅关闭吗? 你不得等正在跑的流程跑完了才重启??? 跑完了锁就会正常释放了呀.
|
![]() |
17
Misakas 2024-07-01 15:38:29 +08:00
从程序的角度来说一下,可以在代码侧监听 signal 信号,一般使用 kill 命令、systemd 停止的时候会收到。当程序被要求停止时去把需要清理的给删一下。当然只在应用正常关闭时有用,崩溃是不行的
|
![]() |
18
Shinu 2024-07-01 15:52:55 +08:00
"如果在生成阶段,应用停止,这些 key 会导致没有删除"
没有做优雅关闭吗? 如果不考虑优雅关闭, 也不需要考虑生成到一半的文件, 那就在启动的时候清理 key 呗 |
![]() |
19
Habyss 2024-07-01 17:15:37 +08:00
toB 的话, 如果不是多服务使用这个 key, 就是如果是单体应用的话, 可以写在内存里 比如 Guava Cache
还有如果关闭应用比较不好处理的话, 可以换个思路, 比如启动应用的时候清理? 这样是不是容易一些 |
![]() |
20
pota 2024-07-01 17:22:35 +08:00
服务启动时初始化一个时间相关的 key 做为全局的 prefix ?
|
21
z1829909 2024-07-01 18:00:30 +08:00
加锁的时候, 把锁的 value 设置为当前时间.
校验锁之前, 先 get 一下 value, 如果在应用启动时间之前, 作为脏数据覆盖掉 然后就是和之前一样的逻辑, 拿锁, 操作, 释放 这样虽然多了一步操作, 但是心智负担比较低. 然后看有人提每次应用启动, 设置锁的 prefix 不一样, 感觉是一个更好的方法 我感觉你如果扫描删除 key, 太依赖删除步骤的可靠性了, 总有特殊情况导致删除没成功, 或者没触发 |
22
WispZhan 2024-07-01 21:12:18 +08:00
Graceful Shutdown 是合理诉求。
Spring 的话看 SmartLifecycle 强烈建议任何应用做好 Lifecycle 维护。 |
23
yangyaofei 2024-07-01 23:00:48 +08:00
@nitouge #12 随便吧, 或者怎么用的怎么清就好了, 这还非要用什么方式去实现么
|
![]() |
24
cdlnls 2024-07-01 23:10:16 +08:00 via Android ![]() 我想为啥不在启动的时候清空 redis 呢
|
25
iseki 2024-07-01 23:20:04 +08:00
如果要增加超时机制,就必须考虑如果程序因为种种原因暂停(垃圾回收、VM 迁移)导致锁超时,恢复运行后,“以为”自己还持有锁会导致何种问题。考虑的最后往往是别用这个破锁了。
|
![]() |
26
kivmi 2024-07-02 08:41:00 +08:00
生成好的和没有生成完的 key 都可以清理掉?
|
![]() |
27
kivmi 2024-07-02 08:49:12 +08:00
你这个 redis 是用来做分布式锁么?还是进程级别的锁?生成文件用分布式锁,貌似吞吐很小啊
|
28
dddd1919 2024-07-02 08:55:48 +08:00 ![]() 如果要关闭服务清空,不如直接内存缓存,redis 多此一举
|
![]() |
29
nitouge OP @BBCCBB 我是接手的项目,没有启用优雅关闭,但是他这个项目有几个接口时间挺长的,但是他们不想做下载中心,业务也不提,就是觉得下载当前出来就行
|
![]() |
31
nitouge OP @Shinu 没有启用优雅关闭,但是他这个项目有几个接口时间挺长的,但是他们不想做下载中心,业务也不提,就是觉得下载当前出来就行,感觉还是启动的时候做比较好
|
![]() |
32
nitouge OP @yangyaofei 倒不是非要什么方式,我只是随便说一个在启动时清理,感觉好实现还好点
|
35
baoshijiagong 2024-07-02 11:21:16 +08:00
启动时候清空 redis 通配符。通配符为包空间,也就是说,所有当前程序用的 key 前都带上包名,以此清空当前程序的所有 redis ,不影响别的程序。
|
![]() |
36
kivmi 2024-07-02 12:16:32 +08:00
加锁的目的是什么?
|
![]() |
37
zvvvvv 2024-07-05 18:51:55 +08:00 via iPhone
看着描述像是单体应用,为啥不直接放内存里
|