전체 글
레디스 코드 변경과 함께 일어났던 인프라 문제 회고
프로덕션 환경 및 주요 라이브러리 윈도우즈 서버 MSSQL Spring Framework 4.3.30.RELEASE Maven 리포지토리 Java 1.8 Redis 5.0.7 Elastic Search 7.17 Spring Session Data Redis 1.3.1.RELEASE Lettuce 6.1.4.RELEASE Mybatis 환경만 봐도 꽤 레거시 서비스이다. 히스토리와 개선 필요성 SI 업체에 의해 서비스가 만들어짐 서비스 자체가 3년이 안됐는데 스프링 4버전을 채택하는 등 기술 선택에 대한 미스가 많았다. '오래된 기술은 나쁘다.' 라는 단순한 이유가 아니라 기술 선택에 대한 이유 없이 그냥 쓴 것이 잘못이라고 생각한다. 초기엔 이용량이 적었기 때문에 인덱싱이나 쿼리 속도에 대..
중재자 패턴 (Mediator Pattern) 이란?
중재자 패턴 (Mediator Pattern) 이란? 여러 객체 간의 의사소통하는 방법을 추상화한다. 객체간의 혼란스러운 종속성을 줄일 수 있는 디자인 패턴이다. 객체간 직접적인 통신을 제한하고 중개자 객체(Mediator Object)를 통해서만 협업하도록 한다. 실생활 예제 아파트의 관리사무소는 주민들간의 갈등을 중간에서 해결해준다. 비행기 이착륙을 돕는 관제탑 다이어그램으로 살펴보기 아래의 형태만 중재자 패턴인 게 아니라, 아래의 형태가 대표적인 중재자 패턴인 것이다. 즉, 다른 다이어그램으로 그려져도 중재자 패턴을 사용한 것일 수 있다. 여러 컴포넌트간 결합도를 중재자를 통해 낮춘다. Colleague 가 Colleague 를 직접 참조하는 선이 없다는 것이 중요하다. Mediator 를 참조하고..
이터레이터 패턴 (Iterator Pattern) 이란?
이터레이터 패턴 (Iterator Pattern) 이란? 컬렉션의 요소를 순회하는 패턴이다. 내부의 표현을 노출시키지 않는다. List, Stack, Tree, Set 과 같이 어떠한 컬렉션인지 노출시키지 않는다. 내부 표현을 노출시키면 컬렉션의 종류가 바뀔 때마다 클라이언트 코드를 변경해주어야 하는 불편함이 생긴다. 다이어그램으로 살펴보기 예시: 게시판 게시글 순회 Before: 인덱스를 직접 이용해 순회하기 전통적인 배열 및 컬렉션 순회 방법이다. 단, 컬렉션의 종류가 바뀌게 되면 클라이언트 코드를 수정해주어야 한다는 단점이 있다. public class Client { public static void main(String[] args) { Board board = new Board(); board..
인터프리터 패턴 (Interpreter Pattern) 이란?
인터프리터 패턴 (Interpreter Pattern) 이란? 인터프리터의 의미 자체는 보통 해석해주거나 통역해주는 역할을 가진 사람 혹은 물건이다. 악보를 음악으로 변환하는 것도 이러한 역할의 하나이기 때문에 연주자라는 의미도 있다. 가장 쉽게 볼 수 있는 예로는 정규표현식이 있다. 자주 등장하는 문제를 별개의 언어로 정의하고 재사용하는 패턴이다. 문법에 등장하는 규칙을 클래스로 표현하고 언어에서의 표현식을 해석하고 평가한다. Expression 이라는 추상 클래스를 만드는 경우가 많다. Expression 클래스에서 파생된 구체적인 클래스는 언어의 다양한 규칙 또는 요소를 나타낸다. 반복되는 문제 패턴을 언어 또는 문법으로 정의하고 확장할 수 있다. 다이어그램으로 살펴보기 컴포짓 패턴과 굉장히 유사하..
회사에서 있었던 레디스 코드 대형 리팩토링 회고
초기의 상황 설명 회사에 Redis 를 이용하는 코드가 있었다. 환경은 자바, 스프링 프레임워크 (4.3.30), Lettuce 를 사용했다. 레디스 이용시 CPU 나 메모리가 팍팍 튀는 현상이 생겼다. 레디스의 코드를 살펴보니 커넥션 풀을 직접 관리하고 있었고, 클라이언트 코드도 정제가 잘 안되어있어 코드의 의도도 알아보기 힘들었다. 리팩토링을 결심했다. 기존 레디스 코드 살펴보기 레디스 유틸 // 레디스 유틸 함수쪽 내용 public void nonClusterAppend(String key, String value) throws Exception { RedisClient client = RedisClient.create(getRedisUri()); client.setOptions(ClientOpti..
커맨드 패턴 (Command Pattern) 이란?
커맨드 패턴 (Command Pattern) 요청을 호출하는 쪽과 요청을 수행하는 쪽을 분리하는 (Decoupling) 패턴이다. 요청을 요청에 대한 모든 정보를 포함하는 독립형 객체 (stand-alone object) 로 변환하는 동작 디자인 패턴이다. 요청을 메서드 인수로 제공하거나 요청 실행을 지연하거나 대기열에 추가하거나 실행 취소 가능한 작업을 지원할 수 있다. 다이어그램으로 살펴보기 호출자, 명령, 수신자가 각각 나누어져 있다. 이 때문에 요청을 처리하는 방법이 바뀌더라도 호출자의 코드는 바뀌지 않는다. 커맨드 자체는 재사용도 가능하다. 로깅 혹은 실행취소 등 문제: 텍스트 에디터 앱의 예시 텍스트 에디터 상단 툴바에는 다양한 버튼들이 존재한다. 버튼들은 모두 다른 기능을 하지만 비슷하게 생..
책임 연쇄 패턴 (Chain Of Responsibility) 이란?
책임 연쇄 패턴 (Chain of Responsibility) 각각의 책임이 연결된 패턴이다. 단일 책임 원칙에서 말하는 그 책임과 비슷하다. ex) 어떤 클래스가 변경되어야 한다면 그 이유는 단 한가지 (단일 책임) 여야만 한다. 요청을 보내는 쪽과 요청을 처리하는 쪽 (핸들러) 을 분리하는 패턴이다. 일련의 핸들러를 따라 요청을 전달하는 패턴이다. 핸들러는 요청을 받으면 자신이 처리할지 다음 핸들러로 넘길지 결정한다. 일련의 핸들러를 가지고 있지만 실제요청이 들어오기 전까지는 어떤 핸들러를 써야할지 모를 때 유용하다. 적절한 핸들러를 찾거나 체인이 모두 소진될 때까지 체인을 따라 요청이 전달된다. 다이어그램으로 살펴보기 클라이언트는 핸들러 체인에 요청을 보내 처리를 요청한다. 클라이언트는 자신이 어떤..
스프링 RedisTemplate 이란?
RedisTemplate 이란? Spring Data Redis 에서 쓰는 핵심 클래스이다. Redis 내부에 있는 데이터 액세스를 도와주는 헬퍼 클래스이다. 클라이언트에서 작성해야 하는 레디스 공통로직을 제공해 레디스 이용을 편리하게 할 수 있도록 도와준다. 역할 커넥션 관리 (Connection management) 레디스 서버와 연결 시에 커넥션 풀과 리소스를 대신 관리해준다. 이로 인해 개발자는 직접 커넥션을 열거나 닫을 필요가 없어진다. 직렬화와 역직렬화 지원 (Serialize and Deserialize) 자바 Serializer 를 통해 Redis 스토리지와 데이터를 직렬화/역직렬화한다. 다른 여러 직렬화 기법도 제공하는데 문자열만 사용한다면 StringRedisTemplate 을 사용하는..
프록시 패턴 (Proxy Pattern) 이란?
프록시 패턴이란? 사전적 의미로 대리 혹은 대리인과 같은 의미가 있다. 사용자가 접근하고 싶은 오브젝트에 접근하기 전에 프록시 오브젝트라 불리는 오브젝트에 접근을 먼저 하도록 강제하는 것이다. 오브젝트 접근 요청 시 해당 요청은 먼저 프록시 오브젝트에게 간다. 실생활에 비유하자면 연예인을 섭외하기 위해서 연예인에게 직접 전화를 거는 것이 아니라 매니저에게 전화를 걸어 섭외하는 것이다. 다이어그램으로 보기 Proxy 는 데코레이터 패턴처럼 필드 내부에서 RealSubject 를 참조하고 있다. 활용 예제: 메서드의 소요시간 측정과 게으른 초기화 (Lazy initialization) 가정 자동차를 만드는 메서드가 있다. 자동차를 만드는데 걸리는 시간은 그때그때 다르다. 평균적으로 1초 ~ 1.5초가 걸린다..
인텔리제이 톰캣 로그 실종 및 스프링 세션 springSessionRepositoryFilter(DelegatingFilterProxy 타입) 빈을 찾지 못하는 에러에 대한 회고
톰캣 로그 실종 web.xml 에서 필터를 하나 수정했다. DelegatingFilterProxy 타입의 springSessionRepositoryFilter 빈을 주석해제하여 이용하고 싶었다. 정상적으로 동작할 것 같았는데, 톰캣 초기화 과정에서 오류가 발생하고 정상적으로 톰캣이 실행되지 않았다. 설상가상으로 오류는 콘솔 창에 로그로 표기되지도 않았다. 로그 18-Apr-2023 10:29:12.540 SEVERE [RMI TCP Connection(2)-127.0.0.1] org.apache.catalina.core.StandardContext.startInternal One or more Filters failed to start. Full details will be found in the app..
클린 코드(Clean Code) 란? 클린 코드의 간단한 정의
리팩토링과 클린코드 리팩토링의 주요 목적은 기술 부채와 싸우는 것이다. 복잡한 코드를 클린 코드와 단순한 디자인으로 바꿔준다. 클린 코드란? 다른 프로그래머들에게 분명히 전달되는 코드이다. 잘못 지은 변수명, 비대해진 클래스와 메서드, 매직넘버 등은 코드를 엉성하고 이해하기 어렵게 만든다. 중복을 포함하지 않는다. 중복된 코드를 업데이트할 때 우리는 모든 인스턴스에 동일한 변화를 주어야 한다는 점을 기억해야 한다. 이러한 이유 때문에 인지적인 부하가 늘어나고 진행속도가 느려진다. 최소한의 클래스와 최소한의 변화사항이 생기는 부분만을 포함한다. 코드가 적을수록 머리속에 많은 정보를 넣을 필요가 없다. 코드가 적을수록 유지보수에 필요한 힘이 적다. 더 적은 코드는 더 적은 버그를 만든다. 코드는 책임이므로 ..
잘못된 도파민 보상 체계를 만들었던 경험 회고
회고하게 된 이유 요즘 너무 보상만을 바라고 행동하는 경향이 잦아짐과 동시에 행동 자체에 대한 재미가 조금 사라지는 현상이 있었다. 이 현상이 보기보다 더 큰 문제인 이유는 내가 이 방식이 맞다고 생각하는 그릇된 생각을 가졌기 때문에 이번 기회에 인지하지 못했으면 계속 잘못된 생각을 가지고 무언가 노력하다가 결국 나가떨어졌을 것 같기 때문에 엄청 큰 문제이다. 난 이 현상의 문제 자체를 전혀 인지하지 못하고 있었다. 왜인지 모르게 내 자신에 대한 집중도가 낮아졌던 것 같다. 보상만을 생각하지 말고 원래 과정도 즐겼듯이 과정에서도 항상 즐거운 마음을 잃지 말도록 하자. 이 노력은 나에게 좋은 노력이라는 것을 계속 되새겨야 한다. 도파민 분비 방식을 잘 이해하자. 원본 영상 https://www.youtub..