Go concurrency pattern - channel을 통해 간단히 세마포어처럼 동시 작업 속도 조절하기 (feat. 조회수 증가 기능)

시작하며 얼마 전 Channel use case 라는 Go에서의 채널 사용에 관한 글을 하나 읽었다. 한 동안 스프링 업무 보느라 잊고 지냈던 Go의 concurrency pattern이나 channel의 쓰임에 대해 다시 한 번 고민해볼 기회가 되었다. 항상 어떤 기술이 왜 좋은지, 언제 써야할지를 많이 고민하는 편이라 그 실제적인 유즈 케이스에도 굉장히 관심이 많은 편이다. 해당 글의 아쉬움은 제목은 use case였음에도 구체적인 use case라기 보다는 코드 예시 같은 느낌이 컸다. 아쉬움이 좀 있었던 터라 개인적으로 지인과 얘기해보며 고민을 좀 더 해보았다. 그 결과 channel을 세마포어처럼 이용해서 동시작업 속도를 조절해야하는 경우에 사용하면 좋을 것 같다는 생각이 들었다. 그리고 그 실제적인 예시로는 게시물의 조회수 관리가 될 것 같다. ...

5월 8, 2021 · 7 분

쿼리 최적화하기 - 조회수와 같은 Count 성격의 작업 최적화하기 (N+1 문제 관련, feat. Redis)

시작하며 짧은 영상을 바탕으로 배틀을 할 수 있는 서비스를 Spring Boot MVC + JPA로 개발하던 중 위와 같이 API Latency가 처참하게도 느린 요청들이 감지되기 시작했습니다. 그동안은 쿼리 최적화보다는 로직 개발이 더 우선시하다보니 쿼리 최적화를 미뤄왔는데, 이번 기회에 이에 대해 다뤄보려합니다. 간단하게 코드를 짜서 테스트해보느라 Go 언어를 이용했지만 JPA를 이용하든 뭘 이용하든 문제와 그에 대한 해결책의 요지는 동일할 것입니다. 아무래도 백엔드에서 API를 개발하면서 파일 데이터를 주고 받는 게 아니라면 주로 Latency가 늘어나는 이유는 다음과 같을 것입니다. ...

11월 24, 2021 · 7 분

쿠뮤 MVP 개발기

시작하며 Github PlayStore 출시 프로젝트 및 팀 소개 페이지 학교 수업을 듣다보니 한 학기에 2개 3개의 프로젝트를 개발해야하는 경우가 있었습니다. 완전 개발이 처음이었던 시기에는 이러한 양적인 개발 속에서도 배울 점이 많았지만 어느 정도 지나고 나니 양적인 개발 속에서는 크게 배울 점이 느껴지지 않았고, 머리가 아닌 손으로 개발을 하고 있는 느낌을 받게 되었습니다. 따라서 저는 단순히 찍어내기 식의 개발을 반복하기 보다는 한 서비스를 꾸준히 개발해나가며 그 속에 많은 생각을 담아내고자 했습니다. 처음에는 가볍게 관심있던 기술들을 자유롭게 적용해볼 수 있는 개발 놀이터를 만들고자 하는 마음에 시작했고 제가 관심있던 기술들은 다음과 같았습니다. ...

10월 2, 2021 · 6 분

Golang으로 백엔드 개발하기 - 5. Error Handling. 에러 잘 처리하기 (feat. fiber)

시작하며 드디어 에러를 다뤄볼 차례가 됐네요. 작년까지만 해도 Error나 Exception 처리의 중요성을 잘 몰랐던 것 같습니다. 하지만 API 클라이언트랑 작업을 하면 할수록 에러 처리의 중요성을 느끼게 되는 것 같아요. 왜냐하면 백엔드에서 각각의 에러 케이스에 대한 status_code나 error_type등을 명확히 정의하지 않으면 클라이언트는 에러를 해석할 방법이 없기 때문입니다. 또한 에러를 잘 처리한 뒤 올바르게 응답하거나 로그를 남기는 것은 유지/보수 시에 백엔드 개발자 스스로 에게도 정말 중요할 수 있습니다. 우리는 실제 운영 환경의 로그를 마치 우리가 로컬에서 개발할 때 처럼 항상 보고있을 수는 없기 때문이죠. 즉 에러 로그만 따로 “편리하게” 볼 수 있거나 에러 로그로 인한 Notification System이 있으면 훨씬 에러를 추적(Tracing)하기 쉽겠죠! ...

