সফ্টওয়্যার সিস্টেমে ব্যর্থতা অনিবার্য। এই ব্যর্থতাগুলি কীভাবে পরিচালনা করা হয় তা উল্লেখযোগ্যভাবে সিস্টেমের কার্যকারিতা, নির্ভরযোগ্যতা এবং ব্যবসার নীচের লাইনকে প্রভাবিত করতে পারে। এই পোস্টে, আমি ব্যর্থতার উল্টোদিকে আলোচনা করতে চাই। কেন আপনার ব্যর্থতা খোঁজা উচিত, কেন ব্যর্থতা ভাল, এবং কেন ব্যর্থতা এড়ানো আপনার আবেদনের নির্ভরযোগ্যতা হ্রাস করতে পারে। আমরা ব্যর্থ-দ্রুত বনাম ব্যর্থ-নিরাপদ আলোচনা দিয়ে শুরু করব; এটি আমাদের সাধারণভাবে ব্যর্থতা সম্পর্কে দ্বিতীয় আলোচনায় নিয়ে যাবে।
একটি পার্শ্ব নোট হিসাবে, আপনি যদি এই এবং এই সিরিজের অন্যান্য পোস্টের বিষয়বস্তু পছন্দ করেন, আমার চেক আউট
ব্যর্থ-দ্রুত সিস্টেমগুলি একটি অপ্রত্যাশিত অবস্থার সম্মুখীন হলে অবিলম্বে কাজ বন্ধ করার জন্য ডিজাইন করা হয়েছে। এই তাৎক্ষণিক ব্যর্থতা প্রাথমিকভাবে ত্রুটি ধরতে সাহায্য করে, ডিবাগিংকে আরও সহজ করে তোলে।
ব্যর্থ-দ্রুত পদ্ধতি নিশ্চিত করে যে ত্রুটিগুলি অবিলম্বে ধরা পড়ে। উদাহরণ স্বরূপ, প্রোগ্রামিং ভাষার জগতে, জাভা একটি null
মানের সম্মুখীন হলে তাৎক্ষণিকভাবে একটি NullPointerException
তৈরি করে, সিস্টেমটি বন্ধ করে এবং ত্রুটিটি পরিষ্কার করে এই পদ্ধতিকে মূর্ত করে। এই তাত্ক্ষণিক প্রতিক্রিয়া বিকাশকারীদের সমস্যাগুলিকে দ্রুত সনাক্ত করতে এবং সমাধান করতে সহায়তা করে, তাদের আরও গুরুতর হওয়া থেকে বিরত রাখে।
প্রাথমিকভাবে ত্রুটি ধরা এবং বন্ধ করে, ব্যর্থ-দ্রুত সিস্টেমগুলি ক্যাসকেডিং ব্যর্থতার ঝুঁকি হ্রাস করে, যেখানে একটি ত্রুটি অন্যদের দিকে নিয়ে যায়। এটি সামগ্রিক স্থিতিশীলতা সংরক্ষণ করে, সিস্টেমের মাধ্যমে ছড়িয়ে পড়ার আগে সমস্যাগুলিকে ধারণ করা এবং সমাধান করা সহজ করে তোলে।
ব্যর্থ-দ্রুত সিস্টেমের জন্য ইউনিট এবং ইন্টিগ্রেশন পরীক্ষা লেখা সহজ। এই সুবিধাটি আরও স্পষ্ট হয় যখন আমাদের পরীক্ষা ব্যর্থতা বুঝতে হবে। ব্যর্থ-দ্রুত সিস্টেমগুলি সাধারণত ত্রুটি স্ট্যাক ট্রেসে সমস্যাটির দিকে সরাসরি নির্দেশ করে।
যাইহোক, ব্যর্থ-দ্রুত সিস্টেমগুলি তাদের নিজস্ব ঝুঁকি বহন করে, বিশেষ করে উৎপাদন পরিবেশে:
ব্যর্থ-নিরাপদ সিস্টেমগুলি একটি ভিন্ন পদ্ধতি অবলম্বন করে, এমনকি অপ্রত্যাশিত পরিস্থিতির মুখেও পুনরুদ্ধার এবং চালিয়ে যাওয়ার লক্ষ্য রাখে। এটি তাদের অনিশ্চিত বা অস্থির পরিবেশের জন্য বিশেষভাবে উপযুক্ত করে তোলে।
মাইক্রোসার্ভিসগুলি ব্যর্থ-নিরাপদ সিস্টেমের একটি প্রধান উদাহরণ, তাদের স্থাপত্যের মাধ্যমে স্থিতিস্থাপকতা গ্রহণ করে। সার্কিট ব্রেকার, উভয় ভৌত এবং সফ্টওয়্যার-ভিত্তিক, ক্যাসকেডিং ব্যর্থতা রোধ করতে ব্যর্থ কার্যকারিতা সংযোগ বিচ্ছিন্ন করে, সিস্টেমটিকে কাজ চালিয়ে যেতে সহায়তা করে।
ব্যর্থ-নিরাপদ সিস্টেমগুলি নিশ্চিত করে যে সিস্টেমগুলি এমনকি কঠোর উত্পাদন পরিবেশেও বেঁচে থাকতে পারে, বিপর্যয়কর ব্যর্থতার ঝুঁকি হ্রাস করে। এটি তাদের মিশন-সমালোচনামূলক অ্যাপ্লিকেশনগুলির জন্য বিশেষভাবে উপযুক্ত করে তোলে, যেমন হার্ডওয়্যার ডিভাইস বা মহাকাশ ব্যবস্থায়, যেখানে ত্রুটিগুলি থেকে মসৃণ পুনরুদ্ধার অত্যন্ত গুরুত্বপূর্ণ।
যাইহোক, ব্যর্থ-নিরাপদ সিস্টেমের খারাপ দিক রয়েছে:
কোন পদ্ধতিটি ভাল তা নির্ধারণ করা চ্যালেঞ্জিং, কারণ উভয়েরই তাদের যোগ্যতা রয়েছে। ব্যর্থ-দ্রুত সিস্টেমগুলি অবিলম্বে ডিবাগিং, ক্যাসকেডিং ব্যর্থতার কম ঝুঁকি এবং বাগগুলির দ্রুত সনাক্তকরণ এবং সমাধানের প্রস্তাব দেয়। এটি সমস্যাগুলিকে তাড়াতাড়ি ধরতে এবং সমাধান করতে সাহায্য করে, সেগুলিকে ছড়িয়ে পড়া থেকে রোধ করে৷
ব্যর্থ-নিরাপদ সিস্টেমগুলি ত্রুটিগুলি সুন্দরভাবে পরিচালনা করে, তাদের মিশন-সমালোচনামূলক সিস্টেম এবং অস্থির পরিবেশের জন্য আরও উপযুক্ত করে তোলে, যেখানে বিপর্যয়মূলক ব্যর্থতা বিধ্বংসী হতে পারে।
প্রতিটি পদ্ধতির শক্তি লাভ করতে, একটি সুষম কৌশল কার্যকর হতে পারে:
একটি ভারসাম্যপূর্ণ পদ্ধতির জন্য কোডিং, পর্যালোচনা, টুলিং এবং পরীক্ষার প্রক্রিয়া জুড়ে স্পষ্ট এবং সামঞ্জস্যপূর্ণ বাস্তবায়ন প্রয়োজন, যাতে এটি নির্বিঘ্নে একত্রিত হয় তা নিশ্চিত করে। ব্যর্থ-দ্রুত অর্কেস্ট্রেশন এবং পর্যবেক্ষণযোগ্যতার সাথে ভালভাবে সংহত করতে পারে। কার্যকরীভাবে, এটি ব্যর্থ-নিরাপদ দিকটিকে বিকাশকারী স্তরের পরিবর্তে OPS-এর একটি ভিন্ন স্তরে নিয়ে যায়।
এখানে জিনিস আকর্ষণীয় হয়. এটি ব্যর্থ-নিরাপদ এবং ব্যর্থ-দ্রুত মধ্যে নির্বাচন করার বিষয়ে নয়। এটা তাদের জন্য সঠিক স্তর নির্বাচন সম্পর্কে. উদাহরণস্বরূপ, যদি ব্যর্থ-নিরাপদ পদ্ধতি ব্যবহার করে একটি গভীর স্তরে একটি ত্রুটি পরিচালনা করা হয়, তবে এটি লক্ষ্য করা হবে না। এটি ঠিক হতে পারে, কিন্তু যদি সেই ত্রুটির একটি বিরূপ প্রভাব থাকে (কর্মক্ষমতা, আবর্জনা ডেটা, দুর্নীতি, নিরাপত্তা, ইত্যাদি), তাহলে আমাদের পরবর্তীতে একটি সমস্যা হবে এবং একটি ক্লু থাকবে না।
সঠিক সমাধান হল একটি একক স্তরে সমস্ত ত্রুটি পরিচালনা করা, আধুনিক সিস্টেমে উপরের স্তরটি হল OPS স্তর এবং এটি সবচেয়ে বেশি অর্থবহ। এটি ত্রুটিটি মোকাবেলা করার জন্য সবচেয়ে যোগ্য প্রকৌশলীদের কাছে ত্রুটি রিপোর্ট করতে পারে। কিন্তু তারা অবিলম্বে প্রশমন প্রদান করতে পারে, যেমন একটি পরিষেবা পুনরায় চালু করা, অতিরিক্ত সংস্থান বরাদ্দ করা বা একটি সংস্করণ ফিরিয়ে আনা।
সম্প্রতি, আমি একটি বক্তৃতায় ছিলাম যেখানে বক্তারা তাদের আপডেট করা ক্লাউড আর্কিটেকচার তালিকাভুক্ত করেছেন। তারা একটি ফ্রেমওয়ার্ক ব্যবহার করে মাইক্রোসার্ভিসে একটি শর্টকাট বেছে নিয়েছে যা তাদের ব্যর্থতার ক্ষেত্রে পুনরায় চেষ্টা করার অনুমতি দেয়। দুর্ভাগ্যবশত, ব্যর্থতা আমাদের পছন্দ মতো আচরণ করে না। আপনি একা পরীক্ষার মাধ্যমে এটি সম্পূর্ণরূপে নির্মূল করতে পারবেন না। পুনরায় চেষ্টা করা ব্যর্থ-নিরাপদ নয়। আসলে, এর অর্থ বিপর্যয় হতে পারে।
তারা তাদের সিস্টেম পরীক্ষা করেছে, এবং "এটি কাজ করে", এমনকি উৎপাদনেও। তবে ধরা যাক যে একটি বিপর্যয়কর পরিস্থিতি ঘটে, তাদের পুনরায় চেষ্টা করার প্রক্রিয়াটি তাদের নিজস্ব সার্ভারের বিরুদ্ধে পরিষেবা আক্রমণ অস্বীকার হিসাবে কাজ করতে পারে। এই ধরনের অ্যাড-হক আর্কিটেকচারগুলি যেভাবে ব্যর্থ হতে পারে তার সংখ্যা মন-বিস্ময়কর।
আমরা ব্যর্থতা পুনরায় সংজ্ঞায়িত করার পরে এটি বিশেষভাবে গুরুত্বপূর্ণ।
সফ্টওয়্যার সিস্টেমে ব্যর্থতা শুধুমাত্র ক্র্যাশ সম্পর্কে নয়। একটি ক্র্যাশ একটি সহজ এবং তাত্ক্ষণিক ব্যর্থতা হিসাবে দেখা যেতে পারে, তবে বিবেচনা করার জন্য আরও জটিল সমস্যা রয়েছে। প্রকৃতপক্ষে, পাত্রের বয়সে ক্র্যাশগুলি সম্ভবত সেরা ব্যর্থতা। একটি সিস্টেম সবেমাত্র একটি বাধা সঙ্গে বিরামহীনভাবে পুনরায় চালু হয়.
ডেটা দুর্নীতি একটি ক্র্যাশের চেয়ে অনেক বেশি গুরুতর এবং ছলনাময়। এটি দীর্ঘমেয়াদী পরিণতি বহন করে। দূষিত ডেটা নিরাপত্তা এবং নির্ভরযোগ্যতা সমস্যাগুলির দিকে নিয়ে যেতে পারে যেগুলি সমাধান করা চ্যালেঞ্জিং, ব্যাপক পুনরুদ্ধার করা প্রয়োজন এবং সম্ভাব্যভাবে পুনরুদ্ধারযোগ্য ডেটা।
ক্লাউড কম্পিউটিং ডিফেন্সিভ প্রোগ্রামিং কৌশলের দিকে পরিচালিত করেছে, যেমন সার্কিট ব্রেকার এবং পুনঃপ্রচার, ব্যাপক পরীক্ষার উপর জোর দেয় এবং ব্যর্থতাগুলিকে সুন্দরভাবে ধরতে এবং পরিচালনা করতে লগিং করে। একভাবে, এই পরিবেশ মানের দিক থেকে আমাদের ফিরিয়ে দিয়েছে।
ডেটা স্তরে একটি ব্যর্থ-দ্রুত সিস্টেম এটি ঘটতে বাধা দিতে পারে। একটি বাগ অ্যাড্রেস করা একটি সাধারণ সমাধানের বাইরে যায়৷ এটির মূল কারণ বোঝা এবং পুনরাবৃত্তি প্রতিরোধ করা, ব্যাপক লগিং, পরীক্ষা এবং প্রক্রিয়ার উন্নতিতে প্রসারিত করা প্রয়োজন। এটি নিশ্চিত করে যে বাগটি সম্পূর্ণরূপে সমাধান করা হয়েছে, এটি পুনরায় হওয়ার সম্ভাবনা হ্রাস করে।
যদি এটি উত্পাদনে একটি বাগ হয়, আপনি যদি অবিলম্বে উত্পাদন প্রত্যাবর্তন করতে না পারেন তবে আপনার সম্ভবত প্রত্যাবর্তন করা উচিত। এটি সর্বদা সম্ভব হওয়া উচিত এবং যদি এটি না হয় তবে এটি এমন কিছু যা আপনার কাজ করা উচিত।
একটি ফিক্স করার আগে ব্যর্থতা সম্পূর্ণরূপে বুঝতে হবে. আমার নিজের কোম্পানিগুলিতে আমি প্রায়ই চাপের কারণে সেই পদক্ষেপটি এড়িয়ে যাই, একটি ছোট স্টার্টআপে যা ক্ষমাযোগ্য। বড় কোম্পানিতে, আমাদের মূল কারণ বুঝতে হবে। বাগ এবং উত্পাদন সমস্যাগুলির জন্য ডিব্রিফিংয়ের একটি সংস্কৃতি অপরিহার্য। ফিক্সের মধ্যে প্রসেস মিটিগেশনও অন্তর্ভুক্ত করা উচিত যা অনুরূপ সমস্যাগুলিকে উৎপাদনে পৌঁছাতে বাধা দেয়।
ব্যর্থ-দ্রুত সিস্টেমগুলি ডিবাগ করা অনেক সহজ। তাদের সহজাতভাবে সহজ স্থাপত্য রয়েছে এবং একটি নির্দিষ্ট এলাকায় একটি সমস্যা চিহ্নিত করা সহজ। এমনকি সামান্য লঙ্ঘনের জন্যও ব্যতিক্রমগুলি নিক্ষেপ করা অত্যন্ত গুরুত্বপূর্ণ (যেমন, বৈধতা)। এটি ঢিলেঢালা সিস্টেমে বিদ্যমান বাগগুলির ক্যাসকেডিং প্রতিরোধ করে।
এটি ইউনিট পরীক্ষার দ্বারা আরও প্রয়োগ করা উচিত যা আমরা সংজ্ঞায়িত সীমা যাচাই করে এবং সঠিক ব্যতিক্রমগুলি নিক্ষেপ করা হয়েছে তা যাচাই করে। কোডে পুনরায় চেষ্টা করা এড়ানো উচিত কারণ তারা ডিবাগিংকে ব্যতিক্রমীভাবে কঠিন করে তোলে এবং তাদের সঠিক স্থান OPS স্তরে রয়েছে। এটি আরও সহজ করার জন্য, টাইমআউট ডিফল্টরূপে সংক্ষিপ্ত হওয়া উচিত।
ব্যর্থতা এমন কিছু নয় যা আমরা এড়াতে পারি, ভবিষ্যদ্বাণী করতে পারি বা সম্পূর্ণরূপে পরীক্ষা করতে পারি। একটি ব্যর্থতা ঘটলে ঘা নরম করতে পারি একমাত্র জিনিস। প্রায়শই এই "নরমকরণ" আমাদের অ্যাপ্লিকেশনের দুর্বল স্থানগুলি খুঁজে বের করার লক্ষ্যে যতটা সম্ভব চরম অবস্থার প্রতিলিপি করার জন্য দীর্ঘ-চলমান পরীক্ষাগুলি ব্যবহার করে অর্জন করা হয়। এটি খুব কমই যথেষ্ট। শক্তিশালী সিস্টেমগুলিকে প্রায়ই বাস্তব উত্পাদন ব্যর্থতার উপর ভিত্তি করে এই পরীক্ষাগুলি সংশোধন করতে হবে।
একটি ব্যর্থ-নিরাপদ একটি দুর্দান্ত উদাহরণ হল REST প্রতিক্রিয়াগুলির একটি ক্যাশে যা আমাদের পরিষেবা বন্ধ থাকা সত্ত্বেও কাজ চালিয়ে যেতে দেয়। দুর্ভাগ্যবশত, এটি জটিল কুলুঙ্গির সমস্যা যেমন ক্যাশে বিষক্রিয়া বা এমন পরিস্থিতির দিকে নিয়ে যেতে পারে যেখানে ক্যাশের কারণে নিষিদ্ধ ব্যবহারকারীর এখনও অ্যাক্সেস ছিল।
ব্যর্থ-নিরাপদ শুধুমাত্র উৎপাদন/মঞ্চায়নে এবং OPS স্তরে সর্বোত্তম প্রয়োগ করা হয়। এটি উত্পাদন এবং dev এর মধ্যে পরিবর্তনের পরিমাণ হ্রাস করে, আমরা চাই সেগুলি যতটা সম্ভব একই রকম হোক, তবুও এটি এখনও একটি পরিবর্তন যা উত্পাদনকে নেতিবাচকভাবে প্রভাবিত করতে পারে। যাইহোক, সুবিধাগুলি অসাধারণ, কারণ পর্যবেক্ষণযোগ্যতা সিস্টেমের ব্যর্থতার একটি পরিষ্কার ছবি পেতে পারে।
পর্যবেক্ষণযোগ্য ক্লাউড আর্কিটেকচার নির্মাণের আমার সাম্প্রতিক অভিজ্ঞতা দ্বারা এখানে আলোচনাটি কিছুটা রঙিন। যাইহোক, একই নীতি যেকোন ধরনের সফটওয়্যারের ক্ষেত্রে প্রযোজ্য, তা এমবেডেড বা ক্লাউডে। এই ধরনের ক্ষেত্রে আমরা প্রায়ই কোডে ব্যর্থ-নিরাপদ প্রয়োগ করতে বেছে নিই, এই ক্ষেত্রে আমি একটি নির্দিষ্ট স্তরে ধারাবাহিকভাবে এবং সচেতনভাবে এটি প্রয়োগ করার পরামর্শ দেব।
লাইব্রেরি/ফ্রেমওয়ার্কগুলির একটি বিশেষ ক্ষেত্রেও রয়েছে যা প্রায়শই এই পরিস্থিতিতে অসঙ্গতিপূর্ণ এবং খারাপভাবে নথিভুক্ত আচরণ প্রদান করে। আমি নিজেও আমার কিছু কাজের এমন অসঙ্গতির জন্য দোষী। এটা করা একটি সহজ ভুল.
এটি ডিবাগিং সিরিজের তত্ত্বের উপর আমার শেষ পোস্ট যা ডিবাগিংয়ের উপর আমার বই/কোর্সের অংশ। আমরা প্রায়শই ডিবাগিংকে কিছু ব্যর্থ হলে আমরা যে ক্রিয়াটি করি তা মনে করি। এটা না. আমরা কোডের প্রথম লাইন লিখার মুহুর্তে ডিবাগিং শুরু হয়। আমরা এমন সিদ্ধান্ত নিই যা আমাদের কোড করার সাথে সাথে ডিবাগিং প্রক্রিয়াকে প্রভাবিত করবে, প্রায়শই আমরা ব্যর্থ না হওয়া পর্যন্ত এই সিদ্ধান্তগুলি সম্পর্কে অবগত থাকি না।
আমি আশা করি এই পোস্ট এবং সিরিজ আপনাকে অজানা জন্য প্রস্তুত করা কোড লিখতে সাহায্য করবে। ডিবাগিং, তার প্রকৃতির দ্বারা, অপ্রত্যাশিত মোকাবেলা করে। পরীক্ষা সাহায্য করতে পারে না. কিন্তু আমি যেমন আমার পূর্ববর্তী পোস্টগুলিতে চিত্রিত করেছি, এমন অনেক সাধারণ অনুশীলন রয়েছে যা আমরা গ্রহণ করতে পারি যা প্রস্তুতিকে সহজ করে তুলবে। এটি একটি এককালীন প্রক্রিয়া নয়, এটি একটি পুনরাবৃত্তিমূলক প্রক্রিয়া যার জন্য আমরা ব্যর্থতার সম্মুখীন হওয়ার সাথে সাথে নেওয়া সিদ্ধান্তগুলির পুনর্মূল্যায়ন প্রয়োজন৷