일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 유사코드
- 티스토리
- 리눅스
- 프로젝트
- 오라클 디비
- JVM
- 자바 프로젝트
- auto configure
- 초대장
- hyperledger
- jsp
- oracle
- 오라클
- K6
- 파이썬 소스
- 백준 알고리즘
- 자바
- resilience4j
- spring
- c#
- 알고리즘
- dynamic query
- 운영체제
- smart cast
- 문법 정리
- MongoDB
- 파이썬
- 학점
- gradle
- SQL
- Today
- Total
목록목차 (231)
모종닷컴
![](http://i1.daumcdn.net/thumb/C150x150.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/kZmVT/btrScP57w9Z/NXaX4ZKv3NFuFoyg8wr731/img.jpg)
MySQL의 경우 flyway를 통해서 데이터 마이그레이션을 진행할 수 있는데 Mongodb의 경우는 데이터 마이그레이션을 하기 위해서는 어떤 라이브러리를 사용할 수 있을까? Mongock 페이지에서 소개하는 간단한 특징 몇 개만 짚어보자면 아래와 같다. 자바 기반 마이그레이션 도구 견고한 락 메커니즘을 이용하기 때문에 분산 환경에서 안정적으로 실행 가능하다. 코드로 마이그레이션 스크립트를 작성할 수 있다. MongoDB 마이그레이션이 가능하며 (자칭) 가장 안정적인 프로덕트 오픈 소스 정기적인 유지보수 Spring과 호환이 좋다. 노란줄만 보더라도 적합해 보이는 툴입니다. MongoDB 마이그레이션으로 가장 많은 스타를 받고 있는 mongobee의 경우 업데이트가 이제는 거의 없는 반면 Mongock은..
![](http://i1.daumcdn.net/thumb/C150x150.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/cCBGmN/btrQZhkp4Ge/fzKNqruRKtAdmBSWkCCsI1/img.png)
Circuit Breaker는 무엇이며 어떠한 상황에서 사용될까? circuit breaker는 이름에서 알 수 있듯이 회로를 차단하는 기능입니다. 주로 외부 콜에 의존하는 부분에 사용합니다. 예를 들어 A와 B 서버가 존재한다고 가정해보겠습니다. A서버에서는 B서버의 API에 의존하고 있는 형태일 때 만약 B서버에 과부하가 걸려 응답을 제시간에 못주게 되는 경우 A서버에서의 API 호출은 응답을 기다리다가 모두 실패하게 될 것입니다. 이렇게 B서버의 장애는 A서버 외에도 B서버를 사용하고 있는 모든 서버에 장애가 전파되게 됩니다. 이때 이런 생각을 해보게 됩니다. "어차피 지금 B서버의 요청은 모두 timeout이 나게 될텐데 A서버가 이 요청을 위해 리소스를 계속 낭비하고 있어야 할까?" 예를 들어 ..
![](http://i1.daumcdn.net/thumb/C150x150.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/cSrYlH/btrQ2S33Wq7/0j9MT5Ps43tZlXEkktxH31/img.png)
담당하던 프로젝트 일정이 조금씩 딜레이 되면서 오랜만에 다시 블로그로 돌아온 것 같습니다. 이번 프로젝트 때 많은 기술적인 이슈들을 마주하였는데 지금부터 조금씩 정리하면서 올리려고 합니다. 그중에서도 오늘은 Intellij IDEA 디버깅과 관련된 간단한 팁을 먼저 공유드리려고 합니다. 멀티스레드 환경에서 디버깅하기 개발을 하다보면 동시성 관련 이슈들을 마주하게 됩니다. 동시성 문제라는 걸 자각하지만 로컬에서 재현한다는 것은 꽤나 귀찮은 부분들이 많습니다. 하지만 Intellij IDEA를 사용하시는 분들이라면 이 동시성 재현을 편하게 할 수 있습니다. 사용법은 간단합니다. 아래 사진과 같이 디버깅을 시작하기 원하는 라인에 브레이크 포인트를 걸어놓습니다. 이 상태에서 빨간색 원위에서 우클릭을 해줍니다. ..
![](http://i1.daumcdn.net/thumb/C150x150.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/bjg8Y2/btrPfWI6RA9/toqK1ecxbmUIn4BJwVdYcK/img.jpg)
개요 작업을 하다가 우연히 발견하게 된 것이 있습니다. MongoDB에 일괄로 저장하는 코드를 작성하고 @Transactional을 붙이면 이 작업이 트랜잭션 단위로 동작하기를 기대했는데 실제로는 전혀 동작이 되고 있지 않았기 때문입니다. 문서들을 찾아본 결과 MongoDB는 4.0 버전 이후부터 Transaction을 지원하기 시작했고, 사용하고 있는 Spring Data MongoDB는 2.1 버전 이후부터 MongoDB의 Transaction을 사용할 수 있다고 합니다. 제가 작업하는 환경은 모두 MongoDB의 Transaction을 사용할 수 있는 버전이었음에도 불구하고 동작이 되지 않았습니다. 그래서 이번 포스팅에서는 스프링 프레임워크에서 MongoDB의 Transaction을 사용하기 위한 ..
![](http://i1.daumcdn.net/thumb/C150x150.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/XnSC6/btrPkqhzHJ0/j9z2IVYYr3CZLsIseq0Z1k/img.jpg)
Transaction 먼저 트랜잭션이란 연속되는 연산들을 묶은 단위입니다. 이 단위에 정의된 연속된 연산들이 모두 성공해야 트랜잭션이 성공하며, 이 연산들 중 일부가 실패하면 정의된 연산들은 모두 실행되지 않았던 시점으로 다시 돌아가야 합니다. 예를 들어 A가 B에게 M원을 송금하는 것을 트랜젝션으로 정의한다면 아래와 같은 연산들이 포함될 것입니다. A가 B에게 M원을 송금한다 B의 계좌 상태가 유효한지 체크 A의 계좌에서 M원을 차감할 수 있는지 체크 A의 계좌에서 M원을 차감 B의 계좌에 M원을 더한다. 연산이 제대로 이루어졌는지 체크 트랜잭션 완료. 이러한 연산을 실행하는 중 4번 연산(=B의 계좌에 M원을 더하는 연산)에서 이 알 수 없는 오류에 실패하였을 때 A의 계좌에서 M원을 차감했던 것을 ..
![](http://i1.daumcdn.net/thumb/C150x150.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/cfLvR3/btrOYn1fTD3/j4si2SqMkiGK9dHs8vLOgK/img.png)
MongoDB 준비 MongoDB replication 세팅을 위해서는 2개 이상의 몽고 인스턴스가 필요합니다. 문서를 보면 일반적으로는 3개의 인스턴스로 구성하는 게 가장 일반적인 설정인 것 같습니다. 테스트 편의를 위해 도커를 사용하도록 하겠습니다. 도커가 없다면 로컬에 몽고DB 인스턴스를 3개 준비해주셔도 무방 할 겁니다. version: "3.6" services: mongo-1: image: mongo:4.4 container_name: mongo-1 ports: - "30000:30000" command: mongod --replSet replset --port 30000 mongo-2: image: mongo:4.4 container_name: mongo-2 ports: - "30001:30..
![](http://i1.daumcdn.net/thumb/C150x150.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/tZGUC/btrOeSsxuPR/FquOSzFTpjtmOMTEke2KM1/img.gif)
진행하고 있는 프로젝트가 슬슬 마무리가 되어가네요.. 포스팅할 거리가 많은데 프로젝트가 끝나면 하나씩 정리해서 올리도록 하겠습니다. 너무 오랫동안 글을 못 올리는 게 싫어서 짧은 글이지만 소개해보려고 합니다. 의존하고 있는 빈이 많은 클래스들이 간혹 보입니다. 설계를 잘못한걸수도 있지만 이런 클래스들은 특히 단위 테스트 코드를 짤 때 정말 귀찮습니다. 예시를 보도록 하겠습니다. 예시 코드 private val log = KotlinLogging.logger { } @Service class WelcomeStep { fun execute() { log.info("welcome") } } @Service class EnjoyStep { fun execute() { log.info("enjoy") } } @S..
![](http://i1.daumcdn.net/thumb/C150x150.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/b65enI/btrMUL3n8n2/B4EXj9lzXAklM6mGzIYl61/img.png)
CompletableFuture의 예외를 핸들링하는 3가지 handle, whenComplete, excetpionally CompletableFuture의 예외를 처리하는 방법에 대해 알아보려고 합니다. 여러 가지 방법들이 존재하지만 이번 포스팅에서 다룰 방법들은 자바에서 제공하는 기본 메서드들을 설명하려고 합니다. 이에는 handle(), whenComplete(), exceptionally() 세 가지 메서드가 존재합니다. 처음에 봤을 때 뭐가 다른 거지 하고 굉장히 헷갈려서 이번 기회에 글로 조금 정리해보려고 합니다. handle 먼저 handle 메서드를 보도록 하겠습니다. public CompletableFuture handle( BiFunction
![](http://i1.daumcdn.net/thumb/C150x150.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/llRfX/btrMUUed2EG/Gtk9NFcwKv0Km7Fk5SrHAK/img.png)
오늘은 정말 간단한 글 하나를 올려보려고 합니다. 내용은 멀티 모듈 프로젝트에서 모듈의 겹치는 이름으로 인해 겪은 삽질기입니다. 상황을 재현해보기 간단하게 세팅을 먼저 해보도록 하겠습니다. 프로젝트 구조 프로젝트는 projectA, projectB 두 개로 만들어져 있습니다. projectA는 app, domain 모듈을 지니고 있고, projectB는 domain 모듈만 지니고 있습니다. projectA 빌드스크립트 war 관련 파일 설정이 추가되어있습니다. apply plugin: 'war' bootWar { mainClassName = "com.example.projectA.app.MainAppKt" // 코틀린 파일이 자바로 해석되면서 클래스명 뒤에 'Kt'가 붙는다 archiveName("${p..
![](http://i1.daumcdn.net/thumb/C150x150.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/oj84G/btrMi3Q0P7n/SYphgcuc2KsKKcdf64cxg1/img.png)
그레이들 빌드 스크립트 작성의 기본적인 부분들을 다룹니다. 글에서 간단한 예시를 보면서 기초 개념들에 대해 알려줍니다. Projects, plugins and tasks 모든 그레이들 빌드는 하나 이상의 projects로 구성됩니다. 그레이들로 무엇을 하려는지에 따라 project가 정의가 달라집니다. 예를 들어 project는 JAR 라이브러리 혹은 웹 애플리케이션을 말하는 걸수도 있습니다. 혹은 다른 프로젝트에서 생산된 JAR로부터 어셈블된 ZIP을 말하는 걸수도 있습니다. 프로젝트가 반드시 무엇인가를 만들어야 한다는 것이 아닙니다. 스테이징 또는 프로덕션 환경에 애플리케이션을 배포하는 것과 같이 수행해야 할 작업을 나타낼 수도 있습니다(이 이야기들이 좀 애매해 보이는데 걱정하지 말라고 다독이네요ㅋㅋ..