9월 5, 2021 · 9 분

Golang으로 백엔드 개발하기 - 4. Custom Middleware(미들웨어) 작성해보기 (feat. fiber)

시작하며 안녕하세요. 저번 글에서는 fiber 라는 웹 프레임워크로 간단히 웹 애플리케이션을 만드는 방법에 대해 알아봤으니 이번엔 웹 애플리케이션을 만들다보면 꼭 필요해지는 middleware 작성법에 대해 알아보겠습니다. 여태까지 백엔드에서 서버를 개발하면서는 JS의 Express 프레임워크를 제외하고는 미들웨어 개발이 그닥 쉽게 이해되는 부분은 아니었던 것 같습니다. Express에서 미들웨어를 작성하는 방법은 굉장히 직관적이고 문서도 많은 편이었거든요. 하지만 Spring은 Filter나 Interceptor를 이해하기 위해 많은 내용을 알아야하고, Django는 Class based나 function based, 그리고 middleware를 추가하는 법 등이 좀 복잡한 편이라고 생각합니다. ...

9월 1, 2021 · 7 분

Golang으로 백엔드 개발하기 - 3. 웹 애플리케이션 개발해보기 (feat. fiber)

시작하며 이번에는 Go언어에서 유명한 웹 프레임워크를 비교해보고 간단하게 Pingpong 서버를 개발해보겠습니다. 다만 “Golang으로 백엔드 개발하기“를 주제로 글을 쓰면서 주 목적으로 했던 것은 개발하면서 계속 궁금했지만 어딘가에서 뚜렷한 설명을 찾아보기 힘들었던 내용들을 다뤄보고자하는 것이었기 때문에 이번 주제는 그닥 주 목적에 해당하는 주제는 아니므로 이번엔 아주 가~볍게 훑어보고 넘어가겠습니다. 왜냐하면 웹 프레임워크를 사용하는 것은 해당 웹프레임워크의 문서나 이런 저런 블로그들에 이미 너무도 많이 자료가 존재하기 때문입니다. Golang으로 웹 애플리케이션을 개발하는 방법들 보통 다른 언어 같은 경우 Java에서는 Spring MVC 혹은 Spring WebFlux, Python은 FastApi, Flask, Django, Node.js는 Express, nest, koa처럼 각 언어마다 손에 꼽을 만한 대표적인 웹 프레임워크들이 있는 것 같은데 Go는 그렇지가 않습니다. Go는 잘 나가는 웹 프레임워크들이 너무도 다양하게 존재합니다. 아주 아주 다양한 프레임워크가 존재하지만 그닥 우위가 뚜렷하진 않습니다. 어떤 한 기술이 생태계를 독점해버리거나 그 기술만이 강요되는 일 없이 서로(프레임워크간)가 경쟁하며 좋은 기술로 나아가는 게 장점이 될 수도 있고, 너무 프레임워크가 다양해서 선택하기 곤란하다는 것이 단점이 될 수도 있을 것 같습니다. 커뮤니티가 한 데 집중된다면 더 버그 픽스하기 쉬울텐데 그런 면에서는 조금 아쉽기도 합니다. ...

8월 13, 2021 · 4 분

Golang으로 백엔드 개발하기 - 2. 테스트 코드 작성 및 Go에서 Mocking 이용하기 (gomock, testify 이용)

시작하며 저는 Go 언어를 공부하면서 처음으로 테스트 코드라는 것을 접하게 되었습니다. 과거에는 그저 기능을 구현하는 것에만 관심이 있었지 애플리케이션을 어떻게 계층을 나눠 설계할지, 어떻게 해야 유지 보수하기 쉬우면서 안정적인 개발을 할 수 있을지에 대한 고민을 하지 않았습니다. 하지만 Go를 공부하면서부터는 클린 아키텍쳐나 MSA, 동시성 패턴 등을 비롯해 테스트 코드에 대해서도 공부해볼 수 있었습니다. 그 중에서도 테스트 코드에 대해 공부해보며 익혔던 점들을 바탕으로 이번 글에서는 Golang으로 백엔드 개발을 하면서 테스트 코드를 어떻게 작성할 수 있을지에 대해 알아보려합니다. ...

