ক্লাউড প্রোফাইলারের সাথে উত্পাদন কর্মক্ষমতা বিশ্লেষণ করুন

1. সংক্ষিপ্ত বিবরণ

যদিও ক্লায়েন্ট অ্যাপ এবং ফ্রন্টএন্ড ওয়েব ডেভেলপাররা সাধারণত তাদের কোডের কর্মক্ষমতা উন্নত করার জন্য অ্যান্ড্রয়েড স্টুডিও সিপিইউ প্রোফাইলার বা ক্রোমে অন্তর্ভুক্ত প্রোফাইলিং টুলের মতো টুল ব্যবহার করেন, ব্যাকএন্ড পরিষেবাগুলিতে কাজ করা ব্যক্তিদের দ্বারা সমতুল্য কৌশলগুলি প্রায় অ্যাক্সেসযোগ্য বা ভালভাবে গৃহীত হয়নি। ক্লাউড প্রোফাইলার পরিষেবা ডেভেলপারদের জন্য একই ক্ষমতা নিয়ে আসে, তাদের কোড গুগল ক্লাউড প্ল্যাটফর্মে বা অন্য কোথাও চলছে কিনা তা নির্বিশেষে।

95c034c70c9cac22.png সম্পর্কে

এই টুলটি আপনার প্রোডাকশন অ্যাপ্লিকেশন থেকে CPU ব্যবহার এবং মেমোরি-অ্যালোকেশন তথ্য সংগ্রহ করে। এটি সেই তথ্য অ্যাপ্লিকেশনের সোর্স কোডের সাথে যুক্ত করে, যা আপনাকে অ্যাপ্লিকেশনের কোন অংশগুলি সর্বাধিক রিসোর্স ব্যবহার করে তা সনাক্ত করতে সাহায্য করে এবং অন্যথায় কোডের কর্মক্ষমতা বৈশিষ্ট্যগুলি আলোকিত করে। টুল দ্বারা ব্যবহৃত সংগ্রহ কৌশলগুলির কম ওভারহেড এটিকে উৎপাদন পরিবেশে ক্রমাগত ব্যবহারের জন্য উপযুক্ত করে তোলে।

এই কোডল্যাবে, আপনি শিখবেন কিভাবে একটি Go প্রোগ্রামের জন্য ক্লাউড প্রোফাইলার সেট আপ করতে হয় এবং টুলটি অ্যাপ্লিকেশন কর্মক্ষমতা সম্পর্কে কী ধরণের অন্তর্দৃষ্টি উপস্থাপন করতে পারে তার সাথে পরিচিত হবেন।

তুমি কি শিখবে

  • ক্লাউড প্রোফাইলার দিয়ে প্রোফাইলিংয়ের জন্য একটি গো প্রোগ্রাম কীভাবে কনফিগার করবেন।
  • ক্লাউড প্রোফাইলারের সাহায্যে কীভাবে পারফরম্যান্স ডেটা সংগ্রহ, দেখা এবং বিশ্লেষণ করবেন।

তোমার যা লাগবে

  • একটি গুগল ক্লাউড প্ল্যাটফর্ম প্রকল্প
  • একটি ব্রাউজার, যেমন ক্রোম বা ফায়ারফক্স
  • ভিম, ইএমএসি বা ন্যানোর মতো স্ট্যান্ডার্ড লিনাক্স টেক্সট এডিটরগুলির সাথে পরিচিতি।

এই টিউটোরিয়ালটি কীভাবে ব্যবহার করবেন?

শুধু পুরোটা পড়ুন এটি পড়ুন এবং অনুশীলনগুলি সম্পূর্ণ করুন।

গুগল ক্লাউড প্ল্যাটফর্মের সাথে আপনার অভিজ্ঞতাকে আপনি কীভাবে মূল্যায়ন করবেন?

নবীন মধ্যবর্তী দক্ষ

2. সেটআপ এবং প্রয়োজনীয়তা

স্ব-গতিসম্পন্ন পরিবেশ সেটআপ

  1. ক্লাউড কনসোলে সাইন ইন করুন এবং একটি নতুন প্রকল্প তৈরি করুন অথবা বিদ্যমান একটি পুনরায় ব্যবহার করুন। যদি আপনার ইতিমধ্যেই একটি Gmail বা Google Workspace অ্যাকাউন্ট না থাকে, তাহলে আপনাকে অবশ্যই একটি তৈরি করতে হবে।

