주요 업데이트
Go embed
go:embed {embed file path}
디렉티브를 통해 컴파일 과정에서 파일 임베드를 지원하게 됨.
이것이 좋은 이유!
Go언어에서는 기본적으로 conf-{stage}.yaml 등의 설정 파일을 가지고 불러오는 등의 설정을 가진 경우, 개발 과정에서는 문제가 없이 동작하지만 go build를 한 이후 설정 파일이 execute file에 포함되지 않아 설정 파일을 못찾는 현상이 발생합니다. 또한 보안 문제도 발생하게 된다.
따라서 실행 파일과 함께 설정 파일을 동봉하거나 viper 등을 통해 설정을 직접 입력하는 형식, 혹은 Consul이나 etcd와 같은 원격 키스토어에 설정을 저장하고 네트워크 트래픽을 거쳐 설정을 받아오는 방식을 사용했다.
1.16 버전 이전에는 정식으로 임베딩을 지원하지 않으므로 https://github.com/go-bindata/go-bindata 오픈소스 등을 이용하여 literal byte 정보를 담은 변수를 정의한 {xxx}.go 파일을 생성하고 그것을 불러오는 방식으로 사용했다.
Go embed 기능을 사용하면 파일을 동봉하지 않고 실행 파일에 임베드(embed)하기 때문에 앞선 제약사항들이 해소된다.
예를들어 아래와 같이 config yaml을 embed하고 viper에 연결하여 사용할 수 있다.
//go:embed config.yml
var f embed.FS
data, _ := f.ReadFile("config.yml")
viper.SetConfigType("yaml")
viper.ReadConfig(bytes.NewBuffer(data))
viper.Get("message") // "Hello go 1.16!"
이 기능은 cli를 개발할 때 설정을 보관하는 위치를 고민하는 과정을 줄여주게 된다. 대신 embed는 결국 특정 데이터를 실행 파일에 포함한다는 의미로 실행 파일 크기가 커지는 것에 유의해야 한다.
Go module
기존에 Go module-aware 옵션을 조정하는 GO111MODULE 이 default로 on으로 적용됩니다. 따라서 현재 폴더나 부모 폴더에 go.mod 가 있다면 Go module을 사용하는 것으로 인식됩니다.
또한 go install example.go/cmd@v1.0.0 과 같이 버전 접미사를 포함하는 go install 구문을 허용합니다. 이 경우 현재 폴더나 부모 폴더에 go.mod가 존재하더라도 이를 무시합니다. 이런 방식은 메인 모듈의 종속성 영향을 최소화하는데 유용합니다.
go.mod 파일에서 retract directive를 지원합니다. 이를 통해 문제가 있는 버전을 모듈이 사용자들이 사용하는 것을 방지할 수 있습니다.
io/ioutil
Go 언어의 코어 로직 중 io/ioutil 패키지가 deprecated 되었고, io/ioutil 의 하위 함수들을 각각의 목적에 맞게 이관하였다.
Discard => io.Discard
NopCloser => io.NopCloser
ReadAll => io.ReadAll
ReadDir => os.ReadDir (노트: fs.FileInfo 대신 os.DirEntry 슬라이스를 반환)
ReadFile => os.ReadFile
TempDir => os.MkdirTemp
TempFile => os.CreateTemp
WriteFile => os.WriteFile
Apple M1 칩 / Apple Silicon 지원
Go 1.16은 64 비트 ARM 아키텍처 기반의 macOS를 지원하도록 추가되었습니다. GOOS=darwin, GOARCH=arm64 GOOS=darwin, GOARCH=amd64
fs.FS 구현체
코어 라이브러리 중 io/fs 패키지가 추가되었다. 패키지 내에 fs.FS 인터페이스가 추가되었다.
type FS interface {
// Open opens the named file.
//
// When Open returns an error, it should be of type *PathError
// with the Op field set to "open", the Path field set to name,
// and the Err field describing the problem.
//
// Open should reject attempts to open names that do not satisfy
// ValidPath(name), returning a *PathError with Err set to
// ErrInvalid or ErrNotExist.
Open(name string) (File, error)
}
이번에 새롭게 추가된 embed.FS 타입은 fs.FS 인터페이스를 구현한다.
Go linker 개선
Go 링커 현대화 작업의 일환으로 Go 1.16 릴리즈에 링커 구조가 개선되고 성능이 올라갔다.
성능 개선
- 대규모 Go 어플리케이션의 경우 1.15 대비 20-25% 빠름.
- linux/amd 기준 평균 5-15% 더 적은 메모리를 사용.
Go 링커 개선작업 참조)
https://docs.google.com/document/d/1D13QhciikbdLtaI67U6Ble5d_1nsI4befEd6_k1z91U/view
Go 인라이너 개선
이제 컴파일러는 레이블이 지정되지 않은 for loop, 메소드 값, 타입 스위치등을 사용하여 함수를 인라인 할 수 있게 되었다. 인라이너는 조금 더 많은 함수를 인라인에 포함한다.
Function Inlining
Only short and simple functions are inlined. To be inlined a function must contain less than ~40 expressions and does not contain complex things like loops, labels, closures, panic's, recover's, select's, switch'es, etc.
gc: 1.0+
gccgo: -O1 and above.
runtime/metrics 패키지
runetime.ReadMemStats나 debug.GCStats 등으로 분산되어 있던 런타임 메트릭들의 공용 인터페이스 패키지가 추가되었습니다. 이제 runtime/metrics에서 모든 런타임 메트릭에 대한 샘플값을 읽어올 수 있어요. 메트릭은 런타임에 추가될 때마다 runtime/metrics 패키지에 지속적으로 추가된다고 합니다.
APM을 만드는 개발사에서 이 부분을 많이 쓰지 않을까함.
성능을 시각화 한다거나, 그 안쪽에 있는 것을 X-ray처럼 잘 드려다 보기 위해, 성능이라는 것을 극대화 하기 위해서 사용함.
Caution
하위 호환성
Go 1.16은 macOS 10.12 Sierra를 지원하는 마지막 릴리즈입니다. Go 1.17부터는 macOS 10.13 High Sierra를 요구합니다.
'프로그래밍(Web) > Golang' 카테고리의 다른 글
[바미] 디버그 모드 시 Version of Delve is too old for this version of Go 에러 뜰 때 해결 방법 (0) | 2021.06.08 |
---|---|
[바미] go-callvis에 대해 알아보자! (0) | 2021.04.13 |
[바미] Go - Websocket (0) | 2020.12.18 |
[바미] Go - PostgreDB(2) feat. 드디어 풀린 에러 (0) | 2020.12.18 |
[바미] Go - PostgreDB (0) | 2020.12.18 |