목록경력 실무경험/실무 주제 (15)
공부한것들을 정리하는 블로그 입니다.
* 해당 글은 계속 수정 예정입니다. 최초 작성일 2022.12.12 마지막 수정일 2023.04 # 현금영수증 서비스? 현금영수증 서비스는 현금성 결제에 대한 국세청 영수증을 발급해주는 서비스이다. 실시간 계좌이체, 가상계좌 등 현금성 결제 성공 후 서비스가 호출되는 경우도 있고, (이 경우 트랜잭션/ID가 연계) 현금영수증 서비스만 단독으로 호출되는 경우가 있다. (이 경우 트랜잭션/ID가 독립 부여) 현금영수증은 배치 스케줄러를 통해 익일 새벽에 대상건을 파일로 만든 뒤, 국세청으로 FTP 송수신하여 처리되며 서비스가 일단락 된다. # 일련번호가 중복채번되면? 만약, 현금영수증 서비스에서 DB 시퀀스를 이용해 승인번호(승인취소번호) 채번되고 있다고 가정하면 일련번호가 중복채번 될 경우 익일 국세청으..
* 해당 글은 계속 수정 예정입니다. 최초 작성일 2021.11.25 마지막 수정일 2023.04 # 조회쿼리 수행결과 오류 발생 특정 테이블에 데이터를 Insert 하고 이후 Select 한다고 가정하자. 잘못된 날짜가 입력되었을 경우, 조회 조건으로 날짜를 입력시 조회쿼리 수행결과 오류가 발생 가능하다 (ORA-01847 : 달의 날짜는 1에서 말일 사이여야 합니다.) 이에 대한 해결법은, DB에 날짜데이터를 Insert 해야 할 경우에는 정합성 체크가 선행될 수 있도록 하거나. 조회쿼리에서 조건문을 작성 할 때 주의해야 할 것이다. 조회쿼리에서 조건문을 작성시 날짜데이터를 이용하는 경우 ex) TO_CHAR(TO_DATE(DT_INPUT, 'YYYYMMDD') + 20211120 , 'YYYYMMD..
* 해당 글은 계속 수정 예정입니다. 최초 작성일 2022.05.10 마지막 수정일 2023.04 # 노티서비스에서 이슈 발생 승인결과를 보내주는 노티(알림)서비스가 특정 가맹점에 400 오류응답을 하고 있다고 가정해보자. 아마 모니터링에서 감지되는것이 아니라면, 가맹점에서 먼저 확인요청이 들어올 수도 있다. 400 에러는 클라이언트 에러이므로 결국 가맹점 서버에서 오류응답 한 것이다. (4xx : 클라이언트 에러, 5xx : 서버 에러) 그러면 해당 이슈는 무조건 가맹점측 서버 문제일까? # 상황 설명 1. 클라이언트로 부터 결제승인 요청 2. 비즈니스 로직 처리 후 외부 API 호출 원천사/중계사 통신하여 승인요청 3. 외부 API 통신 결과에 따라 클라이언트로 응답 성공, 실패, 타임아웃 등 4. ..
* 해당 글은 계속 수정 예정입니다. 최초 작성일 2022.03.16 마지막 수정일 2023.04 # 가상계좌(무통장입금) 서비스 가상 계좌란, 고객이 자신이 원하는 은행을 선택 후 생성된 고유의 가상 계좌로 입금하는 서비스를 말한다. ATM 기기를 통한 입금, 인터넷뱅킹, 폰뱅킹 등 다양한 방법으로 입금이 가능하다. 가상계좌 제휴사는, 각 은행과 가상계좌 서비스를 제공 사업자를 연결 및 관리해 주는 제휴 기관을 말한다. 가상계좌 서비스는, 가상계좌 채번, 수취조회, 입금, 환불 등이 있다. # 수취조회시 개설기관 장애 응답 발생 DB동기화 점검 작업간 모니터링 진행중, 수취조회시 개설기관 장애 응답 발생을 감지 한 상황이라 가정해보자. DB동기화 점검 작업시 L4를 제어하여 한쪽 서버씩 번갈아 작업을 ..
* 해당 글은 계속 수정 예정입니다. 최초 작성일 2022.05.14 마지막 수정일 2023.04 # 카드사 장애 발생 감지 1. VAN에서 카드사 TIMEOUT 응답 발생 횟수가 일정이상 감지되어 서비스 모니터링에 감지된다. 2. 운영팀에서 카드사 상황실로 확인요청을 보낸다. 3. 카드사 터널 끊김을 감지하게 되고 VAN 담당자는 카드 통신 프로세스 재기동을 진행한다. => L4 스위치 제거 4. 인프라팀을 통해 각 서버별 카드 연동 전용회선 DOWN 이력 및 회선 정상여부 확인을 진행한다. => DOWN이력 O. 현재 정상 O 5. PG에서도 카드 거래건에 대해 VAN으로부터 카드사 TIMEOUT 응답 확인된다. => 카드사 TIMEOUT이라면 PG입장에서는 장애설정 혹은 서비스 조치 대상은 아닐 것..
* 해당 글은 계속 수정 예정입니다. 최초 작성일 2022.03 마지막 수정일 2023.04 # 레거시 서버 장비노후 이슈 새벽에 레거시 서버에서 장비노후로 인한 문제가 발생한 적이 있었다. 운영팀으로부터 디스크 컨디션 로그 Top I/O 처리율 90% 이상으로 지속 유지되고 있음을 공유받았고 실제로 확인해보니 거의 100% 근사치라서 계정 접속도 힘든 정도였다. 이에 대하여 다음과 같이 대응하였다. 1. 모니터링 프로그램 오탐 가능성 확인하고자, 레거시 서버(배치 컨테이너 용도)에 접속하여 실제 IO 사용량을 확인 2. 서버 프로세스 및 배치 스케줄러 목록 확인 후, 프로세스 중지 및 재기동을 하여도 특이사항이 없을지 확인 3. 서버 프로세스 중지 후 IO 사용량 모니터링 (정상화 되면 재기동 예정) ..
* 해당 글은 계속 수정 예정입니다. 최초 작성일 2021.04 마지막 수정일 2023.04 # 배치컨테이너 배포와 스케줄러 실행이 동시에 진행 결론부터 말하자면 오류가 발생가능하며, 이 경우 배치가 돌던 중 오류가 발생하고 데이터의 정합성을 보장 할 수 없을 것이다. 그러면 해당 컨테이너의 로그를 직접 보면서 데이터 보정 작업을 진행해야 될 수 있다. 또한 배치를 마저 돌려야 되는지, 그냥 재수행만 해도 될지 아니면 데이터 보정 후 재수행을 해야될지 등을 판단해야 한다. ex) admin 컨테이너 로그상 배포(HotDeploy)와 배치 실행이 겹치게 되어, InvalidGlobalDeployVersionException, InvalidGlobalDeployVersion 발생 프레임워크/서버에 따라 안전..
* 해당 글은 계속 수정 예정입니다. 최초 작성일 2021.04 마지막 수정일 2023.04 # 계좌이체 서비스의 도메인에 대해 은행은 계좌이체 서비스를 창구에서 직접 처리하는 경우가 있기때문에 입금이 완료되어도 바로 중계사를 통해 입금통보처리를 진행하지 않는다. 최초 입금수취조회 후 약 2분정도의 딜레이를 가진 뒤, 이후 다시한번 입금수취조회 후 입금통보처리를 하게 된다. 이를 API를 호출하는 흐름으로 나타내면 아래와 같다. 1. 최초 입금수취조회 : 은행 => 중계사 => PG사 2. 2분 딜레이(이 사이에 은행 시스템취소가 발생하면, 더이상 flow 진행 x) 3. 입금수취조회 : 은행 => 중계사 => PG사 4. 입금수취조회 성공응답시, 입금통보요청 : 은행 => 중계사 => PG사 # 은행점..
* 해당 글은 계속 수정 예정입니다. 최초 작성일 2020.12.30 마지막 수정일 2023.04 # 연말에 문제 발생 자바에서 SimpleDateFormat 메소드를 사용시, 반드시 주의해야 할 내용이 있는데 바로 년도 포맷의 사용방식이다. ex) 년도 포맷 - 대문자 사용 (YYYY 또는 YY) : 오류발생 O - 소문자 사용 (yyyy 또는 yy) : 오류발생 X 위 형식을 지키지 않을 경우, 1년 빠른 날짜를 가져오게 되어 문제가 발생된다. YYMMdd, YYMM, YYMMDD 등올 사용시에도 마찬가지로 연말(12/31)에 오류가 발생하므로 반드시 아래와 같이 포맷을 사용하도록 하자 ex) 이렇게 사용해야 함 년 : yyyy 또는 yy 월 : MM 일 : dd 시 : HH 분 : mm 초 : ss..
* 해당 글은 계속 수정 예정입니다. 최초 작성일 2021.02 마지막 수정일 2023.04 # 상황 설명 무중단 서비스를 지향하는. 이중화 되어있는 서버 상황(Active - Active)에서 한쪽 서버에 대해 스케일 업(Scale Up) 또는 정기점검 진행을 위해. 잠시 단일서버로 운영되어야 하는 상황이다. ex) A서버,B서버 중 L4제어하여 A서버로의 연결을 C서버로 변경하여 테스트 or A서버의 거래비를 제외하여 서비스를 제공하지 않는 상태로 만듦 대다수 고객 입장에서는 이중화된 서버(Active - Active)를 잠시 단일화(Active - Standby) 하는 상황이고 이는 즉, 특정 고객의 경우터 단일화 서버(Active - Standby)인 상황에서 서비스가 제공되지 않는 상태로 변경됨..

