Chimy's Program
정보처리기사 실기 - 서버프로그램 구현 : 배치 프로그램 구현 본문
정보처리기사 실기 - 서버프로그램 구현 : 배치 프로그램 구현
배치 프로그램
- 사용자와의 상호 작용 없이 일련의 작업들을 작업 단위로 묶어 정기적 으로 반복 수행하거나 정해진 규칙에 따라 일괄 처리
ⓞ 배치 프로그램 필수 요소
(1) 대용량 데이터
- 대용량의 데이터를 처리 가능
(2) 자동화
- 심각한 오류 상황 외에는 사용자의 개입 없이 동작
(3) 견고함
- 유효하지 않은 데이터의 경우도 처리해서 비정상적인 동작 중단이 발생하지 않아야 함
(4) 안정성
- 어떤 문제가 생겼는지, 언제 발생했는지 추적
(5) 성능
- 주어진 시간 내 처리완료 필요, 동시에 동작하고 있는 다른 애플리케이션 방해금지
ⓞ 배치 스케줄러(Scheduler)
- 일괄 처리(Batch Processing)를 위해 주기적으로 발생하거나 반복적으로 발생하는 작업을 지원하는 도구
(1) 배치 스케줄러의 종류
(가) 스프링 배치(Spring Batch)
- Spring Source사와 Accenture사의 공동 작업으로 2007년에 탄생한 배치 기반 오픈소스 프레임워크
컴포넌트 | 설명 |
Job Repository | Job Execution 관련 메타 데이터를 저장하는 기반 컴포넌트 |
Job Launcher | Job Execution을 실행하는 기반 컴포넌트 |
JPA(Java Persistence API) | 페이징 기능 제공 |
Job | 배치 처리를 의미하는 애플리케이션 컴포넌트 |
Step | Job의 각 단계 의미, Job은 연속된 Step으로 구성 |
Item | Data Source로부터 읽거나 Data Source로 저장하는 각 레코드를 의미 |
Chunk | 특정 크기를 갖는 아이템 목록 의미 |
Item Reader | 데이터 소스로부터 아이템을 읽어 들이는 컴포넌트 |
Item Processor | Item Reader로 읽어 들인 아이템을 Item Writer를 사용해 저장하기 전에 처리하는 컴포넌트 |
Item Writer | Item Chunk를 데이터 소스에 저장하는 컴포넌트 |
(a) 스프링 배치의 핵심 기능
- 스프링 프레임 워크 기반 : 스프링의 DI, AOP 및 다양한 엔터프라이즈 지원 기능 사용
- 자체 제공 컴포넌트 : 배치 처리(데이터베이스나 파일로부터 데이터를 읽거나 쓰는 등) 시 공통적으로 필요한 컴포넌트 제공
- 견고함과 안정성 : 선언적 생략과 처리 실패 후 재시도 설정 제공
(나) Quartz 스케줄러(Scheduler)
- Spring Framework에 플러그인(Plug-in)되어 수행하는 Job과 실행 스케줄을 정의하는 Trigger를 분리하여 유연성을 제공하는 오픈소스 스케줄러
컴포넌트 | 설명 |
Scheduler | Quartz 실행환경을 관리하는 핵심 개체 |
Job | 사용자가 수행할 작업을 정의하는 인터페이스로서 Trigger 개체를 이용하여 스케줄 |
JobDetail | 작업명과 작업 그룹과 같은 수행할 Job에 대한 상세 정보를 정의하는 개체 |
Trigger | 정의한 Job 개체의 실행 스케줄을 정의하는 개체로서 Scheduler 개체에게 Job 수행 시점을 알려 주는 개체 |
(a) Quartz 스케줄러의 사용 예제
public class SampleJob extends QuartzJobBean{
private MyService myService;
private String name;
//Inject "MyService" bean
public void setMyService(MyService myService){ .. }
//Inject the "name" job data property
public void serName(String name) { .. }
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
...
}
}
수행
① 애플리케이션 설계를 기반으로 배치 프로그램 확인
(1) 프로그램 관리 대장을 확인
(2) 배치 설계서를 확인
- 프로그램 관리 대장의 ID와 일치하는 배치 설계 확인
② 애플리케이션 설계를 기반으로 배치 프로그램 구현
(1) 배치 프로그램을 구현하기 위한 SQL 작성
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ncs.sql">
<select id="selectRetireUsers" resultType="com.ncs.vo.UserVo">
SELETE SABUN FROM TBL_USERS
WHERE DATE_FORMAT(RETIREDATE,'%Y-%m-%d') <![CDATA[<]]> DATE_FORMAT(CURDATE(),'%Y-%m-%d')
</select>
<delete id="deleteRetireUser" parameterType="com.ncs.vo.UserVo">
DELETE FROM USERS WHERE SABUN=#{sabun}
</delete>
</mapper>
(2) 배치 프로그램을 구현하기 위한 I/O 오브젝트(DTO/VO) 정의
package com.ncs.vo;
public class UserVo {
private String sabun;
private String userid;
private String userpwd;
private String name;
private String email;
private String mobile;
private String authcd;
private String orgcd;
private String regdate;
private String retiredate;
public String getSabun(){
return sabun;
}
public void setSabun(String sabun){
this.sabun=sabun;
}
public String getUserid(){
return userid;
public void setUserid(String userid){
this.user.id=userid;
}
...
}
(3) 배치 프로그램을 구현하기 위한 데이터 접근 오브젝트(DAO)를 작성
package com.ncs.dao;
import java.util.list;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.ncs.vo.UserVo;
@Repository("userDao")
public class UserDao{
@Autowired
private SqlSession sqlSession;
//DB에서 업무 종료된 사용자 목록 조회
public List<UserVo> selectRetireUsers() throws Exception{
return sqlSession.selectList("com.ncs.sql.selectRetireUsers");
}
//DB에서 업무 종료된 사용자 삭제
public int deleteRetireUser(UserVo userVo) throws Exception{
return sqlSession.delete("com.ncs.sql.deleteRetireUser",userVo);
}
}
(4) 배치 프로그램을 구현하기 위한 스케줄러 클래스 작성
@Scheduled(cron="0 0 1 * * ?")
public void scheduleRun(){
String batchResult="성공";
try{
//1. 업무 종료된 사용자 정보를 조회한다
List<UserVo> userList=userDao.selectRetireUsers();
//2. 업무 종료가 된 사용자 정보가 존재하지 않은 경우 4번을 진행하고 존재하는 경우 3번 작업을 진행
if(userList !=null){
for(int i=0;i<userList.size();i++){
UserVo userVo=userList.get(i);
//3. 해당 사용자 정보를 삭제
userDao.deleteRetireUser(userVo);
}
}
}catch(Exception e){
batchResult="실패";
}
//4. 삭제 대상 정보에 대한 로그 정보를 생성
Calendar calendar=Calendar.getInstance();
SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Logger.info("스케줄 실행 : ["+batchResult+"] "+dateFormat.format(calendar.getTime()));
}
※ Cron 표현식(Expression)
필드명 | 허용값(범위) | 허용된 특수 문자 |
Seconds | 0~59 | , - * / |
Minutes | 0~59 | , - * / |
Hours | 0~23 | , - * / |
Day-of-month | 1~31 | , - * ? / L W |
Month | 1~12 or JAN~DEC | , - * / |
Day-Of-Week | 1~7 or SUN~SAT | , - * ? / L # |
Year(optional) | empty, 1970~2099 | , - * / |
'BASE' 카테고리의 다른 글
정보처리기사 실기 - 인터페이스 구현 : 내외부 모듈 간 공통 기능 및 데이터 인터페이스 확인 (0) | 2020.07.07 |
---|---|
정보처리기사 실기 - 서버프로그램 구현 : 배치 프로그램 테스트 (0) | 2020.07.06 |
정보처리기사 실기 - 서버프로그램 구현 : 서버 프로그램 테스트 (0) | 2020.07.05 |
정보처리기사 실기 - 서버프로그램 구현 : 서버 프로그램 구현 (0) | 2020.07.04 |
정보처리기사 실기 - 서버프로그램 구현 : 업무 프로세스 확인 (0) | 2020.07.03 |
Comments