কারণ ডায়াগ্রাম পুনরায় আঁকার জন্য জীবন খুব ছোট
আমি সম্প্রতি একটি সফটওয়্যার ইঞ্জিনিয়ার হিসাবে একটি নতুন কোম্পানিতে যোগদান করেছি। এটা সবসময় ঘটবে, আমি স্ক্র্যাচ থেকে শুরু ছিল. জিনিসগুলি যেমন: একটি অ্যাপ লাইভের কোড কোথায়? এটা কিভাবে স্থাপন করা হয়? কনফিগারেশন কোথা থেকে আসে? সৌভাগ্যক্রমে, আমার সহকর্মীরা সবকিছুকে 'কোড হিসাবে অবকাঠামো' তৈরি করার একটি দুর্দান্ত কাজ করেছে। তাই আমি নিজেকে ধরে ফেললাম: যদি সবকিছু কোডে থাকে তবে কেন সমস্ত বিন্দু সংযোগ করার জন্য একটি সরঞ্জাম নেই?
এই টুলটি কোডবেস পর্যালোচনা করবে এবং মূল দিকগুলি হাইলাইট করে একটি অ্যাপ্লিকেশন আর্কিটেকচার ডায়াগ্রাম তৈরি করবে। একজন নতুন প্রকৌশলী ডায়াগ্রামটি দেখে বলতে পারেন, "আহ, ঠিক আছে, এইভাবে এটি কাজ করে।"
আমি যতই খোঁজাখুঁজি করেও তেমন কিছু পেলাম না। আমি যে সবথেকে কাছের মিল খুঁজে পেয়েছি সেগুলি হল পরিকাঠামোর চিত্র আঁকে। আমি তাদের কিছু এই পর্যালোচনাতে রেখেছি যাতে আপনি আরও ঘনিষ্ঠভাবে দেখতে পারেন। অবশেষে, আমি গুগলিং ছেড়ে দিয়েছিলাম এবং কিছু নতুন দুর্দান্ত জিনিস তৈরিতে আমার হাত চেষ্টা করার সিদ্ধান্ত নিয়েছিলাম।
প্রথমে, আমি Gradle, Docker , এবং Terraform সহ একটি নমুনা জাভা অ্যাপ তৈরি করেছি। GitHub অ্যাকশন পাইপলাইন অ্যামাজন ইলাস্টিক কন্টেইনার পরিষেবাতে অ্যাপ স্থাপন করে। এই রেপোটি আমি যে টুলটি তৈরি করব তার একটি উৎস হবে (কোড এখানে রয়েছে)।
দ্বিতীয়ত, আমি ফলাফল হিসাবে যা দেখতে চেয়েছিলাম তার একটি খুব উচ্চ-স্তরের চিত্র আঁকলাম:
আমি সিদ্ধান্ত নিয়েছি যে দুটি ধরণের সংস্থান থাকবে:
আমি আর্টিফ্যাক্ট শব্দটি খুব ওভারলোডেড পেয়েছি, তাই আমি Relic বেছে নিয়েছি। তাই একটি রিলিক কি? আপনি যা দেখতে চান তার 90% এটি। সহ, কিন্তু সীমাবদ্ধ নয়:
প্রতিটি রিলিকের একটি নাম থাকে (যেমন, my-shiny-app), ঐচ্ছিক প্রকার (যেমন, Jar), এবং কী → মান জোড়ার একটি সেট (যেমন, পাথ → /build/libs/my-shiny-app.jar) সম্পূর্ণরূপে Relic বর্ণনা. তাদের সংজ্ঞা বলা হয়। রিলিকের যত বেশি সংজ্ঞা আছে - তত ভালো।
দ্বিতীয় প্রকারটি একটি উত্স । উত্সগুলি ধ্বংসাবশেষকে সংজ্ঞায়িত করে, তৈরি করে বা বিধান করে (যেমন, উপরে হলুদ বাক্স)। একটি উৎস কোন জায়গায় একটি অবশেষ বর্ণনা করে এবং এটি কোথা থেকে এসেছে তার একটি ধারনা দেয়। যদিও উৎস হল সেই উপাদান যা থেকে আমরা সবচেয়ে বেশি তথ্য পাই, সেগুলি সাধারণত ডায়াগ্রামে গৌণ অর্থ থাকে। আপনার সম্ভবত টেরাফর্ম বা গ্রেডল থেকে অন্য সমস্ত রিলিকে যাওয়ার জন্য প্রচুর তীর চিহ্নের প্রয়োজন নেই।
রিলিক এবং উত্সের মধ্যে বহু-থেকে-অনেক সম্পর্ক রয়েছে।
কোডের প্রতিটি অংশ কভার করা অসম্ভব। আধুনিক অ্যাপে অনেক ফ্রেমওয়ার্ক, টুল বা ক্লাউড উপাদান থাকতে পারে। AWS একাই Terraform এর জন্য প্রায় 950 টি রিসোর্স এবং ডেটা সোর্স আছে! টুলটিকে সহজেই প্রসারিত করতে হবে এবং ডিজাইনের মাধ্যমে ডিকপল করতে হবে যাতে অন্যান্য ব্যক্তি বা সংস্থাগুলি অবদান রাখতে পারে।
যদিও আমি অবিশ্বাস্যভাবে প্লাগেবল টেরাফর্ম প্রদানকারীদের আর্কিটেকচারের একটি বিশাল অনুরাগী, আমি সরলীকৃত হওয়া সত্ত্বেও একই নির্মাণ করার সিদ্ধান্ত নিয়েছি:
প্রদানকারীর একটি স্পষ্ট দায়িত্ব রয়েছে: অনুরোধ করা উৎস ফাইলের উপর ভিত্তি করে অবশেষ তৈরি করা। উদাহরণস্বরূপ, GradleProvider *.gradle ফাইলগুলি পড়ে এবং Jar , War , বা Gz Relics ফেরত দেয়। প্রতিটি প্রদানকারী তারা যে ধরনের অবশেষ সম্পর্কে সচেতন তা তৈরি করে। প্রদানকারীরা অবশেষের মধ্যে মিথস্ক্রিয়া সম্পর্কে চিন্তা করেন না। তারা ঘোষণামূলকভাবে ধ্বংসাবশেষ তৈরি করে, একে অপরের থেকে সম্পূর্ণ বিচ্ছিন্ন।
এই পদ্ধতির সাথে, আপনি যতটা চান তত গভীরে যাওয়া সহজ। একটি ভাল উদাহরণ হল গিটহাব অ্যাকশন। একটি সাধারণ ওয়ার্কফ্লো YAML ফাইল শিথিলভাবে সংযুক্ত উপাদান এবং পরিষেবাগুলি ব্যবহার করে কয়েক ডজন ধাপ নিয়ে গঠিত। একটি ওয়ার্কফ্লো একটি JAR, তারপর একটি ডকার ইমেজ তৈরি করতে পারে এবং এটি পরিবেশে স্থাপন করতে পারে। কর্মপ্রবাহের প্রতিটি একক পদক্ষেপ তার প্রদানকারী দ্বারা আচ্ছাদিত হতে পারে। সুতরাং, এর ডেভেলপাররা, ধরা যাক, ডকার অ্যাকশনগুলি তাদের যত্ন নেওয়া পদক্ষেপগুলির সাথে সম্পর্কিত একটি প্রদানকারী তৈরি করে।
এই পদ্ধতিটি যেকোন সংখ্যক লোককে সমান্তরালভাবে কাজ করার অনুমতি দেয়, টুলটিতে আরও যুক্তি যোগ করে। শেষ ব্যবহারকারীরাও তাদের প্রদানকারীদের দ্রুত বাস্তবায়ন করতে পারে (কিছু মালিকানাধীন প্রযুক্তির ক্ষেত্রে)। নিচে কাস্টমাইজেশনের অধীনে আরও দেখুন।
রসালো অংশে যাওয়ার আগে আসুন পরবর্তী ফাঁদটি দেখুন। দুটি প্রদানকারী, যার প্রত্যেকটি একটি রিলিক তৈরি করে। সেটা ঠিক আছে। কিন্তু যদি এই দুটি অবশেষ দুটি স্থানে সংজ্ঞায়িত একই উপাদানের প্রতিনিধিত্ব হয়? এখানে একটি উদাহরণ.
AmazonECSPprovider টাস্ক ডেফিনিশন JSON পার্স করে এবং AmazonECSTask টাইপ সহ একটি Relic তৈরি করে। GitHub অ্যাকশন ওয়ার্কফ্লোতে একটি ECS-সম্পর্কিত পদক্ষেপ রয়েছে, তাই অন্য প্রদানকারী একটি AmazonECSTaskDeployment Relic তৈরি করে। এখন, আমাদের ডুপ্লিকেট আছে কারণ উভয় প্রদানকারী একে অপরের সম্পর্কে কিছুই জানে না। তদুপরি, তাদের কারও পক্ষে অনুমান করা ভুল যে অন্য একজন ইতিমধ্যে একটি রিলিক তৈরি করেছে। তারপর কি?
তাদের প্রত্যেকের সংজ্ঞা (গুণাবলী) থাকার কারণে আমরা সদৃশগুলির একটিও বাদ দিতে পারি না। একমাত্র উপায় হল তাদের একত্রিত করা। ডিফল্টরূপে, পরবর্তী যুক্তি একত্রিতকরণের সিদ্ধান্তকে সংজ্ঞায়িত করে:
relic1.name() == relic2.name() && relic1.source() != relic2.source()
আমরা দুটি অবশেষ একত্রিত করি যদি তাদের নাম সমান হয় তবে সেগুলি বিভিন্ন উত্সে সংজ্ঞায়িত করা হয়েছে (যেমন আমাদের উদাহরণে, রেপোতে JSON এবং টাস্ক ডেফিনিশন রেফারেন্স GithHub অ্যাকশনগুলিতে রয়েছে)।
যখন আমরা একত্রিত হই, আমরা:
আমি ইচ্ছাকৃতভাবে একটি রিলিকের একটি গুরুত্বপূর্ণ দিক বাদ দিয়েছি। এটির একটি ম্যাচার থাকতে পারে - এবং এটি থাকা ভাল! ম্যাচার একটি বুলিয়ান ফাংশন যা একটি আর্গুমেন্ট নেয় এবং এটি পরীক্ষা করে। ম্যাচার্স একটি লিঙ্কিং প্রক্রিয়ার গুরুত্বপূর্ণ অংশ। যদি একটি রিলিক অন্যের রিলিকের কোনো সংজ্ঞার সাথে মিলে যায়, তাহলে সেগুলিকে একসাথে সংযুক্ত করা হবে।
মনে আছে যখন আমি বলেছিলাম যে প্রোভাইডারদের অন্য প্রোভাইডারদের দ্বারা তৈরি করা অবশেষ সম্পর্কে কোন ধারণা নেই? এটা এখনও সত্য. যাইহোক, একটি প্রদানকারী একটি রিলিকের জন্য একটি ম্যাচারকে সংজ্ঞায়িত করে। অন্য কথায়, এটি ফলস্বরূপ ডায়াগ্রামে দুটি বাক্সের মধ্যে একটি তীরের একপাশে প্রতিনিধিত্ব করে।
উদাহরণ। Dockerfile একটি ENTRYPOINT নির্দেশ আছে.
ENTRYPOINT java -jar /app/arch-diagram-sample.jar
কিছু নিশ্চিততার সাথে, আমরা বলতে পারি যে ডকার ENTRYPOINT-এর অধীনে যা নির্দিষ্ট করা আছে তা কন্টেইনারাইজ করে । সুতরাং, ডকারফাইল রিলিকের একটি সাধারণ ম্যাচার ফাংশন রয়েছে: entrypointInstruction.contains(anotherRelicsDefinition)
। খুব সম্ভবত, সংজ্ঞায় arch-diagram-sample.jar
সহ কিছু জার রিলিক এর সাথে মিলবে। যদি হ্যাঁ, ডকারফাইল এবং জার রিলিক্সের মধ্যে একটি তীর প্রদর্শিত হয়।
ম্যাচার সংজ্ঞায়িত করার সাথে সাথে, লিঙ্কিং প্রক্রিয়াটি বেশ সহজবোধ্য দেখাচ্ছে। লিঙ্কিং পরিষেবা সমস্ত অবশেষের উপর পুনরাবৃত্তি করে এবং তাদের ম্যাচারের ফাংশনগুলিকে কল করে। Relic A কি Relic এর B সংজ্ঞাগুলির সাথে মেলে? হ্যাঁ? ফলস্বরূপ গ্রাফে সেই অবশেষগুলির মধ্যে একটি প্রান্ত যুক্ত করুন। প্রান্তের নামও করা যেত।
শেষ ধাপ হল পূর্ববর্তী পর্যায়ের আমাদের চূড়ান্ত গ্রাফটি কল্পনা করা। সুস্পষ্ট PNG ছাড়াও, টুলটি অতিরিক্ত ফরম্যাট সমর্থন করে, যেমন মারমেইড , প্ল্যান্ট ইউএমএল , এবং ডট । এই পাঠ্য বিন্যাসগুলি কম আকর্ষণীয় দেখাতে পারে, তবে বিশাল সুবিধা হল আপনি এই পাঠ্যগুলিকে প্রায় যেকোনো উইকি পৃষ্ঠায় এম্বেড করতে পারেন (
এখানে নমুনা রেপোর চূড়ান্ত চিত্রটি কেমন দেখায়:
কাস্টম উপাদান প্লাগ ইন করার ক্ষমতা বা বিদ্যমান লজিক পরিবর্তন করার ক্ষমতা অপরিহার্য, বিশেষ করে যখন একটি টুল তার প্রাথমিক পর্যায়ে থাকে। অবশেষ এবং উৎস ডিফল্টরূপে যথেষ্ট নমনীয়; আপনি তাদের মধ্যে যা খুশি রাখতে পারেন। প্রতিটি অন্যান্য উপাদান কাস্টমাইজযোগ্য. বিদ্যমান সরবরাহকারীরা আপনার প্রয়োজনীয় সংস্থানগুলিকে কভার করে না? সহজে আপনার নিজের বাস্তবায়ন. উপরে বর্ণিত একত্রীকরণ বা লিঙ্কিং যুক্তির সাথে সন্তুষ্ট নন? সমস্যা নেই; আপনার নিজস্ব LinkStrategy বা MergeStrategy যোগ করুন। একটি JAR ফাইলে সবকিছু প্যাক করুন এবং এটি স্টার্টআপে যোগ করুন। এখানে আরো পড়ুন.
সোর্স কোডের উপর ভিত্তি করে একটি ডায়াগ্রাম তৈরি করা সম্ভবত ট্র্যাকশন লাভ করবে। এবং বিশেষ করে NoReDraw টুল (হ্যাঁ, আমি যে টুলের কথা বলছিলাম তার নাম এটি)। অবদানকারীদের স্বাগত জানাই !
সবচেয়ে উল্লেখযোগ্য সুবিধা (যা নাম থেকে আসে) হল যে উপাদানগুলি পরিবর্তন হলে একটি ডায়াগ্রাম পুনরায় আঁকার প্রয়োজন নেই। ইঞ্জিনিয়ারিং মনোযোগের অভাব কেন সাধারণভাবে ডকুমেন্টেশন (এবং বিশেষভাবে চিত্র) পুরানো হয়ে যায়। NoReDraw- এর মতো সরঞ্জামগুলির সাথে, এটি আর কোনও সমস্যা হওয়া উচিত নয় কারণ এটি যেকোনো PR/CI পাইপলাইনে সহজেই প্লাগ করা যায়। মনে রাখবেন, ডায়াগ্রাম পুনরায় আঁকার জন্য জীবন খুব ছোট