PowerJob的GridFsManager工作流程源码解读

 更新时间:2024年01月23日 09:10:47   作者:codecraft  
这篇文章主要为大家介绍了PowerJob的GridFsManager工作流程源码解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

本文主要研究一下PowerJob的GridFsManager

GridFsManager

tech/powerjob/server/persistence/mongodb/GridFsManager.java

@Slf4j
@Service
public class GridFsManager implements InitializingBean {
    private final Environment environment;
    private final MongoDatabase db;
    private boolean available;
    private final Map<String, GridFSBucket> bucketCache = Maps.newConcurrentMap();
    public static final String LOG_BUCKET = "log";
    public static final String CONTAINER_BUCKET = "container";
    public GridFsManager(Environment environment, @Autowired(required = false) MongoTemplate mongoTemplate) {
        this.environment = environment;
        if (mongoTemplate != null) {
            this.db = mongoTemplate.getDb();
        } else {
            this.db = null;
        }
    }
    /**
     * 是否可用
     * @return true:可用;false:不可用
     */
    public boolean available() {
        return available;
    }
    //......
    private GridFSBucket getBucket(String bucketName) {
        return bucketCache.computeIfAbsent(bucketName, ignore -> GridFSBuckets.create(db, bucketName));
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        String enable = environment.getProperty(PowerJobServerConfigKey.MONGODB_ENABLE, Boolean.FALSE.toString());
        available = Boolean.TRUE.toString().equals(enable) && db != null;
        log.info("[GridFsManager] available: {}, db: {}", available, db);
    }
}
GridFsManager实现了InitializingBean接口,其afterPropertiesSet从environment读取oms.mongodb.enable配置,默认为false;其构造器注入mongoTemplate,若为null则available为false;其getBucket方法则根据bucketName缓存到bucketCache,若不存在则通过GridFSBuckets.create创建

store

/**
     * 存储文件到 GridFS
     * @param localFile 本地文件
     * @param bucketName 桶名称
     * @param fileName GirdFS中的文件名称
     * @throws IOException 异常
     */
    public void store(File localFile, String bucketName, String fileName) throws IOException {
        if (available()) {
            GridFSBucket bucket = getBucket(bucketName);
            try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(localFile))) {
                bucket.uploadFromStream(fileName, bis);
            }
        }
    }
store方法先获取bucket,再读取localFile,通过bucket.uploadFromStream上传

download

/**
     * 从 GridFS 下载文件
     * @param targetFile 下载的目标文件(本地文件)
     * @param bucketName 桶名称
     * @param fileName GirdFS中的文件名称
     * @throws IOException 异常
     */
    public void download(File targetFile, String bucketName, String fileName) throws IOException {
        if (available()) {
            GridFSBucket bucket = getBucket(bucketName);
            try (GridFSDownloadStream gis = bucket.openDownloadStream(fileName);
                 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(targetFile))
            ) {
                byte[] buffer = new byte[1024];
                int bytes = 0;
                while ((bytes = gis.read(buffer)) != -1) {
                    bos.write(buffer, 0, bytes);
                }
                bos.flush();
            }
        }
    }
download方法则先获取bucket,再通过bucket.openDownloadStream获取GridFSDownloadStream,最后写到targetFile

deleteBefore

/**
     * 删除几天前的文件
     * @param bucketName 桶名称
     * @param day 日期偏移量,单位 天
     */
    public void deleteBefore(String bucketName, int day) {
        Stopwatch sw = Stopwatch.createStarted();
        Date date = DateUtils.addDays(new Date(), -day);
        GridFSBucket bucket = getBucket(bucketName);
        Bson filter = Filters.lt("uploadDate", date);
        // 循环删除性能很差?我猜你肯定没看过官方实现[狗头]:org.springframework.data.mongodb.gridfs.GridFsTemplate.delete
        bucket.find(filter).forEach((Consumer<GridFSFile>) gridFSFile -> {
            ObjectId objectId = gridFSFile.getObjectId();
            try {
                bucket.delete(objectId);
                log.info("[GridFsManager] deleted {}#{}", bucketName, objectId);
            }catch (Exception e) {
                log.error("[GridFsManager] deleted {}#{} failed.", bucketName, objectId, e);
            }
        });
        log.info("[GridFsManager] clean bucket({}) successfully, delete all files before {}, using {}.", bucketName, date, sw.stop());
    }
deleteBefore主要通过bucket.find(Filters.lt("uploadDate", date))找到GridFSFile,再挨个执行delete

exists

public boolean exists(String bucketName, String fileName) {
        GridFSBucket bucket = getBucket(bucketName);
        GridFSFindIterable files = bucket.find(Filters.eq("filename", fileName));
        try {
            GridFSFile first = files.first();
            return first != null;
        }catch (Exception ignore) {
        }
        return false;
    }
