VM Proxy 설정에 대한 HttpURLConnection & HttpClient 차이

프록시 서버 구성을 하는 과정에서 알게된 Java 클래스 몇가지를 비교하여 정리하였다.

2024년 3월 17일 · 1 분 · An Seongjin

Quick Guide: How to Identify Your Package Manager

Linux를 사용하다보면 그 안에서 사용 가능한 패키지 관리자 확인이 필요할 때가 있다. 쿠버네티스나 도커를 사용하면 image를 통해 pod container를 편리하게 구성할 수 있지만, 그 image가 구성된 OS가 어떤 배보판인지 확인하고 적합한 패키지관리자를 찾아야했다.

2024년 3월 4일 · 1 분 · An Seongjin

Spring Optimization: Refactoring Object-to-Map Conversion Methods

기존 Reflection 사용 방식 Object to Map 컨버팅 메서드의 성능 및 유지보수성 개선하기 위한 방법

2024년 3월 1일 · 2 분 · An Seongjin

Docker Pull Error: 두 가지 해결 방법

로컬 쿠버네티스 환경에 애플리케이션 배포를 하면서 겪은 Docker Image Pull 에러. 이것을 해결할 수 있었던 몇 가지 방법에 대한 기록.

2024년 2월 26일 · 1 분 · An Seongjin

Redis 세션 클러스터링 설정 (feat. Redisson)

How to Enable Session Clustering in “Low-level Spring Framework” and “Redis with Encryption”

2023년 10월 3일 · 2 분 · An Seongjin

Delimiter를 통한 다중 검색 처리

들어가며 현재 투입되어있는 프로젝트의 서비스 중에는 특정 데이터를 조회할 수 있는 화면이 있습니다. 그런데 이 화면을 사용하게되는 업무 특성상 데이터를 일일이 하나씩 조회하기가 번거롭다는 불편사항이있어 이를 한번에 다중 검색 가능하도록 수정 조치하였고, 당시 작업내용을 핵심부분만 간략하게 정리하였습니다. 기존 방식 mapper.xml <sql id="ticketSearch"> <if test="(method_info != null and method_info != '')"> <if test="method_id == 'gkId'"> AND GK_ID = #{method_info} </if> <if test="method_id == 'parentTicketId'"> AND UPPER(PRNT_TKT_ID) LIKE CONCAT('%',UPPER(REPLACE(#{method_info}, '_', '#_')),'%') ESCAPE '#' </if> <if test="method_id == 'ticketId'"> AND UPPER(TKT_ID) LIKE CONCAT('%',UPPER(REPLACE(#{method_info}, '_', '#_')),'%') ESCAPE '#' </if> <if test="method_id == 'guid'"> AND GUID LIKE CONCAT('%',#{method_info},'%') </if> </if> </sql> <select id="list" parameterType="map" resultMap="ticketVO"> SELECT 컬럼 1, 컬럼 2, 컬럼 3 FROM 테이블 A WHERE DEL_YN_FG = 'N' <include refid="ticketSearch"/> </select> ▲ 화면에서 입력한 문자열 1개를 포함하고있는 데이터를 “like” 검색을 통한 단일 조회 방식 ...

2023년 9월 25일 · 2 분 · An Seongjin

Autoscaling 적용을 위한 스케줄(@Scheduled) 로직 변경

