Jib के साथ Google App Engine Java ऐप्लिकेशन से क्लाउड रन पर माइग्रेट करना

1. खास जानकारी

कोडलैब की इस सीरीज़ (अपने हिसाब से सीखने और प्रैक्टिकल करने वाले ट्यूटोरियल) का मकसद, Google App Engine (स्टैंडर्ड) के Java डेवलपर की मदद करना है. इसके तहत, उन्हें माइग्रेशन की सीरीज़ के बारे में जानकारी देकर, अपने ऐप्लिकेशन को बेहतर बनाने में मदद की जाती है. यह तरीका अपनाकर, अपने ऐप्लिकेशन को ज़्यादा पोर्टेबल बनाया जा सकता है. साथ ही, उन्हें Cloud Run, App Engine की कंटेनर-होस्टिंग से जुड़ी सेवा, और कंटेनर-होस्टिंग की अन्य सेवाओं के लिए कंटेनर में बदला जा सकता है.

इस ट्यूटोरियल में, Jib का इस्तेमाल करके, App Engine ऐप्लिकेशन को कंटेनर में बदलने का तरीका बताया गया है, ताकि उसे Cloud Run की पूरी तरह से मैनेज की गई सेवा पर डिप्लॉय किया जा सके. Jib की मदद से, Docker इमेज बनाई जा सकती हैं. यह इंडस्ट्री में कंटेनर में ऐप्लिकेशन डेवलप करने, शिप करने, और चलाने के लिए एक जाना-माना प्लैटफ़ॉर्म है.

इस कोडलैब में, App Engine से Cloud Run पर माइग्रेट करने के लिए ज़रूरी चरणों के बारे में बताया गया है. साथ ही, इसमें Java 8 App Engine ऐप्लिकेशन को Java 17 पर अपग्रेड करने का तरीका भी बताया गया है.

अगर आपका ऐप्लिकेशन, App Engine की लेगसी बंडल की गई सेवाओं या App Engine की अन्य सुविधाओं का ज़्यादा इस्तेमाल करता है, तो हमारा सुझाव है कि Cloud Run पर माइग्रेट करने से पहले, उन बंडल की गई सेवाओं को बंद कर दें या उन सुविधाओं को बदल दें. अगर आपको माइग्रेशन के विकल्पों के बारे में ज़्यादा जानकारी चाहिए या कुछ समय के लिए बंडल की गई लेगसी सेवाओं का इस्तेमाल जारी रखना है, तो नए रनटाइम पर अपग्रेड करते समय, Java 11/17 के लिए App Engine की बंडल की गई सेवाओं को ऐक्सेस किया जा सकता है. जब आपका ऐप्लिकेशन ज़्यादा पोर्टेबल हो जाए, तब इस कोडलैब पर वापस आएं. यहां आपको अपने ऐप्लिकेशन में निर्देशों को लागू करने का तरीका मिलेगा.

आपको इनके बारे में जानकारी मिलेगी

  • Cloud Shell का इस्तेमाल करना
  • Cloud Run, Artifact Registry, और Cloud Build API चालू करें
  • Jib और Cloud Build का इस्तेमाल करके, अपने ऐप्लिकेशन का कोड बंडल करना
  • अपनी कंटेनर इमेज को Cloud Run पर डिप्लॉय करना

आपको इन चीज़ों की ज़रूरत होगी

सर्वे

इस ट्यूटोरियल का इस्तेमाल कैसे किया जाएगा?

सिर्फ़ इसे पढ़ें इसे पढ़ें और एक्सरसाइज़ पूरी करें

Java के साथ अपने अनुभव को आप क्या रेटिंग देंगे?

शुरुआती सामान्य एडवांस

Google Cloud की सेवाओं को इस्तेमाल करने के अपने अनुभव को आप क्या रेटिंग देंगे?

शुरुआती सामान्य एडवांस

2. बैकग्राउंड