* 해당 글은 계속 수정 예정입니다. 최초 작성일 2022.03 마지막 수정일 2023.04 #상황 설명 이중화 되어있는 서버(A,B)의 엔드포인트에서 추가적으로 분산처리를 위하여 라운드로빈 방식을 사용중인 상황이라 가정 => 동일한 지불수단의 거래여도 1번,2번 컨테이너로 순차적으로 서비스를 호출 #상황 흐름 1. L4제어 L4를 통해 A서버의 거래를 제어하여, A서버의 A1컨테이너로 거래가 들어오지 않도록 제어 거래비 A:B = 50:50 A1 컨테이너 : 25 A2 컨테이너 : 25 B1 컨테이너 : 25 B2 컨테이너 : 25 => (L4 제어) 거래비 A:B = 50:50 A1 컨테이너 : 0 A2 컨테이너 : 50 B1 컨테이너 : 25 B2 컨테이너 : 25 2. DB변경 A서버의 A1 컨테..
* 해당 글은 계속 수정 예정입니다. 최초 작성일 2022.03 마지막 수정일 2023.04 # SELECT ~ FOR UPDATE SELECT FOR UPDATE 구문은, 동시성 제어를 위하여 특정 데이터 ROW에 대해 배타적 락(Exclusive LOCK)을 거는 기능입니다. ex) 영화관 예매 시스템의 잔여좌석 조회 등에 사용 가능 보통은 DB보안 관련 툴(DBSafer 등)을 사용중인 경우에 DDL, 운영DB로의 DML, LOCK 등이 차단되어야 마땅하나 위 SELECT FOR UPDATE 구문 등은 차단되지 않아 배타적 락이 걸리는 경우가 있습니다. 즉, 개발자가 해당 쿼리를 잘못 수행 할 경우, 세션이 유지되는 동안에는 해당 테이블/ROW에 락이 걸리게 될 수 있습니다. 개발자 입장에서 로컬P..