96a9c957bc475304.png সম্পর্কে

b9a10ebdf5b5a448.png সম্পর্কে

a1e3c01a38fa61c2.png সম্পর্কে

প্রোজেক্ট আইডি মনে রাখবেন, সমস্ত গুগল ক্লাউড প্রোজেক্টের জন্য একটি অনন্য নাম (উপরের নামটি ইতিমধ্যেই নেওয়া হয়েছে এবং আপনার জন্য কাজ করবে না, দুঃখিত!)। এই কোডল্যাবে পরে এটিকে PROJECT_ID হিসাবে উল্লেখ করা হবে।

  1. এরপর, গুগল ক্লাউড রিসোর্স ব্যবহার করার জন্য আপনাকে ক্লাউড কনসোলে বিলিং সক্ষম করতে হবে।

এই কোডল্যাবটি চালাতে খুব বেশি খরচ হবে না, এমনকি যদি কিছু হয়ও। "ক্লিনিং আপ" বিভাগে থাকা যেকোনো নির্দেশাবলী অনুসরণ করতে ভুলবেন না যা আপনাকে পরামর্শ দেয় যে কীভাবে রিসোর্সগুলি বন্ধ করতে হবে যাতে এই টিউটোরিয়ালের বাইরে আপনাকে বিলিংয়ের সম্মুখীন না হতে হয়। গুগল ক্লাউডের নতুন ব্যবহারকারীরা $300 USD ফ্রি ট্রায়াল প্রোগ্রামের জন্য যোগ্য।

গুগল ক্লাউড শেল

যদিও গুগল ক্লাউড আপনার ল্যাপটপ থেকে দূরবর্তীভাবে পরিচালিত হতে পারে, এই কোডল্যাবে সেটআপটি সহজ করার জন্য আমরা গুগল ক্লাউড শেল ব্যবহার করব, যা ক্লাউডে চলমান একটি কমান্ড লাইন পরিবেশ।

ক্লাউড শেল সক্রিয় করুন

  1. ক্লাউড কনসোল থেকে, ক্লাউড শেল সক্রিয় করুন ক্লিক করুন 4292cbf4971c9786.png সম্পর্কে .

bce75f34b2c53987.png সম্পর্কে

যদি আপনি আগে কখনও ক্লাউড শেল শুরু না করে থাকেন, তাহলে আপনাকে একটি মধ্যবর্তী স্ক্রিন (ভাঁজের নীচে) দেখানো হবে যেখানে এটি কী তা বর্ণনা করা হবে। যদি তাই হয়, তাহলে Continue এ ক্লিক করুন (এবং আপনি এটি আর কখনও দেখতে পাবেন না)। এই এককালীন স্ক্রিনটি কেমন দেখাবে:

70f315d7b402b476.png সম্পর্কে

ক্লাউড শেলের সাথে সংযোগ স্থাপন এবং সংযোগ স্থাপন করতে মাত্র কয়েক মুহূর্ত সময় লাগবে।

fbe3a0674c982259.png সম্পর্কে

এই ভার্চুয়াল মেশিনটি আপনার প্রয়োজনীয় সকল ডেভেলপমেন্ট টুল দিয়ে পূর্ণ। এটি একটি স্থায়ী 5GB হোম ডিরেক্টরি অফার করে এবং Google Cloud-এ চলে, যা নেটওয়ার্ক কর্মক্ষমতা এবং প্রমাণীকরণকে ব্যাপকভাবে উন্নত করে। এই কোডল্যাবে আপনার বেশিরভাগ কাজ, যদি সব না হয়, কেবল একটি ব্রাউজার বা আপনার Chromebook দিয়ে করা যেতে পারে।

একবার ক্লাউড শেলের সাথে সংযুক্ত হয়ে গেলে, আপনি দেখতে পাবেন যে আপনি ইতিমধ্যেই প্রমাণিত এবং প্রকল্পটি ইতিমধ্যেই আপনার প্রকল্প আইডিতে সেট করা আছে।

  1. আপনি প্রমাণিত কিনা তা নিশ্চিত করতে ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালান:
gcloud auth list

কমান্ড আউটপুট

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. gcloud কমান্ড আপনার প্রকল্প সম্পর্কে জানে কিনা তা নিশ্চিত করতে ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালান:
gcloud config list project

