| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
- nodejs
- 맛집
- java8
- kibana
- jface
- effective
- JPA
- Git
- 자바스크립트
- 자바
- Web
- 인터페이스
- 엘라스틱서치
- 백준
- Spring
- node
- elasticsearch
- 스프링
- MySQL
- javascript
- 리뷰
- Spring Boot
- error
- java
- boot
- 이펙티브
- 후기
- 독후감
- 알고리즘
- RCP
- Today
- Total
목록분류 전체보기 (693)
wedul
회사에서 jpa를 사용하고 있지 않고 기존에 spring-data-jdbc를 사용하고 있었다. 그리고 대부분은 findById, findAll을 제외한 쿼리는 @Query annotaion을 붙여서 사용하고 있었다. 팀의 다른 프로젝트들이 mybatis, ibatis를 사용하고 있다보니 그대로 쿼리만 가져와서 spring data jdbc를 사용하도록만 바꾼 것 같다. mybatis가 나쁜건 아니지만 런타임시가 아니면 에러를 확인하기도 어렵고 값 매핑도 어렵다 보니 요새는 많이 선호하지 않아서 바꾼것 같은데 사실 annotaion으로 쿼리를 사용한다면 그것도 크게 다르지 않다고 본다. 그래서 입사 후 jooq나 query dsl 형태의 dsl 구조를 도입해서 컴파일 단위에서 타입 세이프한 쿼리를 사용할 ..
회사에서 사용하고 있는 서버가 파일관련 서버이다 보니 조건이 많아 호출에 대한 종류가 생각보다 많았다. 호출되는 api도 mvc server endpoint도 100개가 넘었고 내부에서 webclient로 호출하는 외부 api client도 100개가 넘었다. 어느날 새로운 api가 개발이 되고 선 배포 된 이후 실제 배포일자가 되서 호출이 되었는데 metric정보를 찾을수가 없었다. 처음에는 exporter에서 관련 tags cardinality가 높아서 정상 수집이 안되나 확인해봤지만 이슈가 없었고 각 서버에 들어가서 /actuator/prometheus를 통해 수집되는 메트릭 지표를 확인해봤는데 해당 endpoint가 없었다. 하나의 서버에서 이렇게 많은 api를 호출하는것도 호출받는것도 처음이어서..
회사에서 사용하고 있는 rpc library가 있는데 해당 rpc는 proto를 사용하는것이 아닌 java class로 만든 IDL을 사용하고 있다. https://youtu.be/iOoquUhKT5g method를 정의하고 method에 사용된 request, response 객체를 사용해서 rpc 호출을 하는 구조이다. 기존에 http로 통신하는 경우에는 spring rest docs를 사용하거나 spring swagger ui를 사용해서 api명세를 편하게 만들어서 외부 사용하는 팀에 전달 할 수 있었다. 하지만 java method기반으로 통신 프로토콜을 정의하는 방식에서는 swagger 기존 방식으로는 사용할 수 없기 때문에 이를 custom해줘야했다. 그 과정에서 문서를 만들기 위해서 cust..
virtual threadjava 21부터 virtual thread가 나온 것은 대부분의 알고 있는 사실이다. 간단하게 virtual thread는 기존 jvm에 사용하는 thread가 os kernal thread에 매핑되어 사용되던 걸 carrier thread (platform thread)에 virtual thread(향후 vt)를 사용하여 내부적 요청에 vt를 carrier thead에 mount, unmont하여 kernal os를 덜 사용하는 전략을 사용하는 thread를 말한다. 내부적으로 실행되는 로직을 확인해보자. openjdk에 있는 테스트용 VThreadRunner.java 코드를 이용해서 호출해보면서 내부적으로 VThread에서 사용되는 carrier thread 호출 sched..
lettuce를 사용해서 레디스를 사용을 하고 있었는데 어느날 갑자기 아래처럼 레디스 커넥션을 못잡는 이슈가 발생했다.org.springframework.data.redis.RedisSystemException: Redis exception; nested exception is io.lettuce.core.RedisException: Master is currently unknown: [RedisMasterReplicaNode [redisURI=redis://xxx.xxx.com?timeout=20s, role=REPLICA]] 처음에는 aws 레디스쪽 이슈일것으로 의심했으나 레디스쪽에는 별다른 지표가 없었고 애플리케이션에서 커넥션을 사용하지 못하는 것 같았다. 이번에 배포 하면서 들어간 코드는 비동기 ..
spring batch에서 job param을 전달할 때 관용적으로 -를 붙여서 사용했다. 문제가 된 시점은 프로젝트에서 중복으로 돌면 안되는 배치에 preventrestart를 붙히고 돌리고 있는데 주기적으로 already job param으로 동작한 배치가 있다면서 배치가 자꾸 죽는 이슈가 발생했다. 원인을 파악하기 위해 디버깅을 하던 중 spring batch에서 job의 unique를 판단하는 부분에서 job param으로 전달하고 있는 값들을 job instance에 유니크로 확인하는데 사용을 못하고 있는 부분을 발견했다. 그림을 보면 알겠지만 실제 parameter는 push라는 형태로 전달 되지만 identifying이 false로 되어있는걸 확인할 수 있다. 이러다보니 job instan..
beta에는 restdocs를 만들어서 static/index.html에 위치시키고 싶었고 운영에 경우에는 이로직을 빼고 싶었다.그러기 위해서는 build시점에 profile을 전달받아야했고 그것에 따라서 로직 분리가 필요했다. 그러기 위해서는 ./gradlew build 시 param으로 값을 전달하고 그 전달한 값을 사용하여 빌드 로직을 분리해야했다. 우선 build를 할 build.gradle에 argument를 받는코드와 분기로직을 작성했다.bootJar { enabled = true String activeProfile = project.findProperty('profiles') ?: '' println "zone: $activeProfile" if (activeProfi..
[기본구조] elasticserch에서 데이터는 index에 저장되고 index는 shard로 구성되어 있다. 기본적으로 데이터가 shard에 들어가는 기준은 document에 _id를 기준으로 들어가게 된다. 그렇기 때문에 index에 데이터를 조회할 때 어떤 샤드에 값이 저장되어 있는지 알수 없기 때문에 모든 shard에 값을 질의하고 그 값을 조합해서 값을 내려준다. 한번 일반적인 index를 만들고 조회해보자. 아래처럼 Index를 생성하고 "name"에 wedul을 넣고 조회해보겠다. PUT localhost:19200/before-route { "settings": { "number_of_shards": 4, "number_of_replicas": 0 }, "mappings": { "prope..
elasticsearch에서는 들어온 요청에 대해서 primary shard, replica shard를 병렬로 요청을하기 때문에 replica가 있는게 좋긴하다. 하지만 replica shard나 primary shard가 제대로 노드에 분배되어 있지 않으면 조회가 특정노드에 몰리거나 인덱싱 시 노드에 부하가 심해질 수 있다. 분배를 위해서는 기본적으로 es cluster에 아래 옵션들이 제공된다. (링크) cluster.routing.allocation.balance.shard - 노드에 샤드를 균등하게 분배 (기본값 0.45f, 값이 높아질수록 노드들에 샤드들이 골고루 분배됨) cluster.routing.allocation.balance.index - 인덱스당 샤드 분배를 균등하게 (기본값은 0...
elasticsearch cluster를 사용하기 위해서 cluster를 구성하기전에 꼭 추가해야하는 부분이 있는데 기본으로 생성되는 index에 대한 disable처리가 필요하다. geoip_databases 인덱스 기본적으로 cluster 구성 시 geoip_databases가 인덱스가 추가가 되어있는데 이게 hidden index여서 모르고 지나칠 수 있다. 만약 모르고 클러스터를 구성하고 노드를 조작할 경우 해당 인덱스의 primary shard가 unassigned되면서 cluster 상태가 red가 될 수 있다. 그럼 왜 geoip_databases가 기본적으로 생기는가? 생기지 않도록 할 수 없는가? 해당 인덱스가 생성되는 이유는 ingest.geoip.downloader.enabled 속성..