App Engine और Cloud Functions जैसे प्लैटफ़ॉर्म ऐज़ अ सर्विस (PaaS) सिस्टम, आपकी टीम और ऐप्लिकेशन के लिए कई सुविधाएं उपलब्ध कराते हैं. जैसे, SysAdmins और Devops को समाधान बनाने पर फ़ोकस करने की सुविधा. सर्वरलेस प्लैटफ़ॉर्म की मदद से, आपका ऐप्लिकेशन ज़रूरत के हिसाब से अपने-आप स्केल अप हो सकता है. साथ ही, इस्तेमाल के हिसाब से बिलिंग की सुविधा के साथ, लागत को कंट्रोल करने के लिए स्केल डाउन होकर शून्य पर आ सकता है. इसके अलावा, यह डेवलपमेंट के लिए इस्तेमाल की जाने वाली कई सामान्य भाषाओं का इस्तेमाल कर सकता है.

हालांकि, कंटेनर की सुविधा भी काफ़ी काम की है. कंटेनर की मदद से, किसी भी भाषा, लाइब्रेरी, और बाइनरी को चुना जा सकता है. इससे आपको दो फ़ायदे मिलते हैं: सर्वरलेस की सुविधा के साथ-साथ कंटेनर का इस्तेमाल करने की सुविधा. Cloud Run इसी तरह काम करता है.

इस कोडलैब में, Cloud Run को इस्तेमाल करने का तरीका नहीं बताया गया है. इसके बारे में जानने के लिए, Cloud Run के दस्तावेज़ पढ़ें. इस गाइड का मकसद यह है कि आप Cloud Run या कंटेनर होस्ट करने वाली अन्य सेवाओं के लिए, अपने App Engine ऐप्लिकेशन को कंटेनर में बदलने का तरीका जान सकें. आगे बढ़ने से पहले, आपको कुछ बातें जाननी चाहिए. इनमें सबसे अहम यह है कि आपको थोड़ा अलग अनुभव मिलेगा.

इस कोडलैब में, कंटेनर बनाने और उन्हें डिप्लॉय करने का तरीका बताया गया है. आपको, इनके बारे में जानकारी मिलेगी:

  • Jib की मदद से अपने ऐप्लिकेशन को कंटेनर में बदलना
  • App Engine कॉन्फ़िगरेशन से माइग्रेट करना
  • इसके अलावा, Cloud Build के लिए बिल्ड के चरणों को तय करें.

इसके लिए, आपको App Engine की कुछ खास सुविधाओं का इस्तेमाल बंद करना होगा. अगर आपको यह तरीका नहीं अपनाना है, तो भी Java 11/17 रनटाइम पर अपग्रेड किया जा सकता है. इसके लिए, आपको अपने ऐप्लिकेशन को App Engine पर ही रखना होगा.

3. सेटअप/प्रीवर्क

1. प्रोजेक्ट सेट अप करें

इस ट्यूटोरियल के लिए, आपको नए प्रोजेक्ट पर appengine-java-migration-samples रिपॉज़िटरी से सैंपल ऐप्लिकेशन का इस्तेमाल करना होगा. पक्का करें कि प्रोजेक्ट के लिए, बिलिंग खाता चालू हो.

अगर आपको किसी मौजूदा App Engine ऐप्लिकेशन को Cloud Run पर ले जाना है, तो इसके लिए उस ऐप्लिकेशन का इस्तेमाल किया जा सकता है.

अपने प्रोजेक्ट के लिए ज़रूरी एपीआई चालू करने के लिए, यह कमांड चलाएं:

gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com run.googleapis.com

2. बेसलाइन का सैंपल ऐप्लिकेशन पाएं

सैंपल ऐप्लिकेशन को अपनी मशीन या Cloud Shell पर क्लोन करें. इसके बाद, baseline फ़ोल्डर पर जाएं.

यह सैंपल, Java 8 और Servlet पर आधारित Datastore ऐप्लिकेशन है. इसे App Engine पर डिप्लॉय करने के लिए बनाया गया है. App Engine पर डिप्लॉय करने के लिए इस ऐप्लिकेशन को तैयार करने का तरीका जानने के लिए, README में दिए गए निर्देशों का पालन करें.

3. (ज़रूरी नहीं) बेसलाइन ऐप्लिकेशन डिप्लॉय करना

अगर आपको यह पुष्टि करनी है कि ऐप्लिकेशन, Cloud Run पर माइग्रेट करने से पहले App Engine पर काम करता है, तो आपको यह तरीका अपनाना होगा.

README.md में दिए गए निर्देशों का पालन करें:

  1. gcloud सीएलआई इंस्टॉल करें/इसके बारे में फिर से जानें
  2. gcloud init की मदद से, अपने प्रोजेक्ट के लिए gcloud सीएलआई का इस्तेमाल शुरू करें
  3. gcloud app create की मदद से App Engine प्रोजेक्ट बनाएं
  4. App Engine पर सैंपल ऐप्लिकेशन डिप्लॉय करना
./mvnw package appengine:deploy -Dapp.projectId=$PROJECT_ID
  1. पुष्टि करें कि ऐप्लिकेशन, App Engine पर बिना किसी समस्या के काम करता है

4. Artifact Registry में डेटा स्टोर करने की जगह बनाना

अपने ऐप्लिकेशन को कंटेनर में बदलने के बाद, आपको अपनी इमेज को पुश और सेव करने के लिए किसी जगह की ज़रूरत होगी. Google Cloud पर ऐसा करने का सबसे सही तरीका, Artifact Registry का इस्तेमाल करना है.

gcloud का इस्तेमाल करके, migration नाम की रिपॉज़िटरी बनाएं. इसके लिए, यह तरीका अपनाएं:

gcloud artifacts repositories create migration --repository-format=docker \
--description="Docker repository for the migrated app" \
--location="northamerica-northeast1"

ध्यान दें कि इस रिपॉज़िटरी में docker फ़ॉर्मैट टाइप का इस्तेमाल किया गया है. हालांकि, कई तरह की रिपॉज़िटरी उपलब्ध हैं.

इस समय, आपके पास App Engine ऐप्लिकेशन का बेसलाइन वर्शन है. साथ ही, आपका Google Cloud प्रोजेक्ट, इसे Cloud Run पर माइग्रेट करने के लिए तैयार है.

4. ऐप्लिकेशन की फ़ाइलों में बदलाव करना

अगर आपका ऐप्लिकेशन, App Engine की लेगसी बंडल की गई सेवाओं, कॉन्फ़िगरेशन या App Engine की अन्य सुविधाओं का ज़्यादा इस्तेमाल करता है, तो हमारा सुझाव है कि नए रनटाइम पर अपग्रेड करते समय, उन सेवाओं का ऐक्सेस जारी रखें. इस कोडलैब में, उन ऐप्लिकेशन के लिए माइग्रेशन का तरीका बताया गया है जो पहले से ही स्टैंडअलोन सेवाओं का इस्तेमाल करते हैं या जिन्हें ऐसा करने के लिए आसानी से रीफ़ैक्टर किया जा सकता है.

1. Java 17 पर अपग्रेड करना

अगर आपका ऐप्लिकेशन Java 8 पर है, तो सुरक्षा से जुड़े अपडेट पाने और भाषा से जुड़ी नई सुविधाओं का ऐक्सेस पाने के लिए, इसे एलटीएस के नए वर्शन, जैसे कि 11 या 17 पर अपग्रेड करें.

pom.xml में मौजूद प्रॉपर्टी अपडेट करें. इनमें ये प्रॉपर्टी शामिल करें:

<properties>
    <java.version>17</java.version>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
</properties>

इससे प्रोजेक्ट का वर्शन 17 पर सेट हो जाएगा. साथ ही, कंपाइलर प्लगिन को यह सूचना मिल जाएगी कि आपको Java 17 की भाषा से जुड़ी सुविधाओं का ऐक्सेस चाहिए. इसके अलावा, कंपाइल की गई क्लास Java 17 JVM के साथ काम करेंगी.

2. इसमें वेब सर्वर भी शामिल है

App Engine और Cloud Run के बीच कई अंतर हैं. इसलिए, एक से दूसरे पर माइग्रेट करते समय इन अंतरों पर ध्यान देना ज़रूरी है. एक अंतर यह है कि App Engine के Java 8 रनटाइम में, होस्ट किए गए ऐप्लिकेशन के लिए Jetty सर्वर उपलब्ध कराया जाता था और उसे मैनेज किया जाता था. हालांकि, Cloud Run में ऐसा नहीं होता. हम वेब सर्वर और सर्वलेट कंटेनर के लिए, Spring Boot का इस्तेमाल करेंगे.

ये डिपेंडेंसी जोड़ें:

<dependencies>
<!-- ... -->
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
       <version>2.6.6</version>
       <exclusions>
           <!-- Exclude the Tomcat dependency -->
           <exclusion>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-starter-tomcat</artifactId>
           </exclusion>
       </exclusions>
   </dependency>
   <!-- Use Jetty instead -->
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-jetty</artifactId>
       <version>2.6.6</version>
   </dependency>
<!-- ... -->
</dependencies>

Spring Boot, डिफ़ॉल्ट रूप से Tomcat सर्वर को एम्बेड करता है. हालांकि, यह सैंपल उस आर्टफ़ैक्ट को शामिल नहीं करेगा और Jetty का इस्तेमाल करेगा, ताकि माइग्रेशन के बाद डिफ़ॉल्ट व्यवहार में अंतर कम से कम हो. हम Jetty के वर्शन को भी कॉन्फ़िगर कर सकते हैं, ताकि यह App Engine के डिफ़ॉल्ट वर्शन से मेल खाए.

<properties>
    <java.version>17</java.version>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <jetty.version>9.4.46.v20220331</jetty.version>
</properties>

3. Spring Boot सेटअप करना

Spring Boot, आपके सर्वलेट को बिना किसी बदलाव के फिर से इस्तेमाल कर पाएगा. हालांकि, उन्हें ढूंढने के लिए कुछ कॉन्फ़िगरेशन की ज़रूरत होगी.

com.example.appengine पैकेज में यह MigratedServletApplication.java क्लास बनाएं:

package com.example.appengine;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@ServletComponentScan
@SpringBootApplication
@EnableAutoConfiguration
public class MigratedServletApplication {
    public static void main(String[] args) {
        SpringApplication.run(MigratedServletApplication.class, args);
    }
}

ध्यान दें कि इसमें @ServletComponentScan एनोटेशन शामिल है. यह डिफ़ॉल्ट रूप से मौजूदा पैकेज में किसी भी @WebServlets को खोजेगा और उन्हें उम्मीद के मुताबिक उपलब्ध कराएगा.

4. ऐप्लिकेशन को JAR के तौर पर पैकेज करना

Jib की मदद से, अपने ऐप्लिकेशन को WAR फ़ाइल से शुरू करके कंटेनर में बदला जा सकता है. हालांकि, अगर ऐप्लिकेशन को एक्ज़ीक्यूटेबल JAR के तौर पर पैकेज किया जाता है, तो यह प्रोसेस आसान हो जाती है. इसके लिए, ज़्यादा कॉन्फ़िगरेशन की ज़रूरत नहीं होगी. खास तौर पर, Maven का इस्तेमाल बिल्ड टूल के तौर पर करने वाले प्रोजेक्ट के लिए, क्योंकि जार पैकेजिंग डिफ़ॉल्ट रूप से चालू होती है.

pom.xml फ़ाइल में मौजूद packaging टैग हटाएं:

<packaging>war</packaging>

इसके बाद, spring-boot-maven-plugin जोड़ें:

<plugins>
<!-- ... -->
  <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>2.6.6</version>
  </plugin>
<!-- ... -->
</plugins>

5. App Engine के कॉन्फ़िगरेशन, सेवाओं, और डिपेंडेंसी से माइग्रेट करना

कोड लैब की शुरुआत में बताया गया है कि Cloud Run और App Engine को अलग-अलग उपयोगकर्ता अनुभव देने के लिए डिज़ाइन किया गया है. App Engine की कुछ ऐसी सुविधाएं हैं जो बॉक्स से बाहर उपलब्ध होती हैं. जैसे, Cron और Task Queue सेवाएं. इन्हें मैन्युअल तरीके से फिर से बनाना होगा. इनके बारे में ज़्यादा जानकारी, आने वाले मॉड्यूल में दी जाएगी.