exists方法则通过bucket.find(Filters.eq("filename", fileName))来进行查找

sync

tech/powerjob/server/core/instance/InstanceLogService.java

@Async(PJThreadPool.BACKGROUND_POOL)
    public void sync(Long instanceId) {
        Stopwatch sw = Stopwatch.createStarted();
        try {
            // 先持久化到本地文件
            File stableLogFile = genStableLogFile(instanceId);
            // 将文件推送到 MongoDB
            if (gridFsManager.available()) {
                try {
                    gridFsManager.store(stableLogFile, GridFsManager.LOG_BUCKET, genMongoFileName(instanceId));
                    log.info("[InstanceLog-{}] push local instanceLogs to mongoDB succeed, using: {}.", instanceId, sw.stop());
                }catch (Exception e) {
                    log.warn("[InstanceLog-{}] push local instanceLogs to mongoDB failed.", instanceId, e);
                }
            }
        }catch (Exception e) {
            log.warn("[InstanceLog-{}] sync local instanceLogs failed.", instanceId, e);
        }
        // 删除本地数据库数据
        try {
            instanceId2LastReportTime.remove(instanceId);
            CommonUtils.executeWithRetry0(() -> localInstanceLogRepository.deleteByInstanceId(instanceId));
            log.info("[InstanceLog-{}] delete local instanceLog successfully.", instanceId);
        }catch (Exception e) {
            log.warn("[InstanceLog-{}] delete local instanceLog failed.", instanceId, e);
        }
    }
InstanceLogService的sync方法先持久化到本地文件,再将文件推送到 MongoDB

小结

GridFsManager实现了InitializingBean接口,其afterPropertiesSet从environment读取oms.mongodb.enable配置,默认为false;其构造器注入mongoTemplate,若为null则available为false;其store和download方法都先判断是否available,为false则空操作。

以上就是PowerJob的GridFsManager工作流程源码解读的详细内容,更多关于PowerJob GridFsManager的资料请关注脚本之家其它相关文章!

相关文章

  • java运行时数据区域和类结构详解

    java运行时数据区域和类结构详解

    这篇文章主要介绍了java运行时数据区域和类结构,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • SpringBoot接受参数相关注解方式

    SpringBoot接受参数相关注解方式

    SpringBoot接受参数的注解包括@PathVariable、@RequestHeader、@RequestParameter、@CookieValue、@RequestBody、@RequestAttribute和@SessionAttribute等,每个注解都有详细的使用方法和示例代码
    2024-12-12
  • SpringBoot父子线程数据传递的五种方案介绍

    SpringBoot父子线程数据传递的五种方案介绍

    在实际开发过程中我们需要父子之间传递一些数据,比如用户信息等。该文章从5种解决方案解决父子之间数据传递困扰,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-09-09
  • java中Struts2 的文件上传和下载示例

    java中Struts2 的文件上传和下载示例

    这篇文章主要介绍了java中Struts2 的文件上传和下载示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。
    2016-12-12
  • Java service层获取HttpServletRequest工具类的方法

    Java service层获取HttpServletRequest工具类的方法

    今天小编就为大家分享一篇关于Java service层获取HttpServletRequest工具类的方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • Java中BeanUtils.copyProperties基本用法与小坑

    Java中BeanUtils.copyProperties基本用法与小坑

    本文主要介绍了Java中BeanUtils.copyProperties基本用法与小坑,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • 使用Java全栈实现一个低代码平台的完整方案

    使用Java全栈实现一个低代码平台的完整方案

    随着数字化转型的加速,企业对快速应用开发的需求日益增长,低代码平台作为一种新兴的开发模式,通过可视化界面和拖拽式组件,大大降低了应用开发的门槛,提高了开发效率,本文将详细介绍如何使用Java全栈技术实现一个功能完整的低代码平台,需要的朋友可以参考下
    2025-08-08
  • Java中对List去重 Stream去重的解决方法

    Java中对List去重 Stream去重的解决方法

    这篇文章主要介绍了Java中对List去重, Stream去重的问题解答,文中给大家介绍了Java中List集合去除重复数据的方法,需要的朋友可以参考下
    2018-04-04
  • SpringBoot+Vue+Redis实现单点登录(一处登录另一处退出登录)

    SpringBoot+Vue+Redis实现单点登录(一处登录另一处退出登录)

    小编接到一个需求,需要实现用户在浏览器登录后,跳转到其他页面,当用户在其它地方又登录时,前面用户登录的页面退出登录,这篇文章主要介绍了SpringBoot+Vue+Redis实现单点登录,需要的朋友可以参考下
    2019-12-12
  • Java实现的快速查找算法示例

    Java实现的快速查找算法示例

    这篇文章主要介绍了Java实现的快速查找算法,结合具体实例形式分析了快速查找算法的原理与相关实现技巧,需要的朋友可以参考下
    2017-09-09

最新评论