후행 서비스 개발

본 장에서는 후행 서비스의 소개와 후행 서비스 내부 구성 요소 및 개발에 대해 설명한다.

1. 개요

후행 서비스는 해당 서비스에서 즉시 처리를 하지 않아도 되는 업무 처리거나 서비스에서 처리하지 않아도 되는 부하가 있는 작업들에 대하여 서비스 응답 후 후행 서비스로 분리하여 처리함으로 서비스의 빠른 응답과 부하 있는 작업들에 대하여 분산 작업을 제공하는 기능이다. 후행 서비스를 사용하기 위해서는 JEUS JMS 설정 및 후행 서비스 설정이 필요하다.

후행 서비스는 Publisher가 API(ServiceManager.deferred())를 통해 JMS 및 DB 테이블에 데이터를 삽입하며, Fetcher는 JMS에서 데이터들을 수집하여 서비스를 호출하게 된다.

DeferredFetcher는 JMS 큐(Queue)에 쌓인 데이터를 얻어와 서비스 별로 메모리에 적재하고 FetchSize만큼 도달하게 되면 해당 서비스가 배포되어 있는 노드에서 후행 서비스를 호출하여 처리한다. 호출되는 서비스들은 설정에 따라 하나의 트랜잭션으로(FetchSize가 100일 때 0~98까지 성공하고, 99에서 실패하는 경우 앞에 있는 서비스들에 대해 모두 롤백 처리된다.) 동작할 수도 있으며, 개발 트랜잭션으로 동작하게 할 수 있다.

figure deferred flow
후행 서비스 아키텍처

<consumer>에서 name은 다른 곳에서 활용하지 않으며 변경해도 무방하지만 <message-type>은 'DEFFERRED’로 정확히 입력해야 한다.

2. 후행 서비스 설정

본 절에서는 후행 서비스를 사용하기 위해서 하위 설정들을 필요로 하며 필수 설정으로는, queue-name 설정, 데이터 소스 설정, consumer 설정, batch 및 schedule 설정을 필요로 한다.

2.1. 기본 설정

후행 서비스 설정은 다음의 파일에 <deferred-queue-name> 설정을 해야 한다.

${PROOBJECT_HOME}/system/config/application.xml

해당 설정은 서비스에서 후행 서비스 Publish할 때와 초기 기동할 때 후행 테이블에 INIT 상태의 데이터를 처리하기 위하여 LOAD와 FLUSH_ALL의 JMS 메시지를 큐에 Publish하기 위하여 활용된다.

<deferred-service>
    <deferred-queue-name>deferredQueue</deferred-queue-name>
    <request-table>po_deferred</request-table>
    <history-table>po_deferred_history</history-table>
    <booting-initialize>true</booting-initialize>
    <deferred-service-tx-policy>SEPARATE</deferred-service-tx-policy>
</deferred-service>

다음은 설정 항목에 대한 설명이다.

항목 설명

<deferred-queue-name>

<request-table>과 <history-table>은 설정하지 않는 경우 디폴트값이 po_deferred, po_deferred_history로 동작한다. (필수 설정)

<booting-initialize>

PO를 기동할 때 발행된 후행 서비스들을 자동으로 fetch - flush를 수행할지 여부를 설정한다.

<deferred-service-tx-policy>

수행된 후행 서비스들을 호출할 때 트랜잭션을 묶을지, 개별로 처리할지 설정한다.

2.2. 데이터 소스 설정

후행 테이블에 데이터 삽입 및 접근을 위해 데이터 소스 설정이 필수적이다.

${PROOBJECT_HOME}/config/proobject.xml

해당 설정은 proobject.xml의 <engine-config> 하위에 <proObject-datasource>에 설정한다.

<proObject-datasource>에 이미 ${PROOBJECT_HOME}/system/config/dbio_config.xml에 설정한 alias 중에서 사용할 alias를 설정해야 한다.

<engine-config>
    <proObject-datasource>sc_ds</proObject-datasource>
</engine-config>

2.3. JMS 설정

DeferredMessageListener 등록 및 DeferredService를 Publish하기 위한 설정이다. JEUS에 JMS 설정(QUEUE, Connection Factory)에 대한 자세한 내용은 "JEUS MQ 안내서"를 참고한다.

Consumer의 메시지의 타입을 'DEFERRED’로 설정하면 엔진의 후행 메시지 리스너가 동작하게 된다. Consumer 설정은 JMS 방식을 활용하기 위해서는 필수 설정이다.

Consumer은 반드시 publish하는 서버에 등록할 필요는 없으며, 데이터를 처리할 서버에 설정하거나, 읽어서 나눠줄 서버에 설정한다.

${PROOBJECT_HOME}/system/config/reliablequeue.xml

JEUS의 JMS 큐를 사용하기 위하여 ConnectionFactory가 필요하며, JEUS의 설정한 큐의 <jndi-name>을 하단에 설정한다. 그 후 해당 큐에서 후행 데이터를 얻기 위한 consumer를 설정한다.

다음은 reliablequeue.xml에 DeferredMessageListener를 설정한 예이다(DeferredMessageListener는 모든 애플리케이션 중 하나의 애플리케이션에만 존재해야 한다).

<queue-config>
    <jndi-config>
        <name>ConnectionFactory</name>
        <connection-factory>ConnectionFactory</connection-factory>
        <remote-url>192.168.0.128:9736</remote-url>
    </jndi-config>
    <queue>
        <name>deferredQueue</name>
        <jndi-name>ExamplesQueue</jndi-name>
        <consumer>
            <name>DeferredMessageListener</name>
            <message-type>DEFERRED</message-type>
        </consumer>
    </queue>
</queue-config>

2.4. 센터컷 서비스 설정

다음은 후행 처리를 위한 배치 및 스케줄 설정하는 방법에 대한 설명이다.

${PROOBJECT_HOME}/config/proobject.xml

후행 처리를 배치의 센터컷 서비스(Batch 서비스 그룹)를 통해 수행하기 때문에 <batch-config> 태그가 필요하며 후행 처리를 fetchSize 도달이 아닌 주기적인(스케줄) 처리가 필요한 경우 스케줄러를 활용하고 있기 때문에 <schedule-config> 설정이 필요하다. 배치 및 스케줄 설정은 필수로 설정해야 한다.