सैंपल ऐप्लिकेशन, लेगसी बंडल की गई सेवाओं का इस्तेमाल नहीं करता है. हालांकि, जिन उपयोगकर्ताओं के ऐप्लिकेशन ऐसा करते हैं वे इन गाइड को देख सकते हैं:

अब से Cloud Run पर डिप्लॉय किया जाएगा. इसलिए, appengine-maven-plugin को हटाया जा सकता है:

<plugin>
 <groupId>com.google.cloud.tools</groupId>
 <artifactId>appengine-maven-plugin</artifactId>
 <version>2.4.1</version>
 <configuration>
   <!-- can be set w/ -DprojectId=myProjectId on command line -->
   <projectId>${app.projectId}</projectId>
   <!-- set the GAE version or use "GCLOUD_CONFIG" for an autogenerated GAE version -->
   <version>GCLOUD_CONFIG</version>
 </configuration>
</plugin>

5. ऐप्लिकेशन को कंटेनर में बदलना

इस समय, अपने ऐप्लिकेशन को Cloud Run पर मैन्युअल तरीके से डिप्लॉय किया जा सकता है. इसके लिए, सीधे अपने सोर्स कोड से डिप्लॉय करें. यह एक बेहतरीन विकल्प है. इसमें Cloud Build का इस्तेमाल बैकग्राउंड में किया जाता है, ताकि आपको डिप्लॉयमेंट का बेहतर अनुभव मिल सके. हम बाद के मॉड्यूल में, सोर्स डिप्लॉयमेंट के बारे में ज़्यादा जानकारी देंगे.

इसके अलावा, अगर आपको ऐप्लिकेशन को डिप्लॉय करने के तरीके पर ज़्यादा कंट्रोल चाहिए, तो cloudbuild.yaml फ़ाइल को तय करके ऐसा किया जा सकता है. इस फ़ाइल में, बिल्ड करने के चरणों के बारे में साफ़ तौर पर बताया जाता है:

1. cloudbuild.yaml फ़ाइल के बारे में जानकारी

pom.xml के साथ-साथ, इसी लेवल पर यह cloudbuild.yaml फ़ाइल बनाएं:

steps:
  # Test your build
  - name: maven:eclipse-temurin
    entrypoint: mvn
    args: ["test"]
  # Build with Jib
  - name: maven:eclipse-temurin
    entrypoint: mvn
    args: [ "compile", "com.google.cloud.tools:jib-maven-plugin:3.2.1:build", "-Dimage=northamerica-northeast1-docker.pkg.dev/PROJECT_ID/migration/visitors:jib"]
  # Deploy to Cloud Run
  - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
    entrypoint: gcloud
    args: [ 'run', 'deploy', 'visitors', '--image', 'northamerica-northeast1-docker.pkg.dev/PROJECT_ID/migration/visitors:jib', '--region', 'northamerica-northeast1', '--allow-unauthenticated']

Cloud Build को यह तरीका अपनाने के लिए कहने पर, वह ये काम करेगा:

  1. ./mvnw test की मदद से टेस्ट चलाना
  2. Jib का इस्तेमाल करके, अपनी इमेज को Artifact Registry में बनाएं, पुश करें, और टैग करें
  3. gcloud run deploy की मदद से, अपनी इमेज को Cloud Run पर डिप्लॉय करना

ध्यान दें कि ‘visitors' को Cloud Run में, सेवा के नाम के तौर पर दिया जाता है. –allow-unauthenticated फ़्लैग की मदद से, उपयोगकर्ता बिना पुष्टि किए वेब ऐप्लिकेशन पर जा सकते हैं. पक्का करें कि आपने cloudbuild.yaml फ़ाइल में, PROJECT_ID की जगह अपने प्रोजेक्ट का आईडी डाला हो.

इसके बाद, Cloud Build सेवा खाते को Artifact Registry का ऐक्सेस देने के लिए, आईएएम की ये नीतियां जोड़ें:

export PROJECT_ID=$(gcloud config list --format 'value(core.project)')
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)" )

gcloud projects add-iam-policy-binding $PROJECT_ID \
--member=serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com \
--role=roles/run.admin \
--project=$PROJECT_ID
gcloud iam service-accounts add-iam-policy-binding $PROJECT_NUMBER-compute@developer.gserviceaccount.com \
--member=serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com \
--role roles/iam.serviceAccountUser --project=$PROJECT_ID

2. बिल्ड प्रोसेस चलाना

अब आपने Cloud Build को बिल्ड के ज़रूरी चरणों के बारे में बता दिया है. इसलिए, अब एक क्लिक में डिप्लॉय करने के लिए तैयार रहें.

यह कमांड चलाएं:

gcloud builds submit

प्रोसेस पूरी होने के बाद, आपकी कंटेनर इमेज बन जाएगी. इसे Artifact Registry में सेव कर दिया जाएगा और Cloud Run पर डिप्लॉय कर दिया जाएगा.

इस कोडलैब के आखिर में, आपका ऐप्लिकेशन java17-and-cloud-run/finish में मौजूद ऐप्लिकेशन जैसा दिखना चाहिए.

बस हो गया! आपने Java 8 App Engine ऐप्लिकेशन को Java 17 और Cloud Run पर माइग्रेट कर लिया है. अब आपको स्विच करने और होस्टिंग के विकल्पों में से किसी एक को चुनने के लिए किए जाने वाले काम के बारे में बेहतर जानकारी मिल गई है.

6. खास जानकारी/सफ़ाई

बधाई हो, आपने अपग्रेड कर लिया है, कंटेनर बना लिया है, और माइग्रेट कर लिया है. साथ ही, आपने अपने ऐप्लिकेशन को भी माइग्रेट कर लिया है. इस ट्यूटोरियल में इतना ही!

इसके बाद, अगला चरण CI/CD और सॉफ़्टवेयर सप्लाई चेन की सुरक्षा से जुड़ी उन सुविधाओं के बारे में ज़्यादा जानना है जिन्हें अब Cloud Build के साथ डिप्लॉय किया जा सकता है:

ज़रूरी नहीं: सेवा को बंद करना और/या उससे जुड़ा डेटा मिटाना

अगर आपने इस ट्यूटोरियल के दौरान App Engine पर सैंपल ऐप्लिकेशन डिप्लॉय किया है, तो शुल्क से बचने के लिए ऐप्लिकेशन को बंद करना न भूलें. जब आप अगले कोडलैब पर जाने के लिए तैयार हों, तब इसे फिर से चालू किया जा सकता है. App Engine ऐप्लिकेशन बंद होने पर, उन पर कोई ट्रैफ़िक नहीं आएगा. इसलिए, उनसे कोई शुल्क नहीं लिया जाएगा. हालांकि, अगर Datastore के इस्तेमाल का शुल्क तब भी लिया जा सकता है, जब वह मुफ़्त कोटे से ज़्यादा हो. इसलिए, इतना डेटा मिटाएं कि वह सीमा के अंदर आ जाए.

दूसरी ओर, अगर आपको माइग्रेशन जारी नहीं रखना है और आपको सब कुछ पूरी तरह से मिटाना है, तो आपके पास अपनी सेवा मिटाने या अपने प्रोजेक्ट को पूरी तरह से बंद करने का विकल्प होता है.

7. अन्य संसाधन

App Engine माइग्रेशन मॉड्यूल कोडलैब से जुड़ी समस्याएं/सुझाव/राय

अगर आपको इस कोडलैब में कोई समस्या मिलती है, तो कृपया शिकायत दर्ज करने से पहले अपनी समस्या खोजें. नई समस्याएं खोजने और बनाने के लिए लिंक:

माइग्रेशन के संसाधन

ऑनलाइन संसाधन

यहां कुछ ऑनलाइन संसाधन दिए गए हैं, जो इस ट्यूटोरियल के लिए काम के हो सकते हैं:

App Engine

क्लाउड से जुड़ी अन्य जानकारी

वीडियो

लाइसेंस

इस काम के लिए, Creative Commons एट्रिब्यूशन 2.0 जेनेरिक लाइसेंस के तहत लाइसेंस मिला है.