7월 17, 2021 · 13 분

Golang으로 백엔드 개발하기 - 1. 데이터베이스 작업하기 (Ent 프레임워크 이용)

시작하며 Go 언어를 처음 시작한 지 벌써 1년이 지났다니 시간이 참 빠른 것 같습니다! Java는 Spring이라고하는 거대한 프레임워크가 자리 잡고 있어 딱히 어떤 프레임워크나 라이브러리를 사용할지에 대한 고민이 별로 필요 없었던 것 같습니다. 반면 Go 언어는 정형화된 아키텍쳐에 대한 내용이 별로 없고 프레임워크나 라이브러리의 대세도 참 빠르게 변하다보니 그게 장점이라면 장점이겠지만 이래저래 고생도 했네요. 게다가 Go 언어는 개발 입문자들이 많이 사용하지 않는 언어라 그런지 아직 웹 백엔드 개발에 익숙하지 않은 (저처럼) 사람들을 위한 자료들은 많이 없었던 것 같습니다. 예를 들면 Java의 스프링이나 Node.js의 express, Python의 django 같은 프레임워크들은 인프런만 가봐도 A to Z로 알려주는 강의가 많죠. 하지만 Go 언어는 보통 언어 입문 내용들이 많고, “자~! 여러분들은 어차피 개발 초보자들이 아니시잖아요? 이쯤하면 Golang을 맛보셨으니 알아서들 입맛대로 쓰십시오~!" 식으로 입문 이후의 내용은 보통 동시성 패턴에 대한 내용들일 뿐 백엔드 개발을 위한 아키텍쳐나 Unit test를 어떻게 실제로 적용하는지 같은 예시는 많이 없었습니다. 그래서 이번엔 Golang으로 웹 백엔드 개발을 하는 과정에 대해 좀 적어볼까합니다! ...

7월 3, 2021 · 10 분

Go 언어로 적용해보는 Computer Science - Mutex와 Semaphore

Go 언어로 적용해보는 Computer Science의 첫 번째 내용으로 OS 관련 내용 중 이론적으로는 흔하게 접할 수 있지만 실제 적용에 대한 내용은 찾아보기 힘들었던 Mutex, Semaphore에 대해 알아보려한다. Mutex와 Semaphore은 각각의 추상적인 개념을 바탕으로 OS나 Go 등에서 사용될 수 있기에 세부적인 내용은 문맥에 따라 달라질 수 있다고 생각한다. 예를 들어 Go에서의 Mutex는 주로 sync.Mutex를 이용한 서로 다른 Goroutine의 동시 접근에 대한 제어를 의미하는 반면, 다른 프로그래밍 언어나 OS에서는 주로 서로 다른 Kernel thread나 Process에 대한 동시 접근 제어를 의미할 수 있다. ...

1월 20, 2021 · 10 분

Go vs Java - Go에서의 객체 지향

시작하며 요즘 Go와 Java 모두를 이용해 개발을 하다보니 각각의 장단점에 대해 느껴볼 수 있었다. Go는 리소스를 적게 먹으며 코드가 간결하고 라이브러리나 프레임워크 또한 심플해서 적용하기 편하다. Java는 이런 저런 기능이 많은 반면 그런 기능을 이용하기 위해 이해해야하는 내용들이 많고, 코드가 투명하지는 않다(다양한 Annotation을 이용하게 되면서 코드가 투명하게 그 동작을 나타내지 않음). Java의 장점 중에서는 특히나 객체지향의 대표적인 언어답게 상속과 다형성을 능력에 따라 자유자재로 이용할 수 있다는 점이 매력적이었다. Go 언어를 좋아하는 입장에서 개인적으로 이런 객체지향적인 특징이나 예외 처리를 제외하고는 딱히 Java가 Go에 비해 갖는 장점이 크게 느껴지지 않았다. 예외 처리는 Go가 바라보는 방향이 일반적인 예외 처리와 다르기에 어쩔 수 없지만, 객체지향적의 특징들은 어떻게 적용해볼 수 있을까하는 생각에 공부를 좀 해봤고 그 내용을 정리해본다. (기회가 된다면 Go에서 error를 다루는 철학에 대해 추가적으로 공부해보고싶다.) ...

1월 9, 2021 · 11 분