<batch-config>
      :
</batch-config>
<schedule-config>
      :
</schedule-config>

2.5. FetchSize와 FLUSH 주기 설정(옵션)

FetchSize 설정 및 FLUSH 주기는 다음의 파일에 설정한다.

${PROOBJECT_HOME}/config/system.properties

다음은 파일의 설정 예이다. 설정을 하지 않는 경우 기본값으로 지정된다.

SYSTEM_DEFERRED_FETCH_SIZE=100 //기본값 100
SYSTEM_DEFERRED_FLUSH_SCHEDULE_EXPRESSION=0 0 * ? * * * //기본값 100, “0 0 * ? * * *”(한시간 마다)

2.6. 후행 타켓 서버 설정(옵션)

후행 서비스들을 다른 ProObject 서버에 분산 처리가 필요한 경우 다음의 파일에 설정한다.

${PROOBJECT_HOME}/config/remote.address.properties

다음은 해당 파일에 설정 예이다.

proobject.batch.JobServiceCCTargetSample.address=192.168.0.120:6778,192.168.0.120:6778

{ApplicationName}.{ServiceGroupName}.{ServiceName}.address, {ApplicationName}.{ServiceGroupName}.address, {ApplicationName}.address 키로 하며 콤마(,)를 구분자로 사용한다.

후행 서비스를 실행하는 경우 설정에 해당하지 않는 서비스는 로컬로 호출하며 설정에 해당하는 서비스는 설정된 노드를 Round-Robin으로 호출한다.

2.7. 아이디 기반 후행 서비스 설정(옵션)

후행 서비스 실행에 대한 메타정보를 사전에 등록하고, 등록된 후행 서비스들에 대해서만 동작을 보장하는 기능이다.

해당 기능을 사용하려면 다음의 파일에 아이디 기반 후행 서비스의 적용 여부 추가 옵션들을 설정한다.

${PROOBJECT_HOME}/system/config/application.xml

다음은 설정 예이다.

<deferred-service>
    ...
    <enable-deferredId>true</enable-deferredId>
    <deferred-date-format>YYYY-MM-DD</deferred-date-format>
    <input-time-format>yyyyMMddHHmmss</input-time-format>
</deferred-service>
항목 설명

<enable-deferredId>

아이디 기반 후행 서비스를 사용할 때 필수적으로 설정해야 한다.

<deferred-date-format>

아이디 기반 후행 서비스 사용시 입력하는 후행 작업 일자의 날짜 포맷을 지정한다.

<input-time-format>

후행 서비스의 테이블에서 전반적으로 사용되는 INPUT_TIME과 MODIFY_TIME의 포맷을 지정한다.

3. 아이디 기반 후행 서비스

아이디 기반 후행 서비스는 기존 ServiceManager.deferred()를 통해 후행 서비스를 무조건 발행하던 동작에서 발행할 후행 서비스의 정보를 미리 등록해놓고 등록된 후행 서비스에 대해서만 발행, 실행, 관리를 하는 기능이다.

기존 후행 서비스 기능에서는 ServiceManager.deferred API를 이용해서 후행 서비스를 발행할 때 호출할 ProObject 서비스 이름을 직접 입력했지만, 아이디 기반 후행 서비스에서는 후행 아이디를 입력한다. 후행 서비스를 발행하면 우선 PO_DEFERRED_MAIN 테이블에 등록된 후행 서비스인지 검사하는 로직을 수행한다. 후행 아이디가 등록되어 있다면 PO_DEFERRED 테이블에 후행 서비스가 발행되며, 후행 작업일자도 일치하면 런타임에도 후행 서비스를 발행한다.

런타임에 발행된 후행 서비스는 PO_DEFERRED_MAIN 테이블에 지정된 CHUNK_SIZE만큼 쌓이게 되면 FLUSH 과정을 거쳐서 SVC_NAME에 지정된 PO 서비스를 호출한다. 런타임에 발행되지 않고, DB에만 발행된 후행 서비스들은 사용자가 별도의 커맨드를 호출하여 실행시킬 수 있다. PO_DEFERRED_MAIN 테이블에 발행할 후행 서비스를 미리 정의한다.

다음은 컬럼에 대한 설명이다.

컬럼 설명

DEF_ID

후행 서비스의 발행 / 실행의 기준이 되는 후행 아이디 값이다.

DEF_DATE

후행 서비스의 발행 / 실행의 기준이 되는 후행 작업일자 값이다.

SVC_NAME

후행 아이디로 발행된 후행 서비스가 실제로 호출할 ProObject 서비스 이름이다.

STATUS

후행 서비스의 발행 / 실행 여부를 결정하는 플래그이다.

  • 0 : 발행 및 실행 가능

  • 1 : 발행 중지 및 실행 불가능

STATUS를 '1’로 지정하여도 PO 런타임에 발행이 되지 않는 것이지 PO_DEFERRED 테이블에는 발행되고, DB에 발행된 데이터는 추후 FETCH, FLUSH 명령어를 통해 실행시킬수 있다.

CON_NUM

발행된 후행 서비스를 호출할때 후행 아이디로 발행된 후행 서비스를 동시에 실행시킬수 있는 횟수이다.

CHUNK_SIZE

후행 서비스를 호출할때 한번에 몇건의 후행 서비스를 호출할지 개수이다.

PRE_POST_PROCESS

후행 서비스 호출시 한건의 후행 서비스에서 처리할 선후처리 동작이 정의된 후행 선/후처리 모듈 클래명이다. 입력하지 않을 경우 'com.tmax.proobject.def.DeferredServicePrePostHandlerImple’을 적용한다.

'PRE_POST_PROCESS’에는 발행된 후행 서비스를 호출하기 전 지정한 PO 서비스의 input output을 처리하며 에러가 발생하는 경우 에러 처리를 하는 인터페이스 구현체를 지정한다.

다음은 com.tmax.proobject.def.DeferredServicePrePostHandler 인터페이스에 대한 설명이다.

/*
 * Copyright (c) 2016 by TmaxSoft co., Ltd.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information
 * of TmaxSoft co., Ltd("Confidential Information").  You
 * shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement
 * you entered into with TmaxSoft co., Ltd.
 */

