자바 SDK에는 모든 자바 애플리케이션에서 App Engine 서비스에 투명하게 액세스할 수 있는 Remote API라는 라이브러리가 포함되어 있습니다. 예를 들어 Remote API를 사용하여 로컬 머신에서 실행 중인 앱에서 프로덕션 Datastore에 액세스할 수 있습니다. 또한 Remote API를 사용하여 App Engine 앱에서 다른 App Engine 앱의 Datastore에 액세스할 수도 있습니다.
서버에서 Remote API 구성
Remote API의 서버 구성요소는 자바용 App Engine 런타임의 일부인 자바 서블릿입니다. 이 서블릿은 Remote API 클라이언트로부터 요청을 수신하여 적절한 백엔드 서비스에 전달하고 서비스 호출 결과를 클라이언트에게 반환합니다. Remote API 서블릿을 설치하려면 다음을 web.xml
에 추가합니다.
인증된 사용자가 없거나 인증된 사용자가 애플리케이션의 관리자가 아닌 경우 서블릿은 오류를 반환하므로 보안을 추가로 구성할 필요가 없습니다. 이 설정으로 앱을 배포하고 나면 Remote API 클라이언트가 설치된 모든 앱에서 해당 서비스를 사용할 수 있습니다. 여기에는 Python Remote API를 사용하는 Python 클라이언트도 포함됩니다.
독립형 클라이언트에서 Remote API 구성
자바 애플리케이션 내에서 사용할 수 있도록 Remote API의 클라이언트 구성요소를 구성하려면 클래스 경로에 ${SDK_ROOT}/lib/impl/appengine-api.jar
및 ${SDK_ROOT}/lib/appengine-remote-api.jar
를 추가합니다. 그런 후 코드에서 다음과 같이 Remote API를 구성하고 설치합니다.
import com.google.appengine.tools.remoteapi.RemoteApiInstaller;
import com.google.appengine.tools.remoteapi.RemoteApiOptions;
// ...
RemoteApiOptions options = new RemoteApiOptions()
.server("[APP_ID].[REGION_ID].r.appspot.com", 443)
.useApplicationDefaultCredential();
RemoteApiInstaller installer = new RemoteApiInstaller();
installer.install(options);
// ... all API calls executed remotely
installer.uninstall();
Remote API 클라이언트는 OAuth 2.0을 사용하는 애플리케이션 기본 사용자 인증 정보를 사용합니다.
사용자 인증 정보를 가져오려면 다음을 실행합니다.
gcloud auth application-default login
개발 서버에서 로컬로 실행되는 App Engine 앱에도 다음과 같이 손쉽게 연결할 수 있습니다.
RemoteApiOptions options = new RemoteApiOptions()
.server("localhost", 8888) // server name must equal "localhost"
.useDevelopmentServerCredential();
다음은 실행될 때 Datastore에 항목을 삽입하는 완성된 자바 애플리케이션입니다.
App Engine 클라이언트에서 Remote API 구성
Remote API를 사용하여 App Engine 앱에서 다른 App Engine 앱의 서비스에 액세스할 수도 있습니다. 독립형 자바 클라이언트에서와 마찬가지로 WEB-INF/lib
디렉터리에 ${SDK_ROOT}/lib/appengine-remote-api.jar
를 추가하고 클라이언트 App Engine 앱에서 Remote API를 구성 및 설치해야 합니다.
RemoteApiInstaller
는 설치를 수행하는 스레드에만 Remote API를 설치하므로 스레드 간에 이 클래스의 인스턴스를 공유하지 않도록 주의합니다.
Maven에 Remote API 사용하기
Maven 프로젝트에서 Remote API 기능을 사용하려면 다음 종속 항목을 프로젝트 pom.xml
파일에 추가합니다.
제한사항 및 권장사항
remote_api 모듈은 기본 App Engine Datastore와 완전히 동일하게 작동되도록 하기 위해 최대한으로 시도합니다. 즉, 경우에 따라 효율성이 떨어지는 작업을 수행하기도 한다는 의미입니다. 따라서 remote_api를 사용할 때는 다음 사항에 주의하시기 바랍니다.
모든 Datastore 요청에 왕복이 필요함
HTTP를 통해 Datastore에 액세스하는 경우 로컬에서 액세스할 때보다 오버헤드와 지연 시간이 좀 더 늘어날 수 있습니다. 시간을 단축하고 부하를 줄이기 위해서는 get과 put 작업을 일괄 처리하고 쿼리 항목을 일괄적으로 가져와 왕복 횟수를 제한해야 합니다. 일괄 작업은 단일 Datastore 작업으로만 간주되기 때문에 이 방식은 remote_api뿐만 아니라 일반적으로 Datastore를 사용할 때도 유용합니다.
remote_api 요청 시 할당량이 사용됨
remote_api가 HTTP를 통해 작동하므로 Datastore를 호출할 때마다 HTTP 요청에 대한 할당량(바이트 단위 입출력)뿐만 아니라 일반적으로 예상되는 Datastore 할당량이 차감됩니다. 일괄 업데이트에 remote_api를 사용하는 경우 이 점을 염두에 두시기 바랍니다.
1MB API 제한 적용
기본 실행에서와 마찬가지로 API 요청 및 응답에는 1MB 제한이 계속 적용됩니다. 특히 항목 크기가 큰 경우 이 한도가 초과되지 않도록 한 번에 수행하는 fetch 또는 put 작업 횟수를 제한해야 할 수 있습니다. 이 경우 왕복을 최소화하는 접근 방식과 상충되기 때문에 요청 또는 응답 크기의 제한을 넘지 않는 범위 내에서 가장 큰 배치를 사용하는 것이 좋습니다. 그러나 대부분의 항목에서는 이 제한이 문제가 되지 않습니다.
쿼리 반복 방지
쿼리를 반복 실행하는 경우 SDK에서는 Datastore의 항목을 20개 단위의 배치로 가져오며 기존의 항목이 소모될 때마다 새 배치를 가져옵니다. 각 배치는 remote_api를 통해 별도 요청으로 가져와야 하기 때문에 효율성이 떨어질 수밖에 없습니다. 대신 remote_api는 오프셋 기능을 사용하여 배치별로 완전히 새로운 쿼리를 실행하므로 결과의 정확성이 높아집니다.
필요한 항목 수를 알고 있다면 필요한 숫자를 요청하는 방식으로 하나의 요청에서 전체 가져오기를 처리할 수 있습니다.
원하는 항목 수를 모르는 경우에는 커서를 사용하여 큰 결과 집합을 효율적으로 반복할 수 있습니다. 이렇게 하면 일반적인 Datastore 쿼리에 적용되는 1,000개 항목 제한을 피할 수 있습니다.
트랜잭션의 효율성이 떨어짐
remote_api를 통해 트랜잭션을 구현하기 위해 트랜잭션 내에서 가져온 항목에 대한 정보와 트랜잭션 내에서 배치 또는 삭제한 항목의 사본이 축적됩니다. 트랜잭션이 커밋되면 이 모든 정보가 App Engine 서버로 전송되며, 이때 트랜잭션에 사용된 모든 항목을 다시 가져와 변경되지 않았는지 확인한 다음 트랜잭션에 적용된 모든 변경사항에 대해 put 및 delete 작업을 수행한 후 커밋합니다. 충돌이 발생하면 서버가 트랜잭션을 롤백하고 클라이언트 측에 이를 알립니다. 그러면 클라이언트가 전체 프로세스를 처음부터 다시 반복해야 합니다.
이 접근 방식은 제대로 작동하며 트랜잭션에서 제공된 기능을 로컬 Datastore에 정확하게 복제하지만, 다소 비효율적입니다. 따라서 어떤 경우에도 꼭 필요한 경우에만 트랜잭션을 사용해야 하며 효율성을 위해 실행할 트랜잭션의 수와 복잡성을 제한해야 합니다.