কমান্ড আউটপুট

[core]
project = <PROJECT_ID>

যদি তা না হয়, তাহলে আপনি এই কমান্ড দিয়ে এটি সেট করতে পারেন:

gcloud config set project <PROJECT_ID>

কমান্ড আউটপুট

Updated property [core/project].

৩. ক্লাউড প্রোফাইলারে নেভিগেট করুন

ক্লাউড কনসোলে, বাম নেভিগেশন বারে "প্রোফাইলার" এ ক্লিক করে প্রোফাইলার UI তে নেভিগেট করুন:

37ad0df7ddb2ad17.png সম্পর্কে

বিকল্পভাবে, আপনি ক্লাউড কনসোল সার্চ বার ব্যবহার করে প্রোফাইলার UI-তে যেতে পারেন: শুধু "ক্লাউড প্রোফাইলার" টাইপ করুন এবং পাওয়া আইটেমটি নির্বাচন করুন। যেভাবেই হোক, আপনি নীচের মত "প্রদর্শনের জন্য কোন ডেটা নেই" বার্তা সহ প্রোফাইলার UI দেখতে পাবেন। প্রকল্পটি নতুন, তাই এটিতে এখনও কোনও প্রোফাইলিং ডেটা সংগ্রহ করা হয়নি।

d275a5f61ed31fb2.png সম্পর্কে

এখন কিছু প্রোফাইল করার সময়!

৪. বেঞ্চমার্ক প্রোফাইল করুন

আমরা Github এ উপলব্ধ একটি সহজ সিন্থেটিক Go অ্যাপ্লিকেশন ব্যবহার করব। ক্লাউড শেল টার্মিনালে যা আপনি এখনও খোলা রেখেছেন (এবং প্রোফাইলার UI তে "প্রদর্শনের জন্য কোনও ডেটা নেই" বার্তাটি এখনও প্রদর্শিত হচ্ছে), নিম্নলিখিত কমান্ডটি চালান:

$ go get -u github.com/GoogleCloudPlatform/golang-samples/profiler/...

তারপর অ্যাপ্লিকেশন ডিরেক্টরিতে যান:

$ cd ~/gopath/src/github.com/GoogleCloudPlatform/golang-samples/profiler/hotapp

ডিরেক্টরিতে "main.go" ফাইলটি রয়েছে, যা একটি সিন্থেটিক অ্যাপ যার প্রোফাইলিং এজেন্ট সক্রিয় রয়েছে:

main.go সম্পর্কে

...
import (
        ...
        "cloud.google.com/go/profiler"
)
...
func main() {
        err := profiler.Start(profiler.Config{
                Service:        "hotapp-service",
                DebugLogging:   true,
                MutexProfiling: true,
        })
        if err != nil {
                log.Fatalf("failed to start the profiler: %v", err)
        }
        ...
}

প্রোফাইলিং এজেন্ট ডিফল্টরূপে CPU, হিপ এবং থ্রেড প্রোফাইল সংগ্রহ করে। এখানে কোডটি mutex ("contention" নামেও পরিচিত) প্রোফাইল সংগ্রহ করতে সক্ষম করে।

এখন, প্রোগ্রামটি চালান:

$ go run main.go

প্রোগ্রামটি চলার সাথে সাথে, প্রোফাইলিং এজেন্ট পর্যায়ক্রমে পাঁচটি কনফিগার করা ধরণের প্রোফাইল সংগ্রহ করবে। সংগ্রহটি সময়ের সাথে সাথে র্যান্ডমাইজ করা হয় (প্রতিটি ধরণের জন্য প্রতি মিনিটে একটি প্রোফাইলের গড় হার সহ), তাই প্রতিটি ধরণের সংগ্রহ করতে তিন মিনিট পর্যন্ত সময় লাগতে পারে। প্রোগ্রামটি আপনাকে বলে দেয় যে এটি কখন একটি প্রোফাইল তৈরি করে। উপরের কনফিগারেশনে DebugLogging ফ্ল্যাগ দ্বারা বার্তাগুলি সক্রিয় করা হয়; অন্যথায়, এজেন্ট নীরবে চলে:

