본문으로 바로가기

자동백업 프로그램

category Web DevelopmentJavascript 11년 전

요번주는 오랜만에 개인서버들 정리하고 백업 프로그램(JAVA) 서비스에 등록하다보니 벌써 시간이 ....... 일요일 오후 7시 44분...

Apache Commons Library를 이용한 압축(백업) 프로그램을 개발 하게 되었다.

현재 소스버전은 설정파일.xml 에 등록된 정보로 처리를 하지만 추후에는 별도로 서버 관리시스템을 구축하여 백업등록 및 자동 스케줄러 등록하여 처리하는 프로세스로 개발을 진행할려고 한다.

소개하는 백업 프로그램은 서버 관리 시스템의 하나의 모듈이 되는 부분으로 공개를 하고자 한다.

 

설정파일 (autoBackupConfig.xml)

매주 한번만 백업 NAS Storage에 백업

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<config>
    <path>
        <backup>
            <backuppath>D:/apps/web/php</backuppath>
            <day>4</day> <!--  월(1), 화(2), 수(3), 목(4), 금(5), 토(6), 일(0) -->
            <time>18</time> <!--  시간 01~24 -->
            <backupDir>E:/storage/backup</backupDir> <!-- 백업 경로 -->
        </backup>
        <backup>
            <backuppath>D:/apps/web/jsp</backuppath>
            <day>5</day> <!--  월(1), 화(2), 수(3), 목(4), 금(5), 토(6), 일(0) -->
            <time>10</time> <!--  시간 01~24 -->
            <backupDir>E:/storage/backup</backupDir> <!-- 백업 경로 -->
        </backup>
    </path>
</config>

 

 자동백업 메인 클래스 (JQAutobackup)

log4j를 이용하여 백업로그도 쌓지만 화면상으로도 확인이 필요할듯 해서 swing을 별도로 구현함.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
package com.jqdom.autobackup;
 
import java.awt.BorderLayout;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
 
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
 
import org.apache.log4j.Logger;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
 
import com.jqdom.util.ZipUtils;
 
/**
 * <PRE>
 * <b>Title : 자동 백업</b>
 * JQAutobackup.java - JQAutobackup
 *
 * <b>Description:</b>
 * [DESCRIPTION]
 *
 * <b>Copyright: </b>CopyRight (c) 2013
 * <b>Company: </b>KT
 * </PRE>
 * @author 김종철
 * @version 1.0
 * @created
 * 2014. 5. 21. 오후 1:58:21
 * @updated
 * 2014. 5. 21. 오후 1:58:21 [김종철] 최초 작성
 */
public class JQAutobackup extends JFrame {
    /**
     *
     */
    private static final long serialVersionUID = 1L;
 
 
    static Logger log = Logger.getLogger(JQAutobackup.class);  
     
     
    /**
     * 백업 설정 리스트
     */
    private ArrayList<BackupConfig> AR_FILE_PATH = new ArrayList<BackupConfig>();
     
     
    /**
     * 시간 포멧
     */
    private SimpleDateFormat formateHH = new SimpleDateFormat("H");
     
    /**
     * 현재시간
     */
    private SimpleDateFormat formateTodate = new SimpleDateFormat("yyyyMMddHHmmss"); 
     
    private SimpleDateFormat formateTodate2 = new SimpleDateFormat("yyyy/MM/dd/HH/mm:ss"); 
    /**
     * readConfig - [백업 설정 파일 읽기]
     *
     * @author 김종철
     * @version 1.0
     * @created
     * 2014. 5. 22. 오후 4:57:13
     * @updated
     * 2014. 5. 22. 오후 4:57:13 [김종철] 최초 작성
     */
    private void readConfig() {
        String configfile =  "./autoBackupConfig.xml";
        try {
            SAXBuilder db = new SAXBuilder();
            org.jdom.Document doc = db.build(new File(configfile));
            try
            {
                List<?> lstPath = doc.getRootElement().getChild("path").getChildren("backup");
                for(int i=0;i<lstPath.size();i++) {
                    Element elem = (Element)lstPath.get(i);
                    String sPath = elem.getChild("backuppath").getValue();
                    String sDay = elem.getChild("day").getValue();
                    String sTime = elem.getChild("time").getValue();
                    String sBackupDir = elem.getChild("backupDir").getValue();
                    String[] arPath = sPath.split("/");
 
                    sBackupDir = String.format("%s/%s_%s.zip", sBackupDir,formateTodate.format(new Date()), arPath[arPath.length-1]);
                    AR_FILE_PATH.add(new BackupConfig(sPath, sDay, sTime, sBackupDir));
                }
                log.debug("[jqdom] ============================================");
                log.debug("[jqdom] Auto Backup Server Start ver. 20140522.001 ");
                log.debug("[jqdom] ============================================");
                log.debug("[jqdom] ============================================");
            } catch (Exception ie) {
                log.error("config reading Error" + ie.getMessage());
            }
        }
        catch (Exception e) {
            log.error("Config Read Error ... " + e.getMessage());
        }
    }   
     