* 해당 글은 계속 수정 예정입니다. 최초 작성일 2021.01 마지막 수정일 2023.04 # 메시지 길이 설정 방식 메시지 길이 설정 방식에는 여러가지 종류가 있다. 헤더에 길이 정보를 포함하거나, 고정길이를 사용하거나, 데이터가 한번에 들어오는 경우에는 End of Data로 길이를 읽는 다거나 할 수 있다. 이 중에서 'End of Data로 한 번에 메시지가 들어오는 경우'(EOD)의 경우 발생할 수 있는 오류에 대해 알아보자 # End of Data로 한 번에 메시지가 들어오는 경우(EOD) 해당 방식은 TCP 특성상 네크워크가 느릴 경우 오류 발생 소지가 높으므로 사용에 주의해야 하는데, 네트워크가 느린 경우는 결국 요청건의 개수가 많을 경우에도 적용이 된다. 요청건을 처리하는데 병목이 발생..
* 해당 글은 계속 수정 예정입니다. 최초 작성일 2023.04 마지막 수정일 2023.04 # 쿼리의 결과값이 없으면 Empty Resultset 발생 Empty ResultSet 으로 인한 Illegal operation 에러 상황을 가정해보겠습니다. 가령, 1번쿼리를 수행 후 결과값을 이용해 2번쿼리를 돌리도록 작성하였다면, (ex) 1번쿼리 수행결과 -> while문 -> 2번쿼리 수행) 1번쿼리의 결과가 없거나, 혹은 1번쿼리의 결과는 있더라도 2번쿼리의 결과가 없을 경우. Empty Resultset이 발생합니다. # setEmptyResultCheck 설정 setEmptyResultCheck 설정 후 쿼리 조회결과가 없는 결과의 에러처리는 아래와 같다. 1. setEmptyResultChec..
* 해당 글은 계속 수정 예정입니다. 최초 작성일 2020.11 마지막 수정일 2023.04 # 전각문자를 반각문자로 치환 - 바이트의 차이(반각은 1바이트, 전각은 2바이트로 표현됨)을 고려 할 것 ex) 5바이트가 남은 경우 전각문자는 두개만 삽입 가능 - 특히 공백('0x20')에 대해 주의하고, - 0xfee0 이상의 문자는 전각문자이므로 0xfee0를 빼서 일반 문자로 변환하면 반각문자가 나온다는 것을 이해 할 것. public static String fullToHalf(String str) { StringBuffer sb = new StringBuffer(); char c = 0; int length = PgStringUtils.length(str); for (int i = 0; i < le..