1. ওভারভিউ
এই ল্যাবটি একটি কন্টেইনারাইজড পরিবেশে জাভা অ্যাপ্লিকেশন বিকাশের দায়িত্বপ্রাপ্ত সফ্টওয়্যার ইঞ্জিনিয়ারদের জন্য ডেভেলপমেন্ট ওয়ার্কফ্লোকে প্রবাহিত করার জন্য ডিজাইন করা বৈশিষ্ট্য এবং ক্ষমতা প্রদর্শন করে। সাধারণ কন্টেইনার ডেভেলপমেন্টের জন্য ব্যবহারকারীকে কন্টেইনারের বিবরণ এবং কন্টেইনার তৈরির প্রক্রিয়া বুঝতে হবে। উপরন্তু, ডেভেলপারদের সাধারণত তাদের প্রবাহ ভাঙতে হয়, দূরবর্তী পরিবেশে তাদের অ্যাপ্লিকেশন পরীক্ষা ও ডিবাগ করতে তাদের IDE থেকে বেরিয়ে যেতে হয়। এই টিউটোরিয়ালে উল্লিখিত টুলস এবং প্রযুক্তির সাহায্যে, ডেভেলপাররা তাদের IDE না রেখেই কন্টেইনারাইজড অ্যাপ্লিকেশনের সাথে কার্যকরভাবে কাজ করতে পারে।
যা শিখবেন
এই ল্যাবে আপনি জিসিপি-তে কন্টেইনারগুলি সহ বিকাশের পদ্ধতিগুলি শিখবেন:
- ক্লাউড ওয়ার্কস্টেশনের সাথে ইনারলুপ ডেভেলপমেন্ট
- একটি নতুন জাভা স্টার্টার অ্যাপ্লিকেশন তৈরি করা হচ্ছে
- উন্নয়ন প্রক্রিয়ার মধ্য দিয়ে হাঁটছি
- একটি সাধারণ CRUD বিশ্রাম পরিষেবা বিকাশ করা হচ্ছে
- GKE ক্লাস্টারে ডিবাগিং অ্যাপ্লিকেশন
- CloudSQL ডাটাবেসের সাথে অ্যাপ্লিকেশন সংযুক্ত করা হচ্ছে
2. সেটআপ এবং প্রয়োজনীয়তা
স্ব-গতিসম্পন্ন পরিবেশ সেটআপ
- Google ক্লাউড কনসোলে সাইন-ইন করুন এবং একটি নতুন প্রকল্প তৈরি করুন বা বিদ্যমান একটি পুনরায় ব্যবহার করুন৷ আপনার যদি ইতিমধ্যেই একটি Gmail বা Google Workspace অ্যাকাউন্ট না থাকে, তাহলে আপনাকে অবশ্যই একটি তৈরি করতে হবে।
- প্রকল্পের নাম এই প্রকল্পের অংশগ্রহণকারীদের জন্য প্রদর্শনের নাম। এটি একটি অক্ষর স্ট্রিং যা Google API দ্বারা ব্যবহৃত হয় না। আপনি যে কোনো সময় এটি আপডেট করতে পারেন.
- প্রোজেক্ট আইডি সমস্ত Google ক্লাউড প্রোজেক্ট জুড়ে অনন্য এবং অপরিবর্তনীয় (সেট করার পরে পরিবর্তন করা যাবে না)। ক্লাউড কনসোল স্বয়ংক্রিয়ভাবে একটি অনন্য স্ট্রিং তৈরি করে; সাধারণত আপনি এটা কি যত্ন না. বেশিরভাগ কোডল্যাবে, আপনাকে প্রজেক্ট আইডি উল্লেখ করতে হবে (এটি সাধারণত
PROJECT_ID
হিসাবে চিহ্নিত করা হয়)। আপনি যদি জেনারেট করা আইডি পছন্দ না করেন, তাহলে আপনি অন্য এলোমেলো আইডি তৈরি করতে পারেন। বিকল্পভাবে, আপনি নিজের চেষ্টা করে দেখতে পারেন এবং এটি উপলব্ধ কিনা। এই ধাপের পরে এটি পরিবর্তন করা যাবে না এবং প্রকল্পের সময়কালের জন্য থাকবে। - আপনার তথ্যের জন্য, একটি তৃতীয় মান রয়েছে, একটি প্রকল্প নম্বর যা কিছু API ব্যবহার করে। ডকুমেন্টেশনে এই তিনটি মান সম্পর্কে আরও জানুন।
- এরপরে, ক্লাউড রিসোর্স/এপিআই ব্যবহার করতে আপনাকে ক্লাউড কনসোলে বিলিং সক্ষম করতে হবে। এই কোডল্যাবের মাধ্যমে চালানোর জন্য খুব বেশি খরচ করা উচিত নয়, যদি কিছু থাকে। রিসোর্স বন্ধ করতে যাতে এই টিউটোরিয়ালের বাইরে আপনার বিলিং খরচ না হয়, আপনি আপনার তৈরি করা রিসোর্স মুছে ফেলতে পারেন বা পুরো প্রোজেক্ট মুছে ফেলতে পারেন। Google ক্লাউডের নতুন ব্যবহারকারীরা $300 USD বিনামূল্যের ট্রায়াল প্রোগ্রামের জন্য যোগ্য৷
ক্লাউডশেল এডিটর শুরু করুন
এই ল্যাবটি ডিজাইন করা হয়েছে এবং Google ক্লাউড শেল এডিটরের সাথে ব্যবহারের জন্য পরীক্ষা করা হয়েছে। সম্পাদক অ্যাক্সেস করতে,
- https://console.cloud.google.com- এ আপনার গুগল প্রকল্প অ্যাক্সেস করুন।
- উপরের ডানদিকের কোণায় ক্লাউড শেল এডিটর আইকনে ক্লিক করুন
- আপনার উইন্ডোর নীচে একটি নতুন ফলক খুলবে
- Open Editor বাটনে ক্লিক করুন
- সম্পাদকটি ডানদিকে একটি এক্সপ্লোরার এবং কেন্দ্রীয় অঞ্চলে সম্পাদকের সাথে খুলবে৷
- স্ক্রিনের নীচে একটি টার্মিনাল ফলকও পাওয়া উচিত
- টার্মিনাল খোলা না থাকলে একটি নতুন টার্মিনাল উইন্ডো খুলতে `ctrl+`` এর কী সমন্বয় ব্যবহার করুন
gCloud সেট আপ করুন
ক্লাউড শেল-এ, আপনার প্রজেক্ট আইডি এবং যে অঞ্চলে আপনি আপনার অ্যাপ্লিকেশন স্থাপন করতে চান সেটি সেট করুন। সেগুলিকে PROJECT_ID
এবং REGION
ভেরিয়েবল হিসাবে সংরক্ষণ করুন৷
export REGION=us-central1
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
সোর্স কোড ক্লোন করুন
এই ল্যাবের সোর্স কোডটি GitHub-এ GoogleCloudPlatform-এর কন্টেইনার-ডেভেলপার-ওয়ার্কশপে অবস্থিত। নীচের কমান্ড দিয়ে এটি ক্লোন করুন তারপর ডিরেক্টরিতে পরিবর্তন করুন।
git clone https://github.com/GoogleCloudPlatform/container-developer-workshop.git
cd container-developer-workshop/labs/spring-boot
এই ল্যাবে ব্যবহৃত অবকাঠামোর ব্যবস্থা করুন
এই ল্যাবে আপনি GKE-তে কোড স্থাপন করবেন এবং একটি CloudSQL ডাটাবেসে সংরক্ষিত ডেটা অ্যাক্সেস করবেন। নিচের সেটআপ স্ক্রিপ্টটি আপনার জন্য এই পরিকাঠামো প্রস্তুত করে। প্রভিশনিং প্রক্রিয়ায় 25 মিনিটের বেশি সময় লাগবে। পরবর্তী বিভাগে যাওয়ার আগে স্ক্রিপ্টটি সম্পূর্ণ হওয়ার জন্য অপেক্ষা করুন।
./setup_with_cw.sh &
ক্লাউড ওয়ার্কস্টেশন ক্লাস্টার
ক্লাউড কনসোলে ক্লাউড ওয়ার্কস্টেশন খুলুন। ক্লাস্টারটি READY
অবস্থায় থাকার জন্য অপেক্ষা করুন৷
ওয়ার্কস্টেশন কনফিগারেশন তৈরি করুন
আপনার ক্লাউড শেল সেশন সংযোগ বিচ্ছিন্ন হলে, "পুনরায় সংযোগ করুন" এ ক্লিক করুন এবং তারপরে প্রকল্প আইডি সেট করতে gcloud cli কমান্ডটি চালান। কমান্ড চালানোর আগে আপনার qwiklabs প্রকল্প আইডি দিয়ে নীচের নমুনা প্রকল্প আইডি প্রতিস্থাপন করুন।
gcloud config set project qwiklabs-gcp-project-id
ক্লাউড ওয়ার্কস্টেশন কনফিগারেশন তৈরি করতে টার্মিনালে নীচের স্ক্রিপ্টটি চালান।
cd ~/container-developer-workshop/labs/spring-boot
./workstation_config_setup.sh
কনফিগারেশন বিভাগের অধীনে ফলাফল যাচাই করুন। এটি প্রস্তুত স্থিতিতে রূপান্তর করতে 2 মিনিট সময় নেবে৷
কনসোলে ক্লাউড ওয়ার্কস্টেশন খুলুন এবং নতুন উদাহরণ তৈরি করুন।
my-workstation
নাম পরিবর্তন করুন এবং বিদ্যমান কনফিগারেশন নির্বাচন করুন: codeoss-java
।
ওয়ার্কস্টেশন বিভাগের অধীনে ফলাফল যাচাই করুন।
ওয়ার্কস্টেশন চালু করুন
ওয়ার্কস্টেশন শুরু করুন এবং চালু করুন।
ঠিকানা বারে আইকনে ক্লিক করে তৃতীয় পক্ষের কুকিজকে অনুমতি দিন।
"সাইট কাজ করছে না?" ক্লিক করুন।
"কুকিজ অনুমতি দিন" ক্লিক করুন।
ওয়ার্কস্টেশন চালু হলে আপনি কোড OSS IDE দেখতে পাবেন। ওয়ার্কস্টেশন IDE-এর প্রথম পৃষ্ঠায় "সম্পন্ন চিহ্নিত করুন"-এ ক্লিক করুন
3. একটি নতুন জাভা স্টার্টার অ্যাপ্লিকেশন তৈরি করা
এই বিভাগে আপনি spring.io দ্বারা প্রদত্ত একটি নমুনা অ্যাপ্লিকেশন ব্যবহার করে স্ক্র্যাচ থেকে একটি নতুন জাভা স্প্রিং বুট অ্যাপ্লিকেশন তৈরি করবেন। একটি নতুন টার্মিনাল খুলুন।
নমুনা অ্যাপ্লিকেশন ক্লোন করুন
- একটি স্টার্টার অ্যাপ্লিকেশন তৈরি করুন
curl https://start.spring.io/starter.zip -d dependencies=web -d type=maven-project -d javaVersion=17 -d packageName=com.example.springboot -o sample-app.zip
আপনি যদি এই বার্তাটি দেখতে পান তবে অনুমতি বোতামে ক্লিক করুন, যাতে আপনি ওয়ার্কস্টেশনে কপি পেস্ট করতে পারেন।
- অ্যাপ্লিকেশনটি আনজিপ করুন
unzip sample-app.zip -d sample-app
- "নমুনা-অ্যাপ" ফোল্ডারটি খুলুন
cd sample-app && code-oss-cloud-workstations -r --folder-uri="$PWD"
স্প্রিং-বুট-ডেভটুল এবং জিব যোগ করুন
Spring Boot DevTools সক্ষম করতে আপনার সম্পাদকের এক্সপ্লোরার থেকে pom.xml খুঁজুন এবং খুলুন। পরবর্তীতে বর্ণনা লাইনের পরে নিম্নলিখিত কোডটি পেস্ট করুন যা পড়ে <description>Demo project for Spring Boot</description>
- pom.xml-এ spring-boot-devtools যোগ করুন
প্রজেক্টের রুটে pom.xml
খুলুন। Description
এন্ট্রির পরে নিম্নলিখিত কনফিগারেশন যোগ করুন।
pom.xml
<!-- Spring profiles-->
<profiles>
<profile>
<id>sync</id>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</profile>
</profiles>
- pom.xml-এ jib-maven-plugin সক্রিয় করুন
জিব হল গুগলের একটি ওপেন সোর্স জাভা কনটেইনারাইজিং টুল যা জাভা ডেভেলপারদের তাদের জানা জাভা টুল ব্যবহার করে কন্টেইনার তৈরি করতে দেয়। জিব হল একটি দ্রুত এবং সহজ কন্টেইনার ইমেজ নির্মাতা যা আপনার অ্যাপ্লিকেশনকে একটি কন্টেইনার ইমেজে প্যাকেজ করার সমস্ত ধাপ পরিচালনা করে। এটির জন্য আপনাকে একটি ডকারফাইল লিখতে বা ডকার ইনস্টল করার প্রয়োজন নেই এবং এটি সরাসরি মাভেন এবং গ্রেডলে একত্রিত হয়েছে।
pom.xml
ফাইলে নিচে স্ক্রোল করুন এবং জিব প্লাগইন অন্তর্ভুক্ত করতে Build
বিভাগটি আপডেট করুন। সম্পূর্ণ হলে বিল্ড বিভাগটি নিম্নলিখিতটির সাথে মিলিত হওয়া উচিত।
pom.xml
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- Jib Plugin-->
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<!-- Maven Resources Plugin-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
</plugin>
</plugins>
</build>
ম্যানিফেস্ট তৈরি করুন
স্ক্যাফোল্ড কন্টেইনার ডেভেলপমেন্টকে সহজ করার জন্য সমন্বিত টুল সরবরাহ করে। এই ধাপে আপনি স্ক্যাফোল্ড শুরু করবেন যা স্বয়ংক্রিয়ভাবে বেস কুবারনেটস YAML ফাইল তৈরি করবে। প্রক্রিয়াটি ডকারফাইলের মতো ধারক চিত্র সংজ্ঞা সহ ডিরেক্টরিগুলি সনাক্ত করার চেষ্টা করে এবং তারপরে প্রতিটির জন্য একটি স্থাপনা এবং পরিষেবা ম্যানিফেস্ট তৈরি করে।
প্রক্রিয়া শুরু করতে টার্মিনালে নীচের কমান্ডটি চালান।
- টার্মিনালে নিম্নলিখিত কমান্ডটি চালান
skaffold init --generate-manifests
- যখন অনুরোধ করা হয়:
-
Jib Maven Plugin
আপনার কার্সার সরাতে তীরচিহ্নগুলি ব্যবহার করুন৷ - বিকল্পটি নির্বাচন করতে স্পেসবার টিপুন।
- চালিয়ে যেতে এন্টার টিপুন
- পোর্টের জন্য 8080 লিখুন
- কনফিগারেশন সংরক্ষণ করতে y লিখুন
ওয়ার্কস্পেস skaffold.yaml
এবং deployment.yaml
এ দুটি ফাইল যোগ করা হয়েছে
স্ক্যাফোল্ড আউটপুট:
অ্যাপের নাম আপডেট করুন
কনফিগারেশনে অন্তর্ভুক্ত ডিফল্ট মানগুলি বর্তমানে আপনার অ্যাপ্লিকেশনের নামের সাথে মেলে না। ডিফল্ট মানগুলির পরিবর্তে আপনার অ্যাপ্লিকেশনের নাম উল্লেখ করতে ফাইলগুলি আপডেট করুন৷
- Skaffold কনফিগারেশনে এন্ট্রি পরিবর্তন করুন
-
skaffold.yaml
খুলুন - বর্তমানে
pom-xml-image
হিসাবে সেট করা ছবির নাম নির্বাচন করুন - রাইট ক্লিক করুন এবং সমস্ত ঘটনা পরিবর্তন করুন নির্বাচন করুন
-
demo-app
হিসাবে নতুন নাম টাইপ করুন
- Kubernetes কনফিগারেশনে এন্ট্রি পরিবর্তন করুন
-
deployment.yaml
ফাইল খুলুন - বর্তমানে
pom-xml-image
হিসাবে সেট করা ছবির নাম নির্বাচন করুন - রাইট ক্লিক করুন এবং সমস্ত ঘটনা পরিবর্তন করুন নির্বাচন করুন
-
demo-app
হিসাবে নতুন নাম টাইপ করুন
স্বয়ংক্রিয় সিঙ্ক মোড সক্ষম করুন৷
একটি অপ্টিমাইজ করা হট রিলোড অভিজ্ঞতার সুবিধার জন্য আপনি জিব দ্বারা প্রদত্ত সিঙ্ক বৈশিষ্ট্যটি ব্যবহার করবেন। এই ধাপে আপনি Skaffold কনফিগার করবেন যাতে বিল্ড প্রক্রিয়ায় সেই বৈশিষ্ট্যটি ব্যবহার করা যায়।
দ্রষ্টব্য যে Skaffold কনফিগারেশনে আপনি যে "sync" প্রোফাইলটি কনফিগার করছেন সেটি আগের ধাপে আপনার কনফিগার করা স্প্রিং "sync" প্রোফাইলের সুবিধা দেয়, যেখানে আপনি spring-dev-tools এর জন্য সমর্থন সক্ষম করেছেন।
- Skaffold কনফিগারেশন আপডেট করুন
skaffold.yaml
ফাইলে নিম্নলিখিত স্পেসিফিকেশন দিয়ে ফাইলের সম্পূর্ণ বিল্ড সেকশন প্রতিস্থাপন করুন। ফাইলের অন্যান্য বিভাগ পরিবর্তন করবেন না।
skaffold.yaml
build:
artifacts:
- image: demo-app
jib:
project: com.example:demo
type: maven
args:
- --no-transfer-progress
- -Psync
fromImage: gcr.io/distroless/java17-debian11:debug
sync:
auto: true
একটি ডিফল্ট রুট যোগ করুন
/src/main/java/com/example/springboot/
ফোল্ডারে HelloController.java
নামে একটি ফাইল তৈরি করুন।
একটি ডিফল্ট HTTP রুট তৈরি করতে ফাইলে নিম্নলিখিত বিষয়বস্তু পেস্ট করুন।
HelloController.java
package com.example.springboot;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.beans.factory.annotation.Value;
@RestController
public class HelloController {
@Value("${target:local}")
String target;
@GetMapping("/")
public String hello()
{
return String.format("Hello from your %s environment!", target);
}
}
4. উন্নয়ন প্রক্রিয়ার মধ্য দিয়ে হাঁটা
এই বিভাগে আপনি মৌলিক প্রক্রিয়াগুলি শিখতে এবং আপনার স্টার্টার অ্যাপ্লিকেশনটির কনফিগারেশন এবং সেটআপ যাচাই করতে ক্লাউড কোড প্লাগইন ব্যবহার করে কয়েকটি ধাপ অতিক্রম করবেন।
ক্লাউড কোড স্ক্যাফোল্ডের সাথে সংহত করে আপনার উন্নয়ন প্রক্রিয়াকে স্ট্রিমলাইন করতে। আপনি যখন নিম্নলিখিত ধাপে GKE-তে স্থাপন করবেন, ক্লাউড কোড এবং Skaffold স্বয়ংক্রিয়ভাবে আপনার কন্টেইনার ইমেজ তৈরি করবে, এটি একটি কন্টেইনার রেজিস্ট্রিতে ঠেলে দেবে এবং তারপর GKE-তে আপনার অ্যাপ্লিকেশন স্থাপন করবে। এটি বিকাশকারীর প্রবাহ থেকে বিশদ বিবরণকে বিমূর্ত করে পর্দার আড়ালে ঘটে। ক্লাউড কোড কনটেইনার ভিত্তিক ডেভেলপমেন্টে প্রথাগত ডিবাগ এবং হটসিঙ্ক ক্ষমতা প্রদান করে আপনার উন্নয়ন প্রক্রিয়াকেও উন্নত করে।
গুগল ক্লাউডে সাইন ইন করুন
ক্লাউড কোড আইকনে ক্লিক করুন এবং "গুগল ক্লাউডে সাইন ইন করুন" নির্বাচন করুন:
"সাইন ইন করতে এগিয়ে যান" এ ক্লিক করুন।
টার্মিনালে আউটপুট পরীক্ষা করুন এবং লিঙ্কটি খুলুন:
আপনার Qwiklabs ছাত্রদের শংসাপত্র দিয়ে লগইন করুন।
"অনুমতি দিন" নির্বাচন করুন:
যাচাইকরণ কোড কপি করুন এবং ওয়ার্কস্টেশন ট্যাবে ফিরে যান।
যাচাইকরণ কোড পেস্ট করুন এবং এন্টার টিপুন।
কুবারনেটস ক্লাস্টার যোগ করুন
- একটি ক্লাস্টার যোগ করুন
- Google Kubernetes ইঞ্জিন নির্বাচন করুন:
- প্রকল্প নির্বাচন করুন।
- প্রাথমিক সেটআপে তৈরি করা "উদ্ধৃতি-ক্লাস্টার" নির্বাচন করুন।
gcloud cli ব্যবহার করে বর্তমান প্রকল্প আইডি সেট করুন
qwiklabs পৃষ্ঠা থেকে এই ল্যাবের জন্য প্রজেক্ট আইডি কপি করুন।
প্রকল্প আইডি সেট করতে gcloud cli কমান্ড চালান। কমান্ড চালানোর আগে নমুনা প্রকল্প আইডি প্রতিস্থাপন করুন।
gcloud config set project qwiklabs-gcp-project-id
নমুনা আউটপুট:
Kubernetes-এ ডিবাগ করুন
- নীচে বাম প্যানেলে ক্লাউড কোড নির্বাচন করুন।
- ডেভেলপমেন্ট সেশনের অধীনে প্রদর্শিত প্যানেলে, কুবারনেটে ডিবাগ নির্বাচন করুন।
বিকল্পটি দৃশ্যমান না হলে নিচে স্ক্রোল করুন।
- বর্তমান প্রসঙ্গ ব্যবহার করতে "হ্যাঁ" নির্বাচন করুন।
- প্রাথমিক সেটআপের সময় তৈরি করা "উদ্ধৃতি-ক্লাস্টার" নির্বাচন করুন।
- ধারক সংগ্রহস্থল নির্বাচন করুন।
- অগ্রগতি এবং বিজ্ঞপ্তিগুলি দেখতে নীচের ফলকে আউটপুট ট্যাবটি নির্বাচন করুন৷
- কনটেইনারগুলি থেকে লাইভ স্ট্রিমিং অতিরিক্ত বিবরণ এবং লগগুলি দেখতে ডানদিকে ড্রপ ডাউন চ্যানেলে "কুবারনেটস: রান/ডিবাগ - বিস্তারিত" নির্বাচন করুন
অ্যাপ্লিকেশন স্থাপন করার জন্য অপেক্ষা করুন.
- ক্লাউড কনসোলে GKE-তে স্থাপন করা অ্যাপ্লিকেশন পর্যালোচনা করুন।
- OUTPUT ট্যাবে ড্রপডাউন থেকে "Kubernetes: Run/Debug" নির্বাচন করে সরলীকৃত দৃশ্যে ফিরে যান।
- যখন বিল্ড এবং পরীক্ষা করা হয়, আউটপুট ট্যাবটি বলে:
Resource deployment/demo-app status completed successfully
, এবং একটি url তালিকাভুক্ত করা হয়েছে: "পরিষেবা ডেমো-অ্যাপ থেকে ফরওয়ার্ড করা URL: http://localhost:8080" - ক্লাউড কোড টার্মিনালে, আউটপুট (http://localhost:8080) এর URL-এর উপর হোভার করুন এবং তারপরে প্রদর্শিত টুল টিপে অনুসরণ করুন লিঙ্ক নির্বাচন করুন।
নতুন ট্যাব খোলা হবে এবং আপনি নীচের আউটপুট দেখতে পাবেন:
ব্রেকপয়েন্ট ব্যবহার করুন
-
/src/main/java/com/example/springboot/HelloController.java
এ অবস্থিতHelloController.java
অ্যাপ্লিকেশনটি খুলুন - রুট পাথের জন্য রিটার্ন স্টেটমেন্ট সনাক্ত করুন যা
return String.format("Hello from your %s environment!", target);
- লাইন নম্বরের বাম দিকের ফাঁকা জায়গায় ক্লিক করে সেই লাইনে একটি ব্রেকপয়েন্ট যোগ করুন। ব্রেকপয়েন্ট সেট করা হয়েছে লক্ষ্য করার জন্য একটি লাল সূচক দেখাবে
- আপনার ব্রাউজার পুনরায় লোড করুন এবং নোট করুন ডিবাগার ব্রেকপয়েন্টে প্রক্রিয়াটি বন্ধ করে দেয় এবং আপনাকে GKE-তে দূরবর্তীভাবে চলমান অ্যাপ্লিকেশনের ভেরিয়েবল এবং অবস্থা তদন্ত করতে দেয়
- আপনি "টার্গেট" ভেরিয়েবল না পাওয়া পর্যন্ত ভেরিয়েবল বিভাগে ক্লিক করুন।
- বর্তমান মানটিকে "স্থানীয়" হিসাবে পর্যবেক্ষণ করুন
- "টার্গেট" ভেরিয়েবল নামের উপর ডাবল ক্লিক করুন এবং পপআপে,
"ক্লাউড ওয়ার্কস্টেশন" এ মান পরিবর্তন করুন
- ডিবাগ কন্ট্রোল প্যানেলে Continue বাটনে ক্লিক করুন
- আপনার ব্রাউজারে প্রতিক্রিয়া পর্যালোচনা করুন যা এখন আপনার প্রবেশ করা আপডেট করা মান দেখায়।
- লাইন নম্বরের বাম দিকে লাল সূচকে ক্লিক করে ব্রেকপয়েন্টটি সরান। আপনি এই ল্যাবে এগিয়ে যাওয়ার সাথে সাথে এটি আপনার কোডকে এই লাইনে কার্যকর করা বন্ধ করতে বাধা দেবে।
হট রিলোড
- "%s কোড থেকে হ্যালো" এর মতো একটি ভিন্ন মান ফেরত দিতে বিবৃতিটি পরিবর্তন করুন
- ফাইলটি স্বয়ংক্রিয়ভাবে সংরক্ষিত হয় এবং GKE-তে দূরবর্তী পাত্রে সিঙ্ক হয়
- আপডেট ফলাফল দেখতে আপনার ব্রাউজার রিফ্রেশ করুন.
- ডিবাগ টুলবারে লাল বর্গক্ষেত্রে ক্লিক করে ডিবাগিং সেশন বন্ধ করুন
"হ্যাঁ প্রতিটি রানের পরে পরিষ্কার করুন" নির্বাচন করুন।
5. একটি সাধারণ CRUD বিশ্রাম পরিষেবা বিকাশ করা
এই মুহুর্তে আপনার অ্যাপ্লিকেশনটি সম্পূর্ণরূপে কনটেইনারাইজড ডেভেলপমেন্টের জন্য কনফিগার করা হয়েছে এবং আপনি ক্লাউড কোডের সাথে মৌলিক উন্নয়ন কর্মপ্রবাহের মধ্য দিয়ে গেছেন। নিম্নলিখিত বিভাগগুলিতে আপনি Google ক্লাউডে একটি পরিচালিত ডাটাবেসের সাথে সংযুক্ত REST পরিষেবার শেষ পয়েন্ট যোগ করে যা শিখেছেন তা অনুশীলন করেন।
নির্ভরতা কনফিগার করুন
অ্যাপ্লিকেশন কোড একটি ডাটাবেস ব্যবহার করে বাকি পরিষেবা ডেটা বজায় রাখতে। pom.xl এ নিম্নলিখিত যোগ করে নির্ভরতা উপলব্ধ রয়েছে তা নিশ্চিত করুন
-
pom.xml
ফাইলটি খুলুন এবং কনফিগারেশনের নির্ভরতা বিভাগে নিম্নলিখিত যোগ করুন
pom.xml
<!-- Database dependencies-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
কোড REST পরিষেবা
উদ্ধৃতি.জাভা
/src/main/java/com/example/springboot/
এ Quote.java
নামে একটি ফাইল তৈরি করুন এবং নীচের কোডে অনুলিপি করুন। এটি অ্যাপ্লিকেশনে ব্যবহৃত উদ্ধৃতি বস্তুর জন্য সত্তা মডেলকে সংজ্ঞায়িত করে।
package com.example.springboot;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.util.Objects;
@Entity
@Table(name = "quotes")
public class Quote
{
@Id
@Column(name = "id")
private Integer id;
@Column(name="quote")
private String quote;
@Column(name="author")
private String author;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getQuote() {
return quote;
}
public void setQuote(String quote) {
this.quote = quote;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Quote quote1 = (Quote) o;
return Objects.equals(id, quote1.id) &&
Objects.equals(quote, quote1.quote) &&
Objects.equals(author, quote1.author);
}
@Override
public int hashCode() {
return Objects.hash(id, quote, author);
}
}
QuoteRepository.java
src/main/java/com/example/springboot
এ QuoteRepository.java
নামে একটি ফাইল তৈরি করুন এবং নিম্নলিখিত কোডে অনুলিপি করুন
package com.example.springboot;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
public interface QuoteRepository extends JpaRepository<Quote,Integer> {
@Query( nativeQuery = true, value =
"SELECT id,quote,author FROM quotes ORDER BY RANDOM() LIMIT 1")
Quote findRandomQuote();
}
এই কোডটি ডেটা ধরে রাখার জন্য JPA ব্যবহার করে। ক্লাস স্প্রিং JPARepository
ইন্টারফেস প্রসারিত করে এবং কাস্টম কোড তৈরির অনুমতি দেয়। কোডটিতে আপনি একটি findRandomQuote
কাস্টম পদ্ধতি যোগ করেছেন।
QuoteController.java
পরিষেবার জন্য শেষ পয়েন্ট প্রকাশ করতে, একটি QuoteController
ক্লাস এই কার্যকারিতা প্রদান করবে।
src/main/java/com/example/springboot
এ QuoteController.java
নামে একটি ফাইল তৈরি করুন এবং নিম্নলিখিত বিষয়বস্তুতে অনুলিপি করুন
package com.example.springboot;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class QuoteController {
private final QuoteRepository quoteRepository;
public QuoteController(QuoteRepository quoteRepository) {
this.quoteRepository = quoteRepository;
}
@GetMapping("/random-quote")
public Quote randomQuote()
{
return quoteRepository.findRandomQuote();
}
@GetMapping("/quotes")
public ResponseEntity<List<Quote>> allQuotes()
{
try {
List<Quote> quotes = new ArrayList<Quote>();
quoteRepository.findAll().forEach(quotes::add);
if (quotes.size()==0 || quotes.isEmpty())
return new ResponseEntity<List<Quote>>(HttpStatus.NO_CONTENT);
return new ResponseEntity<List<Quote>>(quotes, HttpStatus.OK);
} catch (Exception e) {
System.out.println(e.getMessage());
return new ResponseEntity<List<Quote>>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@PostMapping("/quotes")
public ResponseEntity<Quote> createQuote(@RequestBody Quote quote) {
try {
Quote saved = quoteRepository.save(quote);
return new ResponseEntity<Quote>(saved, HttpStatus.CREATED);
} catch (Exception e) {
System.out.println(e.getMessage());
return new ResponseEntity<Quote>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@PutMapping("/quotes/{id}")
public ResponseEntity<Quote> updateQuote(@PathVariable("id") Integer id, @RequestBody Quote quote) {
try {
Optional<Quote> existingQuote = quoteRepository.findById(id);
if(existingQuote.isPresent()){
Quote updatedQuote = existingQuote.get();
updatedQuote.setAuthor(quote.getAuthor());
updatedQuote.setQuote(quote.getQuote());
return new ResponseEntity<Quote>(updatedQuote, HttpStatus.OK);
} else {
return new ResponseEntity<Quote>(HttpStatus.NOT_FOUND);
}
} catch (Exception e) {
System.out.println(e.getMessage());
return new ResponseEntity<Quote>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@DeleteMapping("/quotes/{id}")
public ResponseEntity<HttpStatus> deleteQuote(@PathVariable("id") Integer id) {
Optional<Quote> quote = quoteRepository.findById(id);
if (quote.isPresent()) {
quoteRepository.deleteById(id);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} else {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
ডাটাবেস কনফিগারেশন যোগ করুন
application.yaml
পরিষেবা দ্বারা অ্যাক্সেস করা ব্যাকএন্ড ডাটাবেসের জন্য কনফিগারেশন যোগ করুন। src/main/resources
এর অধীনে application.yaml
ফাইল নামক ফাইলটি সম্পাদনা করুন (বা উপস্থিত না থাকলে তৈরি করুন) এবং ব্যাকএন্ডের জন্য একটি প্যারামিটারাইজড স্প্রিং কনফিগারেশন যোগ করুন।
target: local
spring:
config:
activate:
on-profile: cloud-dev
datasource:
url: 'jdbc:postgresql://${DB_HOST:127.0.0.1}/${DB_NAME:quote_db}'
username: '${DB_USER:user}'
password: '${DB_PASS:password}'
jpa:
properties:
hibernate:
jdbc:
lob:
non_contextual_creation: true
dialect: org.hibernate.dialect.PostgreSQLDialect
hibernate:
ddl-auto: update
ডাটাবেস মাইগ্রেশন যোগ করুন
src/main/resources
এর অধীনে ফোল্ডার db/migration
তৈরি করুন
একটি SQL ফাইল তৈরি করুন: V1__create_quotes_table.sql
ফাইলে নিম্নলিখিত বিষয়বস্তু পেস্ট করুন
V1__create_quotes_table.sql
CREATE TABLE quotes(
id INTEGER PRIMARY KEY,
quote VARCHAR(1024),
author VARCHAR(256)
);
INSERT INTO quotes (id,quote,author) VALUES (1,'Never, never, never give up','Winston Churchill');
INSERT INTO quotes (id,quote,author) VALUES (2,'While there''s life, there''s hope','Marcus Tullius Cicero');
INSERT INTO quotes (id,quote,author) VALUES (3,'Failure is success in progress','Anonymous');
INSERT INTO quotes (id,quote,author) VALUES (4,'Success demands singleness of purpose','Vincent Lombardi');
INSERT INTO quotes (id,quote,author) VALUES (5,'The shortest answer is doing','Lord Herbert');
কুবারনেটস কনফিগারেশন
deployment.yaml
ফাইলে নিম্নলিখিত সংযোজনগুলি অ্যাপ্লিকেশনটিকে CloudSQL দৃষ্টান্তগুলির সাথে সংযোগ করার অনুমতি দেয়৷
- টার্গেট - যেখানে অ্যাপটি চালানো হয় সেই পরিবেশ নির্দেশ করতে ভেরিয়েবল কনফিগার করে
- SPRING_PROFILES_ACTIVE - সক্রিয় স্প্রিং প্রোফাইল দেখায়, যা
cloud-dev
কনফিগার করা হবে - DB_HOST - ডাটাবেসের জন্য ব্যক্তিগত আইপি, যা ডাটাবেস ইনস্ট্যান্স তৈরি হওয়ার সময় বা Google ক্লাউড কনসোলের নেভিগেশন মেনুতে
SQL
এ ক্লিক করে উল্লেখ করা হয়েছে - অনুগ্রহ করে মান পরিবর্তন করুন! - DB_USER এবং DB_PASS - ক্লাউডএসকিউএল ইনস্ট্যান্স কনফিগারেশনে সেট করা, জিসিপি-তে সিক্রেট হিসাবে সংরক্ষিত
নিচের বিষয়বস্তু সহ আপনার deployment.yaml আপডেট করুন।
deployment.yaml
apiVersion: v1
kind: Service
metadata:
name: demo-app
labels:
app: demo-app
spec:
ports:
- port: 8080
protocol: TCP
clusterIP: None
selector:
app: demo-app
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app
labels:
app: demo-app
spec:
replicas: 1
selector:
matchLabels:
app: demo-app
template:
metadata:
labels:
app: demo-app
spec:
containers:
- name: demo-app
image: demo-app
env:
- name: PORT
value: "8080"
- name: TARGET
value: "Local Dev - CloudSQL Database - K8s Cluster"
- name: SPRING_PROFILES_ACTIVE
value: cloud-dev
- name: DB_HOST
value: ${DB_INSTANCE_IP}
- name: DB_PORT
value: "5432"
- name: DB_USER
valueFrom:
secretKeyRef:
name: gke-cloud-sql-secrets
key: username
- name: DB_PASS
valueFrom:
secretKeyRef:
name: gke-cloud-sql-secrets
key: password
- name: DB_NAME
valueFrom:
secretKeyRef:
name: gke-cloud-sql-secrets
key: database
টার্মিনালে নীচের কমান্ডগুলি চালিয়ে আপনার ডাটাবেসের ঠিকানা দিয়ে DB_HOST মান প্রতিস্থাপন করুন:
export DB_INSTANCE_IP=$(gcloud sql instances describe quote-db-instance \
--format=json | jq \
--raw-output ".ipAddresses[].ipAddress")
envsubst < deployment.yaml > deployment.new && mv deployment.new deployment.yaml
deployment.yaml খুলুন এবং যাচাই করুন যে DB_HOST মান ইনস্ট্যান্স আইপি দিয়ে আপডেট করা হয়েছে।
প্রয়োগ করুন এবং আবেদন যাচাই করুন
- ক্লাউড শেল এডিটরের নীচের প্যানে, ক্লাউড কোড নির্বাচন করুন তারপর পর্দার শীর্ষে কুবারনেটে ডিবাগ নির্বাচন করুন।
- যখন বিল্ড এবং পরীক্ষা করা হয়, আউটপুট ট্যাবটি বলে:
Resource deployment/demo-app status completed successfully
এবং একটি url তালিকাভুক্ত করা হয়েছে: "পরিষেবা ডেমো-অ্যাপ থেকে ফরওয়ার্ড করা URL: http://localhost:8080 "। মনে রাখবেন যে কখনও কখনও পোর্ট 8081 এর মত ভিন্ন হতে পারে। যদি তাই হয় উপযুক্ত মান সেট করুন। টার্মিনালে URL এর মান সেট করুন
export URL=localhost:8080
- এলোমেলো উদ্ধৃতি দেখুন
টার্মিনাল থেকে, র্যান্ডম-কোট এন্ডপয়েন্টের বিরুদ্ধে একাধিকবার নীচের কমান্ডটি চালান। বিভিন্ন উদ্ধৃতি ফেরত বারবার কল পর্যবেক্ষণ করুন
curl $URL/random-quote | jq
- একটি উদ্ধৃতি যোগ করুন
নীচে তালিকাভুক্ত কমান্ডটি ব্যবহার করে id=6 সহ একটি নতুন উদ্ধৃতি তৈরি করুন এবং অনুরোধটি প্রতিধ্বনিত হচ্ছে পর্যবেক্ষণ করুন
curl -H 'Content-Type: application/json' -d '{"id":"6","author":"Henry David Thoreau","quote":"Go confidently in the direction of your dreams! Live the life you have imagined"}' -X POST $URL/quotes
- একটি উদ্ধৃতি মুছুন
এখন আপনি মুছে ফেলা পদ্ধতির সাথে যোগ করা উদ্ধৃতিটি মুছুন এবং একটি HTTP/1.1 204
প্রতিক্রিয়া কোড পর্যবেক্ষণ করুন।
curl -v -X DELETE $URL/quotes/6
- সার্ভার ত্রুটি
এন্ট্রিটি ইতিমধ্যে মুছে ফেলার পরে আবার শেষ অনুরোধটি চালিয়ে একটি ত্রুটির অবস্থার অভিজ্ঞতা নিন
curl -v -X DELETE $URL/quotes/6
লক্ষ্য করুন প্রতিক্রিয়াটি একটি HTTP:500 Internal Server Error
প্রদান করে।
অ্যাপ্লিকেশন ডিবাগ করুন
পূর্ববর্তী বিভাগে আপনি অ্যাপ্লিকেশনটিতে একটি ত্রুটির অবস্থা খুঁজে পেয়েছেন যখন আপনি একটি এন্ট্রি মুছে ফেলার চেষ্টা করেছিলেন যা ডাটাবেসে ছিল না। এই বিভাগে আপনি সমস্যাটি সনাক্ত করতে একটি ব্রেকপয়েন্ট সেট করবেন। DELETE অপারেশনে ত্রুটি ঘটেছে, তাই আপনি QuoteController ক্লাসের সাথে কাজ করবেন।
-
src/main/java/com/example/springboot/QuoteController.java
খুলুন -
deleteQuote()
পদ্ধতি খুঁজুন - লাইনটি খুঁজুন:
Optional<Quote> quote = quoteRepository.findById(id);
- লাইন নম্বরের বাম দিকের ফাঁকা জায়গায় ক্লিক করে সেই লাইনে একটি ব্রেকপয়েন্ট সেট করুন।
- ব্রেকপয়েন্ট সেট করা হয়েছে তা নির্দেশ করে একটি লাল সূচক উপস্থিত হবে
-
delete
কমান্ডটি আবার চালান
curl -v -X DELETE $URL/quotes/6
- বাম কলামে আইকনে ক্লিক করে ডিবাগ ভিউতে ফিরে যান
- QuoteController ক্লাসে ডিবাগ লাইন বন্ধ করা পর্যবেক্ষণ করুন।
- ডিবাগারে,
step over
আইকনে ক্লিক করুন - লক্ষ্য করুন যে একটি কোড ক্লায়েন্টকে একটি অভ্যন্তরীণ সার্ভার ত্রুটি HTTP 500 প্রদান করে যা আদর্শ নয়।
Trying 127.0.0.1:8080... * Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0) > DELETE /quotes/6 HTTP/1.1 > Host: 127.0.0.1:8080 > User-Agent: curl/7.74.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 500 < Content-Length: 0 < Date: < * Connection #0 to host 127.0.0.1 left intact
কোড আপডেট করুন
কোডটি ভুল এবং HTTP 404 না পাওয়া স্ট্যাটাস কোড ফেরত পাঠাতে else
ব্লকটি রিফ্যাক্টর করা উচিত।
ভুল সংশোধন করুন।
- ডিবাগ সেশন এখনও চলছে, ডিবাগ কন্ট্রোল প্যানেলে "চালিয়ে যান" বোতাম টিপে অনুরোধটি সম্পূর্ণ করুন৷
- এরপর কোডে
else
ব্লক পরিবর্তন করুন:
else {
return new ResponseEntity<HttpStatus>(HttpStatus.NOT_FOUND);
}
পদ্ধতি নিম্নলিখিত মত দেখতে হবে
@DeleteMapping("/quotes/{id}") public ResponseEntity<HttpStatus> deleteQuote(@PathVariable("id") Integer id) { Optional<Quote> quote = quoteRepository.findById(id); if (quote.isPresent()) { quoteRepository.deleteById(id); return new ResponseEntity<>(HttpStatus.NO_CONTENT); } else { return new ResponseEntity<HttpStatus>(HttpStatus.NOT_FOUND); } }
- ডিলিট কমান্ডটি পুনরায় চালান
curl -v -X DELETE $URL/quotes/6
- ডিবাগারের মধ্য দিয়ে যান এবং HTTP 404 নট ফাউন্ড কলারের কাছে ফিরে আসা পর্যবেক্ষণ করুন।
Trying 127.0.0.1:8080... * Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0) > DELETE /quotes/6 HTTP/1.1 > Host: 127.0.0.1:8080 > User-Agent: curl/7.74.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 404 < Content-Length: 0 < Date: < * Connection #0 to host 127.0.0.1 left intact
- ডিবাগ টুলবারে লাল বর্গক্ষেত্রে ক্লিক করে ডিবাগিং সেশন বন্ধ করুন
6. অভিনন্দন
অভিনন্দন! এই ল্যাবে আপনি স্ক্র্যাচ থেকে একটি নতুন জাভা অ্যাপ্লিকেশন তৈরি করেছেন এবং কনটেইনারগুলির সাথে কার্যকরভাবে কাজ করার জন্য এটি কনফিগার করেছেন৷ তারপরে আপনি প্রথাগত অ্যাপ্লিকেশন স্ট্যাকগুলিতে পাওয়া একই বিকাশকারী প্রবাহ অনুসরণ করে একটি দূরবর্তী GKE ক্লাস্টারে আপনার অ্যাপ্লিকেশন স্থাপন এবং ডিবাগ করেছেন।
আপনি যা শিখেছেন
- ক্লাউড ওয়ার্কস্টেশনের সাথে ইনারলুপ ডেভেলপমেন্ট
- একটি নতুন জাভা স্টার্টার অ্যাপ্লিকেশন তৈরি করা হচ্ছে
- উন্নয়ন প্রক্রিয়ার মধ্য দিয়ে হাঁটছি
- একটি সাধারণ CRUD REST পরিষেবা তৈরি করা হচ্ছে
- GKE ক্লাস্টারে ডিবাগিং অ্যাপ্লিকেশন
- CloudSQL ডাটাবেসের সাথে অ্যাপ্লিকেশন সংযুক্ত করা হচ্ছে