
이번에 꽤 흥미로운 이슈를 하나 겪었다. 동일한 쿼리, 동일한 파라미터로 MyBatis 쿼리를 두 번 실행했는데, 첫 번째 쿼리의 결과와 두 번째 쿼리의 결과가 달랐다. (p6spy를 통해 확인했을 때 두 번째 쿼리는 로그조차 안 찍힘)결론부터 얘기하자면, MyBatis의 1차 캐시 때문에 발생한 문제였다.트랜잭션과 1차 캐시트랜잭션 내에서 1차 캐시가 동작한다는 점을 이해하는 것이 중요하다. MyBatis에서 1차 캐시는 SqlSession 단위로 관리되며, 하나의 트랜잭션 내에서 같은 SqlSession을 사용하기 때문에 트랜잭션 동안 캐시된 데이터는 계속 유지된다. 이 말은 트랜잭션 내에서 같은 쿼리와 파라미터로 데이터 조회 시, 쿼리가 실행되지 않고 1차 캐시에서 결과를 가져온다는 의미다.따라서 ..

문제JPA에서는 1차 캐시를 사용하기 때문에 같은 엔티티에 대해서는 동일성(주소값이 같음)을 만족한다고 알고 사용해왔다. 그래서 나는 객체를 비교할 때 id가 아닌 객체 그 자체로 비교해 왔다. 그런데 어느 날 id로 가지고 온 객체를 이용해 fetch join을 통해 가지고 온 객체 중 하나를 찾는 로직을 작성했는데, 하나도 못 찾는 문제가 발생했다. 확인해보니 id를 통해 가지고 온 객체와 fetch join을 통해 가지고 온 객체의 주소값이 달랐다. 결론부터 말하자면 원인은 @Transactional을 붙이지 않아 발생했다. 테스트1. @Transactional 없이 조회아래 코드는 테스트를 위해 작성한 코드로, findByIdPerson은 personRepository에서 id를 이용해 perso..
우리 팀에서는 사용자의 조작에 따라 카프카의 특정 토픽을 구독하거나 구독 취소하는 기능을 구현하고 있다. 이 과정에서 topicList라는 리스트를 통해 구독할 토픽을 관리하고, 해당 리스트의 사이즈를 체크하여 구독할 대상이 있는 경우에만 로직을 실행하도록 개발했다. 그런데 topicList에 데이터가 하나도 없을 때 무한루프에 빠져 새로운 토픽이 추가되어도 무한루프를 빠져나오지 못하는 현상이 발생했다.문제의 원인아래는 대략적인 코드이다. 코드를 살펴보면, topicList의 사이즈가 0일 때 while문 안에서 continue가 호출되어 무한루프에 빠지는 것을 알 수 있다. 사실 이 코드는 애초에 잘못 짜여진 코드이다. 토픽이 없는 경우에도 무한루프에 빠지가 코드를 짜면 안된다. 하지만 그렇다고 하더라..

전체적인 로직깃허브에서 pull request 를 만들면 api gateway로 요청을 보낸다 api gateway 는 lambda의 함수를 호출하고 lambda 의 함수 로직에서 mattermost를에 메세지를 전송한다api gateway : API 만들어주는 친구. 외부 클라이언트로부터 요청을 받아 람다 함수로 연결해줌lambda : 서버리스 컴퓨팅 플랫폼(메서드만 작성해서 실행시킬 수 있음)1. Mattermost에 webhook 추가하기먼저 mattermost에 외부 메세지를 받을 수 있도록 webhook을 추가해 준다좌상단 > 통합전체 Incoming WebhookIncoming Webhook 추가하기 내용 입력 생성된 URL → 람다에서 메세지 전송할 URL 로 사용2. aws lambda 함..

최근에 DL(Data Lake) 데이터 저장소를 Logpresso에서 ClickHouse(+Nifi)로 전환하는 작업을 진행했다. 이에 따라 API 서버(Spring Boot)에서도 Logpresso에서 가지고 오던 데이터를 ClickHouse에서 가져오도록 전환을 진행했다. 이를 위해 하나의 프로젝트에 다중 데이터소스(pg, ClickHouse)를 연결해야 했다. 이 글은 그 내용을 다룬다. 1. build.gradle 에 clickhouse jdbc 추가ClickHouse JDBC를 사용하기 위해 build.gradle에 의존성을 추가해준다. 2. yml 에 clickhouse 접속 정보 추가application.yml 파일에 ClickHouse 접속 정보를 추가해준다.datasource 위의 pos..

우리 팀에서는 브랜치에 push 될 때 마다 jar를 넥서스에 올려놓는 형식으로 사용중이다넥서스를 설치한 이후 보관주기를 설정한적이 없어 서버용량의 99% 를 사용중이었고 nexus 의 기능을 이용해 cleanup 설정을 걸어줬다 1. Cleanup Policies 설정정리 정책 설정Nexus Repository Manager에 로그인한다Administration > Repository > Cleanup Policies로 이동한다 기본적인 정보들을 적어준다 Cleanup Criteria 설정:Component Age: 게시일로부터 설정한 날짜가 지났을 경우Component Usage: 설정한 날짜 동안 다운로드되지 않았을 경우Asset Name Matcher: 삭제할 대상 이름의 정규식 설정 조건을 설정..

✔ 목표 : centOS7에 제우스8 설치하고 띄워보자 0. 설치 파일 다운로드 - 아래 링크에서 진행 https://technet.tmax.co.kr/ko/front/download/findDownloadList.do TmaxSoft Technical Network [technet-01] 데모라이선스 신청 데모라이선스는 제품구입 전 테스트 및 검토를 위하여 제한 된 기간 동안 발급받아 사용가능한 라이선스 입니다. technet.tmax.co.kr 1. jeus8500_unix_generic_ko.bin 파일이 위치한 디렉터리로 이동 후 설치 파일을 실행 ./jeus8500_unix_generic_ko.bin 1)소개 -> ENTER 2) 라이센스 -> ENTER 라이센스 이어서 -> ENTER -> E..

우리 프로젝트에서는 여러개의 쓰레드를 이용하여 작업을 실행하기 위해 ThreadPoolExecutor를 이용하고 있다 쓰레드 풀의 개수는 고정적으로 사용하고 있으며, 해당 쓰레드를 실행하는 부분에서 쓰레드의 개수를 관리하며 쓰레드 풀 이상의 요청은 하지 않기 때문에 이론적으로는 쓰레드 풀이 터지는 경우는 없어야 했다. 하지만 여러 프로젝트를 진행하며 종종 쓰레드 풀이 터지곤 했는데 이번에 조금 더 깊이 파봤다 발생한 오류 는 아래와 같다 RejectedExecutionException: Task cohttp://m.xxx.xx.TrainWorker rejected from java.util.concurrent.ThreadPoolExecutor[Running, pool size = 16, active th..
- Total
- Today
- Yesterday
- 넥서스 파일 보관주기
- s3
- multiple datasource
- db 두개
- php
- myabatis
- API Gateway
- 네트워크
- docker
- 다중 데이터소스
- 1차캐시
- SynchronousQueue
- AWS
- 제우스8.5
- 넥서스 보관주기
- 카프카
- 캐시
- 도커
- spring boot
- volatile
- 보관주기
- 제우스8
- 주키퍼 없는 카프카
- 오블완
- jpa 1차 캐시
- cleanup policy
- 쓰레드 변수
- 제우스 로그
- cleanup policies
- 스레드 동기화
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |