Java 8은 지원이 종료되었으며 2026년 1월 31일에 지원 중단됩니다. 지원 중단 후에는 조직에서 이전에 조직 정책을 사용하여 레거시 런타임의 배포를 다시 사용 설정한 경우에도 Java 8 애플리케이션을 배포할 수 없습니다. 기존 Java 8 애플리케이션은 지원 중단 날짜 이후에도 계속 실행되고 트래픽을 수신합니다. 지원되는 최신 Java 버전으로 마이그레이션하는 것이 좋습니다.
Google Cloud Platform은 App Engine 인스턴스 세부정보(예: 포함하는 프로젝트의 ID, 서비스 계정, 서비스 계정에 사용되는 토큰)를 알고 있는 메타데이터 서버를 제공합니다. 간단한 HTTP 요청을 사용하여 이 데이터에 액세스할 수 있습니다. 이때 클라이언트 라이브러리는 필요하지 않습니다.
이 페이지에서는 적절한 메타데이터 서버 엔드포인트에 대한 HTTP 호출을 수행하여 배포된 자바 8 런타임 애플리케이션에서 인스턴스 메타데이터에 액세스하는 방법을 보여줍니다.
서비스 계정 토큰을 가져와서 이를 Google Cloud API 중 하나의 승인 헤더에 Bearer 토큰으로 제공하여 해당 API 서비스에 대해 애플리케이션을 인증하는 것도 이 API를 유용하게 사용하는 한 방법입니다.
이러한 Bearer 토큰을 사용하는 방법을 보여주는 예는 Google Cloud Translation API를 참조하세요.
사용할 메타데이터 엔드포인트 식별
다음 표에는 특정 메타데이터에 대해 HTTP 요청을 수행할 수 있는 엔드포인트가 나와 있습니다. 메타데이터 서버는 http://metadata.google.internal에서 액세스할 수 있습니다.
다른 Google Cloud API에 애플리케이션을 인증하기 위해 사용할 수 있는 인증 토큰을 반환합니다.
예를 들어 프로젝트 ID를 검색하려면 http://metadata.google.internal/computeMetadata/v1/project/project-id에 요청을 보냅니다.
메타데이터 요청
다음 샘플 코드에서는 서비스 계정 토큰을 제외하고 인스턴스에서 사용 가능한 모든 메타데이터를 가져와서 표시합니다.
@SuppressWarnings("serial")// With @WebServlet annotation the webapp/WEB-INF/web.xml is no longer required.@WebServlet(name="Metadata",description="Metadata: Write info about GAE Standard",urlPatterns="/metadata")publicclassMetadataServletextendsHttpServlet{privatefinalString[]metaPath={"/computeMetadata/v1/project/numeric-project-id",// (pending)"/computeMetadata/v1/project/project-id","/computeMetadata/v1/instance/zone","/computeMetadata/v1/instance/service-accounts/default/aliases","/computeMetadata/v1/instance/service-accounts/default/email","/computeMetadata/v1/instance/service-accounts/default/","/computeMetadata/v1/instance/service-accounts/default/scopes",// Tokens work - but are a security risk to display// "/computeMetadata/v1/instance/service-accounts/default/token"};finalString[]metaServiceAcct={"/computeMetadata/v1/instance/service-accounts/{account}/aliases","/computeMetadata/v1/instance/service-accounts/{account}/email","/computeMetadata/v1/instance/service-accounts/{account}/scopes",// Tokens work - but are a security risk to display// "/computeMetadata/v1/instance/service-accounts/{account}/token"};privatefinalStringmetadata="http://metadata.google.internal";privateTemplateEnginetemplateEngine;// Use OkHttp from Square as it's quite easy to use for simple fetches.privatefinalOkHttpClientok=newOkHttpClient.Builder().readTimeout(500,TimeUnit.MILLISECONDS)// Don't dawdle.writeTimeout(500,TimeUnit.MILLISECONDS).build();// Setup to pretty print returned jsonprivatefinalGsongson=newGsonBuilder().setPrettyPrinting().create();privatefinalJsonParserjp=newJsonParser();// Fetch MetadataStringfetchMetadata(Stringkey)throwsIOException{Requestrequest=newRequest.Builder().url(metadata+key).addHeader("Metadata-Flavor","Google").get().build();Responseresponse=ok.newCall(request).execute();returnresponse.body().string();}StringfetchJsonMetadata(Stringprefix)throwsIOException{Requestrequest=newRequest.Builder().url(metadata+prefix).addHeader("Metadata-Flavor","Google").get().build();Responseresponse=ok.newCall(request).execute();// Convert json to prety jsonreturngson.toJson(jp.parse(response.body().string()));}@Overridepublicvoidinit(){// Setup ThymeLeafServletContextTemplateResolvertemplateResolver=newServletContextTemplateResolver(this.getServletContext());templateResolver.setPrefix("/WEB-INF/templates/");templateResolver.setSuffix(".html");templateResolver.setCacheTTLMs(Long.valueOf(1200000L));// TTL=20m// Cache is set to true by default. Set to false if you want templates to// be automatically updated when modified.templateResolver.setCacheable(true);templateEngine=newTemplateEngine();templateEngine.setTemplateResolver(templateResolver);}@OverridepublicvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)throwsIOException{StringdefaultServiceAccount="";WebContextctx=newWebContext(req,resp,getServletContext(),req.getLocale());resp.setContentType("text/html");Stringenvironment=(String)System.getProperties().get("com.google.appengine.runtime.environment");ctx.setVariable("production",environment);// The metadata server is only on a production systemif(environment.equals("Production")){TreeMap<String,String>m=newTreeMap<>();for(Stringkey:metaPath){m.put(key,fetchMetadata(key));if(key.contains("default/email")){defaultServiceAccount=m.get(key);}}ctx.setVariable("Metadata",m.descendingMap());m=newTreeMap<>();for(Stringkey:metaServiceAcct){// substitute a service account for {account}key=key.replace("{account}",defaultServiceAccount);m.put(key,fetchMetadata(key));}ctx.setVariable("sam",m.descendingMap());// Recursivly get all info about service accounts -- Note tokens are leftout by default.ctx.setVariable("rsa",fetchJsonMetadata("/computeMetadata/v1/instance/service-accounts/?recursive=true"));// Recursivly get all data on Metadata server.ctx.setVariable("ram",fetchJsonMetadata("/?recursive=true"));}templateEngine.process("index",ctx,resp.getWriter());}}
샘플 코드에서 앱이 프로덕션 환경에서 실행 중인지 보는 검사를 확인합니다. 앱이 로컬에서 실행 중인 경우 요청에서 메타데이터가 반환되지 않습니다.
배포된 애플리케이션에서 메타데이터 서버를 사용할 수 있습니다. 개발 서버에서 로컬로 실행하는 것은 지원되지 않습니다. 위에 제공된 샘플 코드와 같이 앱이 프로덕션 환경에서 실행 중인 경우에만 메타데이터 결과를 반환하도록 코드에 환경 검사를 추가할 수 있습니다.
Stringenvironment=(String)System.getProperties().get("com.google.appengine.runtime.environment");ctx.setVariable("production",environment);// The metadata server is only on a production systemif(environment.equals("Production")){...//show metadata results}
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["이해하기 어려움","hardToUnderstand","thumb-down"],["잘못된 정보 또는 샘플 코드","incorrectInformationOrSampleCode","thumb-down"],["필요한 정보/샘플이 없음","missingTheInformationSamplesINeed","thumb-down"],["번역 문제","translationIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2025-09-04(UTC)"],[[["\u003cp\u003eGoogle Cloud Platform's metadata server provides details about your App Engine instance, accessible via simple HTTP requests to endpoints like \u003ccode\u003ehttp://metadata.google.internal\u003c/code\u003e, without needing client libraries.\u003c/p\u003e\n"],["\u003cp\u003eThe metadata server allows you to retrieve information such as project ID, zone, and service account details, including email and supported scopes.\u003c/p\u003e\n"],["\u003cp\u003eA key feature is the ability to retrieve a service account token from the metadata server, which can be used as a bearer token to authenticate your application with other Google Cloud APIs.\u003c/p\u003e\n"],["\u003cp\u003eAccessing the metadata server requires using native sockets like \u003ccode\u003ejava.net.HttpURLConnection\u003c/code\u003e and does not support the urlfetch service.\u003c/p\u003e\n"],["\u003cp\u003eThe metadata server is only accessible in a deployed environment; local development environments will not return metadata results, as shown in the example code's production check.\u003c/p\u003e\n"]]],[],null,["# Accessing Instance Metadata\n\nGoogle Cloud Platform provides a metadata server that knows details about your\nApp Engine instance, such as its containing project ID, service accounts, and\ntokens used by the service accounts. You can access this data using simple HTTP\nrequests: no client libraries are required.\n\nThis page shows how to access instance metadata from your deployed Java 8\nruntime application\nby making HTTP calls to the appropriate metadata server endpoints.\n| **Note:** Metadata access is currently read only: you cannot write your own metadata for an instance.\n\nOne useful way to use this API is to get the service account token and\nsupply it as a bearer token in the Authorization header of one of the Google\nCloud APIs, to authenticate your application to that particular API service.\nSee the [Google Cloud Translation API](/translate/docs/quickstart)\ndocumentation for an example of how these bearer tokens are used.\n\nIdentifying which metadata endpoint to use\n------------------------------------------\n\nThe following table lists the endpoints where you can make HTTP requests for\nspecific metadata. The metadata server is accessible at\n`http://metadata.google.internal`.\n\nFor example, to retrieve your project ID, send a request to\n`http://metadata.google.internal/computeMetadata/v1/project/project-id`.\n\nMaking metadata requests\n------------------------\n\n| **Important:** Access to the metadata server must use native sockets, such as those provided by `java.net.HttpURLConnection` or the native `url-stream-handler`. The metadata server does not support the [urlfetch](/appengine/docs/legacy/standard/java/issue-requests#using_urlfetch_in_a_java_8_app) service.\n\nThe following sample code gets all of the metadata available for the instance\nand displays it, except for the service account token. \n\n @SuppressWarnings(\"serial\")\n // With @WebServlet annotation the webapp/WEB-INF/web.xml is no longer required.\n @WebServlet(name = \"Metadata\", description = \"Metadata: Write info about GAE Standard\",\n urlPatterns = \"/metadata\")\n public class MetadataServlet extends HttpServlet {\n\n private final String[] metaPath = {\n \"/computeMetadata/v1/project/numeric-project-id\", // (pending)\n \"/computeMetadata/v1/project/project-id\",\n \"/computeMetadata/v1/instance/zone\",\n \"/computeMetadata/v1/instance/service-accounts/default/aliases\",\n \"/computeMetadata/v1/instance/service-accounts/default/email\",\n \"/computeMetadata/v1/instance/service-accounts/default/\",\n \"/computeMetadata/v1/instance/service-accounts/default/scopes\",\n // Tokens work - but are a security risk to display\n // \"/computeMetadata/v1/instance/service-accounts/default/token\"\n };\n\n final String[] metaServiceAcct = {\n \"/computeMetadata/v1/instance/service-accounts/{account}/aliases\",\n \"/computeMetadata/v1/instance/service-accounts/{account}/email\",\n \"/computeMetadata/v1/instance/service-accounts/{account}/scopes\",\n // Tokens work - but are a security risk to display\n // \"/computeMetadata/v1/instance/service-accounts/{account}/token\"\n };\n\n private final String metadata = \"http://metadata.google.internal\";\n private TemplateEngine templateEngine;\n\n // Use OkHttp from Square as it's quite easy to use for simple fetches.\n private final OkHttpClient ok = new OkHttpClient.Builder()\n .readTimeout(500, TimeUnit.MILLISECONDS) // Don't dawdle\n .writeTimeout(500, TimeUnit.MILLISECONDS)\n .build();\n\n // Setup to pretty print returned json\n private final Gson gson = new GsonBuilder()\n .setPrettyPrinting()\n .create();\n private final JsonParser jp = new JsonParser();\n\n // Fetch Metadata\n String fetchMetadata(String key) throws IOException {\n Request request = new Request.Builder()\n .url(metadata + key)\n .addHeader(\"Metadata-Flavor\", \"Google\")\n .get()\n .build();\n\n Response response = ok.newCall(request).execute();\n return response.body().string();\n }\n\n String fetchJsonMetadata(String prefix) throws IOException {\n Request request = new Request.Builder()\n .url(metadata + prefix)\n .addHeader(\"Metadata-Flavor\", \"Google\")\n .get()\n .build();\n\n Response response = ok.newCall(request).execute();\n\n // Convert json to prety json\n return gson.toJson(jp.parse(response.body().string()));\n }\n\n @Override\n public void init() {\n // Setup ThymeLeaf\n ServletContextTemplateResolver templateResolver =\n new ServletContextTemplateResolver(this.getServletContext());\n\n templateResolver.setPrefix(\"/WEB-INF/templates/\");\n templateResolver.setSuffix(\".html\");\n templateResolver.setCacheTTLMs(Long.valueOf(1200000L)); // TTL=20m\n\n // Cache is set to true by default. Set to false if you want templates to\n // be automatically updated when modified.\n templateResolver.setCacheable(true);\n\n templateEngine = new TemplateEngine();\n templateEngine.setTemplateResolver(templateResolver);\n }\n\n @Override\n public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {\n String defaultServiceAccount = \"\";\n WebContext ctx = new WebContext(req, resp, getServletContext(), req.getLocale());\n\n resp.setContentType(\"text/html\");\n\n String environment =\n (String) System.getProperties().get(\"com.google.appengine.runtime.environment\");\n ctx.setVariable(\"production\", environment);\n\n // The metadata server is only on a production system\n if (environment.equals(\"Production\")) {\n\n TreeMap\u003cString, String\u003e m = new TreeMap\u003c\u003e();\n\n for (String key : metaPath) {\n m.put(key, fetchMetadata(key));\n if (key.contains(\"default/email\")) {\n defaultServiceAccount = m.get(key);\n }\n }\n\n ctx.setVariable(\"Metadata\", m.descendingMap());\n\n m = new TreeMap\u003c\u003e();\n for (String key : metaServiceAcct) {\n // substitute a service account for {account}\n key = key.replace(\"{account}\", defaultServiceAccount);\n m.put(key, fetchMetadata(key));\n }\n ctx.setVariable(\"sam\", m.descendingMap());\n\n // Recursivly get all info about service accounts -- Note tokens are leftout by default.\n ctx.setVariable(\"rsa\",\n fetchJsonMetadata(\"/computeMetadata/v1/instance/service-accounts/?recursive=true\"));\n // Recursivly get all data on Metadata server.\n ctx.setVariable(\"ram\", fetchJsonMetadata(\"/?recursive=true\"));\n }\n\n templateEngine.process(\"index\", ctx, resp.getWriter());\n\n }\n }\n\nIn the sample code, notice the check to make sure the app is running in\nproduction. If the app is running locally, no metadata will be returned from\nthe requests.\n\nAlso, notice the use of the [Google Gson JSON](https://github.com/google/gson)\nserializer / deserializer, the [OkHttp](http://square.github.io/okhttp/) HTTP\nand HTTP2 client, and the [Thymeleaf](http://www.thymeleaf.org/) templating\nsystem. These are not required, but they are useful libraries for your own\nprojects.\n\nRunning locally\n---------------\n\nThe metadata server is available for deployed applications: running locally\non the development server is not supported. You can add an environment check to\nyour code to expect metadata results only if the app is running in production,\nas shown in the sample code provided above: \n\n String environment =\n (String) System.getProperties().get(\"com.google.appengine.runtime.environment\");\n ctx.setVariable(\"production\", environment);\n\n // The metadata server is only on a production system\n if (environment.equals(\"Production\")) {\n ... //show metadata results\n }"]]