package com.tmax.proobject.def;

import com.tmax.proobject.model.dataobject.DataObject;
import com.tmax.proobject.model.network.RequestContext;

public interface DeferredServicePrePostHandler {
    /**
     * @since 2020. 9. 18.
     * @param serviceName    호출될 서비스 이름
     * @param requestContext 호출에 활용하는 requestContext
     * @param inputString    호출에 활용되는 inputString
     * @return               호출에 활용되는 input
     */
    public DataObject preProcess(String serviceName, RequestContext requestContext, String inputString,
            String headerString) throws Throwable;

    /**
     * @since 2020. 9. 18.
     * @param serviceName   호출된 서비스 이름
     * @param input         호출된 input
     * @param output        호출의 output
     * @return output 남기고자 하는 outputString
     */
    public String postProcess(String serviceName, DataObject input, DataObject output) throws Throwable;

    /**
     * @since 2020. 9. 18.
     * @param serviceName    호출된 서비스 이름
     * @param input          호출된 input
     * @param exception      호출의 exception
     * @return 남기고자 하는 exceptionString
     */
    public String postProcessOnError(String serviceName, DataObject input,
            Throwable exception);
}

사용자는 com.tmax.proobject.def.DeferredServicePrePostHandler 인터페이스를 상속받은 구현체를 지정해놓으면 PO 런타임에서는 서비스를 호출하기 전 preProcess API를 호출하고 그 결과값을 서비스 호출의 input으로 설정한다. 서비스 호출 응답이 돌아오면 postProcess API를 호출하고 그 결과값을 PO_DEFERRED_HISTORY 테이블에 기록한다. 서비스 호출 결과 에러가 발생하면 postProcessOnError API를 호출하고 그 결과를 PO_DEFERRED_HISTORY에 남긴다.

3.1. 후행 서비스의 재시도

발행한 후행 서비스의 응답이 에러가 발생했거나 기타 다른 이유로 실행에 실패한 경우, 해당 후행 서비스는 실패 처리가된다. 이때 후행 서비스가 발행되는 PO_DEFERRED 테이블의 RETRY_CNT 값이 1씩 증가하게 된다. RETRY_CNT 값이 RETRY_LIMIT과 동일하거나 더 큰 경우 발행된 후행 서비스는 최종 실패 처리가되며 PO_DEFERRED 테이블에서 삭제된다. 하지만 재시도 횟수에 여유가 있다면 발행된 후행 서비스는 PO_DEFERRED 테이블에서 삭제되지 않으며, 언제든 사용자의 FETCH, FLUSH 명령을 통해 재수행 될수 있다.

3.2. Chunk 단위 발행된 후행 서비스의 실행 이력

후행 서비스는 발행하는 건마다 바로 호출되지 않고 지정된 size만큼 chunk를 만들어 실행하게 된다.

기존 후행 서비스에서는 chunk 단위의 이력이 남지 않고 개별 이력만 PO_DEFERRED_HISTORY에 남았으나, 아이디 기반 후행 서비스에서는 PO_DEFERRED_SVCM 테이블을 통해 chunk 단위의 이력도 관리할 수 있다.

해당 테이블에는 호출된 chunk의 총 크기와 정상 수행 건수, 에러 발생 건수를 기록하며 각 chunk 단위별 svcm id를 생성해서 PO_DEFERRED_HISTORY에 기록된 개별 후행 서비스 건수가 어느 chunk에서 수행된 것인지 파악할 수 있다.

3.3. 후행 서비스의 일시중지와 재시작

사용자는 커맨드를 통해 후행 아이디 별로 후행 서비스의 발행 및 실행 중지와 중지된 후행 서비스를 재시작하는 제어를 할 수 있다. 커맨드를 통해 발행이 중지된 후행 서비스는 런타임으로 발행은 안되지만, 후행 아이디만 등록되어있다면 PO_DEFERRED 테이블에 발행된다. 또한 기존에 발행된 후행 서비스라도 FETCH, FLUSH 명령어를 수행하는 경우 발행 중지가 되어 있는 상태라면 해당 동작을 수행하지 않는다.

발행 중지 상태였던 후행 서비스가 재시작 상태로 변경되면 이후 발행되는 후행 서비스들에 대해서는 다시 발행 및 호출을 수행한다.

3.4. 후행 서비스 재처리

후행 서비스 호출이 실패한 경우 혹은 발행 된 후행 서비스의 정보를 수정해야하는 경우 'proobject.schedule.DeferredUpdateService' 서비스를 통해 재처리 또는 수정을 진행할 수 있다.

다음은 해당 서비스의 입력값인 DO의 필드명과 설명이다.

KEY 설명

inputData

발행한 후행 서비스의 입력값을 변경한다. JSON String 형태로 입력한다.

headerData

발행한 후행 서비스의 헤더값을 변경한다. JSON String 형태로 입력한다.

guid

재처리할 후행 서비스의 PO_DEFERRED에 기록된 GUID 값을 입력한다.

euid

재처리할 후행 서비스의 PO_DEFERRED에 기록된 EUID 값을 입력한다.

seq

재처리할 후행 서비스의 PO_DEFERRED에 기록된 SEQ 값을 입력한다.

defDate

재처리할 후행 서비스의 PO_DEFERRED에 기록된 DEF_DATE 값을 입력한다.

svc

재처리할 후행 서비스의 PO_DEFERRED에 기록된 SVC 값을 입력한다.

retryLimit

발행한 후행 서비스의 재처리 가능 횟수를 변경한다.

enableFlush

수정한 후행 서비스를 바로 호출할지 결정한다. (기본값 : true)

해당 서비스가 호출되면 기본적으로는 변경된 후행 서비스에 대해서 FETCH, FLUSH 명령어를 수행한다.

3.5. 발행된 후행 서비스 삭제

발행된 후행 서비스의 경우 커맨드를 통해 삭제할 수 있다. 커맨드의 입력값으로 삭제할 후행 서비스의 guid, euid, seq와 후행 아이디, 작업일자를 파라미터로 입력하면 해당 후행 서비스는 PO_DEFERRED에서 삭제되며 런타임에서도 제거되어 FETCH, FLUSH 대상에서 제외된다.