$ go run main.go
2018/03/28 15:10:24 profiler has started
2018/03/28 15:10:57 successfully created profile THREADS
2018/03/28 15:10:57 start uploading profile
2018/03/28 15:11:19 successfully created profile CONTENTION
2018/03/28 15:11:30 start uploading profile
2018/03/28 15:11:40 successfully created profile CPU
2018/03/28 15:11:51 start uploading profile
2018/03/28 15:11:53 successfully created profile CONTENTION
2018/03/28 15:12:03 start uploading profile
2018/03/28 15:12:04 successfully created profile HEAP
2018/03/28 15:12:04 start uploading profile
2018/03/28 15:12:04 successfully created profile THREADS
2018/03/28 15:12:04 start uploading profile
2018/03/28 15:12:25 successfully created profile HEAP
2018/03/28 15:12:25 start uploading profile
2018/03/28 15:12:37 successfully created profile CPU
...

প্রথম প্রোফাইল সংগ্রহ করার কিছুক্ষণ পরেই UI নিজেই আপডেট হবে। এর পরে এটি স্বয়ংক্রিয়ভাবে আপডেট হবে না, তাই নতুন ডেটা দেখতে, আপনাকে প্রোফাইলার UI ম্যানুয়ালি রিফ্রেশ করতে হবে। এটি করার জন্য, সময় ব্যবধান পিকারে Now বোতামে দুবার ক্লিক করুন:

650051097b651b91.png সম্পর্কে

UI রিফ্রেশ করার পরে, আপনি এরকম কিছু দেখতে পাবেন:

47a763d4dc78b6e8.png সম্পর্কে

প্রোফাইল টাইপ নির্বাচকটি উপলব্ধ পাঁচটি প্রোফাইল টাইপ দেখায়:

b5d7b4b5051687c9.png সম্পর্কে

এবার আসুন প্রতিটি প্রোফাইলের ধরণ এবং কিছু গুরুত্বপূর্ণ UI ক্ষমতা পর্যালোচনা করি, এবং তারপর কিছু পরীক্ষা-নিরীক্ষা করি। এই পর্যায়ে, আপনার আর ক্লাউড শেল টার্মিনালের প্রয়োজন নেই, তাই আপনি CTRL-C টিপে এবং "exit" টাইপ করে এটি থেকে বেরিয়ে আসতে পারেন।

৫. প্রোফাইলার ডেটা বিশ্লেষণ করুন

এখন যেহেতু আমরা কিছু তথ্য সংগ্রহ করেছি, আসুন এটি আরও ঘনিষ্ঠভাবে দেখি। আমরা একটি সিন্থেটিক অ্যাপ ব্যবহার করছি (উৎসটি Github এ উপলব্ধ ) যা উৎপাদনে বিভিন্ন ধরণের কর্মক্ষমতা সমস্যার জন্য সাধারণ আচরণগুলিকে অনুকরণ করে।

CPU-নিবিড় কোড

CPU প্রোফাইলের ধরণ নির্বাচন করুন। UI লোড করার পরে, আপনি ফ্লেম গ্রাফে load ফাংশনের জন্য চারটি পাতার ব্লক দেখতে পাবেন, যা সম্মিলিতভাবে সমস্ত CPU খরচের জন্য দায়ী:

অনুসরণ

এই ফাংশনটি বিশেষভাবে একটি টাইট লুপ চালিয়ে প্রচুর CPU চক্র ব্যবহার করার জন্য লেখা হয়েছে:

main.go সম্পর্কে

func load() {
        for i := 0; i < (1 << 20); i++ {
        }
}

ফাংশনটি পরোক্ষভাবে busyloop () থেকে চারটি কল পাথের মাধ্যমে কল করা হয়: busyloop → { foo1 , foo2 } → { bar , baz } → load । একটি ফাংশন বক্সের প্রস্থ নির্দিষ্ট কল পাথের আপেক্ষিক খরচ প্রতিনিধিত্ব করে। এই ক্ষেত্রে চারটি পাথের প্রায় একই খরচ হয়। একটি বাস্তব প্রোগ্রামে, আপনি কর্মক্ষমতার দিক থেকে সবচেয়ে গুরুত্বপূর্ণ কল পাথগুলি অপ্টিমাইজ করার উপর ফোকাস করতে চান। শিখা গ্রাফ, যা দৃশ্যত বৃহত্তর বাক্স সহ আরও ব্যয়বহুল পাথগুলিকে জোর দেয়, এই পাথগুলিকে সনাক্ত করা সহজ করে তোলে।

