Compute Engine 및 REST를 사용하여 모바일 앱 빌드

Compute Engine에서 모바일 백엔드를 실행하고 모바일 앱과 백엔드 서버 간에 REST를 통신 프로토콜로 사용하면 여러 가지 이점이 있습니다.

  • 온프레미스 또는 가상 머신에서 실행되는 기존 서비스를 Google Cloud로 이동하는 가장 빠른 방법입니다.
  • 가상 머신 및 서버 구성을 완벽하게 제어할 수 있습니다.
  • 타사 라이브러리를 사용할 수 있습니다.
  • 수요에 맞춰 가상 머신 수를 확장하도록 자동 확장 처리를 구성할 수 있습니다.

Compute Engine에서 서비스를 실행할 때의 단점은 서버 유지관리와 업데이트를 직접 책임져야 한다는 것입니다.

이 가이드에서는 Stickynotes라는 샘플 모바일 앱을 빌드하는 방법을 안내합니다. 이 샘플 앱은 REST를 사용하여 Compute Engine에서 실행되는 백엔드 서비스에 연결합니다.

Stickynotes 샘플에는 프런트엔드 모바일 앱 및 백엔드 서비스를 위한 코드가 있으며 다음 워크플로에서 함께 작동합니다.

  1. 모바일 앱에서 텍스트 필드에 메시지를 입력할 수 있습니다.
  2. 앱이 메시지를 백엔드 서비스의 REST 엔드포인트로 보냅니다.
  3. 백엔드 서비스가 draw2d 라이브러리를 사용하여 텍스트 메시지가 포함된 이미지를 만듭니다.
  4. 백엔드 서비스가 이미지를 모바일 앱에 반환합니다.
  5. 모바일 앱이 메시지가 포함된 이미지를 표시합니다.

클라이언트 앱은 iOS 앱이고, 백엔드 서비스는 Go 프로그래밍 언어로 작성되었습니다.

목표

이 가이드는 다음 방법을 보여줍니다.

  • 백엔드 서비스의 REST 엔드포인트에 연결하는 iOS 모바일 앱을 만듭니다.
  • Compute Engine에서 REST 백엔드 서비스를 구성하고 실행합니다.

비용

이 가이드에서는 Google Cloud의 비용 청구 가능한 구성요소인 Compute Engine 인스턴스를 사용합니다.

가격 계산기를 사용하면 예상 사용량을 기준으로 예상 비용을 산출할 수 있습니다. GCP 신규 사용자는 무료 체험판을 이용할 수 있습니다.

시작하기 전에

  1. Google 계정으로 로그인합니다.

    아직 계정이 없으면 새 계정을 등록하세요.

  2. Cloud Console의 프로젝트 선택기 페이지에서 Cloud 프로젝트를 선택하거나 만듭니다.

    프로젝트 선택기 페이지로 이동

  3. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다. 프로젝트에 결제가 사용 설정되어 있는지 확인하는 방법을 알아보세요.

다음 소프트웨어를 설치합니다.

  • Git
  • Xcode 7.2 이상
  • Go
    • Go 설치가 PATH 변수에 속해 있는지 확인합니다. 일반적으로 /usr/local/go/bin입니다.

샘플 코드 클론

다음 명령어를 실행하여 샘플 코드를 클론합니다.

git clone https://github.com/GoogleCloudPlatform/ios-docs-samples.git

이제 /solutions/stickynoteapi/REST 디렉터리로 이동하여 이 솔루션의 샘플 코드를 찾습니다.

로컬에서 서버 실행

/stickynoteapi/REST/Go 디렉터리에서 다음 명령어를 실행합니다.

sh SETUP

이 명령어는 다음 출력을 표시합니다.

1. Set gopath and search path
2. Get the server and client dependencies
3. Build the server and client
4. Stop any previously-running instances of the server
5. Start the server
6. Run the client
2016/03/02 11:34:48 OK: message.png
7. Open the image in message.png

'Remember the milk'라는 구문으로 서버를 테스트하기 위한 로컬 클라이언트도 설정에서 실행됩니다. 해당 이미지를 포함하는 message.png 파일이 서버에서 생성됩니다.

Remember the milk.

명령줄 클라이언트를 사용하여 자체 메시지를 기반으로 이미지를 생성하려면 다음 명령어를 실행합니다.

./client "This is a test..."

/stickynoteapi/REST/Go/go/src/server/server.go 파일에는 REST 서버를 실행하는 코드가 포함됩니다. 기본 함수는 루트 수준 디렉터리의 핸들러를 정의하고 포트 8080에서 트래픽을 리슨합니다.

func main() {
	http.HandleFunc("/stickynote", handler)
	http.ListenAndServe(":8080", nil)
	//http.ListenAndServeTLS(":443", "ssl.crt", "ssl.key", nil)
}

서버는 handler 함수에 수신 요청을 전달하고, 이 함수는 다음과 같은 작업을 수행합니다.

  1. REST 요청에서 텍스트 메시지를 추출합니다.
  2. sticky.go에 정의된 함수를 사용하여 텍스트 메시지를 기반으로 이미지를 빌드합니다.
  3. 이미지를 REST 응답으로 클라이언트에 반환합니다.