들어가며 현재 투입되어있는 프로젝트에서는 최근 기존의 인프라 구성에서 많은 부분 전환된 일정이 있었습니다. 그 당시 Autoscaling을 적용하기 위해서 예상되는 문제점은 무엇이 있었는지, 그리고 그것을 어떻게 극복했는지 다음과 같이 정리하였습니다. 기존 환경 Autoscaling이 적용되어있지 않은 was EC2 2개 운영 해당 서버의 Spring Framework 애플리케이션 내에는 @Scheduled 어노테이션을 통한 스케줄잡 사용 일부 스케줄 관련 코드 : @Scheduled(cron = "0 30 9 ? * *", zone = "GMT+9:00") public void notifyLongTermNoUseAdmin() { if("1".equals(GkConstant.WAS_NUMBER)) { // STG, PRD 의 1번 서버인 경우에만 Batch 실행 try { List<LongTermNoUseAdminVO> notifyAdminDataList = longTermNoUseAdminSvc.getNotifyAdminDataList(); for (LongTermNoUseAdminVO voNotifyAdmin : notifyAdminDataList) { try { List<String> mailReceiverIDList = new ArrayList<>(Arrays.asList(voNotifyAdmin.getAccountId())); // 메일 수신인 리스트에 장기 미사용자의 이메일 주소만 추출해 추가 // 대상자별 mail template parameter 가 다르기 때문에 for 문을 통해 개별 메일 발송 awssesClient.sendEmail(mailReceiverIDList, "[" + ospAppConfig.getGkServerType() + "]" + MailEnum.NOTIFICATION.getMailSubject(), setMailHtmlBody(MailEnum.NOTIFICATION, voNotifyAdmin), null); LOG.info("##### SUCCESS Sending Notification Email : {}, {}", voNotifyAdmin.getSaGuid(), voNotifyAdmin.getAccountId()); } catch (Exception e) { e.printStackTrace(); LOG.info("##### FAIL Sending Notification Email : {}, {}", voNotifyAdmin.getSaGuid(), voNotifyAdmin.getAccountId()); } } LOG.info("##### SUCCESS notifyLongTermNoUseAdmin Batch"); } catch (Exception e) { e.printStackTrace(); LOG.info("##### FAIL notifyLongTermNoUseAdmin Batch"); } } } 위와 같이 “코드가 실행되는 두대의 서버 중 vm option의 특정 시스템 프로퍼티가 ‘1’로 되어있는 서버에서만 동작”하도록 조건이 설정 (if("1".equals(GkConstant.WAS_NUMBER))) 문제점 Autoscaling을 적용하게되면 서버가 동적으로 생성 및 삭제되기 때문에 어느서버가 1번 서버인지 기준이 사라지는 상황. 따라서 기존의 Scheduled 로직이 여러 서버에서 중복으로 실행되거나 혹은 전혀 실행될 수 없는 로직 ...

2023년 9월 21일 · 4 분 · An Seongjin

Tomcat 배포 방식의 올바른 이해와 구조적 분석

Tomcat 서버의 애플리케이션 배포는 웹 애플리케이션 운영에서 가장 기본적인 영역이면서도, 실제로는 많은 개발자들이 정확한 동작 원리를 놓치고 있는 부분이다. 최근 고객사 운영 서버의 server.xml 설정을 분석하던 중, <Context> 태그와 <Host>의 appBase 속성이 혼재된 구성에서 WAR 파일 배포 과정에 대한 오해를 발견했다. 기존의 배포 설정 운영 중인 서버의 server.xml 설정: <Host name="localhost" appBase="/home/manager/eps/webapps" unpackWARs="true" autoDeploy="true"> <Context path="" docBase="/home/manager/eps/webapps/legacy" reloadable="false" /> <Context path="/v5" docBase="/home/manager/eps/webapps/ui5" reloadable="false" /> <!-- ... AccessLogValve 설정 ... --> </Host> 이 설정에서 명시적인 <Context> 배포와 appBase를 통한 자동 배포가 공존하고 있었음.. 그런데 여기서 문제가 발생. 새로운 버전의 ui5.war 파일을 배포하려 할 때, 기존 관리자는 다음과 같은 절차를 따르고 있었다. ...

2023년 5월 11일 · 4 분 · An Seongjin

Try Python's argparse

Argparse argparse를 이용하면 파이썬 스크립트 실행시 사용자 임의의 Argument값을 넘겨서 활용할 수 있다. 유용한 argparse에 대하여 간단한 예제 import argparse # 인자값을 받을 수 있는 인스턴스 생성 parser = argparse.ArgumentParser(description='사용법 테스트입니다.') # 입력받을 인자값 등록 parser.add_argument("-testArg", dest="testDest", help="python argparse.py -testArg={입력값} 형태로 입력하세요~") # 입력받은 인자값을 args에 저장 (type: namespace) args = parser.parse_args() if args.testDest: print("결과값: ", args.testDest) **사용예시 : ** » python argparseTest.py --help usage: argparseTest.py [-h] [-testArg TESTDEST] 사용법 테스트입니다. optional arguments: -h, --help show this help message and exit -testArg TESTDEST python argparse.py -testArg={입력값} 형태로 입력하세요~ 결과값 : » python argparseTest.py -testArg=123 결과값: 123`

2023년 4월 23일 · 1 분 · An Seongjin

How to separate Python's development environment (venv)

venv(가상환경) 사용 이유 파이썬을 다루다보면 다양한 패키지들을 사용하게 된다. 그렇게, pip3 install {패키지명}을 무분별하게 사용하다보면 로컬에 있는 다른 프로젝트 간 패키지 버전 충돌 혹은 패키지(라이브러리)간 의존성 문제가 발생하기도 한다. 이를 해결하기 위해 ‘venv’라는 파이썬 모듈로 패키지 환경 분리가 가능하며, 작업환경이 바뀌더라도 필요한 패키지들을 동일한 버전으로 설치해 작업할 수도 있다. 현재 설치되어있는 파이썬 패키지 목록 확인 pip list 가상환경 생성 python -m venv myenv venv 라는 모듈을 사용하겠다는 의미 myenv는 사용자 임의의 가상환경 별칭 ...

2023년 4월 22일 · 2 분 · An Seongjin