어떻게 GoLang 프로젝트를 시작하지..?

Sunwu Park·2024년 10월 23일

싱송생송

목록 보기
1/6

들어가기 전에 - 참고사항

이 글에서 나오는 이야기는 그저 3명이서 프로젝트를 개발한는 과정을, 고민등을 한풀이 하는 공간으로 어떠한 문제가 있었고, 이를 해결하기 위해 어떠한 과정을 겪었는지를 나열하는 공간으로 정확하지 않는 정보일 수 있습니다.

이 글의 목적은, 제가 지금까지 겪은 고민점들을 문서화한 다음 앞으로 비슷한 고민을 겪을때 참고하기 위한 것입니다. 참고로 이번이 GoLang을 사용한 첫 프로젝트입니다.. 완전 입문자.. ㅠ

Go를 선택한 이유

  • 기존 Java, Spring Boot나 Python, Fastapi만을 활용하여 백엔드를 구축하였는데 이번 프로젝트는 빠르게 개발을 하고 실제로 앱스토어, 플레이스토어에 배포를 하고 마케팅까지 진행을 할 예정이었던 터라 어떻게 하면 빠르게 개발하고 배포할 수 있을까를 생각해보았을때 배우는 것도 빠르고 성능도 좋은, 또한 가벼운 언어로 백엔드를 구축할 수 있을까? 를 고민하다 요즘 많은 기업들이 사용한다는 GoLang에 관심을 가지게 되습니다. 특히 GoLang을 도입한 컨퍼런스를 찾아보다보니

https://www.youtube.com/watch?v=75X_eBW0mog

  • Golang 도입, 그리고 4년 간의 기록 - 변규현, 당근마켓 | GopherCon Korea 2023
    이런 영상이 있었는데 더 흥미를 끌게 되었습니다.

여기서 장점과 단점을 정리를 해주셨는데 간단하게 본다면

Go의 장점

  • 컴파일 속도 가 빠르고 효율적이다
  • 빠른 애플리케이션 시작 시간, 재시작이 필요한 경우 빠르게 복구가 가능하다
  • GC(Garbage Collection)가 있어서 높은 성능을 유지하면서 코드 관리가 용이하다
  • 멀티코어 CPU를 잘 활용 할 수 있다,
    - Goroutine + Channel
  • 언어 표현이 단순하다
  • 애플리케이션 프로파일링, 메트릭 수집 등 표준 라이브러리에 포함되어 있어서 서비스 운영에 필요한 세부 모니털이과 성능 튜닝에 용이하다

Go의 아쉬운점

  • 에러처리가 번거롭다
  • GC는 대규모 힙을 가진 시스템에서는 성능저하를 일으킬 수 있다
  • 다른 언어 대비 Generic 사용이 제한적이다
  • 표준화된 개발 방법론이 서비스 개발에 강제되지 않았다. 사람에 따라 코드 작성 방식이 다를 수 있다

Golang 도입, 그리고 4년 간의 기록 - 변규현, 당근마켓 | GopherCon Korea 2023 => 링크

여기서 아쉬운점에 있어서 대규모 힙을 가진 시스템에서는 왜 성능저하가 일어날까? 라는 것이 궁금했고 찾아본 결과

  • Go의 성능 저하 문제는 주로 GC에서 비롯된다
  • Go는 자동 메모리 관리 언어로 가비지 컬렉터가 사용하지 않는 메모리를 주기적으로 회수하여 메모리 누수를 방지한다
    - GC Pause Time: Go의 GC는 stop-the-world 방식을 사용해서 메모리를 관리한다
    -> 모든 고루틴을 일시적으로 멈춘다는 것을 의미한다.
    -> 힙의 크기가 커질수록 참조할 객체의 수가 많아지며 메모리 회수에 소요되는 시간이 길어질 수 있다
    - 대규모 힙에서는 메모리 관리가 복잡 + 메모리 추적 회수하는 과정에서 추가적인 CPU자원 소비
    - 메모리 단편화 -> 메모리의 사용 가능한 공간이 비효율적으로 분산

이 부분을 보니 GoLang의 Garbage Collection에 대해서 좀 자세하게 알아볼 필요를 느꼈습니다 (한번 정리해서 올려볼게용). 물론 제가 뭐 트래픽이 아직 얼마나 나올지도 몰라 대규모 힙을 가질 것 같지는 않아서 크게 단점으로 다가오지는 않았고 그저 장점에 크게 집중을 하게 되었습니다.

