crontab 등록 정보 현행화

불편해

프로그램정보를 관리하고 있는 화면과 테이블이 있다. 그 중 일부는 crontab에 등록해서 주기적으로 실행하고 있는데, 관리가 잘 되지 않아서 부정확한 정보가 많다. 그렇다고 필요할 때마다 서버에 접속해서 crontab을 확인하자니 힘이 빠진다. crontab을 읽어서 자동으로 동기화 해주는 걸 만들면 두고두고 편할 것 같다.


계획

먼저 crontab에 저장된 작업 정보를 읽어서 Map 형태로 저장한다.
프로그램정보를 DB에서 읽어서 Map 형태로 저장한다.
프로그램정보에 해당하는 crontab 정보가 있는 경우, 프로그램정보 Map에서 해당 crontab 정보를 추가한다.
crontab 정보가 추가된 프로그램정보를 DB에서 업데이트 처리한다.


crontab 정보 읽기

crontab 정보를 하루에 한 번 백업하고 있었다. 그러면 최근 백업한 파일을 한 줄씩 읽어 들이면서, 프로그램정보에 해당하는 것들만 Map에 저장해서 활용하면 될 것 같다.

    private Map<String, String[]> cronMap;
    
    public Map<String, String[]> initCronDictionary(File file) {
        cronMap = new HashMap();

        try (Stream<String> lines = Files.lines(Paths.get(file.getPath()), StandardCharsets.UTF_8);   // 파일을 줄 단위로 Stream 생성
       Stream<String> cronJob = lines.filter(k -> !(k.startsWith("#"))).filter(k -> k.length() > 10)) {  // 주석 및 10글자 미만은 제외
            cronJob.forEach(x -> {
                addCronMap(x);
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        return cronMap;
    }
    
    public void addCronMap(String cmd) {
        // TODO: 동일한 **키가 있을 수도 있는데, 이렇게 처리하는 것이 최선일까?
        // - 중복키를 별도로 관리해서 후처리하도록 할까?
        if (cronMap.containsKey(getId(cmd))) {
            cronMap.put(getCompositeId(cmd)+"#", getCronExpArray(cmd));
        } else {
            cronMap.put(getCompositeId(cmd), getCronExpArray(cmd));
        }
    }

Stream을 이용해서 파일을 줄 단위로 읽어 들인다. 이 때 주석을 제외하도록 filter를 걸었다. 그리고 프로그램 키로 식별되는 것들만을 Map에 저장하도록 처리했다.

initCronDictionary 메서드에서 사용한 try-with-resources 문은 꽤 편리하다. 리소스가 AutoCloseable 인터페이스를 구현하는 클래스라면 굳이 리소스를 명시적으로 close 할 필요가 없기 때문이다. 이 때 리소스는 초기화의 역순으로 닫힌다.

지금은 crontab에 등록된 프로그램 키의 중복이 없는 구조여서 addCronMap 메서드를 저렇게 마무리 하긴 했는데, 좀 찜찜하다. crontab에 중복되는 프로그램 키가 있는 경우 어떻게 처리해야 할까? 예를 들어 동일한 프로그램 작업이 서로 다른 실행 주기로 crontab에 2번 정의된 경우 말이다. 애매하다.


crontab 등록정보 현행화

DB에 있는 정보를 읽어들여 Map에 저장하는 작업은 특별할게 없다. 프로그램정보에서 crontab에 실행정보가 있는 것들만 업데이트 해주고, DB에 반영하도록 했다. 그리고 추가로 opencsv를 이용하여 csv 파일형식으로 저장했다. 아무래도 엑셀이 제일 편하긴 하지.

댓글 쓰기

0 댓글