embedded-redis macOS 호환성 문제 해결

배경 통합 테스트에서 로컬 환경을 위한 embedded-redis 를 사용하고 있었다. 다른 사람 환경에서는 테스트가 통과하는데, 내 컴퓨터에서는 아래와 같은 에러로 테스트가 실패했다. java.lang.RuntimeException: Can't start redis server. Check logs for details. at redis.embedded.AbstractRedisInstance.awaitRedisServerReady(AbstractRedisInstance.java:61) at redis.embedded.AbstractRedisInstance.start(AbstractRedisInstance.java:39) at redis.embedded.RedisServer.start(RedisServer.java:9) 원인 macOS 14 Sonoma 에서 it.ozimov embedded-redis 0.7.3 기준으로 redis server 실행이 실패하고 있었다. https://github.com/kstyrc/embedded-redis/issues/135 macOS 14 를 지원하는 redis server 바이너리가 해당 라이브러리 내에 존재하지 않기 때문에 발생하는 이슈다. 해결 해당 라이브러리가 2020년 이후로 커밋이 끊긴 상태여서, redis server 바이너리 파일을 직접 받아서 실행하도록 수정했다....

2024-09-15 · 1 min · 191 words

Elasticsearch 시작하기

Elasticsearch 내부 동작을 이해한다. Elasticsearch에 새로운 컬럼?을 추가해본다. 구조 데이터 색인 색인(indexing): 데이터가 검색될 수 있는 구조로 변경하기 위해 원본 문서를 검색어 토큰들로 변환하여 저장하는 과정 인덱스(index): 색인을 거친 결과물, 또는 색인된 데이터가 저장되는 저장소. Elasticsearch에서 도큐먼트들의 논리적인 집합을 표현하는 단위이기도 하다. 검색(search): 인덱스에 들어있는 검색어 토큰들을 포함하고 있는 문서를 찾아과는 과정 질의(query): 사용자가 원하는 문서를 찾거나 집계 결과를 출력하기 위해 검색 시 입력하는 검색어 또는 검색 조건 Elasticsearch 환경 설정 config/jvm....

2024-09-15 · 6 min · 1166 words

EJB, Java Bean, POJO, Spring Bean

EJB(Enterprise JavaBeans): J2EE(Java EE)가 자바 웹 애플리케이션 시장을 차지하고 있을 때, 사용되었던 애플리케이션측의 컴포넌트 모델. 여기에는 Session Bean, Entity Bean, Message-driven Bean 등이 있다. 하지만 이는 객체지향적이지 못하고 특정 환경/기술에 종속적이라는 단점이 있다. Java Bean: J2EE(Java EE)에서는 데이터를 표현하기 위해서 어떤 규약을 지켜야했다. 이 규약을 Java Bean이라고 부른다. POJO: 위의 EJB의 단점을 지적하여 일반 자바 객체로 비즈니스 로직을 구현하자는 주장이 만들어졌다(마틴 파울러). 이 때 이 자바 객체를 POJO라고 부른다. Spring Bean: 컨테이너에 의해서 생명주기가 관리되는 객체로 이 때 객체를 POJO 형식을 따르고 있다....

2024-09-15 · 1 min · 83 words

EhCache 알아보기

목표 EhCache가 무엇인지 이해한다. EhCache가 다른 캐싱 기술과 어떤 차이점이 있는지 이해한다. EhCache를 사용 방법을 이해한다. EhCache란? Java 기반의 오픈 소스 캐시다. 메모리, 디스크 저장, 리스너, 캐시 로더, RESTful API, SOAP API 등을 지원한다. EhCache? Redis? EhCache, Redis 여러 형태의 캐시 기술이 존재한다. 각 기술의 특징을 비교해본다. EhCache Java에서만 사용할 수 있고, 객체를 단순 직렬화해서 저장하는 형태다. 기본적으로 로컬 환경에서 메모리에 데이터가 저장된다. Redis 미리 정의된 데이터 구조(String, List, Set 등)에 따라 데이터를 저장한다....

2024-09-15 · 2 min · 359 words

EC2 vs Lightsail