func handler(w http.ResponseWriter, r *http.Request) {
	var sticky Sticky
	sticky.Message = r.FormValue("message")
	sticky.Centered = false
	stickyBytes, err := sticky.DrawPNG(512, 512)
	if err == nil {
		w.Write(*stickyBytes)
	}
}

다음 섹션에서 클라이언트 앱을 테스트하는 데 사용할 수 있도록 로컬 서버를 실행 중인 상태로 둡니다.

로컬 서버로 iOS 클라이언트 실행

  1. stickynoteapi/REST/Objective-C/ 디렉터리에서 stickynotes.xcodeproj를 Xcode로 엽니다.
  2. Product(제품) > Run(실행)을 선택하여 클라이언트 앱을 빌드하고 시작합니다.
  3. 텍스트 필드에 메시지를 입력하고 Return(돌아가기)을 누릅니다.

메시지가 적힌 노란색 스티커 메모 이미지가 텍스트 필드 아래에 나타납니다.

This is a test...

클라이언트 앱이 StickyNotesViewController.m 파일에서 백엔드 서비스의 위치를 설정합니다. 위치는 일단 테스트용으로 포트 8080에서 localhost로 설정됩니다.

static NSString * const kHostAddress = @"localhost:8080";

텍스트 필드에 메시지를 입력한 후에 Return(돌아가기)을 누르면 앱이 메시지를 쿼리 문자열에 인코딩하여 REST 요청으로 서버에 보냅니다. 앱은 REST 응답을 받고, 생성된 이미지를 추출하고, 이미지 뷰로 표시합니다. 다음 코드는 이 작업을 처리하는 동작을 보여줍니다.

- (IBAction) textFieldDidEndEditing:(UITextField *)textField
{
  NSString *queryString = [NSString stringWithFormat:@"http://%@/stickynote?message=%@",
                           kHostAddress,
                           [textField.text urlencode]];
  NSURL *URL = [NSURL URLWithString:queryString];
  _request = [NSMutableURLRequest requestWithURL:URL];

  NSURLSession *session = [NSURLSession sharedSession];
  _task = [session dataTaskWithRequest:_request
                     completionHandler:
           ^(NSData *data, NSURLResponse *response, NSError *error) {
             UIImage *image = [UIImage imageWithData:data];
             dispatch_async(dispatch_get_main_queue(), ^{
                              self.imageView.image = image;
                            });
           }];
  [_task resume];
}

Compute Engine에서 서버 실행

Compute Engine에서 서버를 호스팅하려면 컴퓨팅 인스턴스를 만듭니다.

  1. Cloud Console에서 VM 인스턴스 페이지로 이동합니다.

    VM 인스턴스 페이지로 이동

  2. 인스턴스 만들기를 클릭합니다.
  3. 이름sticky-rest로 설정합니다.
  4. 부팅 디스크 섹션에서 변경을 클릭하여 부팅 디스크 구성을 시작합니다.
  5. Public images 탭에서 Google Drawfork Debian GNU/Linux 9를 선택합니다.

  6. 선택을 클릭합니다.
  7. 방화벽 섹션에서 HTTP 트래픽 허용HTTPS 트래픽 허용을 선택합니다.
  8. 만들기를 클릭하여 인스턴스를 만듭니다.

인스턴스에 대한 클라이언트 요청을 허용하려면 방화벽 규칙을 만듭니다.

  1. Cloud Console에서 방화벽 페이지로 이동합니다.

    방화벽 페이지로 이동

  2. 방화벽 규칙 만들기 페이지에서 다음 정보를 입력합니다.

    • 이름: sticky-rest
    • 대상 태그: http-server
    • 소스 IP 범위: 0.0.0.0/0
    • 프로토콜 및 포트: tcp:8080
  3. 만들기를 클릭합니다.

인스턴스에서 서버를 시작하려면 서버 코드를 클론하고 설정 스크립트를 실행합니다.

  1. 가상 머신 인스턴스 목록에서 연결할 인스턴스 행의 SSH를 클릭합니다.

    인스턴스 이름 옆에 있는 SSH 버튼

  2. VM 인스턴스의 IP 주소를 기록합니다. 이 주소는 외부 IP 열에서 볼 수 있습니다.
  3. 인스턴스에 Git를 설치합니다.

    sudo apt update
    sudo apt install git
    
  4. Go 도구를 설치합니다.

    sudo wget https://storage.googleapis.com/golang/go1.10.linux-amd64.tar.gz
    sudo tar -C /usr/local -xzf go1.10.linux-amd64.tar.gz
    export PATH="/usr/local/go/bin:${PATH}"
    
  5. Stickynotes 서버 코드를 복제합니다.

    git clone https://github.com/GoogleCloudPlatform/ios-docs-samples.git
    
  6. 인스턴스에서 Stickynotes 서버를 시작합니다. /solutions/stickynoteapi/REST/Go 디렉터리에서 다음 명령어를 실행합니다.

    sh SETUP
    

