DMS-SMS / v1-health-check

시스템 및 각종 서비스의 상태를 주기적으로 확인하여 기록하고, 원할한 운영을 위한 최적의 상태를 유지해주는 plug-in 개념의 시스템

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SMS-Health-Check

대덕소프트웨어마이스터고등학교 SMS(학교 지원 시스템) 서버 Health Check 서비스



INDEX

1. SMS Health Check란?

2. Health Check 종류

3. Clean한 코드에 대해

4. 패키지 종류 및 구조

5. 패키지 의존성 그래프



SMS Health Check란?

  • SMS(School Management System)는 대덕소프트웨어마이스터고등학교 전공 동아리 DMS에서 개발하여 현재 운영하고 있는 학교 지원 시스템입니다.

  • SMS Health Check는 SMS 서버를 운영중인 환경과 서버를 구성중인 여러 서비스들의 상태를 주기적으로 관리하는 플러그인 식의 서비스입니다.

  • 특정 서비스의 상태 확인 결과가 특정 기준을 통해 정상적이지 않다고 판단이 되면 해당 서비스의 상태 회복을 위한 작업을 수행합니다.



Health Check 종류

모든 Health Check는 수행 결과를 Elasticsearch에 저장하여 관리합니다.

1. System Check

  • disk check
    • 디스크 사용 용량 특정 수치 초과 시 알람 발행 후 Docker Prune 실행
    • 디스크 사용의 주요 원인에는 로그 및 DB 데이터 또한 존재하지만, 해당 데이터를 건드는건 위험하다 판단하여 Docker Prune만 실행
  • memory check
    • 총 메모리 사용량 특정 수치 초과 시 알람 발행 후 메모리 과다 사용 프로세스 재부팅
    • 프로세스 메모리 사용 조회 및 재부팅은 Docker Engine API를 통해 수행
    • 참고로, 서버 구성에 있어서 부재가 발생하면 안되는 서비스들은 재부팅하지 않음

2. Service Check

  • elasticsearch check
    • Elasticsearch Shard 갯수 특정 수치 초과 시 알람 발행 후 Jaeger Index 삭제
    • Jaeger에서 매일 새로운 Index를 생성하여 데이터를 저장하기에 주기적으로 관리 필요
    • 예전에 생성된 Index부터 삭제를 진행하며, 최근 한 달 내에 생성된 Index는 삭제되지 않음
  • swarmpit check
    • Swarmpit App 컨테이너 메모리 사용량 특정 기준 초과 시 알람 발행 후 해당 서비스 재부팅
    • Swarmpit App의 경우, 메모리 사용량이 지속적으로 증가하기 때문에 특정 수치에 도달할 때 마다 재부팅이 필요함
  • consul check
    • Consul에 작동되지 않는 노드가 등록되었다면 알람 발행 후 해당 노드 등록 해제
    • 또한, MSA 상의 서비스별로 등록된 노드가 존재하지 않는 경우 알람 발행 후 해당 서비스 재부팅
    • 작동되지 않는 노드인지는 해당 노드와 gRPC 연결 시도를 통해 판별
    • 노드 부재시에는, 서비스 재부팅을 함으로써 재시작 시점에 스스로 노드를 등록하게 함


Clean한 코드에 대해

Clean한 코드의 기준은 무엇일까요? 제가 생각하는 기준은 다음과 같습니다.

1. 의존적인 관계에서 서로의 계층을 명확하게 분리하였고, 그 관계가 느슨하게 결합되었는가?

-> 모든 의존 관계 추상화 완료시, mocking을 이용한 business logic 단위 테스트 가능

  • 기능에 따라 계층을 분리하고, 분리된 계층별로 패키지를 생성하여 해당 패키지에 구현
  • 직접적인 타입의 명시가 아닌 인터페이스 추상화를 통해 느슨한 상하위 계층 간의 의존 관계 형성
  • 상위 계층에서, 하위 계층의 처리 방식을 모른채로 데이터 처리의 책임을 빌려주는 구조
  • 따라서 계층끼리의 의존성을 편리하게 관리하기 위해서 모든 의존성 주입main에서 발생

2. 하위 계층과의 의존 관계를 표현하는 추상화(인터페이스)를 상위 계층이 소유하고 있는가?

-> DIP 패턴 적용 완료시, domain을 제외한 모든 패키지의 임포트가 main 패키지에서만 발생

  • 만약 인터페이스를 하위 계층이 소유하고 있다면, 여전히 하위 계층에 명시적으로 결합된 상태
  • 따라서 인터페이스 소유권을 사용하는 계층으로 옮김으로써, 하위 계층과의 명시적인 결합을 완전히 끊을 수 있다.
  • SOLID 중 DIP(의존성 역전) 원칙으로, 사용할 메서드들만 추상화하여 의존성을 생성할 수 있다는 장점 또한 존재한다.
  • 예외) domain model 관련 패키지(repo, use case)들에 대한 추상화는 domain 패키지에 묶어서 관리


패키지 종류 및 구조

프로젝트를 구성하는 패키지들을 크게 세 가지 종류로 나누어 설명합니다.

1. App

프로세스를 시작하고, main문에서 사용하는 설정 값들을 관리하기 위한 패키지입니다.

  • app
    • main function을 가지고 있는 main package로, Health Check를 실행시키는 시작점
    • 모든 의존성 객체 생성 및 주입이 여기서 일어나며, domain 패키지를 제외한 다른 패키지를 명시적으로 import하는 유일한 패키지
  • app/config
    • app(main) 패키지에서 사용하는 config value들을 관리하고 반환하는 패키지
    • 싱글톤 패턴으로 구현되어 있으며, environment variable 또는 fixed value 반환
    • 특정 인터페이스의 구현체가 아니라, 단순히 app 패키지에서 명시적으로 불러와서 사용하는 객체이다.

