%ED%8C%81

2024-09-22
하나의 로그스태시 파이프라인에서 서로 다른 데이터를 수집, 서로 다른 인덱스에 저장하는 구성에 대한 질문을 받았다. 방법은 input 구간에서 출처별로 수집 플러그인을 분리한 후, output 구간에서 조건에 따라 저장명을 달리하는 것. 데이터 전처리를 잘 하면 분석이 쉬워진다가 강의 주제인지라 filter 구간 활용에 집중한다. 자연스럽게 input이나 output 멀티 구성에 대한 필요성을 느낀 적이 없음. 개인의 경험은 한계가 있다. 그래서 타인의 경험이 공유될 때 강의가 재밌어진다. 당연히 질문에 대한 답을 처음부터 알지 못했다. 하지만 답을 찾는 게 어렵진 않았다. 모르면 물어보면 되니까....
2022-12-26
이번 포스팅도 어떤 백엔드 서비스의 코드를 리팩터링한 내용을 정리하는 것으로, 이번에는 코드 복잡도 줄인 리팩터링에 대한 내용을 정리한다. 이전에 포스팅했던 ' 가변 Context 클래스는 신중하게 사용하자 '와 ' 고차 함수로 의존성 줄이기 '로 코드의 의존성 문제들이 많이 정리된 상태라서 복잡도 줄이기를 진행할 수 있었다. 아래는 어떤 백엔드 서비스 코드의 리팩터링 전과 후의 코드 복잡도 Cyclomatic Complexity와 NPath Complexity의 수치 변화다. 많이 줄어든 것을 볼 수 있다....
2022-11-02
배경 티스토리를 사용한 지 10년이 넘다 보니 글도 제법 쌓였고, 백업도 한번 받고 싶은데, 백업 기능이 없다. (없었다.) 백업 기능을 만들어 달라고 문의도 해봤는데, 안 만들어준다. 구글링을 해보니 티스토리 백업 유틸리티가 제법 많이 나오기는 하는 데 사용하기가 조금 애매하던 차에 이번에 고등학교 로봇동아리 학생들을 대상으로 '개발자에 대한 궁금증'에 대한 강연을 할 일이 생겼는데, 길지 않은 코드로 동작하고 실제 용도가 있는 예제로 보여줄 겸 해서 티스토리가 제공하는 Open API로 간단히 구현해보기로 했다. 다 만들고 보니 백업 기능이 생겼네...? 티스토리 관리 메뉴에 '블로그 백업'이 생겼다. 사용해보니 압축 파일로 잘 백업해준다. 다만, 어떤 게시글은 파일명이 게시물 제목으로 잘 되어 있고, 어떤 게시글은 게시글 번호로 되어 있다....
2022-09-22
스프링을 사용한 프로젝트에서 종종 보이는 어노테이션에 사용한 의존성 주입의 남용과 오랜 세월의 흐름으로 의도치 않게 서비스 간의 의존성 그래프가 복잡하게 강결합으로 묶이면서 코드를 읽기도 어렵고 단위 테스트를 구성하기도 어려운 상황이 생긴다. 아래는 어떤 백엔드 서비스의 의존성 그래프다. 순환 종속성이 포함된 복잡한 왼쪽의 의존성 그래프를 오른쪽의 단순한 의존성 그래프로 리팩터링하여 라이브 서비스에 반영하였다. 이번 글은 오랜 세월의 흐름으로 서비스 의존성 그래프가 복잡해진 라이브 서비스를 리팩터링한 내용을 일반화하여 작은 예제로 만들어서 정리한다....
2022-08-18
배경 최근에 읽은 ‘ 구글 엔지니어는 이렇게 일한다. ’에서 컴파일러 버전업에 대한 이야기가 나와서 예전에 작업했던 GCC 컴파일러 버전업에 대한 내용을 정리해본다. 몇 년 전 새로운 팀에 합류했을 때 서비스 중인 서버군들 중에서 C++ 구현된 서버군이 gcc 4.4.7을 사용하고 있었고, 컴파일러 버전이 낮아서 모던 C++의 시작인 C++ 11를 사용할 수 없었다. GCC 4.4.7은 C++ 0x까지 지원한다. C++ 11을 사용하려면 최소한 GCC 4.7 이상이 필요하다. 버전업 타깃은 CentOS 7 Base repo에 있는 GCC 4.8.5 버전으로 맞추고 진행했었다. 작업 당시 오랜 세월의 흔적으로 개발, 배포, 서비스 환경 등 각각 OS 버전이 달랐다. OS 버전이 다르다는 것은 OS가 기본적으로 가지고 있는 C 표준 라이브러리...
2022-04-18
요즘 라이브 서비스의 레거시 코드 리팩터링을 하고 있다. 흔히 가변 상태를 관리하는 Context 클래스가 레거시 코드에 있는 건 새삼스럽지 않았지만, 과도하게 사용하고 있어서 정리가 필요했다. 가변 상태 Context 사용 시 문제점 가변 상태를 가지는 Context 클래스가 2, 3개도 도 아니고 10개쯤 되면 과하다고 생각한다. 이렇게 많은 Context 클래스들이 서로 물고 물리는 종속성을 가지고 각기 다른 클래스에 넘기고, 넘겨받고, 가변 Context의 레퍼런스가 다양한 함수들로 넘겨져 전역 변수처럼 여기저기서 사용되면서 어딘가에서 A가 set을 하고 다른 곳에서는 B가 get을 하는 상황은 코드를 매우 읽기 어렵게 만들었다. 읽기 어렵다는 것은 Context를 수정할 때, 사용처를 모두 추적하는 것이 어렵고, 문제 발생 시 디버깅 역시 어렵다는 것이다.   다른 것보다 이걸 먼저 해결하기로 했다. 이 Context 클래스를 정리하는 리팩터링을 점진적으로 진행하여 총 10개에서 6개를 삭제하고 2개는 사이즈를 많이 줄였다. 프로덕션 코드에서 총 568라인을 삭제했다. 당연히 기능에 변화는 없다. Context를 정리하는 리팩터링이 일단락되어 ...
2021-12-13
자바 객체를 영속화하는 방법의 하나로 자바 직렬화를 사용할 수 있다. 단순하게는 Serializable 인터페이스를 구현하거나 더 확장성 있는 방법으로는 Externalizable 인터페이스를 구현하는 것을 선택할 수 있고, 자바 직렬화에 종속되지 않는 다른 방법을 선택할 수도 있다. 일단, Serializable 인터페이스를 구현한 클래스의 인스턴스가 외부 저장소에 영속화되면 호환성을 유지하면서 해당 클래스의 필드를 수정하기는 어렵다. ( https://docs.oracle.com/en/java/javase/11/docs/specs/serialization/version.html...
2020-05-07
이전 포스팅 에서 이어지는 내용이다. 전체 프로젝트는 여기 에서 받을 수 있다. 이번에는 리모트 디버그에 대해서 정리할 것이다. 공식 문서 에도 소개가 잘 되어 있지만, 이 문서도 보고 바로 따라하기에는 좀 어렵다. 여기서 정리할 내용이다. Docker Compose 설정 GDB 설정 Remote Debug via GDB/gdbserver Use Remote GDB Server Use GDB Remote Debug GDB Server로 Target Process를 실행 Target Process를 실행 후에 GDB Server를 해당 PID로 Attach Dockerfile, docker-compose.yml 그리고 CMake의 build type, compile debug option, release option과 같은 세부 사항이나 GDB Server의 옵션 등과 기타 디버그 설정 등도 여기서 모두 설명하면 너무 길어지므로 생략하고, 리모트 디버그 연동만 정리하겠다. 이전 포스팅에서 Debugger 설정을 다음과 같은 상태로 두고 넘어갔었다....
2020-04-26
0과 1로 구분된 데이터가 있다. 그런데 이상하게 구분값 1은 0, 0은 1로 바꾸고 싶네? 치환 명령어 ' %s/1$/0/ '와 ' %s/0$/1/ '를 순서대로 실행하면 1 -> 0, 0 -> 1로 바뀔까? 첫 번째 작업에서 1이 사라지고 0만 남기 때문에, 결과적으로 마지막엔 1만 남는다. 이럴 때 흔히 쓰이는 꼼수 ① 0 -> 1 치환 시 중복을 막기 위해 1 -> 11로 잠시 피신. ② 0 -> 1 치환 ③ 11 -> 0 치환 이게 귀찮다면? 구글신께 물어봤다. 오~ 조건 치환이 가능하단다. Conditional replace in vim ① 정규표현식 '...
2020-04-23
자바로 개발된 프로젝트를 유지 보수하다 보면 Object Serialization, Deserialization이 사용된 코드를 흔하게 볼 수 있다. 간단하게 Serializable 인터페이스를 구현했거나 Externalizable 인터페이스를 구현해서 JSON 등의 다른 포맷으로 영속화를 시켰는지는 여기서 중요하지 않다. serialVersionUID를 명시적으로 정의하지 않고 생략했다면, 모두 동일한 문제를 가지고 있다.   문제는 아래와 같은 상황에서 발생한다. A 객체를 직렬화하여 Redis나 DB 등 외부에 저장하고, 저장된 값을 A 객체로 역직렬화하여 사용하고 있다....
더보기