Lightsail 컴퓨팅, 스토리지, 네트워킹 및 DNS를 제공하는 VPS(가상 사설 서버)다. VPS는 하나의 물리서버를 여러 개의 가상 서버로 쪼개서 사용하는 것을 의미한다. 그래서 하나의 물리 서버를 여러명의 클라이언트와 나누어 쓰게된다. 하지만 나누어진 서버들은 독립 적인 서버 공간을 가진다. EC2와 다른 점 Lightsail 인스턴스는 실제로 t2클래스의 EC2 인스턴스다. 하지만 Lightsail은 여러 가지 기능이 간소화 되어있다. 고정된 EBS SSD 볼륨 중지되어도 청구되는 요금 유연하지 않은 보안 그룹 Lightsail을 사용해야되는 경우 단순한 인프라 구조를 가지는 경우에 유리하다....

2024-09-15 · 1 min · 99 words

DynamicSQL

목표 MyBatis의 dynamic sql 사용법을 이해한다. if 조건을 만족했을 때만 쿼리 추가 <select id="findActiveBlogWithTitleLike" resultType="Blog"> SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <if test="title != null"> AND title like #{title} </if> </select> choose, when, otherwise Java의 switch 문과 같이 조건을 만족하는 하나의 구문만 추가 모두 만족하지 않을 경우 otherwise 구문 추가 <select id="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <choose> <when test="title != null"> AND title like #{title} </when> <when test="author !...

2024-09-15 · 2 min · 399 words

Duque 사용하기

목표 kotlin에서 deque을 사용하는 방법을 알아본다. ArrayDeque kotlin에서 제공하는 배열기반의 Deque 구현체다. LinkedList와 비교했을 때 메모리 오버헤드가 적고 런타임 속도가 더 빠르다. 사용법 생성 val deque = ArrayDeque(listOf(1, 2, 3, 4)) 추가 deque.addFirst(1) // 앞 deque.addLast(5) // 뒤 제거 removeFirst, removeLast의 경우 요소가 존재하지 않으면 NoSuchElementException 예외가 발생한다. deque.removeFirst() deque.removeLast() deque.removeFirstOrNull() deque.removeLastOrNull() 참고 자료 https://www.baeldung.com/kotlin/arraydeque

2024-09-15 · 1 min · 55 words

DSR

목표 DSR(Direct Server Return)이 무엇인지 이해한다. L3DSR이 무엇인지 이해한다. DSR DSR: 로드 밸런서로부터 분산된 트래픽의 응답을 다시 로드밸런서로 보내지 않고, 클라이언트에 직접 보내는 기법. DSR을 사용하기 전의 로드밸런싱 과정 클라이언트가 로드밸런서의 VIP를 통해, 로드밸런서로 패킷이 보내진다. 로드밸런서는 트래픽 분산을 위해 서버를 하나 선택해서 패킷을 다시 전송한다. 서버는 응답을 로드밸런서로 보낸다. 로드밸런서가 클라이언트에게 응답을 보낸다. DSR을 사용한 로드밸런싱 과정 서버의 응답이 로드밸런서가 아닌 클라이언트로 직접 보낸다. 장점 일반적인 서비스에서는 요청에비해 응답의 크기가 훨씬 크다....

2024-09-15 · 2 min · 249 words

DOM Element 제거하기

remove() 메서드를 통해 쉽게 제거가 가능하다. const element = document.getElementById("demo"); element.remove(); 참고 자료 https://www.w3schools.com/jsref/met_element_remove.asp

2024-09-15 · 1 min · 14 words

Dockerfile multi-stage

목표 Dockerfile에서 multi-stage 가 무엇인지 이해한다. multi-stage 란 단일 Dockerfile에서 여러 개의 이미지를 빌드 할 수 있는 기능이다. Dockerfile에서 여러 개의 FROM 절을 사용하면 multi-stage가 된다. FROM golang:1.21 WORKDIR /src COPY <<EOF ./main.go package main import "fmt" func main() { fmt.Println("hello, world") } EOF RUN go build -o /bin/hello ./main.go FROM scratch COPY --from=0 /bin/hello /bin/hello CMD ["/bin/hello"] multi-stage 장점 빌드시 필요한 환경과 실행시 필요한 환경이 다를 수 있다. 위의 예시에서도 go를 빌드 하기위해서 FROM golang:1....

