mirror of
https://github.com/Estom/notes.git
synced 2026-02-03 02:23:31 +08:00
缓存更新
This commit is contained in:
@@ -182,6 +182,7 @@ public static void demo() throws ExecutionException, InterruptedException {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## 3 数据驱逐
|
||||
|
||||
Caffeine提供以下几种剔除方式:基于大小、基于权重、基于时间、基于引用
|
||||
@@ -530,4 +531,45 @@ public class MyTicker implements Ticker {
|
||||
return this.nanos.get();
|
||||
}
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
|
||||
## 7 缓存常见问题处理
|
||||
|
||||
### 缓存穿透——不存在的key
|
||||
|
||||
尝试返回一个空对象。
|
||||
|
||||
|
||||
### 缓存击穿——大量线程同时访问同一个Key
|
||||
* 在一个key失效的瞬间有大量访问进入。
|
||||
* 多线程单一key互斥(该包已经实现。)
|
||||
* 如果对 get(K) 的另一个调用当前正在加载键的值,则该线程只是等待该线程完成并返回其加载的值。 请注意,多个线程可以同时加载不同键的值。
|
||||
* 如果指定的键尚未与值关联,则尝试计算其值并将其输入此缓存,除非为空。 整个方法调用是原子执行的,因此每个键最多应用一次函数。 当计算正在进行时,其他线程对此缓存的一些尝试更新操作可能会被阻塞,因此计算应该简短,并且不得尝试更新此缓存的任何其他映射。
|
||||
|
||||
* 在一开始的时候,该key还没有加入有大量key同时访问
|
||||
* 缓存预热。
|
||||
|
||||
```java
|
||||
@PostConstruct
|
||||
private void preLoading(){
|
||||
List<InstanceMetaDO> instanceMetaDOS = instanceMetaDAO.findByQuery();
|
||||
int nums = 0;
|
||||
for(InstanceMetaDO metaDO:instanceMetaDOS){
|
||||
if(StringUtils.isNotEmpty(metaDO.getInstanceId())){
|
||||
nums++;
|
||||
if(StringUtils.isNotEmpty(metaDO.getWorkspaceId())){
|
||||
workspaceIdCache.put(metaDO.getInstanceId(),metaDO.getWorkspaceId());
|
||||
}
|
||||
if(StringUtils.isNotEmpty(metaDO.getInstanceId())){
|
||||
tenantIdCache.put(metaDO.getInstanceId(),metaDO.getTenantId());
|
||||
}
|
||||
}
|
||||
}
|
||||
log.info("[InstanceMetaCacheService] preload count:{}",nums);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### 缓存雪崩——大量key同时失效
|
||||
|
||||
|
||||
115
Java基础教程/Java实用技巧/04 缓存穿透、击穿和雪崩.md
Normal file
115
Java基础教程/Java实用技巧/04 缓存穿透、击穿和雪崩.md
Normal file
@@ -0,0 +1,115 @@
|
||||
在生产环境中,会因为很多的原因造成访问请求绕过了缓存,都需要访问数据库持久层,虽然对Redsi缓存服务器不会造成影响,但是数据库的负载就会增大,使缓存的作用降低
|
||||
|
||||
## 1 缓存穿透
|
||||
|
||||
### 1、缓存穿透理解
|
||||
|
||||
缓存穿透是指查询一个根本不存在的数据,缓存层和持久层都不会命中。在日常工作中出于容错的考虑,如果从持久层查不到数据则不写入缓存层,缓存穿透将导致不存在的数据每次请求都要到持久层去查询,失去了缓存保护后端持久的意义。
|
||||
|
||||
缓存穿透示意图:
|
||||
|
||||

|
||||
|
||||
缓存穿透问题可能会使后端存储负载加大,由于很多后端持久层不具备高并发性,甚至可能造成后端存储宕机。通常可以在程序中统计总调用数、缓存层命中数、如果同一个Key的缓存命中率很低,可能就是出现了缓存穿透问题。
|
||||
|
||||
|
||||
造成缓存穿透的基本原因有两个。第一,自身业务代码或者数据出现问题(例如:set 和 get 的key不一致),第二,一些恶意攻击、爬虫等造成大量空命中(爬取线上商城商品数据,超大循环递增商品的ID)
|
||||
|
||||
### 2、解决方案
|
||||
|
||||
**2.1 缓存空对象**
|
||||
缓存空对象:是指在持久层没有命中的情况下,对key进行set (key,null)
|
||||
|
||||
缓存空对象会有两个问题:
|
||||
* 第一,value为null 不代表不占用内存空间,空值做了缓存,意味着缓存层中存了更多的键,需要更多的内存空间,比较有效的方法是针对这类数据设置一个较短的过期时间,让其自动剔除。
|
||||
|
||||
* 第二,缓存层和存储层的数据会有一段时间窗口的不一致,可能会对业务有一定影响。例如过期时间设置为5分钟,如果此时存储层添加了这个数据,那此段时间就会出现缓存层和存储层数据的不一致,此时可以利用消息系统或者其他方式清除掉缓存层中的空对象。
|
||||
|
||||
**2.2 布隆过滤器拦截**
|
||||
|
||||
在访问缓存层和存储层之前,将存在的key用布隆过滤器提前保存起来,做第一层拦截,当收到一个对key请求时先用布隆过滤器验证是key否存在,如果存在在进入缓存层、存储层。可以使用bitmap做布隆过滤器。这种方法适用于数据命中不高、数据相对固定、实时性低的应用场景,代码维护较为复杂,但是缓存空间占用少。
|
||||
|
||||
布隆过滤器实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。
|
||||
|
||||
它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。
|
||||
|
||||
布隆过滤器拦截的算法描述:
|
||||
|
||||
* 初始状态时,BloomFilter是一个长度为m的位数组,每一位都置为0。
|
||||
|
||||
* 添加元素x时,x使用k个hash函数得到k个hash值,对m取余,对应的bit位设置为1。
|
||||
|
||||
* 判断y是否属于这个集合,对y使用k个哈希函数得到k个哈希值,对m取余,所有对应的位置都是1,则认为y属于该集合(哈希冲突,可能存在误判),否则就认为y不属于该集合。可以通过增加哈希函数和增加二进制位数组的长度来降低错报率。
|
||||
|
||||
|
||||
**2.3、两种方案的对比**
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## 2 缓存击穿
|
||||
|
||||
### 1、缓存击穿的理解
|
||||
|
||||
系统中存在以下两个问题时需要引起注意:
|
||||
|
||||
* 当前key是一个热点key(例如一个秒杀活动),并发量非常大。
|
||||
* 重建缓存不能在短时间完成,可能是一个复杂计算,例如复杂的SQL、多次IO、多个依赖等。
|
||||
|
||||
在缓存失效的瞬间,有大量线程来重建缓存,造成后端负载加大,甚至可能会让应用崩溃。
|
||||
|
||||
|
||||
|
||||
### 2、解决方案
|
||||
|
||||
**2.1 分布式互斥锁**
|
||||
只允许一个线程重建缓存,其他线程等待重建缓存的线程执行完,重新从缓存获取数据即可。set(key,value,timeout)
|
||||
|
||||

|
||||
|
||||
|
||||
**2.2、永不过期**
|
||||
从缓存层面来看,确实没有设置过期时间,所以不会出现热点key过期后产生的问题,也就是“物理”不过期。
|
||||
从功能层面来看,为每个value设置一个逻辑过期时间,当发现超过逻辑过期时间后,会使用单独的线程去更新缓
|
||||
|
||||

|
||||
|
||||
|
||||
### 3、两种方案对比:
|
||||
|
||||
* 分布式互斥锁:这种方案思路比较简单,但是存在一定的隐患,如果在查询数据库 + 和 重建缓存(key失效后进行了大量的计算)时间过长,也可能会存在死锁和线程池阻塞的风险,高并发情景下吞吐量会大大降低!但是这种方法能够较好地降低后端存储负载,并在一致性上做得比较好。
|
||||
|
||||
* 永远不过期:这种方案由于没有设置真正的过期时间,实际上已经不存在热点key产生的一系列危害,但是会存在数据不一致的情况,同时代码复杂度会增大。
|
||||
|
||||
|
||||
## 3 缓存雪崩
|
||||
### 1、概念理解
|
||||
|
||||
如果缓存集中在一段时间内失效,发生大量的缓存穿透,所有的查询都落在数据库上,造成了缓存雪崩。
|
||||
|
||||
这个没有完美解决办法,但可以分析用户行为,尽量让失效时间点均匀分布。大多数系统设计者考虑用加锁或者队列的方式保证缓存的单线程(进程)写,从而避免失效时大量的并发请求落到底层存储系统上。
|
||||
|
||||
### 2、解决方案
|
||||
|
||||
**2.1 缓存层高可用:**
|
||||
可以把缓存层设计成高可用的,即使个别节点、个别机器、甚至是机房宕掉,依然可以提供服务。利用sentinel或cluster实现。
|
||||
**2.2 做二级缓存,或者双缓存策略:**
|
||||
采用多级缓存,本地进程作为一级缓存,redis作为二级缓存,不同级别的缓存设置的超时时间不同,即使某级缓存过期了,也有其他级别缓存兜底
|
||||
**2.3 数据预热:**
|
||||
可以通过缓存reload机制,预先去更新缓存,再即将发生大并发访问前手动触发加载缓存不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀
|
||||
**2.4 加锁排队**
|
||||
* 限流-- 限流算法. 1.计数 2.滑动窗口 3. 令牌桶Token Bucket 4.漏桶 leaky bucket [1]
|
||||
* 在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。
|
||||
* 业界比较常用的做法,是使用mutex。简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即去load db,而是先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX或者Memcache的ADD)去set一个mutex key,当操作返回成功时,再进行load db的操作并回设缓存;否则,就重试整个get缓存的方法。
|
||||
* SETNX,是「SET if Not eXists」的缩写,也就是只有不存在的时候才设置,可以利用它来实现锁的效果。
|
||||
|
||||
|
||||
## 总结
|
||||
* 不存在的key——缓存穿透——缓存空对象
|
||||
* 同一个Key失效大量访问——缓存击穿——加锁互斥
|
||||
* 大量key同时失效——缓存雪崩——双缓存、队列
|
||||
|
||||
GuavaCache本身实现了加锁互斥,有效防止缓存击穿。
|
||||
|
||||
* 更新锁定:类似于分布式锁,作用体现于对同一个key,只让一个请求去读源并回填缓存,其他请求阻塞等待。
|
||||
BIN
Java基础教程/Java实用技巧/image/2022-12-30-16-29-15.png
Normal file
BIN
Java基础教程/Java实用技巧/image/2022-12-30-16-29-15.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
BIN
Java基础教程/Java实用技巧/image/2022-12-30-16-31-00.png
Normal file
BIN
Java基础教程/Java实用技巧/image/2022-12-30-16-31-00.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 88 KiB |
BIN
Java基础教程/Java实用技巧/image/2022-12-30-16-31-48.png
Normal file
BIN
Java基础教程/Java实用技巧/image/2022-12-30-16-31-48.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 166 KiB |
BIN
Java基础教程/Java实用技巧/image/2022-12-30-16-33-01.png
Normal file
BIN
Java基础教程/Java实用技巧/image/2022-12-30-16-33-01.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 238 KiB |
@@ -168,6 +168,22 @@ lambda表达式是为了简化接口的实现的。在lambda表达式中,不
|
||||
|
||||
函数引用:引用⼀个已经存在的方法,使其替代lambda表达式完成接口的实现
|
||||
|
||||
### 与lambda表达式的不同
|
||||
|
||||
lambda和方法引用之间有一个关键的区别:
|
||||
* Lambda 是惰性的,它们只会在调用方法时调用类构造函数。
|
||||
* 方法引用,构造函数只会在分配了方法引用的地方被立即调用,而不是在方法调用时调用。
|
||||
|
||||
对象方法引用,对象必须已经初始化。类方法引用,类也一定会进行初始化。例如
|
||||
* lambda表达式,这一行不会创建对象
|
||||
```java
|
||||
Runnable universeImpactRunnable = () -> new ChuckNorris().roundHouseKick();
|
||||
```
|
||||
* 方法引用,这一行会创建对象。
|
||||
```
|
||||
Runnable galaxyImpactRunnable = new ChuckNorris()::roundHouseKick;
|
||||
```
|
||||
|
||||
|
||||
### 静态方法的引用
|
||||
```
|
||||
|
||||
192
test.json
192
test.json
@@ -1,191 +1 @@
|
||||
| sofa.ms.sg.apprelations.query | 获取应用关联数据 |
|
||||
| sofa.ms.sg.apps.list | 获取应用列表 |
|
||||
| sofa.ms.sg.serviceclients.sync | 微服务-同步客户端下线事件 |
|
||||
| sofa.ms.sg.serviceheartbeats.sync | 微服务-同步心跳数据 |
|
||||
| sofa.ms.sg.servicekeyword.query | 获取服务候选词 |
|
||||
| sofa.ms.sg.serviceparam.batchquery | 微服务-查询全部服务参数信息 |
|
||||
| sofa.ms.sg.serviceparams.disable | 禁用一个服务下某个服务提供者 |
|
||||
| sofa.ms.sg.serviceparams.enable | 启动一个服务下某个服务提供者 |
|
||||
| sofa.ms.sg.serviceparams.reinit | 恢复服务提供者默认设置 |
|
||||
| sofa.ms.sg.serviceparamweight.set | 设置服务提供者权重 |
|
||||
| sofa.ms.sg.servicepubkeys.query | 根据ip搜索服务提供方 |
|
||||
| sofa.ms.sg.servicepublishers.offline | 提供给 paas 平台,发布时先调用下线接口,再发布 |
|
||||
| sofa.ms.sg.servicepublishers.query | 分页查询发布者信息 |
|
||||
| sofa.ms.sg.servicepublishers.sync | 微服务-同步服务发布者信息 |
|
||||
| sofa.ms.sg.servicepubrelations.query | 获取服务发布者关系 |
|
||||
| sofa.ms.sg.servicepubs.list | 微服务-通过DataId和IP获取pub服务详情 |
|
||||
| sofa.ms.sg.servicepubs.query | 获取发布者服务详情 |
|
||||
| sofa.ms.sg.services.query | 微服务-根据关键词搜索 |
|
||||
| sofa.ms.sg.servicesubkeys.query | 根据ip搜索消费者 |
|
||||
| sofa.ms.sg.servicesubrelations.query | 获取服务消费者数据 |
|
||||
| sofa.ms.sg.servicesubs.list | 微服务-通过DataId和IP获取sub服务详情 |
|
||||
| sofa.ms.sg.servicesubs.query | 获取订阅者服务详情 |
|
||||
| sofa.ms.sg.servicesubscribers.query | 分页查询消费者 |
|
||||
| sofa.ms.sg.servicesubscribers.sync | 微服务-同步服务发布者信息 |
|
||||
| sofa.ms.sg.servicesummarys.query | 微服务-获取服务汇总信息 |
|
||||
| sofa.ms.sg.serviceapps.list | 获取发布服务的应用列表 |
|
||||
|
||||
|
||||
|
||||
### DRM动态配置
|
||||
| 接口名称 | 描述 |
|
||||
| ---- | ---- |
|
||||
| sofa.ms.drm.drmapps.all | 查询实例App name |
|
||||
| sofa.ms.drm.drmattributes.add | 添加drm属性 |
|
||||
| sofa.ms.drm.drmattributes.delete | 删除drm资源属性 |
|
||||
| sofa.ms.drm.drmattributes.get | 获取drm资源属性 |
|
||||
| sofa.ms.drm.drmattributes.update | 更新drm资源属性 |
|
||||
| sofa.ms.drm.drmcells.all | 获取实例的单元格 |
|
||||
| sofa.ms.drm.drmclients.query | 搜索客户端信息 |
|
||||
| sofa.ms.drm.drmdata.add | 推送drm配置 |
|
||||
| sofa.ms.drm.drmdatacells.list | 获取Drm数据单元信息 |
|
||||
| sofa.ms.drm.drmgraydata.add | 灰度推送数据 |
|
||||
| sofa.ms.drm.drmhosts.query | 搜索客户端信息 |
|
||||
| sofa.ms.drm.drmpushlogs.list | 分页搜索推送日志 |
|
||||
| sofa.ms.drm.drmpushlogs.query | 按条件分页查询推送日志 |
|
||||
| sofa.ms.drm.drmresources.add | 添加drm资源 |
|
||||
| sofa.ms.drm.drmresources.delete | Delete resource |
|
||||
| sofa.ms.drm.drmresources.export | 当前workspace下所有资源元信息 |
|
||||
| sofa.ms.drm.drmresources.import | 导入drm资源元信息 |
|
||||
| sofa.ms.drm.drmresources.query | 分页查询Drm资源 |
|
||||
| sofa.ms.drm.drmresources.update | 更新drm资源 |
|
||||
| sofa.ms.sg.resource.export | 资源以文件形式导出 |
|
||||
| sofa.ms.sg.resource.import | 资源以文件形式导入导出 |
|
||||
|
||||
|
||||
|
||||
### 服务治理——服务限流
|
||||
| 接口名称 | 描述 |
|
||||
| ---- | ---- |
|
||||
| sofa.ms.guardian.guardianappnames.all | 微服务-查询appName列表 |
|
||||
| sofa.ms.guardian.guardianapps.add | 添加 监控App |
|
||||
| sofa.ms.guardian.guardianapps.all | 微服务-获取app列表 |
|
||||
| sofa.ms.guardian.guardianapps.delete | 删除监控 app |
|
||||
| sofa.ms.guardian.guardianapps.get | ms -根据appName获取app |
|
||||
| sofa.ms.guardian.guardianapps.query | 微服务-分页查询app |
|
||||
| sofa.ms.guardian.guardianapps.update | ws-更新监控app |
|
||||
| sofa.ms.guardian.guardianconfig.get | 微服务-配置获取 |
|
||||
| sofa.ms.guardian.guardiangrayrules.add | 灰度推送 |
|
||||
| sofa.ms.guardian.guardiangrayrulestatus.update | 更改规则灰度状态 |
|
||||
| sofa.ms.guardian.guardianrulepushhistorys.list | 查询推送历史 |
|
||||
| sofa.ms.guardian.guardianrulepushhistorys.query | 分页查询推送历史 |
|
||||
| sofa.ms.guardian.guardianrules.add | 添加规则 |
|
||||
| sofa.ms.guardian.guardianrules.delete | 删除规则 |
|
||||
| sofa.ms.guardian.guardianrules.export | 导出guardian路由规则 |
|
||||
| sofa.ms.guardian.guardianrules.get | 根据id获取规则 |
|
||||
| sofa.ms.guardian.guardianrules.import | 导入guardian规则 |
|
||||
| sofa.ms.guardian.guardianrules.query | ms - 规则配置分页 |
|
||||
| sofa.ms.guardian.guardianrules.update | 更新规则 |
|
||||
| sofa.ms.guardian.guardianrulestatus.update | 更新规则状态 |
|
||||
|
||||
|
||||
### 服务治理——服务路由
|
||||
| 接口名称 | 描述 |
|
||||
| ---- | ---- |
|
||||
| sofa.ms.sg.routerruleallapps.list | 查询已存在服务路由规则的应用接口 |
|
||||
| sofa.ms.sg.routerruleallservices.list | 查询已存在服务路由规则的服务接口 |
|
||||
| sofa.ms.sg.routerruleappnames.list | 微服务-通过DataId获取AppNames |
|
||||
| sofa.ms.sg.routerruledispatchlogs.query | 微服务-获取调度日志 |
|
||||
| sofa.ms.sg.routerrulegroup.delete | 删除路由规则组 |
|
||||
| sofa.ms.sg.routerrulegroup.export | 路由规则导出 |
|
||||
| sofa.ms.sg.routerrulegroup.import | 路由规则导出 |
|
||||
| sofa.ms.sg.routerrulegroupapps.list | 查询服务路由一级列表 |
|
||||
| sofa.ms.sg.routerrulegroups.add | 添加服务路由规则 |
|
||||
| sofa.ms.sg.routerrulegroups.list | 查询服务路由二级例表 |
|
||||
| sofa.ms.sg.routerrulegroups.update | 更新服务路由规则 |
|
||||
| sofa.ms.sg.routerrulegroupstatus.update | 更新路由规则组状态 |
|
||||
| sofa.ms.sg.routerrules.enable | 微服务-启用路由器规则组 |
|
||||
| sofa.ms.sg.routerrules.get | 查询路由规则 |
|
||||
| sofa.ms.sg.routerrulesnapshots.get | 微服务-获取快照最后一个 |
|
||||
| sofa.ms.sg.routerrulesnapshots.rollback | 微服务-回滚快照最后一个 |
|
||||
| sofa.ms.sg.routerrulestatus.query | 获取路由规则状态 |
|
||||
| sofa.ms.sg.routerruleversions.list | 获取路由规则组版本列表 |
|
||||
|
||||
|
||||
|
||||
### 服务治理——服务熔断
|
||||
|
||||
| 接口名称 | 描述 |
|
||||
| ---- | ---- |
|
||||
| sofa.ms.sg.circuitbreakerrules.add | 添加熔断规则 |
|
||||
| sofa.ms.sg.circuitbreakerrules.all | 查询所有的服务熔断的appName及对应的规则数 |
|
||||
| sofa.ms.sg.circuitbreakerrules.delete | 删除熔断规则 |
|
||||
| sofa.ms.sg.circuitbreakerrules.enable | 生效熔断规则 |
|
||||
| sofa.ms.sg.circuitbreakerrules.export | 熔断规则导出 |
|
||||
| sofa.ms.sg.circuitbreakerrules.get | 通过appName查询熔断规则 |
|
||||
| sofa.ms.sg.circuitbreakerrules.import | 熔断规则导入 |
|
||||
| sofa.ms.sg.circuitbreakerrules.list | 获取租户下服务熔断规则 |
|
||||
| sofa.ms.sg.circuitbreakerrules.query | 根据实例id和服务id获取所有荣富安规则 |
|
||||
| sofa.ms.sg.circuitbreakerrules.set | 设置熔断规则运行模式 |
|
||||
| sofa.ms.sg.circuitbreakerrules.update | 更新熔断规则 |
|
||||
| sofa.ms.sg.downgradegroups.disable | 全局关闭降级规则 |
|
||||
|
||||
### 服务治理——服务降级
|
||||
|
||||
| 接口名称 | 描述 |
|
||||
| ---- | ---- |
|
||||
| sofa.ms.sg.downgradegroups.enable | 全局开启降级规则 |
|
||||
| sofa.ms.sg.downgradegroups.query | 查询降级规则组列表 |
|
||||
| sofa.ms.sg.downgrades.add | 新增降级规则 |
|
||||
| sofa.ms.sg.downgrades.delete | 删除降级规则 |
|
||||
| sofa.ms.sg.downgrades.disable | 关闭一条降级规则 |
|
||||
| sofa.ms.sg.downgrades.enable | 开启一条降级规则 |
|
||||
| sofa.ms.sg.downgrades.export | 导出降级规则 |
|
||||
| sofa.ms.sg.downgrades.import | 导入降级规则 |
|
||||
| sofa.ms.sg.downgrades.update | 更新降级规则 |
|
||||
|
||||
### 服务治理——故障注入
|
||||
|
||||
| 接口名称 | 描述 |
|
||||
| ---- | ---- |
|
||||
| sofa.ms.sg.faultinjectallapps.list | 查询已添加故障注入规则的应用 |
|
||||
| sofa.ms.sg.faultinjectallservices.list | 查询已添加故障注入规则的服务 |
|
||||
| sofa.ms.sg.faultinjectapps.list | 查询故障注入一级列表 |
|
||||
| sofa.ms.sg.faultinjectrule.add | 新增故障注入规则 |
|
||||
| sofa.ms.sg.faultinjectrule.delete | 删除故障注入规则 |
|
||||
| sofa.ms.sg.faultinjectrule.export | 导出故障注入 |
|
||||
| sofa.ms.sg.faultinjectrule.import | 导入故障注入 |
|
||||
| sofa.ms.sg.faultinjectrule.update | 更新故障注入规则 |
|
||||
| sofa.ms.sg.faultinjectrules.list | 分页查询故障注入二级列表 |
|
||||
| sofa.ms.sg.faultinjectrulestatus.update | 更新故障注入规则状态 |
|
||||
| sofa.ms.sg.faulttoleranceapps.list | 故障隔离App列表及其规则数量 |
|
||||
| sofa.ms.sg.faulttolerancerule.add | 故障隔离规则新增 |
|
||||
| sofa.ms.sg.faulttolerancerule.delete | 故障隔离规则删除 |
|
||||
| sofa.ms.sg.faulttolerancerule.enable | 故障隔离规则启用 |
|
||||
| sofa.ms.sg.faulttolerancerule.export | 导出故障隔离规则 |
|
||||
| sofa.ms.sg.faulttolerancerule.import | 导入故障隔离规则 |
|
||||
| sofa.ms.sg.faulttolerancerule.update | 故障隔离规则更新 |
|
||||
| sofa.ms.sg.faulttolerancerules.list | 故障隔离规则列表 |
|
||||
|
||||
|
||||
|
||||
### 服务治理——服务鉴权
|
||||
| 接口名称 | 描述 |
|
||||
| ---- | ---- |
|
||||
| sofa.ms.sg.authruleactiveappnames.list | 查找出目前存活的应用名称列表 |
|
||||
| sofa.ms.sg.authruleactivedataids.list | 查找该应用下存活的服务列表 |
|
||||
| sofa.ms.sg.authruleappnames.list | 查找出所有包含鉴权规则组的应用名(一般用于服务鉴权列表搜索框查询) |
|
||||
| sofa.ms.sg.authruledataids.list | 查找出所有包含鉴权规则组的服务ID(一般用于鉴权规则列表搜索框查询) |
|
||||
| sofa.ms.sg.authrulegroupapps.list | 应用级服务鉴权列表搜索 |
|
||||
| sofa.ms.sg.authrulegroups.disable | 禁止一份服务鉴权黑、白名单 |
|
||||
| sofa.ms.sg.authrulegroups.enable | 启用服务鉴权黑、白名单。黑、白名单不能同时生效 |
|
||||
| sofa.ms.sg.authrulegroups.export | 导出鉴权规则数据 |
|
||||
| sofa.ms.sg.authrulegroups.import | 导入鉴权规则数据 |
|
||||
| sofa.ms.sg.authrulegroups.list | 根据服务接口查询服务鉴权规则 |
|
||||
| sofa.ms.sg.authrulegroups.retry | 服务鉴权规则下发失败,重新下发规则 |
|
||||
| sofa.ms.sg.authrulegroups.save | 创建服务鉴权规则 |
|
||||
| sofa.ms.sg.authrulegroupsbatch.add | 添加鉴权规则 (添加服务级鉴权规则可批量添加) |
|
||||
| sofa.ms.sg.authrulegroupsbatch.disable | 批量关闭鉴权规则 |
|
||||
| sofa.ms.sg.authrulegroupsbatch.enable | 批量开启鉴权规则 |
|
||||
| sofa.ms.sg.authrulegroupservices.list | 服务级服务鉴权列表搜索 |
|
||||
| sofa.ms.sg.authrules.add | 添加一条白、黑名单规则 |
|
||||
| sofa.ms.sg.authrules.delete | 删除鉴权规则 |
|
||||
| sofa.ms.sg.authrules.disable | 禁用黑、白名单中的一条规则 |
|
||||
| sofa.ms.sg.authrules.enable | 启用服务鉴权规则 |
|
||||
| sofa.ms.sg.authrules.reinit | 清空黑白名单下所有鉴权规则 |
|
||||
| sofa.ms.sg.authrules.update | 更新一条服务鉴权规则 |
|
||||
|
||||
### 审计目录
|
||||
| 接口名称 | 描述 |
|
||||
| ---- | ---- |
|
||||
| sofa.ms.sg.auditlogs.list | 分页查询审计日志 |
|
||||
"7HBPQOV8F4OK","VRULPU2VVMZN","LARX4EGMTLT9","F5Z2YNZT2RNI","3GIVRPTL0IGK","VRULPU2VVMZN","LARX4EGMTLT9","EQLBTL6URR8H","VRULPU2VVMZN","LARX4EGMTLT9","BFHOBR8AYDYC","ZIC5FSHHEKL2","VIFEZDN1YVYU"
|
||||
588
test.sh
588
test.sh
@@ -1,571 +1,17 @@
|
||||
# cat zclean.sh
|
||||
#!/bin/bash
|
||||
# version: 0.9.2
|
||||
export LANG=C
|
||||
export PATH=/sbin:/bin:/usr/local/sbin:/usr/sbin:/usr/local/bin:/usr/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/admin/bin
|
||||
|
||||
|
||||
readonly LOGS_DIR=/home/admin/logs/
|
||||
readonly CONF_FILE=/home/admin/conf/zclean.conf
|
||||
|
||||
# 兼容逻辑,部分老应用通过云游部署会带上 app.env 等前缀,这里为了处理这种情况用 grep 来过滤
|
||||
RESERVE=`([[ -f /opt/antcloud/conf/env.file ]] && cat /opt/antcloud/conf/env.file || env) |grep ZCLEAN_RESERVE_DAYS | awk -F= '{print $2}'`
|
||||
RESERVE=${RESERVE:-14}
|
||||
MAX_LOG_DIR_SIZE=`([[ -f /opt/antcloud/conf/env.file ]] && cat /opt/antcloud/conf/env.file || env) |grep ZCLEAN_MAX_LOG_DIR_SIZE | awk -F= '{print $2}'`
|
||||
MAX_LOG_DIR_SIZE=${MAX_LOG_DIR_SIZE:-100} # unit is G
|
||||
|
||||
DELETE_FLAG='-delete'
|
||||
DEBUG=''
|
||||
CHUNK_SIZE=''
|
||||
INTERACTIVE=0
|
||||
ZCLEAN_DIGEST="${LOGS_DIR}/zclean.log.$(date +%F)"
|
||||
|
||||
|
||||
{
|
||||
readonly ZCLEAN_OK=1
|
||||
readonly ZCLEAN_CRUSH=2
|
||||
readonly ZCLEAN_ERROR=3
|
||||
readonly ZCLEAN_IGNORE=4
|
||||
}
|
||||
|
||||
[[ ! -d $LOGS_DIR ]] && exit
|
||||
|
||||
CMD_PREFIX=''
|
||||
if $(which ionice >& /dev/null); then
|
||||
CMD_PREFIX="ionice -c3 "
|
||||
fi
|
||||
if $(which nice >& /dev/null); then
|
||||
CMD_PREFIX="nice -n 19 $CMD_PREFIX"
|
||||
fi
|
||||
FIND_CMD="${CMD_PREFIX}find"
|
||||
RM_CMD="${CMD_PREFIX}rm"
|
||||
|
||||
TRUNCATE_CMD=''
|
||||
if $(which truncate >& /dev/null); then
|
||||
TRUNCATE_CMD="${CMD_PREFIX}truncate"
|
||||
fi
|
||||
|
||||
LSOF_CMD=''
|
||||
if $(which lsof >& /dev/null); then
|
||||
LSOF_CMD="lsof"
|
||||
fi
|
||||
|
||||
LSOF_FILE=/tmp/zclean_lsof.out
|
||||
if [[ -d /dev/shm ]]; then
|
||||
shm_mode=$(stat -c "%A" /dev/shm)
|
||||
if [[ $shm_mode == drwxrwxrwt ]]; then
|
||||
LSOF_FILE=/dev/shm/zclean_lsof.out
|
||||
fi
|
||||
fi
|
||||
|
||||
prepare_lsof() {
|
||||
# walkaroud for Alios7 kenrel bug
|
||||
if [[ $HOSTNAME =~ paycorecloud-30- ]]; then
|
||||
FIND_CMD $LOGS_DIR -name '*.log' > $LSOF_FILE
|
||||
return
|
||||
fi
|
||||
if [[ $HOSTNAME =~ paycorecloud-31- ]]; then
|
||||
FIND_CMD $LOGS_DIR -name '*.log' > $LSOF_FILE
|
||||
return
|
||||
fi
|
||||
if [[ -n $LSOF_CMD ]]; then
|
||||
ulimit -n 1024
|
||||
$LSOF_CMD +D $LOGS_DIR 2> /dev/null > $LSOF_FILE
|
||||
fi
|
||||
}
|
||||
|
||||
delete_lsof() {
|
||||
$RM_CMD -rf $LSOF_FILE
|
||||
}
|
||||
|
||||
# only return true when all ready
|
||||
file_in_lsof() {
|
||||
local fpath=$1
|
||||
if [[ -n $LSOF_CMD && -f $LSOF_FILE ]]; then
|
||||
grep -q $fpath $LSOF_FILE
|
||||
return $?
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo $(date +"%F %T") [ERROR] $@ >> $ZCLEAN_DIGEST
|
||||
}
|
||||
|
||||
log_info() {
|
||||
echo $(date +"%F %T") [INFO] $@ >> $ZCLEAN_DIGEST
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo $(date +"%F %T") [WARN] $@ >> $ZCLEAN_DIGEST
|
||||
}
|
||||
|
||||
log_debug() {
|
||||
[[ $DEBUG != '-debug' ]] && return
|
||||
echo $(date +"%F %T") [DEBUG] $@ >> $ZCLEAN_DIGEST
|
||||
}
|
||||
|
||||
delete_files() {
|
||||
[[ $DELETE_FLAG != '-delete' ]] && return
|
||||
$RM_CMD -rf "$@" >& /dev/null
|
||||
}
|
||||
|
||||
crush_files() {
|
||||
[[ $DELETE_FLAG != '-delete' ]] && return
|
||||
for f in "$@"; do
|
||||
> $f
|
||||
done
|
||||
}
|
||||
|
||||
clean_file() {
|
||||
# eliminates file in a low-speed way (default: 20MB/S)
|
||||
local fpath=$1
|
||||
local fsize=$2
|
||||
local chunksize=${CHUNK_SIZE:-20}
|
||||
|
||||
if [[ $DELETE_FLAG != '-delete' || ! -f $fpath ]]; then
|
||||
return $ZCLEAN_ERROR
|
||||
fi
|
||||
|
||||
local is_open=0
|
||||
if file_in_lsof $fpath >& /dev/null; then
|
||||
is_open=1
|
||||
fi
|
||||
|
||||
if [[ $is_open -eq 1 && $fsize -eq 0 ]]; then
|
||||
log_debug "ignore $fpath(+) size $fsize"
|
||||
return $ZCLEAN_IGNORE
|
||||
fi
|
||||
|
||||
if [[ $chunksize -eq 0 || -z $TRUNCATE_CMD ]]; then
|
||||
# fast delete
|
||||
if [[ $is_open -eq 1 ]]; then
|
||||
crush_files $fpath
|
||||
log_debug "removed $fpath(+) size $fsize directly"
|
||||
else
|
||||
delete_files $fpath
|
||||
log_debug "removed $fpath size $fsize directly"
|
||||
fi
|
||||
else
|
||||
# slow delete
|
||||
local tstart=$SECONDS
|
||||
local tstake=$((1+tstart))
|
||||
local loop=$((fsize/(1048576*chunksize)+1))
|
||||
local tdiff
|
||||
if [[ $fsize -eq 0 ]]; then
|
||||
loop=0
|
||||
fi
|
||||
for ((i=0; i<loop; ++i)); do
|
||||
$TRUNCATE_CMD -s "-${chunksize}M" $fpath
|
||||
tdiff=$((tstake-SECONDS))
|
||||
if [[ $tdiff -gt 0 ]]; then
|
||||
sleep $tdiff
|
||||
fi
|
||||
tstake=$((tstake+1))
|
||||
done
|
||||
if [[ $is_open -eq 1 ]]; then
|
||||
log_debug \
|
||||
"removed $fpath(+) size $fsize in $((SECONDS-tstart)) seconds"
|
||||
else
|
||||
log_debug \
|
||||
"removed $fpath size $fsize in $((SECONDS-tstart)) seconds"
|
||||
fi
|
||||
fi
|
||||
# here a time delta between lsof and remove
|
||||
if [[ -n $LSOF_CMD && $is_open -eq 0 ]]; then
|
||||
delete_files $fpath
|
||||
return $ZCLEAN_OK
|
||||
else
|
||||
return $ZCLEAN_CRUSH
|
||||
fi
|
||||
}
|
||||
|
||||
get_home_usage() {
|
||||
local usage
|
||||
#usage=$(df $LOGS_DIR|awk 'END {print $5}'|tr -d '%')
|
||||
usage=$(df $LOGS_DIR|tail -n 1|awk '{print $(NF-1)}'|sed -e 's/%//g')
|
||||
if [[ -z $usage ]]; then
|
||||
log_error "can't get home partition usage"
|
||||
exit 1
|
||||
fi
|
||||
usage_by_du=`du -sk $LOGS_DIR | awk '{print $1}'`
|
||||
usage_by_du=$(( (usage_by_du * 100) / (MAX_LOG_DIR_SIZE * 1024 * 1024) ))
|
||||
if [[ $usage_by_du -gt $usage ]]; then
|
||||
log_info "calculate usage based on MAX_LOG_DIR_SIZE, MAX_LOG_DIR_SIZE: $MAX_LOG_DIR_SIZE, usage: $usage_by_du"
|
||||
usage=$usage_by_du
|
||||
fi
|
||||
echo $usage
|
||||
}
|
||||
|
||||
sleep_dif()
|
||||
{
|
||||
local secs idc index
|
||||
if [[ $HOSTNAME =~ ^[a-z0-9]+-[0-9]+-[0-9]+$ ]]; then
|
||||
idc=$(echo $HOSTNAME|awk -F- '{print $2}')
|
||||
index=$(echo $HOSTNAME|awk -F- '{print $3}')
|
||||
secs=$(( (index*19 +idc*7)%233 ))
|
||||
else
|
||||
secs=$((RANDOM%133))
|
||||
fi
|
||||
sleep $secs
|
||||
log_info slept $secs seconds
|
||||
}
|
||||
|
||||
clean_expired() {
|
||||
local keep_days=$((RESERVE-1))
|
||||
if [[ $HOSTNAME =~ paycorecloud-30- ]]; then
|
||||
keep_days=1
|
||||
fi
|
||||
local fpath fsize fmtime how_long expired
|
||||
local ret_code=$ZCLEAN_OK
|
||||
$FIND_CMD $LOGS_DIR \
|
||||
-type f \
|
||||
-name '*log*' \
|
||||
! -name '*\.[0-9]dt\.log*' \
|
||||
! -name '*\.[0-9][0-9]dt\.log*' \
|
||||
! -name '*\.[0-9][0-9][0-9]dt\.log*' \
|
||||
-mtime +$keep_days \
|
||||
-printf '%p %s\n' | \
|
||||
while read fpath fsize; do
|
||||
clean_file $fpath $fsize
|
||||
ret_code=$?
|
||||
if [[ $ret_code -eq $ZCLEAN_OK || $ret_code -eq $ZCLEAN_CRUSH ]]; then
|
||||
log_info "deleted expired file $fpath size $fsize"
|
||||
fi
|
||||
done
|
||||
# http://doc.alipay.net/pages/viewpage.action?pageId=71187095
|
||||
$FIND_CMD $LOGS_DIR \
|
||||
-type f \
|
||||
\( -name '*\.[0-9]dt\.log*' -o \
|
||||
-name '*\.[0-9][0-9]dt\.log*' -o \
|
||||
-name '*\.[0-9][0-9][0-9]dt\.log*' \) \
|
||||
-printf '%p %s %TY-%Tm-%Td\n' | \
|
||||
while read fpath fsize fmtime; do
|
||||
how_long=$(echo $fpath | grep -o '[0-9]\+dt' | tr -d '[a-z]')
|
||||
expired=$(date -d"$how_long days ago" +"%F")
|
||||
if [[ $fmtime > $expired ]]; then
|
||||
continue
|
||||
else
|
||||
clean_file $fpath $fsize
|
||||
ret_code=$?
|
||||
if [[ $ret_code -eq $ZCLEAN_OK || $ret_code -eq $ZCLEAN_CRUSH ]]; then
|
||||
log_info "deleted expired file $fpath size $fsize"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
clean_huge() {
|
||||
local blocks big_size fpath fsize
|
||||
blocks=$(df /home -k|awk 'END {print $2}')
|
||||
if [[ ! $? ]]; then
|
||||
log_error "can't get home partition total size"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $blocks -ge ${MAX_LOG_DIR_SIZE}*1024*1024 ]]; then
|
||||
blocks=$(( MAX_LOG_DIR_SIZE*1024*1024 ))
|
||||
fi
|
||||
|
||||
# 120G
|
||||
if [[ $blocks -ge 125829120 ]]; then
|
||||
big_size=50G
|
||||
else
|
||||
big_size=30G
|
||||
fi
|
||||
$FIND_CMD $LOGS_DIR \
|
||||
-type f \
|
||||
-name '*log*' \
|
||||
-size +$big_size \
|
||||
-printf '%p %s\n' | \
|
||||
while read fpath fsize; do
|
||||
crush_files "$fpath"
|
||||
log_warn "deleted huge file $fpath size $fsize"
|
||||
done
|
||||
}
|
||||
|
||||
clean_by_day() {
|
||||
local how_long=$1
|
||||
local ret_code=$ZCLEAN_OK
|
||||
$FIND_CMD $LOGS_DIR \
|
||||
-type f \
|
||||
-name '*log*' \
|
||||
-mtime "+${how_long}" \
|
||||
-printf '%p %s\n' | \
|
||||
while read fpath fsize; do
|
||||
clean_file $fpath $fsize
|
||||
ret_code=$?
|
||||
if [[ $ret_code -eq $ZCLEAN_OK || $ret_code -eq $ZCLEAN_CRUSH ]]; then
|
||||
log_info "deleted $((how_long+1)) days ago file $fpath size $fsize"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
clean_by_hour() {
|
||||
local how_long=$1
|
||||
local ret_code=$ZCLEAN_OK
|
||||
$FIND_CMD $LOGS_DIR \
|
||||
-type f \
|
||||
-name '*log*' \
|
||||
-mmin "+$((how_long*60))" \
|
||||
-printf '%p %s\n' | \
|
||||
while read fpath fsize; do
|
||||
clean_file $fpath $fsize
|
||||
ret_code=$?
|
||||
if [[ $ret_code -eq $ZCLEAN_OK || $ret_code -eq $ZCLEAN_CRUSH ]]; then
|
||||
log_info "deleted $how_long hours ago file $fpath size $fsize"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
clean_largest() {
|
||||
local fsize fpath fblock
|
||||
local ret_code=$ZCLEAN_OK
|
||||
|
||||
$FIND_CMD $LOGS_DIR \
|
||||
-type f \
|
||||
-printf '%b %s %p\n' | \
|
||||
sort -nr | head -1 | \
|
||||
while read fblock fsize fpath ; do
|
||||
# 10G
|
||||
if [[ $fsize -gt 10737418240 ]]; then
|
||||
crush_files $fpath
|
||||
else
|
||||
clean_file $fpath $fsize
|
||||
fi
|
||||
ret_code=$?
|
||||
if [[ $ret_code -eq $ZCLEAN_OK || $ret_code -eq $ZCLEAN_CRUSH ]]; then
|
||||
log_info "deleted largest file $fpath size $fsize"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
in_low_traffic() {
|
||||
local now=$(date '+%R')
|
||||
if [[ "$now" > "04:00" && "$now" < "04:30" ]]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
clean_until() {
|
||||
local from_rate to_rate cur_usage old_usage how_long count force
|
||||
how_long=$((RESERVE-1))
|
||||
from_rate=$1
|
||||
to_rate=$2
|
||||
force=$3
|
||||
count=0
|
||||
|
||||
cur_usage=$(get_home_usage)
|
||||
|
||||
# should exist some huge files
|
||||
if [[ $cur_usage -ge 97 ]]; then
|
||||
clean_huge
|
||||
old_usage=$cur_usage
|
||||
cur_usage=$(get_home_usage)
|
||||
if [[ $cur_usage -ne $old_usage ]]; then
|
||||
log_info "usage from $old_usage to $cur_usage"
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! in_low_traffic; then
|
||||
[[ $cur_usage -lt $from_rate ]] && return
|
||||
fi
|
||||
|
||||
prepare_lsof
|
||||
|
||||
clean_expired
|
||||
old_usage=$cur_usage
|
||||
cur_usage=$(get_home_usage)
|
||||
if [[ $cur_usage -ne $old_usage ]]; then
|
||||
log_info "usage from $old_usage to $cur_usage"
|
||||
fi
|
||||
|
||||
# now we have to remove recent logs by date
|
||||
while [[ $cur_usage -gt $to_rate ]]; do
|
||||
if [[ $how_long -lt 1 ]]; then
|
||||
break
|
||||
else
|
||||
how_long=$((how_long-1))
|
||||
fi
|
||||
clean_by_day $how_long
|
||||
old_usage=$cur_usage
|
||||
cur_usage=$(get_home_usage)
|
||||
if [[ $cur_usage -ne $old_usage ]]; then
|
||||
log_info "usage from $old_usage to $cur_usage"
|
||||
fi
|
||||
done
|
||||
|
||||
# in hours
|
||||
how_long=24
|
||||
while [[ $cur_usage -gt $to_rate ]]; do
|
||||
if [[ $how_long -lt 2 ]]; then
|
||||
break
|
||||
else
|
||||
how_long=$((how_long-1))
|
||||
fi
|
||||
clean_by_hour $how_long
|
||||
old_usage=$cur_usage
|
||||
cur_usage=$(get_home_usage)
|
||||
if [[ $cur_usage -ne $old_usage ]]; then
|
||||
log_info "usage from $old_usage to $cur_usage"
|
||||
fi
|
||||
done
|
||||
|
||||
[[ $force -ne 1 ]] && return
|
||||
# last resort, find top size logs to deleted
|
||||
|
||||
if [[ $CHUNK_SIZE -ne 0 ]]; then
|
||||
CHUNK_SIZE=100
|
||||
fi
|
||||
while [[ $cur_usage -gt $to_rate ]]; do
|
||||
if [[ $count -gt 5 ]]; then
|
||||
log_error "give up deleting largest files"
|
||||
break
|
||||
fi
|
||||
count=$((count+1))
|
||||
clean_largest
|
||||
old_usage=$cur_usage
|
||||
cur_usage=$(get_home_usage)
|
||||
if [[ $cur_usage -ne $old_usage ]]; then
|
||||
log_info "usage from $old_usage to $cur_usage"
|
||||
fi
|
||||
done
|
||||
|
||||
delete_lsof
|
||||
}
|
||||
|
||||
ensure_unique() {
|
||||
local pgid=$(ps -p $$ -o pgid=)
|
||||
local pids=$(ps -e -o pid,pgid,cmd | \
|
||||
grep [z]clean | grep bash | \
|
||||
awk "\$2 != $pgid {print \$1}")
|
||||
if [[ -n $pids ]]; then
|
||||
if [[ $INTERACTIVE -eq 1 ]]; then
|
||||
kill $pids
|
||||
else
|
||||
log_info "$0 is running, wait for another round of dispatch"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
_main() {
|
||||
local to_rate=90
|
||||
local from_rate=$to_rate
|
||||
local do_sleep=0
|
||||
local force=0
|
||||
|
||||
# load config
|
||||
if [[ -f $CONF_FILE && ! "$*" =~ --noconf ]]; then
|
||||
while read -r line; do
|
||||
key=$(echo $line|cut -d= -f1)
|
||||
value=$(echo $line|cut -d= -f2)
|
||||
case $key in
|
||||
to)
|
||||
to_rate=$value;;
|
||||
block)
|
||||
CHUNK_SIZE=$value;;
|
||||
fast)
|
||||
CHUNK_SIZE=0;;
|
||||
from)
|
||||
from_rate=$value;;
|
||||
max_size)
|
||||
MAX_LOG_DIR_SIZE=$value;;
|
||||
sleep)
|
||||
do_sleep=1;;
|
||||
debug)
|
||||
DEBUG='-debug';;
|
||||
force)
|
||||
force=1;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
done < $CONF_FILE
|
||||
fi
|
||||
|
||||
# option help
|
||||
# -r clean to this ratio
|
||||
# -b wipe this blocksize each time
|
||||
# -t start cleaning when above this ratio
|
||||
# -m max size of log dir,unit is G
|
||||
# -n fast delete (use rm -rf)
|
||||
# -s random sleep awhile in a app clusters
|
||||
# -d extra debug logging
|
||||
# -f force delete largest file
|
||||
while getopts ":r:b:t:nsdfi" opt; do
|
||||
case $opt in
|
||||
r)
|
||||
if [[ ! $OPTARG =~ ^[0-9]+$ ]]; then
|
||||
echo "$0: rate $OPTARG is an invalid number" >&2
|
||||
exit 1;
|
||||
fi
|
||||
if [[ $OPTARG -le 1 || $OPTARG -ge 99 ]]; then
|
||||
echo "$0: rate $OPTARG out of range (1, 99)" >&2
|
||||
exit 1;
|
||||
fi
|
||||
to_rate=$OPTARG ;;
|
||||
b)
|
||||
if [[ ! $OPTARG =~ ^[0-9]+[mMgG]?$ ]]; then
|
||||
echo "$0: block size $OPTARG is invalid" >&2
|
||||
exit 1;
|
||||
fi
|
||||
if [[ $OPTARG =~ [gG]$ ]]; then
|
||||
CHUNK_SIZE=$(echo $OPTARG|tr -d 'gG')
|
||||
CHUNK_SIZE=$((CHUNK_SIZE*1024))
|
||||
else
|
||||
CHUNK_SIZE=$(echo $OPTARG|tr -d 'mM')
|
||||
fi ;;
|
||||
t)
|
||||
if [[ ! $OPTARG =~ ^[0-9]+$ ]]; then
|
||||
echo "$0: rate $OPTARG is an invalid number" >&2
|
||||
exit 1;
|
||||
fi
|
||||
if [[ $OPTARG -le 1 || $OPTARG -ge 99 ]]; then
|
||||
echo "$0: rate $OPTARG out of range (1, 99)" >&2
|
||||
exit 1;
|
||||
fi
|
||||
from_rate=$OPTARG ;;
|
||||
m)
|
||||
if [[ ! $OPTARG =~ ^[0-9]+$ ]]; then
|
||||
echo "$0: max size $OPTARG is invalid" >&2
|
||||
exit 1;
|
||||
fi
|
||||
MAX_LOG_DIR_SIZE=$OPTARG ;;
|
||||
n)
|
||||
CHUNK_SIZE=0 ;;
|
||||
s)
|
||||
do_sleep=1 ;;
|
||||
d)
|
||||
DEBUG='-debug' ;;
|
||||
f)
|
||||
force=1 ;;
|
||||
i)
|
||||
INTERACTIVE=1 ;;
|
||||
|
||||
\?)
|
||||
echo "$0: invalid option: -$OPTARG" >&2
|
||||
exit 1;;
|
||||
:)
|
||||
echo "$0: option -$OPTARG requires an argument" >&2
|
||||
exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ $to_rate -ge $from_rate ]]; then
|
||||
to_rate=$from_rate
|
||||
fi
|
||||
|
||||
ensure_unique
|
||||
[[ $do_sleep -eq 1 ]] && sleep_dif
|
||||
clean_until $from_rate $to_rate $force
|
||||
}
|
||||
|
||||
# TODO make a decision whether /home/admin is innocent
|
||||
# TODO deamonize
|
||||
|
||||
_main "$@"
|
||||
+-----+--------------+---------------+------------------+-----------+----------+---------------------+---------------------+
|
||||
| id | instance_id | instance_name | workspace_id | tenant_id | operator | gmt_create | gmt_modified |
|
||||
+-----+--------------+---------------+------------------+-----------+----------+---------------------+---------------------+
|
||||
| 432 | 7HBPQOV8F4OK | default | acbossprod | ANTCLOUDF | NULL | 2022-02-07 10:13:11 | 2022-02-07 10:13:11 |
|
||||
| 443 | VRULPU2VVMZN | default | acgatewaypre | ANTCLOUDF | NULL | 2022-03-01 21:00:01 | 2022-03-01 21:00:01 |
|
||||
| 461 | LARX4EGMTLT9 | default | acgatewayprod | ANTCLOUDF | NULL | 2022-03-25 16:03:15 | 2022-03-25 16:03:15 |
|
||||
| 425 | F5Z2YNZT2RNI | default | acnbosspre | ANTCLOUDF | NULL | 2021-12-22 21:11:02 | 2021-12-22 21:11:02 |
|
||||
| 424 | 3GIVRPTL0IGK | default | acnbossprod | ANTCLOUDF | NULL | 2021-12-22 21:10:12 | 2021-12-22 21:10:12 |
|
||||
| 404 | VRULPU2VVMZN | default | antchainbosspre | ANTCLOUDF | NULL | 2021-10-13 00:52:24 | 2021-10-13 00:52:24 |
|
||||
| 402 | LARX4EGMTLT9 | default | antchainbossprod | ANTCLOUDF | NULL | 2021-09-30 14:51:19 | 2021-09-30 14:51:19 |
|
||||
| 473 | EQLBTL6URR8H | default | antstackDoc | ANTCLOUDF | NULL | 2022-05-10 14:41:23 | 2022-05-10 14:41:23 |
|
||||
| 428 | VRULPU2VVMZN | default | bosspre | ANTCLOUDF | NULL | 2022-01-05 11:17:40 | 2022-01-05 11:17:40 |
|
||||
| 429 | LARX4EGMTLT9 | default | bossprod | ANTCLOUDF | NULL | 2022-01-05 11:18:10 | 2022-01-05 11:18:10 |
|
||||
| 409 | BFHOBR8AYDYC | default | cnhzpfmayprekms | ANTCLOUDF | NULL | 2021-10-29 10:33:39 | 2021-10-29 10:33:39 |
|
||||
| 401 | ZIC5FSHHEKL2 | default | cnhzpfmaypub01 | ANTCLOUDF | NULL | 2021-09-27 17:15:23 | 2021-09-27 17:15:23 |
|
||||
| 476 | VIFEZDN1YVYU | default | traasprod | ANTCLOUDF | NULL | 2022-05-20 11:51:34 | 2022-05-20 11:51:34 |
|
||||
+-----+--------------+---------------+------------------+-----------+----------+---------------------+---------------------+
|
||||
Reference in New Issue
Block a user