    /**
     * selectPathConfig - [백업설정 조회]
     *
     * @author 김종철
     * @version 1.0
     * @return
     * @created
     * 2014. 5. 22. 오후 6:06:26
     * @updated
     * 2014. 5. 22. 오후 6:06:26 [김종철] 최초 작성
     */
    private ArrayList<BackupConfig> selectPathConfig() {
        ArrayList<BackupConfig> lstBackupPath = new ArrayList<BackupConfig>();
        String sHH = getTime(); //현재시간
        String sDay = getDay(); //현재요일 일0~ 토6
        for(BackupConfig conf : AR_FILE_PATH) {
            if(conf.getDay().equals(sDay) && conf.getTime().equals(sHH)) { //요일 시간
                lstBackupPath.add(new BackupConfig(conf.getPath(), conf.getDay(), conf.getTime(), conf.getBackupDir()));
            }
        }
        return lstBackupPath;
    }
     
    /**
     * Execute - [백업처리 메소드]
     *
     * @author 김종철
     * @version 1.0
     * @created
     * 2014. 5. 22. 오후 4:58:26
     * @updated
     * 2014. 5. 22. 오후 4:58:26 [김종철] 최초 작성
     */
    private void Execute() {
        try{
            readConfig();
            boolean isBackupAct = false;
            while(true) {
                try{
                    Thread.sleep(1000); //6분 딜레이(600000)
                    ArrayList<BackupConfig> lstConfig = selectPathConfig();
                    //백업 할게 없으면 PASS
                    if(lstConfig.size() == 0) {
                        isBackupAct = false;
                        continue;
                    }
                     
                    if(!isBackupAct) {
                        backupExcute(lstConfig);   
                    }
                    isBackupAct = true;
                    break;
                }catch(Exception ex) {
                    log.error(ex.getMessage());
                    throw ex;
                }
            }
        }catch(Exception e) {
             
        }
    }
     
    /**
     * backupExcute - [백업 처리 메소드]
     *
     * @author 김종철
     * @version 1.0
     * @created
     * 2014. 5. 22. 오후 5:00:04
     * @updated
     * 2014. 5. 22. 오후 5:00:04 [김종철] 최초 작성
     */
    private void backupExcute(ArrayList<BackupConfig> lstConfig) {
        //ZIP 압축
        log.debug("[jqdom] ============================================");
        log.debug("[jqdom] ZIP Start                                   ");
        log.debug("[jqdom] ============================================");
        System.out.println("압축시작");
        ZipUtils zipUtils = new ZipUtils();
        for(BackupConfig bkConf : lstConfig) {
            tablemodel.addRow(new String[] {formateTodate2.format(new Date()), bkConf.getPath() });
            zipUtils.zip(bkConf.getPath(), bkConf.getBackupDir()); 
        }
    }
     
    /**
     * getDay - [현재 요일 반환]
     *
     * @author 김종철
     * @version 1.0
     * @return
     * @created
     * 2014. 5. 22. 오후 5:33:31
     * @updated
     * 2014. 5. 22. 오후 5:33:31 [김종철] 최초 작성
     */
    @SuppressWarnings("deprecation")
    private String getDay() {
        Date toDate = new Date();
        return String.valueOf(toDate.getDay()); //일 0 , 월1~ 토6
    }
     