2. Domain

기능을 기준으로 domain을 분리하고, 그에 따라 model을 정의하고 추상화를 진행하는 패키지입니다.

  • domain
    • 특정 domain에서 사용할 model 정의와 그와 연관된 계층들(repo, use case)을 추상화하는 것이 필요
    • 따라서 이와 관련된 것을 해당 패키지에서 묶어서 관리하며, 추상화에 대한 구현domain 이름으로 된 패키지 내부에서 진행한다.
    • 결론적으로 도메인에 대한 model struct, repository와 usecase interface를 정의한다.
    • 현재 추상화 및 구현이 완료된 domain에는 syschecksrvcheck가 있다.
  • syscheck
    • system check 기능의 domain에 대한 추상화를 실제로 구현 하는 패키지
    • domain 패키지에서 정의한 추상화에 의존하고 있으며, 네 가지의 하위 패키지로 구성되어있다.
    • repository
      • domain 패키지에서 추상화system check 관련 repository들을 구현하는 패키지
      • domain 패키지에 정의된 model struct에 의존하고 있으며, 데이터를 명령 혹은 조회하는 기능의 계층이다.
      • 현재로써는 elasticsearch를 저장소로 사용하는 구현체만 존재한다.
    • usecase
      • domain 패키지에서 추상화system check 관련 usecase들을 구현하는 패키지
      • domain 패키지에 정의된 repository 추상화에 의존하고 있으며, 실질적인 business logic을 처리하는 기능의 계층이다.
      • 또한 외부 서비스들에 대해 추상화한 agency 인터페이스에도 의존하고 있으며, 해당 추상화에 대한 소유권은 해당 패키지가 가지고 있다.
      • 외부 서비스들의 추상화에 대한 구현체는 아래의 Agent 패키지에서 확인할 수 있다.
    • delivery
      • 특정 API로부터 들어온 데이터를 usecase layer으로 전달하는 기능의 계층
      • 따라서, domain 패키지에 정의된 usecase 추상화에 의존하고 있다.
      • 해당 프로젝트 내에서 최상위 계층으로, 어떠한 추상화에 대한 구현체가 아니다.
    • config
      • syscheck의 모든 하위 패키지에서 사용하는 config value들을 관리하고 반환하는 패키지
      • 싱글톤 패턴으로 구현되어 있으며, config.yaml 파일에 설정된 값 또는 기본 값 반환
      • repository, usecase, delivery 패키지에서 추상화된 인터페이스들을 모두 구현하고 있음.
    • 같은 도메인 내에서도 기능들끼리의 연관성을 없애기 위해, 모든 기능들에 대한 추상화와 구현체들이 서로 다른 타입으로 분리되어있다.
  • srvcheck
    • syscheck 패키지와 비슷하게, service check 기능의 domain에 대한 추상화구현하는 패키지이다.
    • syscheck 패키지와 하위 구성 또한 동일하지만, 서로 간의 결합이 전혀 존재하지 않다.

3. Agent

모든 Agent 관련 패키지들은 usecase 패키지에서 정의된 agency 인터페이스를 구현하기 위한 패키지입니다.

  • consul
    • consul API를 이용하여 consul agency 인터페이스를 구현하는 agent 객체를 정의하는 패키지
    • consul에 등록된 노드 조회, 노드 등록 해제 등의 기능이 있다.
  • docker
    • docker engine API를 이용하여 docker agency 인터페이스를 구현하는 agent 객체 정의
    • 특정 컨테이너의 ID 및 메모리 사용량 조회, 컨테이너 삭제 등의 기능이 있다.
  • elasticsearch
    • elasticsearch API를 이용하여 elasticsearch agency 인터페이스를 구현하는 agent 객체 정의
    • cluster 정보 조회, indices 조회 및 삭제 등의 기능이 있다.
  • grpc
    • gRPC SDK를 이용하여 gRPC agency 인터페이스를 구현하는 agent 객체 정의
    • connection check를 위한 gRPC ping을 발행하는 기능이 있다.
  • slack
    • slack API를 이용하여 slack agency 인터페이스를 구현하는 agent 객체 정의
    • slack app을 이용하여 특정 채널에 메시지를 전송하는 기능이 있다.
  • system
    • linux kernel API를 이용하여 각종 system agency 인터페이스를 구현하는 agent 객체 정의
    • cpu 및 memory 사용량 조회, disk 잔여 용량 조회 등의 기능이 있다.
  • json
    • reqBodyWriter 인터페이스json 형식으로 구현하는 객체를 정의하는 패키지
    • 위의 패키지들과는 달리, 외부 서비스를 추상화한 인터페이스에 대한 구현체는 아니다.
    • 구현체인 mapWriter는 key값에 dot으로 depth가 구분된 map 타입의 변수를 json 형식으로 변환해준다.
    • Ex) map["a.b": "c", "a.b": "d"] -> map["a": map["b": []string{"c", "d"}]]


패키지 의존성 그래프

의존성 그래프는 godepgraph에서 제공하는 툴을 통해 생성하였습니다.

Domain 패키지간의 의존성 그래프

godepgraph2

Agent 패키지 의존성 그래프

godepgraph1

About

시스템 및 각종 서비스의 상태를 주기적으로 확인하여 기록하고, 원할한 운영을 위한 최적의 상태를 유지해주는 plug-in 개념의 시스템


Languages

Language:Go 99.7%Language:Makefile 0.2%Language:Dockerfile 0.1%