본문 바로가기

SearchDeveloper

(81)
[후기] 도메인 주도 개발 시작하기 느낀 점 ① 도메인 주도적으로 개발을 하지 않아도 기능 구현은 할 수 있다. 하지만 도메인 주도 개발을 하는 궁극적인 이유는 코드 리팩토링을 하는 이유와 같다고 생각한다. DDD를 한다는 것은 - 애그리거트라는 이름으로 같은 역할을 하는 클래스끼리 군집화하는 것 - 금액을 표현하는 필드를 int 가 아닌 Money 클래스로 표현하는 것 - 도메인 로직은 응용 계층이 아닌 도메인 계층에 모아 응집도가 높이는 것 ... 등등 같은 원칙을 지켜가면서 개발을 하는 것인데 이는 코드를 이해하는 것이 보다 쉬워지고, OCP 원칙을 지킬 수 있기 때문이다. 그래서 새로 생성하는 프로젝트 뿐만이 아니라 기존 프로젝트에서 조금씩 조금씩 도메인 주도 개발화를 해보는 것도 괜찮을 것 같다. ② 애플리케이션을 역할에 따라 4..
Kafka-ui 설치하기 (Docker 말고) 환경 kafka: version 3.3.1, kraft 모드 kafka-ui: kafka-ui-api-v0.4.0.jar (도커 아니고 로컬에 설치) Java 13 버전 필요 kafka-ui 를 도커로 띄우려고 했으나 Caused by: [org.apache.kafka.common.errors.TimeoutException](http://org.apache.kafka.common.errors.timeoutexception/): Timed out waiting for a node assignment. Call: fetchMetadata 에러나서 jar로 띄움 설치 1. kafka-ui jar 다운 받기 2. java 13 설치하기 구성 application.yml kafka: clusters: - name..
[JPA] QueryDSL stream DB connection 에러 해결 과정 ② - @Transactional 버전 Spring Boot 2.7.4 QueryDSL 5.0.0 MySQL 5.7 이전 글 https://elsboo.tistory.com/40 [JPA] QueryDSL stream DB connection 에러 해결 과정 ① 버전 Spring Boot 2.7.4 QueryDSL 5.0.0 MySQL 5.7 DB 데이터를 가공해 카프카로 전송하는 애플리케이션을 만들면서 약 1주간 많은 난관에 봉착했고 많은 삽질을 했다. 어떤 에러가 있었고 어떻게 해결하였는 elsboo.tistory.com ② stream 데이터 사용 좀 해보려는데 forEach() 에서 Operation not allowed after ResultSet closed 에러… 결론 @Transactional 가 붙은 메소드는 메소드 종료..
[Docker] <none> image야 잘 가~! 도커에서 컨테이너 생성하는데 자꾸 에러가 나서 Dockerfile을 고치고 이미지 다시 생성하고 컨테이너 생성해보고 반복 삽질 중인 평화로운 나날이었다. 그런데 어느 순간 sudo docker images 를 쳐보니.. 누가 생성했는지도 모르는 : 이미지들이 증식되어있었다. 결론부터 말하자면 sudo docker rmi $(sudo docker images -f "dangling=true" -q) --force 필요없는 이미지이니 지워주면 된다. image가 뭔데요? : 이미지는 어떤 코드에서든 더 이상 참조되지 않는 이미지이다. docker build를 하거나 이미지를 pull했을 때 생겨난다. 현재 도커 이미지의 상황을 보면 IMAGE ID가 7184b27319b4 이고 이름이 test:0.1 인 이..
[JPA] QueryDSL stream DB connection 에러 해결 과정 ① 버전 Spring Boot 2.7.4 QueryDSL 5.0.0 MySQL 5.7 DB 데이터를 가공해 카프카로 전송하는 애플리케이션을 만들면서 약 1주간 많은 난관에 봉착했고 많은 삽질을 했다. 어떤 에러가 있었고 어떻게 해결하였는지에 대해 공유하고자 한다. ① stream() 으로 레코드 한 건씩 가져오는 건 줄 알았는데 왜 타임아웃이 나지!? 결론 .fetch().stream() 는 Java의 스트림, .stream() 은 DB의 스트리밍 방식이다! 에러 현상 쿼리 호출 대상인 tableA 테이블은 몇 십 만건의 데이터를 가지고 있다. 그래서 데이터를 한꺼번에 들고 오면 타임아웃이 나거나 메모리가 터질 수 있으므로 스트리밍 방식을 적용해 한 건씩 처리하기 위해 다음과 같이 구현을 하였다. publi..
편집 거리 알고리즘 이해하기 편집 거리 (Edit Distance) 에 대해 단어 “둥굴랭”과 단어 “둥굴레차” 가 오타와 정타 관계 구나 라는 것을 ‘사람’이라면 직관적으로 인지할 수 있다. 하지만 ‘컴퓨터’는 어떻게 판단할 수 있을까? 이렇게 두 문자열 사이의 유사도를 수치화할 수 있는 방법 중의 하나로 편집거리 알고리즘을 사용한다. 편집 거리는 문자열 A 가 문자열 B와 동일하게 되기 위한 최소 변경(삽입, 삭제, 대체) 횟수를 말한다. 예를 들어 [둥굴랭] 와 [둥굴레차] 의 편집 거리를 구해보자. [둥굴랭] 이 [둥굴레차] 가 되기 위해서는 ‘랭’을 ‘레’로 대체 ‘차’ 는 삭제 하면 [둥굴레차] 가 되므로 이 둘의 편집 거리는 2이다. ※ 편집 거리 알고리즘을 수학자 Vladimir Levenshtein 이 고안했다고 해..
텔레그램 봇으로 메시지 전송 API 호출하기 배치 프로그램이나 실시간으로 운영중인 시스템에 문제가 생겼을 때 바로 알아차릴 수 있도록 텔레그램으로 관제 메시지를 전송할 수 있다. 1. 봇 생성하기 봇은 BotFather 라는 채널에서 생성할 수 있다. 검색창에서 BotFather 를 검색한 후 채널에 들어간다. /newbot 를 보내면 봇 생성을 위한 몇 가지를 물어본다. 봇 이름 정하기 봇 username 정하기 ’bot’으로 끝나야한다. 봇 토큰 얻기 ▶ 봇 토큰: 5650XXX 자 이제 봇의 토큰을 얻었다. elsboo_bot은 이 토큰을 통해 메시지를 송신할 수 있다. 2. 채널 생성 후 봇 추가하기 봇이 활동할 채널(=채팅방)을 생성하고 봇을 관리자로 추가한다. 채널 생성 햄버거 메뉴 > New Channel 클릭 채널명 입력 채널 공개/..
[트러블슈팅] Too many dynamic script compilations within, max: [75/5m] 현상 새롭게 만든 엘라스틱서치 검색 API 를 개발, 스테이지 환경에서 테스트를 마치고 긴장되는 마음으로 운영에 배포를 했는데... 이럴수가 엄청난 에러들이 뚜두두두 쏟아지는게 아닌가 org.elasticsearch.transport.RemoteTransportException: [indices:data/read/search[phase/query]]Caused by: org.elasticsearch.script.GeneralScriptException: Failed to compile inline script [if(doc['name.keyword'].value.toLowerCase().contains('디스프')) return 1; return 0;] using lang [painless] ...Cau..
[JPA] Multi Datasource 설정하기 Spring Data Jpa 에서 한 개의 DB만 사용한다면 application.yml 만 설정해도 auto configuration 을 통해 자동으로 DB 커넥션이 생성된다. 하지만 한 프로젝트에 접근할 DB가 2개 이상이라면? 혹은 다른 DB 서버도 접근해야한다면? 귀찮지만 Configuration 클래스를 생성 해줘야한다. ※ 참고 single datasource 일때 application.yml 설정을 참고하면 좋을 듯하다. application.yml spring: datasource: url: jdbc:h2:tcp://localhost/~/member username: sa password: hikari: idle-timeout: 0 maximum-pool-size: 1 jpa: databa..
[JPA] Querydsl 시작하기 Querydsl 이란? JPQL 생성을 도와주는 라이브러리이다. Querydsl 메소드를 사용해 작성한 쿼리는 JPQL 로 변환되어 SQL 쿼리가 실행된다. 사용하는 이유 쿼리 메소드는 메소드명만으로 하이버네이트가 SQL로 변환해주기 때문에 간단하게 사용할 때는 너무나 강력하다. 하지만 join 을 쓰거나 쿼리가 복잡해지면 JPQL 로도 결국 SQL 쿼리 짜듯이 문자열로 작성하는 수 밖에 없다. 하지만 Querydsl 를 사용하면 여전히 메소드를 활용해 쿼리를 생성하는 것이 가능하다. @Query 애노테이션으로 JPQL을 짜면 syntax error를 애플리케이션 실행을 해봐야 알 수 있다. 하지만 Querydsl를 사용하면 메소드와 변수로 쿼리를 만들기 때문에 애초에 syntax error 나기가 힘들..