    /**
     * getTime - [현재시간 반환]
     *
     * @author 김종철
     * @version 1.0
     * @return
     * @created
     * 2014. 5. 22. 오후 5:33:20
     * @updated
     * 2014. 5. 22. 오후 5:33:20 [김종철] 최초 작성
     */
    private String getTime() {
        Date toDate = new Date();
        return formateHH.format(toDate);
    }
     
     
    /**
     * main - [실행메소드]
     *
     * @author 김종철
     * @version 1.0
     * @param args
     * @throws JDOMException
     * @throws IOException
     * @created
     * 2014. 5. 22. 오후 4:58:14
     * @updated
     * 2014. 5. 22. 오후 4:58:14 [김종철] 최초 작성
     */
    public static void main(String[] args) throws JDOMException, IOException {
        JQAutobackup manager = new JQAutobackup();
        manager.Execute();
         
    }
    //==========================================================================================================================================================
    // Swing Source
    //==========================================================================================================================================================   
     
    private JTable table;
    private DefaultTableModel tablemodel;
     
    public JQAutobackup() {
        super("JQDOM Auto Backup");
        tablemodel = new DefaultTableModel();
        tablemodel.setColumnIdentifiers(new String[] {"백업일시", "백업경로"});
        table = new JTable(tablemodel);
        JScrollPane scroll = new JScrollPane(table);
         
        getContentPane().add(table.getTableHeader(), BorderLayout.NORTH);
        getContentPane().add(scroll, BorderLayout.CENTER);
  
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(500, 300);
        setVisible(true);
    }
     
    //==========================================================================================================================================================
    // 설정 VO
    //==========================================================================================================================================================   
    /**
     * <PRE>
     * <b>Title : 파일 설정VO</b>
     * JQAutobackup.java - BackupConfig
     *
     * <b>Description:</b>
     * [DESCRIPTION]
     *
     * <b>Copyright: </b>CopyRight (c) 2013
     * <b>Company: </b>KT
     * </PRE>
     * @author 김종철
     * @version 1.0
     * @created
     * 2014. 5. 22. 오후 4:57:33
     * @updated
     * 2014. 5. 22. 오후 4:57:33 [김종철] 최초 작성
     */
    public class BackupConfig {
        /**
         * 백업할 경로
         */
        private String path = "";
        /**
         * 백업일시(일0 ~ 토6)
         */
        private String day = "";
        /**
         * 백업시간
         */
        private String time = "";
        /**
         * 백업파일 저장경로
         */
        private String backupDir = "";
         
        public BackupConfig(String p_path, String p_day, String p_time, String p_backupDir) {
            this.path = p_path;
            this.day = p_day;
            this.time = p_time;
            this.backupDir = p_backupDir;
        }
        /**
         * @return the path
         */
        public String getPath() {
            return path;
        }
 
        /**
         * @param path the path to set
         */
        public void setPath(String path) {
            this.path = path;
        }
 
        /**
         * @return the day
         */
        public String getDay() {
            return day;
        }
 
        /**
         * @param day the day to set
         */
        public void setDay(String day) {
            this.day = day;
        }
 
        /**
         * @return the time
         */
        public String getTime() {
            return time;
        }
 
        /**
         * @param time the time to set
         */
        public void setTime(String time) {
            this.time = time;
        }
        /**
         * @return the backupDir
         */
        public String getBackupDir() {
            return backupDir;
        }
        /**
         * @param backupDir the backupDir to set
         */
        public void setBackupDir(String backupDir) {
            this.backupDir = backupDir;
        }
    }
}

Zip Utils 클래스 ( ZipUtils)

개발목적이 백업이여서 압축해제는 굳이  만들지 않았음 ㅎㅎ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package com.jqdom.util;
 
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
 
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.log4j.Logger;
 
public class ZipUtils {
    static Logger log = Logger.getLogger(ZipUtils.class);  
    private static boolean debug = true;
     
     
    String strToDate = "";
     