ডিসপ্লে আরও পরিমার্জন করার জন্য আপনি প্রোফাইল ডেটা ফিল্টার ব্যবহার করতে পারেন। উদাহরণস্বরূপ, "Show stacks" ফিল্টার যোগ করার চেষ্টা করুন যেখানে "baz" কে ফিল্টার স্ট্রিং হিসেবে উল্লেখ করা হয়েছে। আপনি নীচের স্ক্রিনশটের মতো কিছু দেখতে পাবেন, যেখানে load() করার জন্য চারটি কল পাথের মধ্যে মাত্র দুটি প্রদর্শিত হবে। এই দুটি পাথই একমাত্র এমন যা "baz" স্ট্রিং সহ একটি ফাংশনের মধ্য দিয়ে যায়। এই ধরনের ফিল্টারিং তখন কার্যকর যখন আপনি একটি বৃহত্তর প্রোগ্রামের একটি উপ-অংশে ফোকাস করতে চান (উদাহরণস্বরূপ, কারণ আপনি এটির শুধুমাত্র একটি অংশের মালিক)।

eb1d97491782b03f.png সম্পর্কে

মেমোরি-ইনটেনসিভ কোড

এখন "Heap" প্রোফাইল টাইপে স্যুইচ করুন। পূর্ববর্তী পরীক্ষাগুলিতে তৈরি করা যেকোনো ফিল্টার মুছে ফেলতে ভুলবেন না। এখন আপনি একটি ফ্লেম গ্রাফ দেখতে পাবেন যেখানে allocImpl , যা alloc দ্বারা ডাকা হয়, অ্যাপে মেমরির প্রধান গ্রাহক হিসাবে প্রদর্শিত হবে:

f6311c8c841d04c4.png সম্পর্কে

ফ্লেম গ্রাফের উপরে সারাংশ টেবিলটি নির্দেশ করে যে অ্যাপটিতে ব্যবহৃত মোট মেমোরির পরিমাণ গড়ে ~57.4 MiB, যার বেশিরভাগই allocImpl ফাংশন দ্বারা বরাদ্দ করা হয়। এই ফাংশনটি বাস্তবায়নের ক্ষেত্রে এটি আশ্চর্যজনক নয়:

main.go সম্পর্কে

func allocImpl() {
        // Allocate 64 MiB in 64 KiB chunks
        for i := 0; i < 64*16; i++ {
                mem = append(mem, make([]byte, 64*1024))
        }
}

ফাংশনটি একবার কার্যকর হয়, ছোট ছোট অংশে 64 MiB বরাদ্দ করে, তারপর আবর্জনা সংগ্রহ থেকে রক্ষা করার জন্য একটি গ্লোবাল ভেরিয়েবলে সেই অংশগুলিতে পয়েন্টার সংরক্ষণ করে। মনে রাখবেন যে প্রোফাইলার দ্বারা ব্যবহৃত মেমরির পরিমাণ 64 MiB থেকে কিছুটা আলাদা: Go হিপ প্রোফাইলার একটি পরিসংখ্যানগত টুল, তাই পরিমাপগুলি কম ওভারহেড কিন্তু বাইট-সঠিক নয়। এই ধরণের ~10% পার্থক্য দেখলে অবাক হবেন না।

আইও-ইনটেনসিভ কোড

প্রোফাইল টাইপ সিলেক্টরে "থ্রেডস" নির্বাচন করলে, ডিসপ্লেটি একটি ফ্লেম গ্রাফে স্যুইচ করবে যেখানে বেশিরভাগ প্রস্থ wait এবং waitImpl ফাংশন দ্বারা নেওয়া হয়:

ebd57fdff01dede9.png সম্পর্কে

উপরের ফ্লেম গ্রাফের সারসংক্ষেপে, আপনি দেখতে পাচ্ছেন যে ১০০টি গোরুটিন আছে যারা wait ফাংশন থেকে তাদের কল স্ট্যাক বৃদ্ধি করে। এটি একেবারে সঠিক, কারণ এই waits শুরু করার কোডটি এইরকম দেখাচ্ছে:

main.go সম্পর্কে

