목록Spring (12)
개발그래머
요즘 대부분의 서버 통신은 HTTP 기반 API를 주로 사용하지만, 금융권을 비롯한 특정 산업에서는 여전히 TCP 통신이 필수적으로 사용되고 있습니다.실제로 많은 금융 시스템과 일부 기업 환경(현재 회사)에서는 TCP 기반 연동 서버가 다수 존재합니다.HTTP와 TCP 비교구분HTTPTCP표준/호환성매우 높음직접 설계 필요성능헤더/텍스트 오버헤드 큼가볍고 빠름실시간성낮음 (요청-응답)높음 (양방향 스트리밍)보안HTTPS로 간단 적용TLS 직접 적용 필요인프라 친화성게이트웨이, 로드밸런서 지원 풍부포트/방화벽 제약 많음개발 편의성쉬움 (REST, JSON)어렵지만 최적화 가능Spring에서의 TCP 통신 구현 방법Spring 환경에서 TCP 통신을 구현하는 방법으로는 크게 세 가지가 있습니다Java Soc..
서비스를 운영하면서 민원에 응답하기 위해 앱 로그 확인이 필요한 상황이 있었다.현재 서비스에서는 앱 로그를 특정 용량만큼 저장한 후, 필요할 때 푸시를 통해 서버 API를 호출하여 파일을 전송하고 있었다. 어느 날부터인지 해당 기능이 간헐적으로 동작하기 시작했다.어떤 유저의 로그는 API 호출이 정상적으로 되는 반면, 어떤 유저의 로그는 며칠이 지나도 API 호출이 되지 않는 현상이었다.이 기능은 내가 인수인계받기 전부터 개발이 완료된 지 오래되었고 계속 사용해오던 기능이었다.기존 사수 개발자에게 물어봐도 앱 쪽에서 확인해야 할 문제라고 하여, 앱 쪽에 계속 확인해달라고 하는 상황이었다.로그 전송 실패 시 보낼 API를 추가하고 상황을 지켜보았지만, 아무런 소득 없이 현상은 계속되었다. 문득 용량에 대한..
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is java.lang.IllegalStateException: Unable to create the directory [/tmp/tomcat.*] to use as the base directory개발 서버 배포 문제 해결 과정개발 서버를 배포하는 과정에서, 배포가 완료되지 않고 애플리케이션이 계속해서 실행 종료를 반복하는 현상이 발생했다.처음에는 소스 코드 수정 과정에서 발생한..
개요 서비스를 운영하다 보면 간헐적으로 요청 오는 정보(ex. 코드로 처리하면 편리한 경우) 작업들 또는 암호화 / 복호화 같은 애플리케이션 내부에서만 처리할 수 있는 작업(ex. 유저의 복호화된 전화번호 정보가 담긴 엑셀파일이 필요하다) 해당 유저 혹은 작업에 대한 복합적인 여러 정보들을 쉽게 확인할 수 있도록 하는 작업(ex. 여러 테이블들에 있는 정보들이 필요하다) 위의 운영 작업들을 효율적으로 처리하기 위해 ApplicationRunner와 CommandLineRunner를 활용한 방법들을 소개합니다. ApplicationRunner와 CommandLineRunner 인터페이스란? 스프링부트 애플리케이션을 시작할 때 어떤 동작을 수행하도록 지원하는 인터페이스이며 Runner 인터페이스를 상속받고 ..
개요1차 캐시가 동작하지 않아 생각한 쿼리의 양보다 많은 쿼리가 나가는 경우가 종종있었다.어떠한 경우 어떠한 문제로 발생하는지 한번 알아보자.예제 코드@Entity class Post ( var title: String, var content: String, var subTitle: String ) : BaseEntity() @MappedSuperclass abstract class BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long? = null @CreationTimestamp @Column(updatable = false) val createdAt: LocalDateTime? = null @UpdateTi..
Spring의 @TransactionalEventListener를 사용하는 이유?(@EventListener와의 차이점) Spring 4.2부터 이벤트리스너를 트랜잭션 단계에서 바인딩할 수 있는 @EventListener의 확장 애노테이션 트랜잭션 내에서 이벤트를 수신하고 처리함 기존 이벤트리스너는 데이터의 불일치가 생길 가능성이 있음 @Transactional fun save() { aRespository.save(); eventPublisher.publishEvent(aEvent); bRepository.save(); eventPublisher.publishEvent(bEvent); } bRepository를 저장하는 과정에서 에러가 발생한다면 aEvent가 만약 비동기로 발행된 상황이면 예상하지 못..
Spring의 @EventListener를 사용하는 이유? 컴포넌트 간의 결합도를 감소시켜 직접적인 의존성을 줄일 수 있음(느슨한 결합) -> 재사용성 높임 PostService와 MailService가 있을 시 PostService안에 MailService에 대한 의존성을 가지고 있지 않고 Event를 발행함으로써 직접적인 의존도를 가지지 않음 새로운 기능이나 모듈을 추가할 때 적절한 이벤트를 생성하고 리스너를 등록함으로 기존 코드를 변경하지 않고 새로운 기능을 통합할 수 있는 확장성과 유연성을 제공함 클래스별 의존성을 줄이므로 테스트가 용이해짐 사용 방법 스프링 4.2 이전에는 ApplicationEvent를 상속받아야 하고 ApplicationListener 인터페이스를 구현해주어야 했지만 이후에는..
발견 스프링 multiple datasource 설정을 하기 위해 스프링부트에서 제공하는 default datasource를 사용하지 않고 수동으로 등록해 주는 작업을 하였다.(참조 : https://www.baeldung.com/spring-data-jpa-multiple-databases) //datasource 설정 @Configuration @EnableJpaRepositories( basePackages = "com.**.repository", entityManagerFactoryRef = "originEntityManager", transactionManagerRef = "originTransactionManager" ) public class PersistenceOriginConfig { @..