2024-09-15 · 1 min · 97 words

Docker 이해하기

지금까지 도커를 사용하여 배포 환경을 구축해왔지만 사실 도커에대한 이해가 있는 것은 아니다. 최근에 도커를 건드릴 일이 많아졌기 때문에 이 기회에 도커에대해서 학습해보고자 한다. 컨테이너 도커를 사용하면서 가장 많이 언급되는 단어가 컨테이너다. 컨테이너는 하나의 운영 체제 커널에서 다른 프로세스에 영향을 받지않고 독립적으로 실행되는 프로세스의 상태를 말한다. 독립적인 환경을 가지기 때문에 각 컨테이너마다 프로세스 ID도 격리되어 관리된다. 이 컨테이너 덕분에 우리는 배포 환경에 의존적이지 않도록 구성할 수 있다는 장점이 있다. 예전부터 유닉스나 리눅스는 하나의 운영 체제 안에서 자원을 분리해 할당하고, 실행되는 프로세스를 격리하는 방법이 존재했다....

2024-09-15 · 7 min · 1379 words

DNS 지정하기

resolver nginx config 파일에서 resolver 디렉티브를 사용하면, 사용할 DNS 서버 주소를 지정할 수 있다. 아래 예시는 로컬에 있는 DNS 서버를 사용하겠다는 의미이다. port를 지정하지 않으면 기본적으로 53번 포트를 사용하고, 2개 이상 명시하면 라운드 로빈 방식으로 사용한다. resolver 127.0.0.1 참고 자료 http://nginx.org/en/docs/http/ngx_http_core_module.html#resolver https://wooono.tistory.com/685

2024-09-15 · 1 min · 42 words

DispatcherServlet이 모든 경로의 요청을 처리하는가

결론은 아니다. web.xml 에 설정된 경로만 처리하기 한다. 하지만 일반적으로 / 로 설정하기 때문에 모든 경로를 처리하는 것이다.

2024-09-15 · 1 min · 18 words

DDD

배경 우리팀 코드가 DDD를 사용하고 있다고 설명을 들었다. DDD가 무엇인지 이해하고, 어떤 장단점이 있는지 알아본다. 용어 정리 도메인 소프트웨어로 해결하고자 하는 문제 영역 소프트웨어를 사용하는 사용자의 활동이나 관심사와 관련되어 있다. 모델 목적을 위해 현실 세계에 존재하는 것을 가공하고 편집하여 우리에게 정보를 제공한다. 특정 다이어그램이 아니라 다이어그램으로 전달하려는 아이디어와 목적을 가진 의사소통 수단이다. 이 의사소통 수단은 회의, 기획, 디자인, 개발등 여러 이해관계자가 사용한다. 도메인 모델은 특정 도메인을 개념적으로 표현한 것, 도메인 모델을 사용하려면 여러 관계자들이 동일한 모습으로 도메인을 이해하고 도메인 지식을 공유하는 데 도움이 된다....

2024-09-15 · 3 min · 429 words

data class 프로퍼티로 Array가 있는 경우 equals를 오버라이드 하는 이유

상황 data 클래스에 Array 타입의 프로퍼티가 있을 경우에 IDE에서 equals()와 hashCode()를 오버라이드 하라는 알림이 나온다. 원인 data 클래스는 equals()를 자동 생성할 때, 각 프로퍼티의 equals() 메소드를 호출하여 동등성을 비교한다. 아래 사진은 위의 SomeClass를 자바로 디컴파일 한 코드다. Instrinsics.areEqual() 코드를 살펴보면 두 객체의 equals()를 호출하는 것을 확인할 수 있다. Array 타입은 equals() 메소드가 구현되어 있지 않으므로, 오버라이드 해줘야된다. 만약 List 를 사용할 수 있는 상황이라면 Array 대신 List로 대체하는 방법도 있다. 참고 자료 https://stackoverflow....

2024-09-15 · 1 min · 73 words

Custom Directives

