목록Dev (19)

Overview애플리케이션을 개발하다 보면 어떤 특정한 목적을 위해 비동기 처리를 구현해야 하는 상황을 종종 마주하게 된다.비동기 처리를 구현하기 위해 흔히 Apache Kafka 혹은 RabbitMQ와 같은 메시지 큐를 도입하곤 한다. 특히나 요즘은 Application Modernization이라는 명목 하에 여러 기업 뿐만 아니라 공공까지도 MSA와 클라우드 사용이 주가 되는 Cloud Native 환경으로 넘어가는 추세이니 만큼 애플리케이션의 복잡도가 수직 상승하고 있기에 비동기 처리를 위한 메시지 큐 사용은 필수적이라고 볼 수 있다. MSA 환경에서는 각 서비스가 설계자의 의도에 따라 분리되어 있고 모놀리틱 방식에 비해 결합도가 떨어지기 때문에 메시지 큐를 얼마나 잘 활용하느냐가 MSA 환경 구..
가변 인수 함수fmt.Println()fmt.Println(1)fmt.Println(1, 2, 3, 4, 5) fmt 패키지의 Println 함수는 인수 개수가 정해져 있지 않다. 이처럼 인수의 개수가 고정되어 있지 않은 함수를 가벼 인수 함수라고 한다. ... 키워드를 사용해서 가변 인수를 생성할 수 있다. 인수 타입 앞에 ...를 붙여서 해당 타입 인수를 여러 개 받는 가변 인수임을 표시하면 된다.func sum(nums ...int) int { sum := 0 fmt.Printf("nums 타입 : %T\n", nums) for _, v := range nums { sum += v } return sum}func main() { fmt.Println(s..
Interface인터페이스란 구현을 포함하지 않는 메소드 집합으로, 구체화된 타입이 아닌 인터페이스만 가지고 메소드를 호출할 수 있어 추후 프로그램 요구사항 변경 시 유연하게 대처할 수 있다. Go에서는 인터페이스 구현 여부를 특정 타입이 인터페이스에 해당하는 메소드를 가지고 있는지로 판단하는 덕 타이핑을 지원한다. 인터페이스를 사용하는 것으로 객체 간 상호작용을 정의할 수 있으며, 덕 타이핑을 통해 사용자 중심의 코딩이 가능하다.인터페이스 선언 방법은 다음과 같다.type DuckInterface interface { Fly() Walk(distance int) int}인터페이스 또한 구조체처럼 타입의 한 종류이기 때문에 type 키워드를 작성해야 한다. 인터페이스를 작성할 때 유의해야 할 ..
Method이전에 Java를 사용해본 사람이라며 Method라는 이름이 친숙하게 느껴질 것이다. 필자 또한 Java를 주로 사용했기 때문에 이번 파트를 공부하며 Method라는 명칭이 굉장히 반갑게 느껴졌다. 하지만 Go는 Java와 달리 클래스가 존재하지 않기 때문에 어떤 식으로 메소드를 사용하는지 의구심이 들었다. Go에서의 메소드는 구조체 바깥에서 정의되며 리시버를 통해 구조체와 연결된다.Receiver메소드는 구조체 바깥에서 선언되기 때문에 메소드가 어떤 구조체에 속하는지 표시할 방법이 필요하다. 이를 위해 리시버를 사용하여 메소드가 속한 구조체를 알려준다.🚀Method 선언메소드를 선언하기 위해서는 리시버를 ()로 명시해야 한다.func (r Rabbit) info() int { retu..
Slice란?슬라이스는 Go 언어에서 제공하는 자료구조 중 하나로, 동적으로 크기를 증가시키는 동적 배열이다. 또한, 슬라이싱 기능을 이용해 배열의 일부를 나타내는 슬라이스를 만들 수 있다.Slice 선언🚀{}를 이용한 초기화var slice []int일반적인 배열과 달리 [] 내부에 배열의 개수를 적지 않고 선언한다. 별도로 슬라이스의 크기를 지정해주지 않으면, 길이가 0인 슬라이스가 생성된다.var slice []intif len(slice) == 0 { fmt.Println("slice is Empty")}// slice is Empty슬라이스 초기화 시점에 슬라이스 내부에 포함되는 값들을 미리 설정하기 위해서는 배열처럼 {}를 이용하여 요소값을 지정해야 한다.var slice1 = []in..

SRP (Single Responsibility Principle): 단일 책임 원칙"어떤 클래스를 변경해야 하는 이유는 오직 하나뿐이어야 한다."- 로버트 C. 마틴위의 그림과 같이 Man 클래스에 의존하고 있는 다양한 클래스들이 존재한다고 생각해 보자. 그림에서부터 확인이 가능하듯 Man 클래스에 부과된 역할과 책임이 너무 많기 때문에 남성의 표정이 그리 밝지 않다. 어느 날, 여자친구와 헤어질 경우 Man 클래스는 챙길 일 없는 기념일과 사랑한다고 말할 대상이 사라져 힘들어하게 된다. 거기다 여자친구와 결별한 영향이 부모님과 직장 상사에게 까지 영향이 미칠 수 있다. 이렇듯 한 클래스에 너무 많은 책임이 집중될 경우 발생할 수 있는 악영향과 관리의 어려움을 예방하기 위해 책임을 분리하라는 것이 단일..
CPU-Scheduling 이란? 모든 프로세스는 CPU를 필요로 하고 모든 프로세스는 먼저 CPU를 사용하고 싶어 하기에, 여러 프로세스들에게 합리적으로 CPU 자원을 할당하기 위해 운영체제는 어떤 프로세스에 어떤 CPU를 할당할지를 결정한다. 이렇게 운영체제가 프로세스들에게 합리적으로 CPU 자원을 배분하는 것을 CPU-Scheduling 이라고 한다. CPU-Scheduling 이 제대로 동작하지 않는다면, 반드시 실행되어야 할 프로세스들이 실행되지 못하거나, 중요하지 않은 프로세스들만 주로 실행되는 등 컴퓨터 성능에 직결되는 문제라고 볼 수 있다. 프로세스 우선순위 각 프로세스마다 우선순위가 다른데, 우선순위가 높은 프로세스일수록 빨리 처리해야 하는 프로세스들을 의미한다. 우선순위가 높은 프로세스..

RabbitMQ와 STOMP를 사용하는 채팅 서버를 만들던 중 RabbitMQ에 대한 이해가 부족했다는 것을 깨닫고 공부하기 위해 작성한 포스팅이다. RabbitMQ란? AMQP를 구현한 오픈소스 메세지 브로커 Producers 에서 Consumers 로 메세지를 전달할 때 그 중간에서 브로커 역할을 한다. AMQP란? Advanced Message Queueing Protocol의 줄임말로 MQ의 오픈소스에 기반한 표준 프로토콜을 의미한다. AMQP의 가장 대표적인 구현체가 바로 RabbitMQ라고 볼 수 있다. RabbitMQ 구조 RabbitMQ는 Producer가 발행한 메세지를 Consumer가 소비하기 전까지 Queue에 저장하여 보관하는 일련의 과정을 중개한다. Queue는 이름으로 구분되며..

분산락의 필요성 단 하나의 서버만 존재한다면, 앞서 소개했던 synchronized 만으로도 충분한 동시성 제어가 가능하지만 실제 서비스가 운영되고 있는 운영 서버는 하나만으로는 안정적으로 서비스 운영이 힘들기 때문에 보통 여러 개의 운영 서버를 둔다. synchronized 는 단 하나의 프로세스에서만 적용되기 때문에 여러 개의 프로세스가 존재하는 상황에서는 원활한 동시성 제어가 불가능하기 때문에 이를 위해 분산락이라는 것이 등장하게 되었다. Redis를 사용하는 이유 Redis 는 싱글 스레드로 동작하기 때문에, 단일 레디스 노드를 구축해 사용해도 동시성 문제가 발생하지 않는다. MySQL과 Zookeeper를 활용하는 방법을 사용해도 분산락을 구현할 수 있지만 이번 포스팅에서는 우선 Redis를 사..

운영체제란? 운영체제는 컴퓨터의 자원들을 효율적으로 관리하며 사용자가 컴퓨터를 편리하고 효과적으로 사용할 수 있도록 환경을 제공하며, 이를 위해 사용자와 하드웨어 간의 인터페이스로서 동작한다. 운영체제는 응용 프로그램이 실행될 때 필요한 자원을 할당하고, 다른 응용 프로그램이 원활하게 실행될 수 있는 환경을 제공한다. 운영체제 또한 프로그램이기 때문에 메모리에 적재되어야 한다. 다만, 운영체제는 다른 프로그램들이 원활하게 실행될 수 있도록 돕는 특별한 프로그램이기 때문에 컴퓨터가 부팅될 때 메모리 내부의 커널 영역에 적재된다. 참고로 커널 영역을 제외한 다른 프로그램들이 적재되는 메모리 공간을 사용자 영역이라고 한다. CPU 모드 CPU는 사용자 애플리케이션이 시스템을 손상시키는 것을 방지하기 위해 사용..