4. 후행 서비스 명령어

후행 서비스는 'proobject.schedule.DeferredCmdService’를 통해서 특정 명령어를 입력받고 해당 동작을 수행한다.

public enum DeferredMsgType{
    BOOTING_SEQUENCE, PUBLISH, FETCH_N_FLUSH, FETCH, FETCH_MAIN,
    FLUSH, FLUSH_ALL, SCHEDULE_REGIST, SCHEDULE_UNREGIST, SUSPEND,
    RESUME, DELETE, REFRESH
  }

명령어의 종류는 다음과 같다.

명령어 설명

PUBLISH

ServiceManager의 deferred API를 통해 후행 서비스 발행이 요청되었다.

FETCH_N_FLUSH

후행 테이블을 fetch한후 DeferredListener에게 flush하도록 요청한다.

FETCH

후행 테이블을 fetch한다. command value에 특정 후행 아이디 또는 후행 작업일자를 입력한 경우, 해당 데이터만 fetch한다.

FETCH_MAIN

PO_DEFERRED_MAIN 테이블의 내용을 반영한다.

FLUSH

DeferredListener가 fetch한 서비스 내역을 flush한다. command value에 입력된 후행 아이디 또는 후행 작업일자에 대한 데이터만 flush한다.

FLUSH_ALL

DeferredListener가 fetch한 모든 서비스 내역을 flush한다.

SCHEDULE_REGIST

flush 주기를 PO Schedule에 등록한다.

SCHEDULE_UNREGIST

PO Schedule에 등록된 flush 주기를 제거한다.

SUSPEND

후행 서비스 발행을 일시 중지합니다. 명령어가 호출된 이후 발행되는 후행 서비스는 PO_DEFERRED 테이블에 데이터는 쌓지만 fetch되지 않는다.

RESUME

일시중지된 후행 서비스의 발행을 재개한다.

DELETE

발행된 후행 서비스를 제거한다.

REFRESH

PO에 fetch된 후행 서비스를 모두 제거 한다. 메모리에서만 제거하며 PO_DEFERRED에는 그대로 유지한다.

'PUBLISH’와 'BOOTING_SEQUENCE’에 대해서는 런타임 엔진에서 사용하는 명령어들로써, 사용자의 직접적인 사용을 금하고 있다.

'proobject.schedule.DeferredCmdService’는 'com.tmax.proobject.engine.service.deferred.service.dto.DeferredCmdDataObject' 와 'com.tmax.proobject.engine.service.deferred.service.dto.DeferredCmdValueDataObject’를 입력값으로 받는다.

com.tmax.proobject.engine.service.deferred.service.dto.DeferredCmdDataObject는 명령어 종류와 com.tmax.proobject.engine.service.deferred.service.dto.DeferredCmdValueDataObject를 변수로 갖고 있다. com.tmax.proobject.engine.service.deferred.service.dto.DeferredCmdValueDataObject는 명령어의 대상이 되는 후행 서비스의 정보와 FLUSH 주기를 변수로 갖는다.

사용자는 이 서비스를 이용해서 후행 서비스의 FETCH, FLUSH, SUSPEND, RESUME 등의 기본적인 동작 제어와 더불어서 발행된 후행 서비스 제거 및 런타임 발행 취소 등을 수행할 수 있다. 또한 system.properties에서 지정한 flush 주기 외에 추가적인 flush 주기를 지정하거나 삭제할 수도 있다.

5. 후행 서비스 관련 테이블

ProObject의 후행 서비스에 관련된 정보를 테이블에 저장한다.

  • 후행 서비스 테이블

    테이블 설명

    PO_DEFFERED

    후행 서비스를 발행하게 되면, 발행한 후행 서비스를 저장한다.

    PO_DEFERRED_HISTORY

    발행한 후행 서비스가 런타임에 실행되면 실행 기록을 저장한다.

  • 아이디 기반 후행 서비스

    테이블 설명

    PO_DEFERRED_MAIN

    아이디 기반 후행 서비스 기능을 사용할때 후행 서비스의 아이디와 작업일자 등 후행 서비스 정보를 설정한다.

    PO_DEFERRED

    일반 후행 서비스 기능과 다른점은 SVC 컬럼에 후행 서비스가 호출할 서비스 이름이 아닌, PO_DEFERRED_MAIN에 설정한 후행 아이디가 저장된다.

    PO_DEFERRED_SVCM

    후행 아이디에 설정된 chunk 사이즈만큼 후행 서비스가 발행되면, 런타임은 후행 서비스를 chunk 단위로 실행하는데 이 chunk 단위의 실행 이력을 기록한다.

    PO_DEFERRED_HISTORY

    발행된 후행 서비스의 이력을 저장한다.

