Azure Functions에 Go언어 사용 하기

김현성·2020년 7월 9일
0
post-thumbnail

배경


작년 중순부터 진행하던 프로젝트의 인프라는 Go언어를 기반으로 Serverless 환경이 필요 했지만,

하지만 작년 중순까지만해도 Azure Functions는 Go언어를 공식 지원하지 않았고

(작성시점에도 아직 Azure Functions 에서는 Go 언어를 공식지원하지는 않는다.)

Azure Functions에서 지원되는 언어

그에 따라 그나마 자료가 많은 AWS로 프로젝트를 시작하였으나, Azure에 대한 아쉬움이 남아있었습니다.

그렇게 AWS Lambda로 개발을 진행하던 중 올해 3월경 Custom Handler 미리보기를 공개하여 이를 통한 Functions에서의 Go언어 사용이 가능해 졌습니다.

Azure Functions custom handlers (preview)

자세한 내용은 생략하고 실제로 사용해보겠습니다.

Hello, World! 만들어보기


  • 패키지 설치
npm install -g azure-functions-core-tools@3
  • 초기화

수기로 필요한 파일들을 만들수도 있지만 귀찮으니 초기화 명령어(func init)를 사용해줍시다.

mkdir gofunc
cd gofunc
func init
Select a number for worker runtime:
1. dotnet      
2. node        
3. python      
4. powershell  
Choose option: 2
node
Select a number for language:
1. javascript
2. typescript
Choose option: 1
javascript

rm package.json

초기화시 런타임을 선택하라고 하지만 Custom 선택지가 없으므로 일단 node로 언어는 js로 초기화 해주고 불필요한 package.json 을 제거합니다.

  • 함수 추가

이제 함수를 추가하는데 위와 마찬가지로 명령어(func new)를 사용합니다.

 $ func new
Select a number for template:
1. Azure Blob Storage trigger
2. Azure Cosmos DB trigger
3. Durable Functions activity
4. Durable Functions HTTP starter
5. Durable Functions orchestrator
6. Azure Event Grid trigger
7. Azure Event Hub trigger
8. HTTP trigger
9. IoT Hub (Event Hub)
10. Azure Queue Storage trigger
11. SendGrid
12. Azure Service Bus Queue trigger
13. Azure Service Bus Topic trigger
14. SignalR negotiate HTTP trigger
15. Timer trigger
Choose option: 8
HTTP trigger
Function name: [HttpTrigger] hello-world

rm hello-world/index.js

다양한 선택지가 있지만 HTTP trigger를 선택

이후 함수 명을 입력해주고 마찬가지로 불필요한 파일을 제거해 줍니다.

여기까지의 파일 구조는 다음과 같습니다.

│  .gitignore
│  host.json
│  local.settings.json
│
└─ hello-world
        function.json
  • Go 함수 생성 및 빌드

이제 다음으로 Go언어 함수를 만들어 보겠습니다.

// main.go

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"
)

type message struct {
	Body string
}

func handleRequests() {
	// 함수의 경로는 함수명과 동일하게
	http.HandleFunc("/hello-world", func(w http.ResponseWriter, r *http.Request) {
		json.NewEncoder(w).Encode(message{
			Body: "Hello World!",
		})
	})

	// functions 포트 찾기(기본: 7071)
	httpInvokerPort, exists := os.LookupEnv("FUNCTIONS_HTTPWORKER_PORT")
	if exists {
		fmt.Println("FUNCTIONS_HTTPWORKER_PORT: " + httpInvokerPort)
	}
	log.Println("Go server Listening...on httpInvokerPort:", httpInvokerPort)
	log.Fatal(http.ListenAndServe(":"+httpInvokerPort, nil))
}

func main() {
	handleRequests()
}

'FUNCTIONS_HTTPWORKER_PORT' 변수를 선언하여 로컬 테스트 할수도 있습니다.

# 빌드
go build main.go
  • host.json 변경
{
    "version": "2.0",
    "httpWorker": {
        "description": {
            "defaultExecutablePath": "main.exe" // 빌드 된 바이너리
        }
    }
}

defaultExecutablePath 의 값을 빌드된 파일로 변경해줍니다.

이제 설정은 모두 끝났습니다 😀

함수 실행


func start

경로 매핑 확인

결과 확인


Hello World! 가 정상 출력되는것을 확인할수 있습니다.

Hello World가 끝났으니 이제 하나하나 시도해보면 되겠네요. 😏

0개의 댓글