목표 커스텀 디렉티브를 등록하는 방법을 알아본다. 방법 커스텀 디렉티브는 컴포넌트와 유사하게 라이프사이클 훅(hook)을 포함하는 객체로 정의된다. 아래는 autofocus를 디렉티브로 구현한 예시다. const focus = { mounted: (el) => el.focus() } export default { directives: { // enables v-focus in template focus } } 컴포넌트와 마찬가지로 템플릿에서 사용할 수 있도록 등록을 해야된다. 아래는 app 수준에서 커스텀 디렉티브를 등록하는 예시다. const app = createApp({}) // make v-focus usable in all components app.directive('focus', { /* ....

2024-09-15 · 2 min · 285 words

CsvSource에서 빈 문자열 표현하기

문제 상황 아래와 같은 상황에서 param1에 빈 문자열을 넣고 싶은데, null이 인자로 넘겨져서 에러가 발생했다. @CsvSource(value = [",5"]) @ParameterizedTest fun someTest(param1: String, param2: Int) { // ... } 해결 방법 아래와 같이 작은 따옴표를 이용해서 빈 문자열을 표현할 수 있다. @CsvSource(value = ["'',5"]) @ParameterizedTest fun someTest(param1: String, param2: Int) { // ... } 참고 자료 https://github.com/junit-team/junit5/issues/1014

2024-09-15 · 1 min · 56 words

CSRF

목표 CSRF가 무엇인지 이해한다. CSRF의 대응 방법을 이해한다. CSRF란? 피해자가 의도하지 않은 기능을 수행하기 위해 악의적인 요청을 보내도록 하는 공격이다. 요청에 세션 쿠키를 포함한 모든 쿠키가 자동으로 포함되기 때문에, 서버에서는 정상적인 요청과 CSRF 공격을 구분할 수 없다. 공격 예시 일반적으로 사회공학 기법을 사용해서 요청을 보내도록 한다. 악성 페이지, 이메일 등의 html에 <img> 태그를 통해 보이지 않는 요청을 보내도록 하기 악성 페이지에 스크립트 심기 공격시에는 요청을 보낸 사이트에 인증되어 세션이 유지되고 있어야된다....

2024-09-15 · 3 min · 484 words

cron

cron 목적 미리 정해진 시간에 예약된 작업 실행을 자동화하는 도구. 백그라운드 프로세스로 실행되며 사용자의 개입 없이 특정 이벤트나 조건이 트리거될 떄 미리 정의된 시간에 지정된 작업을 수행하는 데몬 프로세스다. cron [-f] [-l] [-L loglevel] crontab cron이 실행할 작업을 나열한 파일 실행할 작업을 추가, 제거, 수정이 가능하다. crontab의 커맨드는 공백단위로 분리되며, 순서대로 나음을 의미한다. Minute (holds a value between 0-59) Hour (holds value between 0-23) Day of Month (holds value between 1-31) Month of the year (holds a value between 1-12 or Jan-Dec, the first three letters of the month’s name shall be used) Day of the week (holds a value between 0-6 or Sun-Sat, here also first three letters of the day shall be used) Command 예시 30 08 10 06 * /home/maverick/full-backup anacron 일, 주, 월 빈도로 작업을 실행할 수 있는 명령어 cron 보다 좋은 점: cron은 예약된 시간에 컴퓨터가 꺼져있으면 실행하지 않지만, anacron은 마지막 작업 시각을 확인해서 마지막 실행 시각을 비교해서 시간이 지났으면 실행한다....

2024-09-15 · 1 min · 172 words

CountDownLatch

목표 CountDownLatch가 무엇인지 이해한다. CountDonwLatch 다른 스레드가 주어진 작업을 완료할 때까지 현재 스레드를 블락하기 위해서 사용할 수 있다. counter 필드를 가지고 있고, 상황에 따라 이를 감소시킬 수 있다. counter 필드가 0이 될 때까지, 호출한 스레드에서는 블락된다. 예제 코드 테스트 코드에서는 assertThat을 호출하기 전에 5개의 Worker 가 모두 동작이 끝나기를 기다려야된다. 테스트 코드에서 CountDownLatch(5)로 선언하고, 각 Worker에서 1씩 감소시키는 방식으로 대기를 시킨다. public class Worker implements Runnable { private List<String> outputScraper; private CountDownLatch countDownLatch; public Worker(List<String> outputScraper, CountDownLatch countDownLatch) { this....

2024-09-15 · 1 min · 194 words