Go 모듈 종속성 고정 #

Go를 사용하여 서버 런타임 코드를 개발할 때 Go 플러그인 모듈이 Nakama 바이너리로 로드되는 방식과 런타임 모듈에 어떤 제한 사항이 적용되는지 인지하는 것이 중요합니다. Go는 컴파일되고 연계되는 언어이기 때문에 최종 바이너리가 결합되는 방식에서 엄격합니다. 그렇기 때문에 컴파일하는 서버 런타임 플러그인을 사용하고 있는 Nakama 서버 바이너리와 동일한 방식으로 컴파일해야 합니다. 이러한 조건이 충족되지 않을 경우 몇 가지 공통적인 오류를 초래할 수 있는 제한 사항이 적용됩니다.

아래는 Go를 사용하여 서버 런타임 코드를 개발하고 문제를 해결하는 과정에서 경험할 수 있는 몇 가지 위험 요소입니다.

플랫폼 불일치 #

문제점 #

Nakama 바이너리가 아닌 다른 플랫폼을 사용하여 컴파일된 서버 런타임 Go 모듈을 로드하려고 하면 문제가 발생합니다. 예를 들어, Linux에서 컴파일된 Go 모듈은 macOS에서 컴파일된 Nakama 바이너리와 함께 사용할 수 없습니다.

1
2
3
4
5
6
7
{
  "level":"error",
  "ts":"...",
  "caller":"...",
  "msg":"Error initialising Go runtime provider",
  "error":"plugin.Open(\"/nakama/data/modules/backend.so\"): /nakama/data/modules/backend.so: invalid ELF header"
}

해결 방법 #

Go 서버 런타임 모듈이 컴파일된 플랫폼이 Nakama 바이너리가 컴파일된 플랫폼과 일치하도록 합니다.

Go 런타임 버전 불일치 #

문제점 #

Nakama 바이너리가 아닌 다른 버전의 Go 런타임을 사용하여 컴파일된 서버 런타임 Go 모듈을 로드하려고 하면 문제가 발생합니다. 예를 들어, Go 버전 1.14로 컴파일된 Go 모듈은 Go 버전 1.15로 컴파일된 Nakama 바이너리와 함께 사용할 수 없습니다.

1
2
3
4
5
6
7
8
{
  "level":"error",
  "ts":"...",
  "caller":"...",
  "msg":"Could not open Go module",
  "path":"/nakama/data/modules/backend.so",
  "error":"plugin.Open(\"/nakama/data/modules/backend\"): plugin was built with a different version of package runtime/internal/sys"
}

해결 방법 #

Go 서버 런타임 모듈을 Nakama 바이너리가 컴파일된 Go와 동일한 버전을 사용하여 컴파일합니다. Dockerfile에서 동일한 태그 버전 번호의 nakamanakama-pluginbuilder Docker 이미지를 사용하면 됩니다.

Go 종속성 버전 불일치 #

문제점 #

직접 또는 간접적(추이 종속성)으로 사용하는 모든 종속성/패키지와 Nakama 바이너리는 동일한 버전이어야 합니다. 예를 들어, 서버 런타임 모듈에서 github.com/gofrs/uuid 패키지의 버전 3.3.0을 사용하고 Nakama 바이너리는 4.0.0 버전을 사용하는 경우, 종속성 버전 불일치 오류가 발생합니다.

1
2
3
4
5
6
7
{
  "level":"fatal",
  "ts":"...",
  "caller":"...",
  "msg":"Failed initializing runtime modules",
  "error":"plugin.Open(\"/nakama/data/modules/backend\"): plugin was built with a different version of package go.uber.org/zap/buffer"
}

해결 방법 #

서버 런타임 모듈을 실행하려고 하는 Nakama 바이너리와 동일한 종속성/패키지 버전을 사용합니다.

직접 종속성에서 불일치가 발생하는 경우, go.mod 파일에서 Nakama가 사용하는 것과 동일한 버전을 불러와야 합니다.

종속성 불일치가 직접(추이) 종속성에서 발생하는 경우, go.mod 파일에서 종속성을 명시적으로 불러와서 동일한 버전을 사용할 수 있습니다. 그 다음, _ (밑줄) 별칭을 사용하는 빈 가져오기 구문을 추가하여 아래의 예시와 같이 직접 종속성을 생성합니다.

1
2
3
import (
  _ "go.uber.org/zap"
)

이 작업을 완료하고 난 후, go mod vendor 명령을 실행하여 종속성을 판매하고 정확한 버전을 사용할 수 있습니다.

Nakama의 vendor/modules.txt 파일과 오류를 초래하는 패키지를 검색하는 것은 플러그인 go.mod 파일에 고정되는 추이 종속성의 정확한 버전을 식별하는 데 도움이 될 수 있습니다.

Nakama는 페일패스트 방식을 사용하는 반면, 서버는 서버 런타임 코드에서 처음 오류 발생 시 바로 차단되기 때문에 이 방법은 약간의 시행착오를 겪을 수 있습니다. 종속성 버전 불일치가 여러 번 발생하면 오류를 차례대로 수정해야 한다는 뜻입니다.