5.1. 후행 서비스 테이블

  • PO_DEFFERED

    후행 서비스를 발행하게 되면, 발행한 후행 서비스를 저장하는 테이블이다.

    발행 후행 서비스 구분을 위해 GUID, EUID를 부여하며, SEQ는 후행 서비스를 발행한 ProObject 서버 공통으로 채번한다. 후행 서비스를 발행하고 나면 'INIT' 상태로 기록되며, 'INIT’상태의 후행 서비스만이 실행 대상이 된다. 발행한 후행 서비스를 실행할때 에러가 발생하면 ProObject는 해당 후행 서비스를 재호출하게되는데 이때 호출된 횟수는 RETRY_CNT에 기록한다.

    컬럼 설명

    GUID

    후행 서비스를 발행한 서비스의 GUID이다.

    EUID

    후행 서비스를 발행할때 발생한 이벤트의 EUID이다.

    SEQ

    후행 서비스가 발행된 순서이다.

    SVC

    후행 서비스가 호출할 프로오브젝트 서비스 이름(애플리케이션.서비스그룹.서비스)이다.

    STATUS

    발행된 후행 서비스가 실행 가능한 상태인지 여부이다.

    • INIT : 후행 서비스가 발행되었고 실행 가능한 상태이다.

    • COMPLETED : 발행된 후행 서비스가 실행 완료했고, 곧 삭제되어 PO_DEFERRED_HISTORY로 옮겨진다.

    TYPE

    후행 서비스가 호출할 서비스의 종류로 현재는 ProObject 서비스만이 후행 서비스의 호출 대상이된다. (기본값 : POJ)

    RETRY_CNT

    등록한 후행 서비스가 실행되고 에러가 발생했을때 재시도한 횟수이다.

    INPUT_TIME

    후행서비스가 발행된 일자이다.

    MODIFY_TIME

    발행된 후행 서비스의 정보가 변경된 일자이다.

    DATA_1 ~5

    SVC에서 지정한 후행서비스를 호출할때 사용할 서비스 입력 데이터로 JSON 형식으로 입력한다.

    HEADER_DATA

    SVC에서 지정한 후행서비스를 호출할때 사용할 서비스 헤더 데이터로 JSON 형식으로 입력한다.

  • PO_DEFERRED_HISTORY

    발행한 후행 서비스가 런타임에 실행되면 실행 기록을 남기는 테이블이다. 후행 서비스를 통해 호출한 서비스가 성공했다면 OUTPUT_DATA에 기록되고, 실패했다면 ERR_MSG에 기록된다.

    컬럼 설명

    GUID

    실행한 후행 서비스의 GUID이다.

    EUID

    실행한 후행 서비스의 EUID이다.

    SEQ

    실행한 후행 서비스의 순서이다.

    RETRY_CNT

    실행한 후행 서비스의 현재 재시도 횟수이다.

    SVC

    실행한 후행 서비스가 호출한 ProObject 서비스 이름이다.

    STATUS

    실행한 후행 서비스의 성공 실패 여부이다.

    • COMPLETED : 성공

    • FAILED : 실패

    TYPE

    실행한 후행 서비스의 종류이다.

    OUTPUT_DATA

    후행 서비스가 호출한 ProObject 서비스의 수행 결과 응답값이다.

    ERR_MSG

    후행 서비스가 호출한 ProObject 서비스 응답값에 예외(Exception)가 발생한 경우 해당 예외 상황에 대한 메시지이다.

    INPUT_TIME

    후행 서비스 이력이 기록된 일자이다.

    SEVER_NAME

    발행된 후행 서비스가 수행된 ProObject 서버 이름이다(proobject.xml에 기재된 서버 이름).