참고로 최근에 올라온 GopherCon Korea 2024 영상에서(38:36초쯤)

https://www.youtube.com/watch?v=zdMuLvK0pNg&t=3116s
에서도 변규현님의


가 올라왔는데 아.. 프로젝트 시작하기 전에 이영상이 올라왔다면 참 좋았겠다는 생각을 하였습니다. 정말 도움이 많이 됩니다.

아무튼 GoLang에 흥미가 생기게 되었고 이로 프로젝트를 만들어 보겠다는 생각을 하게 되었습니다. 어떠한 프로젝트 구조로 해야하는가에 대해서 여러 검색을 해보았는데 대부분 그냥 스프링에서 했던 controller, service, repository, domain뭐 이렇게 나눠서 하는 곳이 많더라고요.

그런데 GoLang에서의 유연한 프로젝트 구조를 사용해보고 싶었고 저희는 간단하게 프로젝트 구조를 나누어서 스프링에서 만들던것처럼 완벽한 계층적? 구조로 하는것이 아니라 conf, internal(db, repository, handler, pkg), middleware, router등의 구조로 나누어서 진행을 해보았습니다

Go Framework?

일단 간단한 프로젝트 구조는 짰는데

  1. GoLang의 http패키지를 사용할까?
  2. gRPC Gateway로 할까?
  3. Go Framework로 할까?

에 대한 여러 고민이 있었습니다.

찾아보니 많은 예시들은 순수 GoLang으로 만든 예제가 많았고 Framework에 대한 호불호도 좀 갈리는 것 같았습니다.

심지어 Framework도 Gin, Fiber, Echo등 하나의 프레임워크를 주로 사용하는 것이 아닌 여러가지를 사용한 것 같았습니다.

여기서 여러 비교를 진행하고 현재의 리소스를 확인해보았을때 그저 두명의 백엔드가 빠르게 개발과 배포를 진행을 해야했으므로 Framework를 사용하기로 결정을 하였습니다. 또한 그중에서 가장 Github Star가 많은 Gin을 사용하게 되었습니다.

Go ORM?

기존 Java, Spring을 쓸때면 그냥 Domain위에다가 @Entity랑 여러 어노테이션을 붙여주면 알아서 foreign key까지 싹다 사용할 수 있었는데 Go에서 잘만든 ORM은 없다고 하더라고요. gorm, ent, sqlboiler등 다양하게 알아보았는데 장단점이 다 있는 것 같았습니다. 하지만 아예 사용하지 않는것은 너무 힘들것 같아서 가장 사용하기 쉽다는 SQL Boiler를 사용하기로 결정을 하였습니다.

[mysql]
  dbname = dbname
  host = host
  port = port
  user = user
  pass = password
  sslmode = "false"
  blacklist = [
    "*.created_at",
    "*.updated_at",
  ]

뭐 이런식으로 toml하나 만들고 이것을 기반으로

 sqlboiler --wipe --no-tests --no-auto-timestamps -p mysql -o ./internal/~~~~

뭐 이런식으로 적용하면 잘 적용이 되더라고요! 물론 이번 기회에 순수 쿼리 작성을 진짜 많이하게 되었습니다.. (sql 배우기 오히려 좋아~)

SQLBoiler 설명하신 블로그

Go Swagger?

go-swagger github 주소

진짜 스웨거는 너무 슬펐습니다. 스프링부트에서는 진짜 Config만들고, implementation하나 진행해주면 알아서 스웨거를 만들어주었는데 GoLang에서는

// GetRecommendation godoc
// @Summary      줄거리
// @Description  설명
// @Tags         태그
// @Accept       json
// @Produce      json
// @Success      200 {object} pkg.BaseResponseStruct{data=nil} "성공"
// @Router       {path} [get]
// @Router       {path} [get]
// @Security BearerAuth

각 함수위에다가 이렇게 달아주어야지 되더라고요.. 하고

 swag init -g ./main.go -o ./docs        

뭐 이런식으로 실행을 하면 스웨거 파일이 docs에 잘 만들어졌습니다.

홍보

'싱송생송' AppStore 링크
'싱송생송' Playstore 링크

한번씩 다운로드해서 리뷰 남겨주시면 감사하겠습니다~~

결론

사실은 정말 간단한 내용인데도 저 언어, 프레임워크, ORM, Swagger등을 정하는데도 꽤 시간이 오래 걸렸습니다. 이게 뭐하나 좀 강하게 정해진게 있으면 참 좋겠다는 생각을 하였습니다..

0개의 댓글