    /**
     * Constructor - [생성자 메소드]
     *
     * @author 김종철
     * @version 1.0
     * @created
     * 2014. 5. 22. 오후 6:19:46
     * @updated
     * 2014. 5. 22. 오후 6:19:46 [김종철] 최초 작성
     */
    public ZipUtils() {
        SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat ( "yyyy.MM.dd HH:mm:ss", Locale.KOREA );
        Date currentTime = new Date ( );
        strToDate = mSimpleDateFormat.format ( currentTime );;
    }
     
     
    /**
     * unzip - [압축해제]
     *
     * @author 김종철
     * @version 1.0
     * @param filePath 백업파일경로
     * @created
     * 2014. 5. 22. 오후 6:18:46
     * @updated
     * 2014. 5. 22. 오후 6:18:46 [김종철] 최초 작성
     */
    public void unzip(String filePath) {
        debug("===================================================================");
        debug("= Backup UnZip Start : "+filePath+"                               =");
        debug("===================================================================");
    }
     
    /**
     * zip - [압축]
     *
     * @author 김종철
     * @version 1.0
     * @param filePath
     * @created
     * 2014. 5. 22. 오후 6:19:20
     * @updated
     * 2014. 5. 22. 오후 6:19:20 [김종철] 최초 작성
     */
    public void zip(String filePath, String backupDir) {
        debug("===================================================================");
        debug("= Backup Zip Start : "+filePath+"                                 =");
        debug("===================================================================");
         
        try{
            System.out.println(String.format("%s, %s",filePath, backupDir));
            createZip(filePath, backupDir);
        }catch(IOException iox) {
            debug(" Zip IOException Error =");
            debug(iox.getMessage());
            iox.printStackTrace();
        }catch(Exception ex) {
            debug(" Zip Exception Error =");
            debug(ex.getMessage());
        }
    }
     
    /**
     * createZip - [압축실행]
     *
     * @author 김종철
     * @version 1.0
     * @param directoryPath
     * @param zipPath
     * @throws IOException
     * @created
     * 2014. 5. 28. 오후 3:31:00
     * @updated
     * 2014. 5. 28. 오후 3:31:00 [김종철] 최초 작성
     */
    public void createZip(String directoryPath, String zipPath) throws IOException {
        FileOutputStream fOut = null;
        BufferedOutputStream bOut = null;
        ZipArchiveOutputStream tOut = null;
        try {
            fOut = new FileOutputStream(new File(zipPath));
            bOut = new BufferedOutputStream(fOut);
            tOut = new ZipArchiveOutputStream(bOut);
            tOut.setEncoding("EUC-KR"); //한글인코딩
            addFileToZip(tOut, directoryPath, "");
        } finally {
            tOut.finish();
            tOut.close();
            bOut.close();
            fOut.close();
        }
    }
 
    /**
     * addFileToZip - [압축 프로세스 실행]
     *
     * @author 김종철
     * @version 1.0
     * @param zOut
     * @param path
     * @param base
     * @throws IOException
     * @created
     * 2014. 5. 28. 오후 3:31:17
     * @updated
     * 2014. 5. 28. 오후 3:31:17 [김종철] 최초 작성
     */
    public void addFileToZip(ZipArchiveOutputStream zOut, String path, String base) throws IOException {
        File f = new File(path);
        String entryName = base + f.getName();
        ZipArchiveEntry zipEntry = new ZipArchiveEntry(f, entryName);
        zOut.putArchiveEntry(zipEntry);
        if (f.isFile()) {
            FileInputStream fInputStream = null;
            try {
                fInputStream = new FileInputStream(f);
                IOUtils.copy(fInputStream, zOut);
                zOut.closeArchiveEntry();
            }finally {
                IOUtils.closeQuietly(fInputStream);
            }
        } else {
            zOut.closeArchiveEntry();
            File[] children = f.listFiles();
            if (children != null) {
                for (File child : children) {
                    addFileToZip(zOut, child.getAbsolutePath(), entryName + "/");
                }
            }
        }
    }
     
    /**
     * debug - [디버깅 로그 등록]
     *
     * @author 김종철
     * @version 1.0
     * @param msg
     * @created
     * 2014. 5. 22. 오후 3:11:27
     * @updated
     * 2014. 5. 22. 오후 3:11:27 [김종철] 최초 작성
     */
    private static void debug(String msg){
        if( debug ) {
            log.debug(msg);
        }
    }
}

하나씩 서버 관리 시스템 모듈을 만들어야겠군 ㅎ

 

JavaDoc : http://commons.apache.org/proper/commons-compress/apidocs/index.html

 

Developer.KimKun

많은 사람들이 실패하는 이유는 성공을 한발 앞에 두고 그만두었기 때문이다. – 셰익스피어 -