카드 서버 리뉴얼

< spring to vertx >

카드 서버가 메모리 릭*으로 서버가 강종되는 일이 빈번히 발생하였다. 카드 서버는 vert.x로 개발되어 있었는데 당시 회사에서 사용하고 있던 버전이 메모리 누수가 있던 버전이었다. 이에 머물고있는 개발자들에게 친숙한 프레임워크인 spring boot로 리뉴얼을 결정하였다.

메모리 릭으로 인한 서버 강종이 가장 큰 문제였기 때문에 tps가 안정적인지를 검토하는 과정이 필요했다. 이에 jmeter를 사용했다.

 

* vert.x 메모리 릭

https://stackoverflow.com/questions/50407914/memory-leak-in-io-vertx-core-impl-eventloopcontext-in-java-application

* event-driven(이벤트 드리븐)이란?

더보기

MSA(분산 아키텍처 환경)가 적용된 시스템을 보완하는 아키텍처이다.

MSA에서 1️⃣이벤트*를 생성하고 2️⃣발행된 이벤트를 수신자에게 전송 3️⃣수신자는 그 이벤트를 처리 하는 방식으로

상호간의 결합도를 낮추기 위해 비동기 방식으로 메세지를 전달하는 패턴이다.

각 서비스는 함께 작동하되 서로 다른 비즈니스 로직을 적용한다. 이벤트는 형식을 제외하고는 서로에 대해 알 필요 없다.

 

*이벤트 : 프로그램에 의해 감지되고 처리될 수 있는 동작이나 사건을 말한다.

 

장점 : 느슨한 결합도와 의존성 배제로 확장성 확보

단점 : 시스템 flow 파악과 디버깅이 어렵다.


< 동시성제어 >

충전과 결제가 동시에 발생하여, 하나의 잔액 row를 select한 뒤 각각 '충전 후 잔액'과 '결제 후 잔액'으로 2건을 insert하는 일이 발생하고 있었다. 이로 인해 잔액사인이 불일치했고 고객은 개발자가 db의 sign값을 수기보정하지 않는 한 서비스를 이용할 수 없었다. 개선이 필요했다.

transactional* 어노테이션을 추가하여 db의 row를 홀드하도록 하고자했는데 적용이되지 않았다.

db 커넥션 풀 설정에 문제가 있음을 파악하여 개선에 들어갔다. 커넥션 풀의 공유는 ~.yml 파일에서 일어나지 않고**, mapper클래스의 @Repository*** 어노테이션이 jdbc connection과 DB연동을 수행한다는 것을 알았다. @Repository가 누락되어 있었기 때문에 transaction의 경계설정이 잡히지 않았고****, 그렇기에 commit 또한 진행되지 않았던 것이다.

해당 어노테이션을 추가하자 db의 원자성 보호를 위한 transactional 어노테이션이 동작하기 시작했다.

 

* @Transactional

더보기

isolation level에 따른 db row lock 비교 https://tistory-pencilcase.tistory.com/115

 

- synchronized

사용할 수 없음. a카드에 대해 thread를 홀드하면 이후의 b, c, d 카드들도 큐에서 대기하게 된다.

 

- serializable 일 때 update한 row에 대해서는 lock이 걸린다.

1. 첫번째 update 요청에서 정상적으로 update 후 10초 슬립을 시작함.
2. 두번째 update 요청 인입까지 로그가 찍힘
3. 첫번째 update 요청의 sleep 이 완료된 뒤 commit 후 response 를 리턴함
4. 두번째 update 요청의 db 락 로그가 찍힘

** 토비의 스프링 vol.1 360p 8line

*** 레포지토리란?

더보기

DB(데이터소스)계층과 연결을 할 때 Repository라는 저장소를 두게 됩니다.

Repository는 흔히 Model이라고 하는데 스프링에서는 Repository라고 부릅니다. 
Repository를 구성하는 클래스는 DAO DTO VO가 되며 이들을 통해서 DB와 연결을 합니다. 
DB연동로직(JDBC)은 DAO에서 insert,update,delete,select를 전담하게 됩니다. 
DB를 사용하는것은 아무래도 온전하게(안정성) 데이터를 보관하고 관리하는 측면에서 유리하기때문에  
프로그램에 필요한 데이터들은 DB에 보관해두고 데이터내용을 입력,수정,삭제 하거나 읽는작업들을 수행해야합니다. 
이런작업들을 Repository계층에서 수행하여 Controller의 부담을 줄이게 합니다. 

 그리고 SQL의 변동이라던가 어떠한 특정 처리의 변동이 일어난다면 DAO안에서 해결할 수 있습니다.


 즉, Repository계층에는 DataAccessObject라는 DAO를 만들어서 DB연동을 수행

https://u-it.tistory.com/entry/Service%EA%B3%84%EC%B8%B5%EA%B3%BC-Repository%EA%B3%84%EC%B8%B5%EC%97%90-%EB%8C%80%ED%95%9C-%EC%9D%B4%ED%95%B4

**** 토비의 스프링 vol.1 357p

 

 

 

 

 

'main' 카테고리의 다른 글

[지음지식] 2025.03 ~  (0) 2025.04.07
목차 정리  (0) 2025.02.18
카드서버 리뉴얼 - 6  (0) 2023.03.22
카드서버 리뉴얼 - 3  (0) 2022.10.04
카드서버 리뉴얼 - 2  (0) 2022.10.01