func main() {
        ...
        // Simulate some waiting goroutines.
        for i := 0; i < 100; i++ {
                go wait()
        }

এই প্রোফাইল টাইপটি প্রোগ্রামটি অপেক্ষা করার সময় (যেমন I/O) কোন অপ্রত্যাশিত সময় ব্যয় করে কিনা তা বোঝার জন্য কার্যকর। এই ধরনের কল স্ট্যাকগুলি সাধারণত CPU প্রোফাইলার দ্বারা নমুনা করা হবে না, কারণ তারা CPU সময়ের কোনও উল্লেখযোগ্য অংশ ব্যয় করে না। আপনি প্রায়শই থ্রেড প্রোফাইলের সাথে "স্ট্যাক লুকান" ফিল্টার ব্যবহার করতে চাইবেন - উদাহরণস্বরূপ, gopark, কারণ এগুলি প্রায়শই নিষ্ক্রিয় গোরুটিন এবং I/O-তে অপেক্ষা করা স্ট্যাকগুলির তুলনায় কম আকর্ষণীয়।

থ্রেড প্রোফাইল টাইপ প্রোগ্রামের এমন পয়েন্টগুলি সনাক্ত করতেও সাহায্য করতে পারে যেখানে থ্রেডগুলি দীর্ঘ সময়ের জন্য প্রোগ্রামের অন্য অংশের মালিকানাধীন একটি মিউটেক্সের জন্য অপেক্ষা করছে, তবে নিম্নলিখিত প্রোফাইল টাইপটি এর জন্য আরও কার্যকর।

বিতর্ক-নিবিড় কোড

কন্টেনশন প্রোফাইল টাইপ প্রোগ্রামের সবচেয়ে "ওয়ান্টেড" লকগুলি সনাক্ত করে। এই প্রোফাইল টাইপটি Go প্রোগ্রামগুলির জন্য উপলব্ধ তবে এজেন্ট কনফিগারেশন কোডে " MutexProfiling: true " নির্দিষ্ট করে স্পষ্টভাবে সক্ষম করতে হবে। সংগ্রহটি ("Contentions" মেট্রিকের অধীনে) রেকর্ড করে কাজ করে যখন একটি নির্দিষ্ট লক, যখন একটি গোরুটিন A দ্বারা আনলক করা হয়, তখন অন্য একটি গোরুটিন B লকটি আনলক হওয়ার জন্য অপেক্ষা করছিল। এটি ("Delay" মেট্রিকের অধীনে) ব্লক করা গোরুটিন লকের জন্য অপেক্ষা করার সময়ও রেকর্ড করে। এই উদাহরণে, একটি একক কন্টেনশন স্ট্যাক রয়েছে এবং লকের জন্য মোট অপেক্ষার সময় ছিল 10.5 সেকেন্ড:

83f00dca4a0f768e.png সম্পর্কে

এই প্রোফাইলটি তৈরি করে এমন কোডটিতে ৪টি গোরুটিন রয়েছে যারা একটি মিউটেক্সের উপর লড়াই করছে:

main.go সম্পর্কে

func contention(d time.Duration) {
        contentionImpl(d)
}

func contentionImpl(d time.Duration) {
        for {
                mu.Lock()
                time.Sleep(d)
                mu.Unlock()
        }
}
...
func main() {
        ...
        for i := 0; i < 4; i++ {
                go contention(time.Duration(i) * 50 * time.Millisecond)
        }
}

6. সারাংশ

এই ল্যাবে, আপনি শিখেছেন কিভাবে ক্লাউড প্রোফাইলারের সাথে ব্যবহারের জন্য একটি Go প্রোগ্রাম কনফিগার করা যায়। আপনি এই টুলটি ব্যবহার করে পারফর্ম্যান্স ডেটা সংগ্রহ, দেখা এবং বিশ্লেষণ করার পদ্ধতিও শিখেছেন। আপনি এখন আপনার নতুন দক্ষতা গুগল ক্লাউড প্ল্যাটফর্মে পরিচালিত প্রকৃত পরিষেবাগুলিতে প্রয়োগ করতে পারেন।

৭. অভিনন্দন!

তুমি ক্লাউড প্রোফাইলার কনফিগার এবং ব্যবহার করতে শিখেছো!

আরও জানুন

লাইসেন্স

এই কাজটি ক্রিয়েটিভ কমন্স অ্যাট্রিবিউশন ২.০ জেনেরিক লাইসেন্সের অধীনে লাইসেন্সপ্রাপ্ত।