클라이언트 앱을 구성하고 실행하려면 다음 안내를 따르세요.

  1. Xcode에서 StickyNotesViewController.m을 편집하여 localhost를 이전 단계에서 기록한 Compute Engine 인스턴스의 외부 IP 필드 값으로 변경합니다.

    // static NSString \* const kHostAddress = @"localhost:8080";
    static NSString \* const kHostAddress = @"[YOUR-INSTANCE-EXTERNAL-IP]:8080";
    
  2. File(파일) > Save(저장)를 선택하여 변경사항을 저장합니다.

  3. Product(제품) > Run(실행)을 선택하여 클라이언트 앱을 빌드하고 시작합니다.

  4. 텍스트 필드에 메시지를 입력하고 Return(돌아가기)을 누릅니다.

메시지가 적힌 노란색 스티커 메모 이미지가 회색 배경을 대체합니다.

Testing on remote server...

삭제

이 가이드에서 사용한 리소스 비용이 Google Cloud Platform 계정에 청구되지 않도록 하려면 다음 안내를 따르세요.

프로젝트 삭제

비용이 청구되지 않도록 하는 가장 쉬운 방법은 가이드에서 만든 프로젝트를 삭제하는 것입니다.

프로젝트를 삭제하려면 다음 안내를 따르세요.

  1. Cloud Console에서 리소스 관리 페이지로 이동합니다.

    리소스 관리 페이지로 이동

  2. 프로젝트 목록에서 삭제할 프로젝트를 선택하고 삭제 를 클릭합니다.
  3. 대화상자에서 프로젝트 ID를 입력한 다음 종료를 클릭하여 프로젝트를 삭제합니다.

인스턴스 삭제

Compute Engine 인스턴스를 삭제하려면 다음 안내를 따르세요.

  1. Cloud Console에서 VM 인스턴스 페이지로 이동합니다.

    VM 인스턴스 페이지로 이동

  2. sticky-rest 인스턴스의 체크박스를 클릭합니다.
  3. 삭제 를 클릭하여 인스턴스를 삭제합니다.

기본 네트워크의 방화벽 규칙 삭제

방화벽 규칙을 삭제하려면 다음 안내를 따르세요.

  1. Cloud Console에서 방화벽 규칙 페이지로 이동합니다.

    방화벽 규칙 페이지로 이동

  2. 삭제할 방화벽 규칙의 체크박스를 클릭합니다.
  3. 삭제 를 클릭하여 방화벽 규칙을 삭제합니다.

다음 단계

이 샘플은 REST를 사용하여 Compute Engine에서 실행 중인 코드에 모바일 앱을 연결하는 방법의 기초를 보여줍니다. 이 샘플을 실제 앱으로 확장하려면 다음과 같은 개선사항을 추가해보세요.

  • 서버에 고정 외부 IP 주소 추가 — 기본적으로 Compute Engine 인스턴스와 연관된 외부 주소는 일시적입니다. 프로덕션 앱에서는 인스턴스에 고정 외부 IP 주소를 연결하세요. 자세한 내용은 인스턴스의 IP 주소 구성을 참조하세요.

  • 사용자 인증 정보를 사용하여 HTTPS 서버에 연결 — 모바일 앱이 사용자 인증 정보를 사용하여 서버에 스스로를 인증하도록 함으로써 해당 모바일 앱만 백엔드 서비스를 호출할 수 있도록 합니다. HTTP 대신 암호화된 HTTPS 프로토콜을 사용하여 사용자가 서버에 보내는 데이터의 개인정보를 보호합니다. 이를 위해 NGINX 서버를 인스턴스에서 SSL 프록시로 실행하거나 App Engine 가변형 환경에서 백엔드 서버를 실행할 수 있습니다. 자세한 내용은 VM 인스턴스에 안전하게 연결하기를 참조하세요.

  • 부하 분산 및 자동 확장 추가 — 수요가 증가할 때 추가 인스턴스를 가동하고 인스턴스에 트래픽을 고르게 전달하는 부하 분산기와 자동 확장 처리를 설정하여 트래픽 급증을 원활하게 처리합니다. 자세한 내용은 HTTP(S) 부하 분산 설정인스턴스 그룹 자동 확장을 참조하세요.

  • REST 대신 gRPC 프로토콜을 사용하여 탐색gRPC는 모바일 앱이 마치 로컬 객체인 것처럼 백엔드 서비스에 있는 메서드를 직접 호출할 수 있도록 하는 프레임워크입니다. gRPC를 사용하여 모바일 앱의 대역폭 효율성을 높이고 GCP에서 실행 중인 백엔드 서비스와 앱 간의 지연 시간을 줄일 수 있습니다. Stickynotes 샘플에서 gRPC를 사용하는 방법의 예시는 Google Compute Engine 및 gRPC를 사용하여 모바일 앱 빌드를 참조하세요.

  • 백엔드 서비스를 위한 다른 호스팅 옵션 고려 — Compute Engine은 가상 머신을 최대한으로 제어할 수 있는 대신에 인스턴스를 수동으로 업데이트하고 관리해야 합니다. Cloud Platform에서 모바일 백엔드 서비스를 호스트하는 다른 방법에 대해서는 Google Cloud를 사용하여 모바일 앱 빌드를 참조하세요.