5.2. 아이디 기반 후행 서비스 테이블

  • PO_DEFERRED_MAIN

    아이디 기반 후행 서비스 기능을 사용할때 후행 서비스의 아이디와 작업일자 등 후행 서비스 정보를 설정하는 테이블이다.

    컬럼 설명

    DEF_ID

    후행 서비스의 발행 / 실행의 기준이 되는 후행 아이디 값이다.

    DEF_DATE

    후행 서비스의 발행 / 실행의 기준이 되는 후행 작업일자 값이다.

    SVC_NAME

    후행 아이디로 발행된 후행 서비스가 실제로 호출할 ProObject 서비스 이름이다.

    STATUS

    후행 서비스의 발행 / 실행 여부를 결정하는 플래그이다.

    • 0 : 발행 및 실행 가능

    • 1 : 발행 중지 및 실행 불가능

    STATUS를 '1’로 지정하여도 PO 런타임에 발행이 되지 않는 것이지 PO_DEFERRED 테이블에는 발행되고, DB에 발행된 데이터는 추후 FETCH, FLUSH 명령어를 통해 실행시킬수 있다.

    CON_NUM

    발행된 후행 서비스를 호출할때 후행 아이디로 발행된 후행 서비스를 동시에 실행시킬수 있는 횟수이다.

    CHUNK_SIZE

    후행 서비스를 호출할때 한번에 몇건의 후행 서비스를 호출할지 개수이다.

    PRE_POST_PROCESS

    후행 서비스 호출시 한건의 후행 서비스에서 처리할 선후처리 동작이 정의된 후행 선/후처리 모듈 클래명이다. 입력하지 않을 경우 'com.tmax.proobject.def.DeferredServicePrePostHandlerImple’을 적용한다.

    'PRE_POST_PROCESS’에는 발행된 후행 서비스를 호출하기 전 지정한 PO 서비스의 input output을 처리하며 에러가 발생하는 경우 에러 처리를 하는 인터페이스 구현체를 지정한다.

  • PO_DEFERRED

    일반 후행 서비스 기능과 다른점은 SVC 컬럼에 후행 서비스가 호출할 서비스 이름이 아닌, PO_DEFERRED_MAIN에 설정한 후행 아이디가 들어간다. 또한 후행 서비스 재처리 횟수에 제한을 둘수 있는 컬럼과 후행 서비스를 발행한 서비스를 기록할 수 있는 컬럼이 추가된다.

    컬럼 설명

    GUID

    후행 서비스를 발행한 서비스의 GUID이다.

    EUID

    후행 서비스를 발행할때 발생한 이벤트의 EUID이다.

    SEQ

    후행 서비스가 발행된 순서이다.

    SVC

    후행 서비스 아이디이다.

    STATUS

    발행된 후행 서비스가 실행 가능한 상태인지 여부이다.

    • INIT : 후행 서비스가 발행되었고 실행 가능한 상태이다.

    • COMPLETED : 발행된 후행 서비스가 실행완료 했고, 곧 삭제되어 PO_DEFERRED_HISTORY로 옮겨진다.

    TYPE

    후행 서비스가 호출할 서비스의 종류로 현재는 ProObject 서비스만이 후행 서비스의 호출 대상이된다. (기본값 : POJ)

    RETRY_CNT

    등록한 후행 서비스가 실행되고 에러가 발생했을 때 재시도한 횟수이다.

    RETRY_LIMIT

    등록한 후행 서비스가 실행되고 에러가 발생했을 때 재시도할 수 있는 최대 횟수이다.

    INPUT_TIME

    후행서비스가 발행된 일자이다.

    MODIFY_TIME

    발행된 후행 서비스의 정보가 변경된 일자이다.

    CALLER_SVC

    후행 서비스를 발행한 ProObject 서비스 명이다.

    DATA_1 ~5

    SVC에서 지정한 후행서비스를 호출할 때 사용할 서비스 입력 데이터로 JSON 형식으로 입력한다.

    HEADER_DATA

    SVC에서 지정한 후행서비스를 호출할 때 사용할 서비스 헤더 데이터로 JSON 형식으로 입력한다.

  • PO_DEFERRED_SVCM

    후행 아이디에 설정된 chunk 사이즈만큼 후행 서비스가 발행되면, 런타임은 후행 서비스를 chunk 단위로 실행하게된다. 이 chunk 단위의 실행 이력을 기록하는 테이블이다. 테이블에는 실행된 후행 서비스의 총 갯수와 그 중 성공한 후행 서비스, 실패한 후행 서비스 갯수를 기록한다. 또한 실행된 chunk에서 가장 작은 시퀀스와 가장 큰 시퀀스를 표기하며, 후행 서비스가 실행중일때는 현재 실행 중인 후행 서비스의 시퀀스도 표기한다.

    컬럼 설명

    DEF_ID

    현재 실행중인 후행 서비스의 아이디이다.

    DEF_SVCM_ID

    후행 서비스가 지정된 chunk 크기가 되어 실행될 때, 해당 후행 서비스의 묶음을 구분하기 위한 집계 아이디이다.

    DEF_DATE

    현재 실행중인 후행 서비스의 작업일자이다.

    START_TIME

    후행 서비스의 집계가 시작된 일자이다.

    END_TIME

    후행 서비스의 집계가 종료된 일자이다.

    TOT_CNT

    총 실행된 후행 서비스의 갯수이다.

    NML_CNT

    성공한 후행 서비스의 갯수이다.

    ERR_CNT

    실패한 후행 서비스의 갯수이다.

    START_SEQ

    실행한 후행 서비스중 제일 작은 시퀀스 값이다.

    CURRENT_SEQ

    현재 실행 중인 후행 서비스의 시퀀스 값이다.

    END_SEQ

    실행 후행 서비스중 제일 큰 시퀀스이다.

    SERVER_NAME

    발행된 후행 서비스가 수행된 ProObject 서버 이름이다(proobject.xml에 기재된 서버 이름).

  • PO_DEFERRED_HISTORY

    발행된 후행 서비스의 이력을 남기는 테이블이다. 수행이 완료된 후행 서비스가 어떤 후행 아이디와 후행 작업일자로 설정되었는지, 어떤 정보를 가지고 실행되었는지를 추가로 기록한다.

    컬럼 설명

    GUID

    실행한 후행 서비스의 GUID이다.

    EUID

    실행한 후행 서비스의 EUID이다.

    SEQ

    실행한 후행 서비스의 순서이다.

    RETRY_CNT

    실행한 후행 서비스의 현재 재시도 횟수이다.

    DEF_ID

    실행한 후행 서비스의 아이디이다.

    DEF_DATE

    실행한 후행 서비스의 작업일자이다.

    SVC

    실행한 후행 서비스가 호출한 ProObject 서비스 이름이다.

    STATUS

    실행한 후행 서비스의 성공 실패 여부이다.

    • COMPLETED : 성공

    • FAILED : 실패

    TYPE

    실행한 후행 서비스의 종류이다.

    OUTPUT_DATA

    후행 서비스가 호출한 ProObject 서비스의 수행 결과 응답값이다.

    ERR_MSG

    후행 서비스가 호출한 ProObject 서비스 응답값에 예외(Exception)가 존재하는 경우 해당 예외상황에 대한 메시지이다.

    INPUT_TIME

    후행 서비스 이력이 기록된 일자이다.

    SEVER_NAME

    발행된 후행 서비스가 수행된 ProObject 서버 이름이다(proobject.xml에 기재된 서버 이름).

    CALLER_SVC

    후행 서비스를 발행한 ProObject 서비스 이름이다.

    DEF_SVCM_ID

    실행된 후행 서비스가 속한 집계 아이디이다.

    INPUT_DATA

    후행 서비스가 ProObject 서비스를 호출할 때 사용한 서비스 입력값이다( JSON 형식 데이터로 기록).

    HEADER_DATA

    후행 서비스가 ProObject 서비스를 호출할 때 사용한 서비스 헤더 값이다(JSON 형식 데이터로 기록).

    START_TIME

    후행 서비스가 수행 시작한 일자이다.

    END_TIME

    후행 서비스가 수행 종료한 일자이다.

5.3. 테이블 생성 스크립트

다음은 후행 서비스 테이블 생성하는 스크립트이다.

CREATE TABLE PO_DEFERRED
(
    GUID           VARCHAR2(50)      NOT NULL,
    EUID           VARCHAR2(50)      NULL,
    SEQ            VARCHAR2(50)      NULL,
    SVC            VARCHAR2(50)      NULL,
    STATUS         VARCHAR2(50)      NULL,
    TYPE           VARCHAR2(50)      NULL,
    RETRY_CNT      NUMBER            NULL,
    INPUT_TIME     VARCHAR2(14)      NULL,
    MODIFY_TIME    VARCHAR2(14)      NULL,
    DATA_1         VARCHAR2(4000)    NULL,
    DATA_2         VARCHAR2(4000)    NULL,
    DATA_3         VARCHAR2(4000)    NULL,
    DATA_4         VARCHAR2(4000)    NULL,
    DATA_5         VARCHAR2(4000)    NULL,
    HEADER_DATA    VARCHAR2(4000)    NULL,값
    CONSTRAINT PO_DEFERRED_PK PRIMARY KEY (GUID, EUID, SEQ)
);
COMMENT ON COLUMN PO_DEFERRED.SVC IS '서비스';
COMMENT ON COLUMN PO_DEFERRED.STATUS IS '상태 INIT, COMPLETED';
COMMENT ON COLUMN PO_DEFERRED.TYPE IS 'JAVA, C++, 등';
COMMENT ON COLUMN PO_DEFERRED.RETRY_CNT IS '재처리 카운트';
COMMENT ON COLUMN PO_DEFERRED.INPUT_TIME IS '입력 시간';
COMMENT ON COLUMN PO_DEFERRED.MODIFY_TIME IS '수정 시간';
COMMENT ON COLUMN PO_DEFERRED.DATA_1 IS '데이터 첫 번째';
COMMENT ON COLUMN PO_DEFERRED.DATA_2 IS '데이터 두 번째';
COMMENT ON COLUMN PO_DEFERRED.DATA_3 IS '데이터 세 번째';
COMMENT ON COLUMN PO_DEFERRED.DATA_4 IS '데이터 네 번째';
COMMENT ON COLUMN PO_DEFERRED.DATA_5 IS '데이터 다섯 번째';
CREATE INDEX PO_DEFERRED_status_Index ON PO_DEFERRED (
    STATUS ASC
);

CREATE TABLE PO_DEFERRED_HISTORY
(
    GUID           VARCHAR2(50)      NOT NULL,
    EUID           VARCHAR2(50)      NULL,
    SEQ            VARCHAR2(50)      NULL,
    RETRY_CNT      NUMBER            NULL,
    SVC            VARCHAR2(50)      NULL,
    STATUS         VARCHAR2(50)      NULL,
    TYPE           VARCHAR2(50)      NULL,
    OUTPUT_DATA    VARCHAR2(5000)    NULL,
    ERR_MSG        VARCHAR2(5000)    NULL,
    INPUT_TIME     VARCHAR2(14)      NULL,
    SERVER_NAME         VARCHAR2(50)      NULL,
    CONSTRAINT PO_DEFERRED_HISTORY_PK PRIMARY KEY (GUID, EUID, SEQ, RETRY_CNT)
);
COMMENT ON COLUMN PO_DEFERRED_HISTORY.RETRY_CNT IS '재처리 카운트';
COMMENT ON COLUMN PO_DEFERRED_HISTORY.SVC IS '서비스';
COMMENT ON COLUMN PO_DEFERRED_HISTORY.STATUS IS '상태 FAILED, COMPLETED';
COMMENT ON COLUMN PO_DEFERRED_HISTORY.TYPE IS 'JAVA, C++, 등';
COMMENT ON COLUMN PO_DEFERRED_HISTORY.OUTPUT_DATA IS '아웃풋 데이터';
COMMENT ON COLUMN PO_DEFERRED_HISTORY.err_msg IS '에러 메시지';
COMMENT ON COLUMN PO_DEFERRED_HISTORY.INPUT_TIME IS '입력 시간';
COMMENT ON COLUMN PO_DEFERRED_HISTORY.SERVER_NAME IS '서버 이름';

CCREATE TABLE PO_DEFERRED_MAIN(
    DEF_ID      VARCHAR2(255) NOT NULL,
    DEF_DATE    VARCHAR2(20) NOT NULL,
    SVC_NAME    VARCHAR2(255) NOT NULL,
    STATUS      NUMBER(3) DEFAULT 0,
    CON_NUM     NUMBER(5) DEFAULT 1,
    CHUNK_SIZE  NUMBER(10) DEFAULT 10,
    PRE_POST_PROCESS VARCHAR2(255) NULL,
    CONSTRAINT PO_DEFERRED_MAIN_PK PRIMARY KEY (DEF_ID)
);
COMMENT ON column PO_DEFERRED_MAIN.DEF_ID IS '후행 ID';
COMMENT ON column PO_DEFERRED_MAIN.DEF_DATE IS '후행 작업일자';
COMMENT ON column PO_DEFERRED_MAIN.SVC_NAME IS '후행 서비스 이름';
COMMENT ON column PO_DEFERRED_MAIN.STATUS IS '후행 작업 상태 0 : 실행가능 1 : 중지상태';
COMMENT ON column PO_DEFERRED_MAIN.CON_NUM IS '후행 병렬 처리 수';
COMMENT ON column PO_DEFERRED_MAIN.CHUNK_SIZE IS '1회 처리 데이터 건수';
COMMENT ON column PO_DEFERRED_MAIN.PRE_POST_PROCESS IS '선/후처리 핸들러의 클래스 이름';

CREATE TABLE PO_DEFERRED
(
    GUID           VARCHAR2(50)      NOT NULL,
    EUID           VARCHAR2(50)      NULL,
    SEQ            VARCHAR2(50)      NULL,
    DEF_DATE       VARCHAR2(20)      NOT NULL,
    SVC            VARCHAR2(50)      NULL, --설정이 있을때는 후행 아이디로 활용
    STATUS         VARCHAR2(50)      NULL,
    TYPE           VARCHAR2(50)      NULL,
    RETRY_CNT      NUMBER            NULL,
    RETRY_LIMIT    NUMBER            NULL,
    INPUT_TIME     VARCHAR2(14)      NULL,
    MODIFY_TIME    VARCHAR2(14)      NULL,
    CALLER_SVC     VARCHAR2(50)      NULL,
    DATA_1         VARCHAR2(4000)    NULL,
    DATA_2         VARCHAR2(4000)    NULL,
    DATA_3         VARCHAR2(4000)    NULL,
    DATA_4         VARCHAR2(4000)    NULL,
    DATA_5         VARCHAR2(4000)    NULL,
    HEADER_DATA    VARCHAR2(4000)    NULL,
    CONSTRAINT PO_DEFERRED_PK PRIMARY KEY (GUID, EUID, SEQ)
);
COMMENT ON COLUMN PO_DEFERRED.DEF_DATE IS '후행 작업일자';
COMMENT ON COLUMN PO_DEFERRED.SVC IS '서비스';
COMMENT ON COLUMN PO_DEFERRED.STATUS IS '상태 INIT, COMPLETED';
COMMENT ON COLUMN PO_DEFERRED.TYPE IS 'JAVA, C++, 등';
COMMENT ON COLUMN PO_DEFERRED.RETRY_CNT IS '재처리 카운트';
COMMENT ON COLUMN PO_DEFERRED.RETRY_LIMIT IS '재처리 가능 최대 횟수';
COMMENT ON COLUMN PO_DEFERRED.INPUT_TIME IS '입력 시간';
COMMENT ON COLUMN PO_DEFERRED.MODIFY_TIME IS '수정 시간';
COMMENT ON COLUMN PO_DEFERRED.CALLER_SVC IS '후행 서비스를 발행한 서비스 이름';
COMMENT ON COLUMN PO_DEFERRED.DATA_1 IS '데이터 첫 번째';
COMMENT ON COLUMN PO_DEFERRED.DATA_2 IS '데이터 두 번째';
COMMENT ON COLUMN PO_DEFERRED.DATA_3 IS '데이터 세 번째';
COMMENT ON COLUMN PO_DEFERRED.DATA_4 IS '데이터 네 번째';
COMMENT ON COLUMN PO_DEFERRED.DATA_5 IS '데이터 다섯 번째';
COMMENT ON COLUMN PO_DEFERRED.HEADER_DATA IS '헤더 데이터';

CREATE INDEX PO_DEFERRED_status_Index ON PO_DEFERRED (
    STATUS ASC
);

CREATE TABLE PO_DEFERRED_SVCM(
    DEF_ID      VARCHAR2(255) NOT NULL,
    DEF_SVCM_ID VARCHAR2(255) NOT NULL,
    DEF_DATE    VARCHAR2(20) NOT NULL,
    START_TIME  TIMESTAMP    DEFAULT SYSDATE,
    END_TIME    TIMESTAMP    DEFAULT SYSDATE,
    TOT_CNT     NUMBER(10) DEFAULT 0,
    NML_CNT     NUMBER(10) DEFAULT 0,
    ERR_CNT     NUMBER(10) DEFAULT 0,
    START_SEQ   NUMBER DEFAULT 0,
    CURRENT_SEQ NUMBER DEFAULT 0,
    END_SEQ     NUMBER DEFAULT 0,
    SERVER_NAME  VARCHAR(255) NULL,
    CONSTRAINT PO_DEFERRED_SVCM_PK PRIMARY KEY (DEF_ID, DEF_SVCM_ID)
);
COMMENT ON column PO_DEFERRED_SVCM.DEF_ID IS '후행 ID';
COMMENT ON column PO_DEFERRED_SVCM.DEF_SVCM_ID IS '후행 집계 ID';
COMMENT ON column PO_DEFERRED_SVCM.DEF_DATE IS '후행 작업일자';
COMMENT ON column PO_DEFERRED_SVCM.START_TIME IS '후행 작업 시작 시간';
COMMENT ON column PO_DEFERRED_SVCM.END_TIME IS '후행 작업 종료 시간';
COMMENT ON column PO_DEFERRED_SVCM.TOT_CNT IS '후행 작업 총 건수';
COMMENT ON column PO_DEFERRED_SVCM.NML_CNT IS '후행 작업 성공 건수';
COMMENT ON column PO_DEFERRED_SVCM.ERR_CNT S '후행 병렬 실패 건수';
COMMENT ON column PO_DEFERRED_SVCM.START_SEQ IS '후행 작업 중 가장 작은 seq';
COMMENT ON column PO_DEFERRED_SVCM.CURRENT_SEQ IS '현재 작업 중인 후행의 seq';
COMMENT ON column PO_DEFERRED_SVCM.END_SEQ IS '후행 작업 중 가장 큰 seq';
COMMENT ON column PO_DEFERRED_SVCM.SERVER_NAME IS '후행 작업 처리하는 서버 이름';

CREATE TABLE PO_DEFERRED_HISTORY
(
    GUID           VARCHAR2(50)      NOT NULL,
    EUID           VARCHAR2(50)      NULL,
    SEQ            VARCHAR2(50)      NULL,
    RETRY_CNT      NUMBER            NULL,
    DEF_ID         VARCHAR2(255)     NULL,
    DEF_DATE       VARCHAR2(20)      NULL,
    SVC            VARCHAR2(50)      NULL,
    STATUS         VARCHAR2(50)      NULL,
    TYPE           VARCHAR2(50)      NULL,
    OUTPUT_DATA    VARCHAR2(5000)    NULL,
    ERR_MSG        VARCHAR2(5000)    NULL,
    INPUT_TIME     VARCHAR2(14)      NULL,
    SERVER_NAME    VARCHAR2(50)      NULL,
    CALLER_SVC     VARCHAR2(50)      NULL,
    DEF_SVCM_ID       VARCHAR2(255)     NULL,
    INPUT_DATA     CLOB              NULL,
    HEADER_DATA    VARCHAR2(4000)    NULL,
    START_TIME     TIMESTAMP         DEFAULT SYSDATE,
    END_TIME       TIMESTAMP         DEFAULT SYSDATE,
    CONSTRAINT PO_DEFERRED_HISTORY_PK PRIMARY KEY (GUID, EUID, SEQ, RETRY_CNT)
);
COMMENT ON COLUMN PO_DEFERRED_HISTORY.RETRY_CNT IS '재처리 카운트';
COMMENT ON COLUMN PO_DEFERRED_HISTORY.DEF_ID IS '후행 서비스 아이디';
COMMENT ON COLUMN PO_DEFERRED_HISTORY.DEF_DATE IS '후행 작업 일자';
COMMENT ON COLUMN PO_DEFERRED_HISTORY.SVC IS '서비스';
COMMENT ON COLUMN PO_DEFERRED_HISTORY.STATUS IS '상태 FAILED, COMPLETED';
COMMENT ON COLUMN PO_DEFERRED_HISTORY.TYPE IS 'JAVA, C++, 등';
COMMENT ON COLUMN PO_DEFERRED_HISTORY.OUTPUT_DATA IS '아웃풋 데이터';
COMMENT ON COLUMN PO_DEFERRED_HISTORY.err_msg IS '에러 메시지';
COMMENT ON COLUMN PO_DEFERRED_HISTORY.INPUT_TIME IS '입력 시간';
COMMENT ON COLUMN PO_DEFERRED_HISTORY.SERVER_NAME IS '서버 이름';
COMMENT ON COLUMN PO_DEFERRED_HISTORY.CALLER_SVC IS '후행 서비스를 발행한 서비스 이름';
COMMENT ON COLUMN PO_DEFERRED_HISTORY.DEF_SVCM_ID IS '후행 집계 ID';
COMMENT ON COLUMN PO_DEFERRED_HISTORY.INPUT_DATA IS '후행 서비스 호출에 사용된 입력 값';
COMMENT ON COLUMN PO_DEFERRED_HISTORY.HEADER_DATA IS '후행 서비스 호출에 사용된 헤더 값';
COMMENT ON COLUMN PO_DEFERRED_HISTORY.START_TIME IS '후행 서비스 시작 시간';
COMMENT ON COLUMN PO_DEFERRED_HISTORY.END_TIME IS '후행 서비스 종료 시간';