درک کارکرد اغلب قطعات رایانه مانند RAM، دیسک ذخیرهسازی، وسایل جانبی و همچنین نرمافزارهایی که در مجموع به کارکرد صحیح رایانه کمک میکنند، کار سادهای است. اما قلب هر سیستم رایانهای CPU است که حتی از نظر بسیاری از کارشناسان رایانه نیز به عنوان قطعهای جادویی نگریسته میشود. در این نوشته تلاش میکنیم کارکرد این جزء رایانه را توصیف کنیم.
نکتهای که پیش از آغاز این مقاله باید در خاطر داشته باشیم این است که اغلب CPU های مدرن از نظر اندازه بزرگی، بسیار پیچیدهتر از مواردی هستند که در این نوشته بررسی خواهیم کرد. در واقع درک همه بخشهای یک تراشه با بیش از یک میلیارد ترانزیستور برای هر فردی ناممکن است. با این وجود، مفاهیم مقدماتی در مورد هماهنگی همه بخشهای یک CPU در مورد همه CPU ها یکسان است و درک این مقدمات باعث میشود که درک بهتری از CPU های مدرن نیز به دست بیاورید.
کارکرد رایانهها به روش دودویی یا باینری است. رایانهها فقط دو حالت را درک میکنند، روشن و خاموش. آنها برای اجرای محاسبات به زبان باینری از قطعهای به نام ترانزیستور استفاده میکنند. ترانزیستور تنها در صورتی اجازه عبور جریان منبع از خود را میدهد که روی گیت آن جریانی اعمال شده باشد. این وضعیت اساس یک سوئیچ باینری را تشکیل میدهد که بسته به سیگنال ورودی ثانویه، اتصال را قطع میکند.
رایانههای مدرن از میلیاردها ترانزیستور برای اجرای محاسبات خود استفاده میکنند؛ اما در پایینترین سطح شما تنها به تعداد معدودی از ترانزیستورها برای تشکیل ابتداییترین اجزا که گیت (gate) نامیده میشوند نیاز دارید.
با گرد هم آوردن صحیح چند ترانزیستور میتوان یک گیت منطقی ساخت. گیتهای منطقی دو ورودی باینری میگیرند و با اجرای یک عملیات روی آنها، مقدار خروجی را بازگشت میدهند. برای مثال، گیت OR در صورتی مقدار True بازمیگرداند که یکی از ورودهایش true باشد. گیت AND بررسی میکند که آیا هر دو ورودی true هستند یا نه و XOR نیز زمانی مقدار true بازمیگرداند که یکی از ورودیهایش true باشند. نسخههای N این گیتهای منطقی (یعنی NOR، NAND و XNOR)، نمونههای معکوس این گیتهای مقدماتی هستند.
صرفاً به کمک دو گیت میتوان یک عمل جمع ابتدایی را اجرا کرد. نمودار فوق یک نیمجمعکننده (half adder را نمایش میدهد). گیت XOR در این مدار زمانی روشن میشود که صرفاً یکی از ورودیهایش true شده باشد و نه هر دو آنها. گیت AND زمانی روشن میشود که هر دو ورودی روشن باشند؛ اما زمانی که ورودی نباشد خاموش میماند. بنابراین اگر هر دو روشن باشند، XOR خاموش میماند و گیت AND روشن میشود و پاسخ صحیح که 2 است به دست میآید:
بدین ترتیب با این تنظیمات ساده به سه خروجی متمایز 0، 1 و 2 دست مییابیم. اما با یک بیت هیچ چیزی بزرگتر از 1 را نمیتوانیم ذخیره کنیم و این ماشین با توجه به این که صرفاً یکی از سادهترین مسائل ریاضی را حل میکند، فایده چندانی نخواهد داشت. اما دقت کنید که این مدار صرفاً یک نیمجمعکننده است و اگر دو مورد از آنها را با استفاده از یک ورودی دیگر به هم متصل کنید، میتوانید یک تمامجمعکننده (Full Adder) به دست آورید:
مدار تمامجمعکننده سه ورودی دارد که دو مورد از آنها اعدادی هستند که باید جمع شوند و یک مورد نیز ورودی نَقلی (carry in) است. این جزء نقلی زمانی که خروجی از حد قابل قبول برای ذخیره در یک بیت منفرد تجاوز میکند، مورد استفاده قرار میگیرد. آدرس کامل در یک زنجیره ذخیره میشود و عنصر نقلی از یک جمعکننده به جمعکننده دیگر ارسال میشود. در نهایت رقم نقلی به نتیجه گیت XOR در نیمجمعکننده اول اضافه میشود و یک گیت OR دیگر نیز برای مدیریت هر دو حالت در موارد نیاز وجود دارد.
زمانی که هردو ورودی روشن باشند، رقم نقلی روشن میشود و آن را به تمامجمعکننده بعدی در زنجیره اضافه میکند.
و بدین ترتیب عمل جمع انجام مییابد. بهرهگیری از بیتهای بیشتر صرفاً به معنی افزودن ایجاد آدرسهای کامل جدید در زنجیرهای طولانیتر است.
اجرای موارد دیگری از عملیات ریاضی نیز با استفاده از جمع امکانپذیر است. ضرب در واقع همان تکرار عمل جمع است، تفریق از طریق نوعی معکوسسازی بیت میسر است و تقسیم صرفاً تکرار عمل تفریق است. با این که اغلب رایانههای مدرن، راهحلهای مبتنی بر سختافزاری برای اجرای موارد پیچیدهتر عملیات ریاضی دارند؛ اما شما میتوانید از نظر فنی همه آنها را با استفاده از تمامجمعکننده نیز انجام دهید.
اینک رایانه ما چیزی به جز یک ماشین حساب بد نیست! دلیل این مسئله آن است که این ماشین حساب نمیتواند هیچ چیز را به خاطر بیاورد و با خروجی خود نیز هیچ کاری انجام نمیدهد. در تصویر فوق یک سلول حافظه را مشاهده میکنید که همه این کارها را میتواند انجام دهد. البته در پسِ این شِماتیک تعداد زیادی گیتهای NAND قرار دارند و در عمل نیز بسته به تکنیک ذخیرهسازی ممکن است کاملاً متفاوت باشد؛ ولی در هر حال کارکرد آن به همین شکل است. شما به این سلول یک ورودی میدهید، بیت نوشتن (write) را روشن میکنید و این سلول، ورودی را درون خود ذخیره میکند. البته ما همواره به عمل خواندن یک سلول حافظه هم نیاز داریم. این کار از طریق یک فعالساز (enabler) که مجموعهای از گیتهای AND برای هر بیت از اطلاعات است میسر میشود. این enabler به ورودی دیگری که بیت خواندن (read) است مرتبط است. بیتهای خواندن و نوشتن غالباً به صورت set و enable نیز خوانده میشوند.
کل این بسته به صورت مجموعهای به نام ثبّات (register) نامیده میشود. این ثباتها به باس (گذرگاه) وصل میشوند که مجموعهای از سیمها است که در کل سیستم میچرخند و به همه اجزا اتصال یافتهاند. در همه رایانههای مدرن باس وجود دارد، و برای بهبود عملکرد چندوظیفگی از باس های چندگانه نیز کمک گرفته میشود.
هر ثبات نیز یک بیت خواندن و نوشتن دارد؛ اما در این تنظیمات، ورودی و خروجی چیز یکسانی هستند. این وضعیت در عمل خوب است. برای مثال اگر بخواهیم محتوای R1 را به R2 کپی کنیم، باید بیت خواندن را برای R1 روشن کنیم که باعث میشود محتوای R1 به باس انتقال یابد. در حالی که بیت خواندن روشن است، باید بیت نوشتن R2 را روشن کنید تا محتوای باس به R2 کپی شود.
ثباتها برای ساخت RAM نیز مورد استفاده قرار میگیرند. رم غالباً به شکل شبکهای طراحی میشود که سیمهای آن در دو جهت کشیده شدهاند:
دیکودرها یک ورودی باینری را میگیرند و شماره سیم مربوطه را روشن میکنند. برای مثال، 11 همان عدد 3 به زبان باینری است و بالاترین عدد 2 بیتی محسوب میشود، از این رو دیکودر باید بالاترین سیم را روشن کند. در هر تقاطع ثباتهایی وجود دارند. همه اینها به باس مرکزی و همچنین به یک ورودی خواندن و نوشتن مرکزی متصل هستند. هر دو ورودی خواندن و نوشتن تنها زمانی روشن میشوند که دو سیم که از روی ثبات میکنند نیز روشن باشند و بدین ترتیب امکان انتخاب ثباتهایی که قرار است خوانده و نوشته شوند ممکن میشود. در این مورد نیز باید اشاره کنیم که RAM های مدرن بسیار پیچیدهتر هستند؛ اما همچنان از این تنظیمات استفاده میکنند.
ثباتها در همه جا استفاده میشوند و ابزاری مقدماتی برای جابجایی دادهها و ذخیرهسازی اطلاعات در CPU محسوب میشوند. اما این کار چگونه صورت میپذیرد؟
ساعت (Clock) نخستین جزئی در هسته CPU است که در بازههای معین که برحسب هرتز یا چرخه بر ثانیه اندازهگیری شده است، روشن و خاموش میشود. این همان سرعتی است که هنگام تبلیغ CPU ها مشاهده میکنید. یک CPU 5 گیگاهرتز میتواند 5 میلیارد چرخه را در هر ثانیه اجرا کند. سرعت ساعت در اغلب موارد معیار خوبی برای محاسبه میزان سریع بودن CPU محسوب میشود.
ساعت سه جزء متفاوت دارد، ساعت پایه، ساعت فعالسازی و ساعت set. ساعت پایه در نیمی از چرخه روشن میشود و در نیمه دیگر خاموش میشود. ساعت فعالسازی برای روشن کردن ثباتها استفاده میشود و باید مدت بیشتری روشن بماند تا مطمئن شویم که دادهها فعال شدهاند. ساعت set همواره باید همزمان با ساعت enable روشن باشد، چون در غیر این صورت دادهها ممکن است به اشتباه نوشته شوند.
ساعت به stepper متصل است که از یک تا بیشترین گام را میشمارد و زمانی که چنین کرد، خود را ریست میکند. ساعت همچنین به گیتهای AND هر ثباتی که CPU میتواند بنویسد متصل است:
این گیتهای AND به خروجی جزء دیگر یعنی دیکودر دستورالعمل نیز اتصال دارند. دیکودر دستورالعمل، یک دستورالعمل مانند «مقدار R2 را برابر با R1 تنظیم کن» دریافت میکند و آن را به چیزی دیکود میکند که CPU بتواند آن را درک کند. این دیکودر یک ثبات درونی دارد که «ثبات دستورالعمل» (Instruction Register) نام دارد و همان جایی است که عملیات جاری در آن ذخیره میشود. طرز کار دقیق این دیکودر به سیستمی که در حال اجرا در میآید وابسته است؛ اما زمانی که دستورالعمل را کدگشایی کرد، set صحیح را روشن میکند و بیتها را برای ثباتهای صحیح فعال میسازد که بر مبنای ساعت تنظیم میشوند.
دستورالعملهای برنامه در RAM (یا در سیستمهای مدرن در کش L1 که به CPU نزدیکتر است) نگهداری میشوند. از آنجا که برنامه در ثباتهایی ذخیره شده است، مانند هر متغیر دیگری میتوان آن را دستکاری کرد و به بخشهای مختلف برنامه jump کرد. برنامهها به همین ترتیب دستورالعملهای خود را با حلقهها و دستورهای if دریافت میکنند. دستورالعمل jump مکان کنونی RAM که دیکودر دستورالعمل، مشغول خواندن است را به مکان دیگری تغییر میدهد.
اینک تصویر بسیار سادهای که از فرایند کاری CPU ارائه کردیم به پایان رسیده است. باس اصلی کل سیستم را شامل میشود و به همه ثباتها اتصال مییابد. تمام جمع کنندهها همراه با دستهای از عملیات دیگر در یک واحد منطقی محاسبات (ALU) تجمیع میشوند. این ALU اتصالهایی به باس دارد و ثباتهایی نیز دارد که عدد دومی که عملیات روی آن صورت میگیرد را ذخیره میکنند.
برای اجرای یک محاسبه، دادههای برنامه از RAM سیستم وارد بخش کنترل میشوند. بخش کنترل دو عدد را از RAM میخواند، عدد نخست را در ثبات دستورالعمل ALU ذخیره میکند و سپس عدد دوم را در باس ذخیره میسازد. به طور همزمان یک کد دستورالعمل به ALU که وظیفه آن را تعیین میکند. در این هنگام ALU همه محاسبات را انجام داده و نتیجه را در ثبات دیگری که CPU میتواند آن را خوانده و ادامه پردازش را پیگیری کند، ذخیره میکند.
بخش مهمی از بحث مدیریت پیکربندی سرور شامل تأمین روشی آسان برای بررسی رابطهای شبکه و آدرسهای IP بر اساس نام از طریق راهاندازی یک «سیستم نام دامنه» (DNS) مناسب است. استفاده از نامهای دامنه جامعالشرایط (FQDN) به جای آدرسهای IP برای اشاره به آدرسهای داخل شبکه باعث میشود که پیکربندی سرویسها و اپلیکیشنها آسانتر شده و قابلیت نگهداری فایلهای پیکربندی افزایش یابد. راهاندازی DNS شخصی برای شبکه خصوصی روشی عالی برای بهبود مدیریت سرورها محسوب میشود.
در این راهنما به بررسی شیوه راهاندازی سرور DNS داخلی با استفاده از نرمافزار سرور نام (BIND (BIND9 روی اوبونتو 18.04 میپردازیم. این سرور نام میتواند از سوی سرورهای کلاینت شما برای resolve کردن نامهای میزبانی و آدرسهای IP خصوصی مورد استفاده قرار گیرد. بدین ترتیب روشی متمرکز برای مدیریت نامهای میزبانی داخلی و آدرسهای IP خصوصی فراهم میشود که هنگام نیاز به گسترش محیط کاری به بیش از چند میزبان امری کاملاً ضروری به حساب میآید.
برای مطالعه این راهنما باید زیرساختهای زیر را داشته باشید. دقت کنید که همه سرورها باید در یک دیتاسنتر باشند و شبکه خصوصی بین آنها فعال شده باشد:
روی هر یک از این سرورهای اضافی باید دسترسیهای مدیریتی از طریق کاربر sudo پیکربندی شده باشد و از یک فایروال نیز استفاده شود.
اگر با مفاهیم DNS آشنایی ندارید توصیه میکنیم، دستکم بخشی از مطالبی را که در ادامه آمدهاند را مطالعه کنید:
با توجه به اهداف این مقاله، موارد زیر جزو فرضیههای ما هستند:
با فرضیات فوق بدیهی است که طرح نامگذاری به نام «nyc3.example.com» برای اشاره به subnet یا zone خصوصی مناسب خواهد بود. از این رو FQDN برای host1 به صورت host1.nyc3.example.com خواهد بود. در جدول زیر جزییات مربوطه به طور کامل ارائه شده است:
میزبان | نقش | FQDN خصوصی | آدرس IP خصوصی |
---|---|---|---|
ns1 | Primary DNS Server | ns1.nyc3.example.com | 10.128.10.11 |
ns2 | Secondary DNS Server | ns2.nyc3.example.com | 10.128.20.12 |
host1 | Generic Host 1 | host1.nyc3.example.com | 10.128.100.101 |
host2 | Generic Host 2 | host2.nyc3.example.com | 10.128.200.102 |
دقت کنید که احتمالاً تنظیمات موجود شما متفاوت است؛ اما نامهای نمونه و آدرسهای IP که برای نمایش شیوه پیکربندی یک سرور DNS ارائه شدهاند، نمونهای از یک DNS داخلی کاملاً عملیاتی را نشان میدهند. شما میتوانید به سادگی این تنظیمات را با جایگزینی نامهای میزبانی و آدرسهای IP خصوصی در محیط موجود خود مورد استفاده قرار دهید. لزومی نیست که از نام منطقه دیتاسنتر در طرح نامگذاری خود استفاده کنید؛ اما دلیل استفاده ما از چنین خصوصیتی این است که نشان دهیم میزبانها همگی متعلق به شبکه خصوصی یک دیتاسنتر واحد هستند. اگر شما از چند دیتاسنتر استفاده میکنید، میتوانید یک DNS داخلی درون هر دیتاسنتر متناظر ایجاد کنید.
در انتهای این راهنما ما یک سرور DNS اصلی به نام ns1 و یک سرور DNS اختیاری ثانویه به نام ns2 خواهیم داشت که به عنوان پشتیبان عمل میکند. کار خود را با نصب سرور DNS اصلی آغاز میکنیم.
دقت کنید مواردی که به رنگ قرمز هایلایت شدهاند، در اغلب موارد متغیرهایی هستند که شما باید مقادیرشان را بر اساس مشخصات سرورهای خودتان جایگزین نمایید. برای نمونه اگر متغیری را به صورت host1.nyc3.example.com دیدید، باید به جای آن FQDN سرور خود را وارد کنید. به طور مشابه به جای host1_private_IP آدرس IP سرور خودتان را جایگزین کنید.
روی هر دو سرور DNS به نامهای ns1 و ns2، بسته apt را با وارد کردن دستور زیر بهروزرسانی کنید:
sudo apt-get update
اینک BIND را نصب میکنیم:
sudo apt-get install bind9 bind9utils bind9-doc
پیش از ادامه مراحل باید BIND را به حالت IPv4 تنظیم کنیم، چون شبکهبندی خصوصی ما به طور انحصاری از IPv4 استفاده میکند. روی هر دو سرور تنظیمات پیشفرض bind9 را با وارد کردن دستور زیر ویرایش میکنیم:
sudo nano /etc/default/bind9
مقدار «4-» را به انتهای پارامتر OPTIONS اضافه میکنیم. بدین ترتیب به صورت زیر در میآید:
...
OPTIONS="-u bind -4"
هنگام پایان کار، فایل را ذخیره کرده و ببندید. سپس BIND را ریاستارت کنید تا تغییرات اعمال شوند:
sudo systemctl restart bind9
اینک که BIND نصب شده است میتوانیم سرور DNS اصلی را پیکربندی کنیم.
پیکربندی BIND شامل چندین فایل است که همه آنها در فایل پیکربندی اصلی به نام named.conf گنجانده شدهاند. نام این فایلها با named آغاز میشود، زیرا این نام پروسسی است که BIND اجرا میکند (اختصاری برای «domain name daemon» محسوب میشود). ما کار خود را با پیکربندی فایل options آغاز میکنیم.
روی سرور ns1 فایل named.conf.options را برای ویرایش باز کنید:
sudo nano /etc/bind/named.conf.options
در بالاتر از بلوک options یک ACL جدید به نام «trusted» ایجاد کنید. ACL، اختصاری برای عبارت «لیست کنترل دسترسی» (access control list) است.
این همان جایی است که لیستی از کلاینتهایی را تعریف میکنیم که اجازه کوئری بازگشتی DNS را دارند. این لیست شامل سرورهای متعلق به شما در همان دیتاسنتر ns1 است. با استفاده از آدرسهای IP خصوصی نمونهای که قبلاً معرفی کردیم، ns1، ns2، host1 و hst2 را به لیست کلاینتهای مورد اعتماد خود اضافه میکنیم:
acl "trusted" { 10.128.10.11; # ns1 - can be set to localhost 10.128.20.12; # ns2 10.128.100.101; # host1 10.128.200.102; # host2 }; options { . . .
اینک که لیست کلاینتهای DNS مورد اعتماد خود را ایجاد کردیم، باید بلوک options را ویرایش کنیم. در حال حاضر آغاز بلوک مانند زیر است:
. . . }; options { directory "/var/cache/bind"; . . . }
زیر دایرکتیو directory خطوط پیکربندی هایلایت شده را اضافه کنید و آدرسهای IP سرور ns1 خود را جایگزین کنید. بدین ترتیب چیزی مانند زیر خواهد بود:
. . . }; options { directory "/var/cache/bind"; recursion yes; # enables resursive queries allow-recursion { trusted; }; # allows recursive queries from "trusted" clients listen-on { 10.128.10.11; }; # ns1 private IP address - listen on private network only allow-transfer { none; }; # disable zone transfers by default forwarders { 8.8.8.8; 8.8.4.4; }; . . . };
زمانی که کارتان پایان یافت، فایل named.conf.options را ذخیره کرده و ببندید. پیکربندی فوق تعیین میکند که صرفاً سرورهای متعلق به شما (یعنی سرورهای trusted) میتوانند به سرورهای DNS در مورد دامنههای خارجی کوئری بزنند.
در ادامه فایل محلی را نیز پیکربندی میکنیم تا zone های DNS را تعیین کنیم.
روی سرور ns1 فایل named.conf.local را برای ویرایش باز کنید:
sudo nano /etc/bind/named.conf.local
این فایل به جز چند کامنت باید چیز دیگری نداشته باشد. در این فایل زونهای فوروارد و معکوس خود را تعیین میکنیم. زونهای دیاناس حوزه خاصی را برای مدیریت و تعریف رکوردهای DNS اختصاص میدهند. از آنجا که دامنههای ما درون زیردامنه «nyc3.example.com» قرار دارند، ما از آن به عنوان زون فوروارد خود استفاده خواهیم کرد. از آنجا که آدرسهای IP خصوصی همگی در فضای IP 10.128.0.0/16 قرار دارند، یک زون معکوس راهاندازی میکنیم تا جستجوهای معکوس درون این محدوده را تعریف کنیم.
زون فوروارد را با خطوط زیر اضافه میکنیم. دقت کنید که نامهای زون خود را جایگزین کنید و آدرسهای IP خصوصی سرور DNS ثانویه را در دایرکتیو allow-transfer اضافه کنید:
zone "nyc3.example.com" { type master; file "/etc/bind/zones/db.nyc3.example.com"; # zone file path allow-transfer { 10.128.20.12; }; # ns2 private IP address - secondary };
با فرض این که subnet خصوصی به صورت 10.128.0.0/16 است، زون معکوس را با افزودن خطوط زیر میتوانید ایجاد کنید. دقت کنید که نامهای زون معکوس ما با 128.10 آغاز میشود که معکوس 10.128 است:
. . . }; zone "128.10.in-addr.arpa" { type master; file "/etc/bind/zones/db.10.128"; # 10.128.0.0/16 subnet allow-transfer { 10.128.20.12; }; # ns2 private IP address - secondary };
اگر سرورهای شما روی چند subnet گسترش یافتهاند؛ اما همگی روی یک دیتاسنتر هستند؛ باید اطمینان حاصل کنید که یک زون اضافی و همچنین فایل زون برای هر subnet متمایز ایجاد کردهاید. زمانی که ویرایش همه زونهای مطلوب پایان یافت، فایل named.conf.local را ذخیره کرده و ببندید.
اینک که زونها در BIND مشخص شدند، باید فایلهای زون فوروارد و معکوس متناظر را ایجاد کنیم.
فایل زون فوروارد جایی است که رکوردهای DNS برای بررسیهای دیاناس فوروارد ذخیره میشوند. یعنی برای مثال هنگامی که DNS یک کوئری نام برای «host1.nyc3.example.com» دریافت میکند، در فایل زون فوروارد به دنبال آدرس IP متناظر برای resolve کردن host1 میگردد.
ابتدا یک دایرکتوری ایجاد میکنیم تا فایلهای زون خود را درون آن قرار دهیم. بر اساس پیکربندی named.conf.local، این مکان باید etc/bind/zones/ باشد:
sudo mkdir /etc/bind/zones
اینک فایل زون فوروارد خود را بر اساس فایل زون نمونه db.local طراحی میکنیم. آن را بر اساس دستورهای زیر به مکان مناسبی کپی کنید:
sudo cp /etc/bind/db.local /etc/bind/zones/db.nyc3.example.com
اینک فایل فوروارد خود را ویرایش میکنیم:
sudo nano /etc/bind/zones/db.nyc3.example.com
در ابتدا این فایل چیزی شبیه زیر است:
$TTL 604800 @ IN SOA localhost. root.localhost. ( 2 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL ; @ IN NS localhost. ; delete this line @ IN A 127.0.0.1 ; delete this line @ IN AAAA ::1 ; delete this line
در اولین گام باید رکورد SOA را ویرایش کنیم. بنابراین FQDN سرور ns1 را به جای localhost قرار میدهیم و سپس root.localhost را با admin.nyc3.example.com جایگزین میکنیم. هر زمان که یک فایل زون را ویرایش میکنید، باید شماره سریال آن را پیش از ریاستارت کردن پروسس named افزایش دهید. ما این مقدار را به 3 افزایش میدهیم و بنابراین به صورت زیر در میآید:
@ IN SOA ns1.nyc3.example.com. admin.nyc3.example.com. (
3 ; Serial
. . .
سپس سه رکورد انتهای فایل (پس از SOA) را حذف میکنیم. اگر مطمئن نیستید که کدام خطها را باید حذف کنید، دقت کنید که در بخش فوق آنها را با «delete this line» مشخص ساختهایم.
در انتهای فایل رکوردهای سرور نام با خطوط زیر را اضافه کنید. دقت کنید که موارد مورد نظر را با مقادیر خودتان جایگزین کنید و این که ستون دوم مشخص میکند اینها رکوردهای NS هستند:
. . . ; name servers - NS records IN NS ns1.nyc3.example.com. IN NS ns2.nyc3.example.com.
اینک رکورد A را به میزبانهایی که به این زون تعلق دارند اضافه کنید. این مورد شامل همه سرورهایی است که میخواهیم نام آنها با «nyc3.example.com» خاتمه یابد. دقت کنید که باید نامها و آدرسهای IP خصوصی مورد نظر خودتان را جایگزین کنید. رکوردهای A را برای ns1، ns2، host1 و host2 با استفاده از نامها و آدرسهای IP خصوصی مورد نظر این راهنما، به صورت زیر اضافه کردهایم:
. . . ; name servers - A records ns1.nyc3.example.com. IN A 10.128.10.11 ns2.nyc3.example.com. IN A 10.128.20.12 ; 10.128.0.0/16 - A records host1.nyc3.example.com. IN A 10.128.100.101 host2.nyc3.example.com. IN A 10.128.200.102
فایل db.nyc3.example.com را ذخیره کرده و خارج شوید. فایل زون فوروارد نمونه نهایی در انتها به صورت زیر خواهد بود:
$TTL 604800 @ IN SOA ns1.nyc3.example.com. admin.nyc3.example.com. ( 3 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL ; ; name servers - NS records IN NS ns1.nyc3.example.com. IN NS ns2.nyc3.example.com. ; name servers - A records ns1.nyc3.example.com. IN A 10.128.10.11 ns2.nyc3.example.com. IN A 10.128.20.12 ; 10.128.0.0/16 - A records host1.nyc3.example.com. IN A 10.128.100.101 host2.nyc3.example.com. IN A 10.128.200.102
اینک به پیکربندی فایل(های) زون معکوس میپردازیم:
زون معکوس که رکوردهای DNS PTR در آن تعریف میشود، به منظور پاسخدهی به جستجوهای DNS معکوس هست. یعنی هنگامی که DNS یک کوئری برای مثال بر اساس آدرس 10.128.100.101 دریافت میکند به فایل (های) زون معکوس نگاه میکند تا FQDN متناظر را که در این مورد «host1.nyc3.example.com» است، بیابد.
روی سرور ns1 برای هر زون معکوس که در فایل named.conf.local تعیین شده است، یک فایل زون معکوس ایجاد میکنیم. فایل (های) زون معکوس بر اساس فایل زون نمونه db.127 ایجاد میشوند. آن را با دستور زیر به مکان مناسبی کپی کنید. دقت کنید که فایل زون معکوس خود را طوری نامگذاری کنید که متناسب با تعریف زون معکوس شما باشد:
sudo cp /etc/bind/db.127 /etc/bind/zones/db.10.128
فایل زون معکوس را که متناظر با زون (های) معکوس تعریف شده در named.conf.local است ویرایش میکنیم:
sudo nano /etc/bind/zones/db.10.128
در ابتدا این فایل مانند زیر است:
$TTL 604800 @ IN SOA localhost. root.localhost. ( 1 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL ; @ IN NS localhost. ; delete this line 1.0.0 IN PTR localhost. ; delete this line
همانند روش ویرایش فایل زون فوروارد باید رکورد SOA را تغییر داده و مقدار سریال را یک واحد افزایش دهیم. بدین ترتیب فایل به صورت زیر در میآید:
@ IN SOA ns1.nyc3.example.com. admin.nyc3.example.com. (
3 ; Serial
. . .
اینک دو رکورد انتهای فایل (پس از رکورد SOA) را ویرایش میکنیم. اگر مطمئن نیستید که کدام خطها باید حذف شوند؛ این خطوط با کامنت «delete this line» در بخش فوق مشخص شدهاند.
در انتهای فایل؛ سرور نام خود را با خطوط زیر اضافه کنید. دقت کنید که نام خود را جایگزین کنید. همچنین توجه داشته باشید که ستون دوم تعیین میکند که اینها رکوردهای NS هستند:
. . . ; name servers - NS records IN NS ns1.nyc3.example.com. IN NS ns2.nyc3.example.com.
سپس رکوردهای PTR را برای همه سرورهایی که آدرس IP آنها در subnet فایل زون مورد ویرایش قرار دارد، اضافه کنید. در مثالی که ما بررسی میکنیم این موارد شامل همه میزبانها میشوند، زیرا همه آنها در subnet با آدرس 10.128.0.0/16 قرار دارند. توجه داشته باشید که ستون نخست شامل دستکم دو بخش از آدرس IP خصوصی سرور به طور معکوس است. مطمئن شوید که تامها و آدرس IP خصوصی خودتان را جایگزین میکنید:
. . . ; PTR Records 11.10 IN PTR ns1.nyc3.example.com. ; 10.128.10.11 12.20 IN PTR ns2.nyc3.example.com. ; 10.128.20.12 101.100 IN PTR host1.nyc3.example.com. ; 10.128.100.101 102.200 IN PTR host2.nyc3.example.com. ; 10.128.200.102
فایل زون معکوس را ذخیره کرده و خارج شوید. اگر لازم است فایلهای زون معکوس دیگری اضافه کنید، مراحل فوق را در مورد آنها نیز تکرار کنید.
فایل زون معکوس نهایی ما چیزی شبیه زیر خواهد بود:
$TTL 604800 @ IN SOA nyc3.example.com. admin.nyc3.example.com. ( 3 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL ; name servers IN NS ns1.nyc3.example.com. IN NS ns2.nyc3.example.com. ; PTR Records 11.10 IN PTR ns1.nyc3.example.com. ; 10.128.10.11 12.20 IN PTR ns2.nyc3.example.com. ; 10.128.20.12 101.100 IN PTR host1.nyc3.example.com. ; 10.128.100.101 102.200 IN PTR host2.nyc3.example.com. ; 10.128.200.102
بدین ترتیب کار ویرایش فایلها به پایان رسیده است و از این رو در مرحله بعد فایلهای خود و خطاهای احتمالی را بررسی میکنیم.
دستور زیر را برای بررسی ساختار فایلهای named.conf* اجرا کنید:
sudo named-checkconf
اگر فایلهای پیکربندی named شما دارای خطاهای ساختاری نباشند، بدون مشاهده هیچ گونه خطایی به خط اعلان فرمان باز میگردید. اما اگر مشکلاتی در فایلهای پیکربندی وجود داشته باشند، باید پیام خطا را بررسی کرده و به بخش «پیکربندی سرور DNS اصلی» این راهنما بازگشته و پس از رفع خطا مجدداً دستور named-checkconf را اجرا کنید.
دستور named-checkzone برای بررسی صحیح بودن فایلهای زون اجرا میشود. آرگومان نخست این دستور نام یک زون است و آرگومان دوم نیز فایل زون متناظر با آن خواهد بود که هر دو باید در فایل named.conf.local تعریف شده باشند.
برای نمونه جهت بررسی پیکربندی زون فوروارد «nyc3.example.com»، دستور زیر را اجرا کنید. دقت کنید که موارد هایلایت شده را با مشخصات سرورهای خودتان جایگزین کنید:
sudo named-checkzone nyc3.example.com db.nyc3.example.com
برای بررسی پیکربندی زون معکوس «128.10.in-addr.arpa»، دستور زیر را اجرا کنید. عددها را تغییر دهید تا متناظر با زون معکوس و فایل شما باشند:
sudo named-checkzone 128.10.in-addr.arpa /etc/bind/zones/db.10.128
زمانی که مطمئن شدید همه فایلهای پیکربندی و زون بدون خطا هستند، آماده هستید تا سرویس BIND را ریاستارت کنید.
با دستور زیر BIND را ریاستارت کنید:
sudo systemctl restart bind9
اگر فایروال UFW را فعال کردهاید، دسترسی به BIND را با دستور زیر باز کنید:
sudo ufw allow Bind9
سرور DNS اصلی شما اینک راهاندازی شده و به کوئریهای DNS پاسخ میدهد. پس در ادامه به پیکربندی و راهاندازی سرور DNS ثانویه میپردازیم.
در اغلب موارد، راهاندازی یک سرور DNS ثانویه که در صورت از کار افتادن سرور اصلی به کوئریها پاسخ میدهد، ایده مناسبی محسوب میشود. خوشبختانه پیکربندی سرور DNS ثانویه بسیار آسانتر است.
روی سرور ns2 فایل named.conf.options را باز کنید:
sudo nano /etc/bind/named.conf.options
در ابتدای فایل، ACL را با آدرسهای IP خصوص همه سرورهای مورد اعتماد ایجاد کنید:
acl "trusted" { 10.128.10.11; # ns1 10.128.20.12; # ns2 - can be set to localhost 10.128.100.101; # host1 10.128.200.102; # host2 }; options { . . .
زیر دایرکتیو directory خطوط زیر را اضافه کنید:
recursion yes;
allow-recursion { trusted; };
listen-on { 10.128.20.12; }; # ns2 private IP address
allow-transfer { none; }; # disable zone transfers by default
forwarders {
8.8.8.8;
8.8.4.4;
};
فایل named.conf.options را ذخیره کرده و ببندید. اینک این فایل باید دقیقاً مانند فایل named.conf.options روی سرور ns1 باشد، به جز این که طوری پیکربندی شده است تا به آدرس IP خصوصی ns2 گوش دهد. سپس فایل named.conf.local را باز کنید:
sudo nano /etc/bind/named.conf.local
زونهایی که متناظر با زونهای master روی سرور DNS اصلی هستند تعریف کنید. توجه داشته باشید که در این مورد نوع برابر با «slave» خواهد بود و بنابراین فایل شامل مسیر نیست و دایرکتیوهای masters وجود دارند که باید برابر با آدرس IP خصوصی DNS اصلی تنظیم شوند. اگر چندین زون معکوس در سرور DNS اصلی تعریف کردهاید، باید مطمئن شوید که همه آنها را در این جا اضافه کردهاید:
zone "nyc3.example.com" { type slave; file "db.nyc3.example.com"; masters { 10.128.10.11; }; # ns1 private IP }; zone "128.10.in-addr.arpa" { type slave; file "db.10.128"; masters { 10.128.10.11; }; # ns1 private IP };
اینک فایل named.conf.local را ذخیره کرده و ببندید. دستور زیر را برای بررسی درستی فایلهای پیکربندی اجرا کنید:
sudo named-checkconf
زمانی که بررسی پایان یافت، BIND را ریاستارت کنید:
sudo systemctl restart bind9
با تغییر دادن فایروال UFW به صورت زیر به اتصال DNS اجازه عبور بدهید:
sudo ufw allow Bind9
اینک سرورهای DNS اصلی و ثانویه برای resolve کردن شبکه خصوصی و آدرسهای IP مربوطه پیکربندی شده است. در ادامه سرورهای کلاینت را برای استفاده از سرورهای DNS خصوصی پیکربندی میکنیم.
پیش از آن که همه سرورهای موجود در ACL به نام «trusted» بتوانند به سرورهای ACL کوئری بزنند، باید هر یک از آنها را برای استفاده از ns1 و ns2 به عنوان سرورهای نام پیکربندی کنیم. این فرایند به نوع سیستم عامل بستگی دارد؛ اما در مورد اغلب توزیعهای لینوکس شامل افزودن سرورهای نام به فایل /etc/resolv.conf است.
شبکهبندی روی سیستم عامل اوبونتو 18.04 با استفاده از Netplan پیکربندی میشود که امکان نوشتن پیکربندی شبکه استاندارد شده و اِعمال آن در مورد نرمافزار شبکهبندی ناسازگار بکاند (backend) را میدهد. برای پیکربندی DNS، باید فایل پیکربندی Netplan را ویرایش کنیم.
ابتدا دایرکتیو مرتبط با شبکه خصوصی خود را با کوئری کردن subnet خصوصی با دستور ip address بیابید:
ip address show to 10.128.0.0/16
خروجی
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
inet 10.128.100.101/16 brd 10.128.255.255 scope global eth1
valid_lft forever preferred_lft forever
در این مثال، رابط خصوصی eth1 نام دارد. سپس فایلی به نام 00-private-nameservers.yaml در مسیر /etc/netplan ایجاد میکنیم:
sudo nano /etc/netplan/00-private-nameservers.yaml
محتوای زیر را درون این فایل قرار میدهیم. دقت کنید که باید رابط شبکه خصوصی، آدرس سرورهای DNS به نام ns1 و ns2 و زون DNS خودتان را جایگزین کنید:
network: version: 2 ethernets: eth1: # Private network interface nameservers: addresses: - 10.128.10.11 # Private IP for ns1 - 10.132.20.12 # Private IP for ns2 search: [ nyc3.example.com ] # DNS zone
دفت کنید که Netplan از فرمت سریالسازی دادهها به صورت YAML برای فایلهای پیکربندی خود استفاده میکند. از آنجا که YAML از تورفتگی و اسپیس برای تعریف ساختار داده خود استفاده میکند، باید مطمئن شوید که تعریف شما از ساختار تورفتگی مناسبی برخوردار است تا خطایی پیش نیاید.
در این مرحله فایل را ذخیره کرده و خارج شوید. سپس باید با دستور netplan try به Netplan بگوییم که تلاش کند از فایل پیکربندی جدید استفاده کند. اگر مشکلی وجود داشته باشد که موجب از دست رفتن شبکهبندی شود، Netplan پس از مدت مشخصی، به طور خودکار تغییرهای ایجاد شده را لغو کرده و وضعیت را به حالت قبل باز میگرداند:
sudo netplan try
خروجی
Warning: Stopping systemd-networkd.service, but it can still be activated by: systemd-networkd.socket Do you want to keep these settings? Press ENTER before the timeout to accept the new configuration Changes will revert in 120 seconds
اگر شمارش معکوس در انتهای خروجی به صورت صحیحی صورت بگیرد، پیکربندی جدید دستکم تا حدی که اتصال SSH شما را قطع نکند، اجرا میشود. با زدن دکمه اینتر پیکربندی جدید را بپذیرید.
اینک resolver DNS سیستم را بررسی کنید تا مشخص شود که آیا پیکربندی DNS اعمال شده است یا نه:
sudo systemd-resolve –status
به سمت پایین اسکرول کنید تا بخشی که به رابط شبکه خصوصی شما مربوط است را ببینید. احتمالاً آدرسهای IP خصوصی سرورهای DNS در ابتدا فهرست شدهاند و سپس مقادیر fallback آماده است. دامنه شما باید در بخش «DNS Domain» مشاهده شود:
خروجی
. . . Link 3 (eth1) Current Scopes: DNS LLMNR setting: yes MulticastDNS setting: no DNSSEC setting: no DNSSEC supported: no DNS Servers: 10.128.10.11 10.128.20.12 67.207.67.2 67.207.67.3 DNS Domain: nyc3.example.com . . .
کلاینت شما اینک باید طوری پیکربندی شده باشد که از سرورهای DNS داخلی استفاده کند:
روی سرورهای لینوکس اوبونتو 16.04 و دبیان، شما باید فایل /etc/network/interfaces را ویرایش کنید:
sudo nano /etc/network/interfaces
درون این فایل خط dns-nameservers را یافته و سرورهای نام خود را به ابتدای فهرست اضافه کنید. زیر این خط یک گزینه dns-search اضافه کنید که به دامنه اصلی زیر ساخت شما اشاره میکند. در مورد این راهنما این گزینه برابر با «nyc3.example.com» است:
. . . dns-nameservers 10.128.10.11 10.128.20.12 8.8.8.8 dns-search nyc3.example.com . . .
زمانی که ویرایشتان پایان یافت، فایل را ذخیره کرده و خارج شوید.
اینک باید سرویسهای شبکه را با دستورهای زیر ریاستارت کنید تا تغییرات جدید اعمال شوند. اطمینان حاصل کید که eth0 را با نام رابط شبکه خودتان جایگزین کردهاید:
sudo ifdown --force eth0 && sudo ip addr flush dev eth0 && sudo ifup --force eth0
بدین ترتیب شبکه بدون قطع اتصال کنونی ریاستارت میشود. در صورتی که همه چیز درست باشد باید خروجی به صورت زیر را مشاهده کنید:
خروجی
RTNETLINK answers: No such process Waiting for DAD... Done
با وارد کردن دستور زیر مطمئن شوید که تنظیمات مورد نظر شما اعمال شده است:
cat /etc/resolv.conf
دران بخش باید سرورهای نام و همچنین دامنه جستجوی خود را در فایل /etc/resolv.conf ببینید:
خروجی
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8) # DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN nameserver 10.128.10.11 nameserver 10.128.20.12 nameserver 8.8.8.8 search nyc3.example.com
اینک کلاینت شما طوری پیکربندی شده است که از سرورهای DNS استفاده کند.
روی سرورهایی که توزیعهای CentOS، RedHat و Fedora را اجرا میکنند باید فایل /etc/sysconfig/network-scripts/ifcfg-eth0 را ویرایش کنید. دقت کنید که به جای eth0 باید نام رابط شبکه خصوصی خود را وارد کنید:
sudo nano /etc/sysconfig/network-scripts/ifcfg-eth0
به دنبال گزینههای DNS1 و DNS2 بگردید و آنها را برابر با آدرسهای IP خصوصی سرورهای نام اصلی و ثانویه خود تعیین کنید. یک پارامتر DOMAIN اضافه کنید که به دامنه اصلی زیر ساخت شما اشاره میکند. در این راهنما ما از مقدار «nyc3.example.com» استفاده میکنیم:
. . . DNS1=10.128.10.11 DNS2=10.128.20.12 DOMAIN='nyc3.example.com' . . .
پس از پایان ویرایش، فایل را ذخیره کرده و ببندید. سپس سرویس شبکه را با دستور زیر ریاستارت کنید:
sudo systemctl restart network
این دستور ممکن است چند ثانیه معلق بماند؛ اما پس از مدت اندکی به اعلان باز میگردید. در این مرحله با وارد کردن دستور زیر بررسی کنید که تغییرات اعمال شده است یا نه:
cat /etc/resolv.conf
در خروجی باید سرورهای نام و دامنه جستجو را مشاهده کنید:
nameserver 10.128.10.11 nameserver 10.128.20.12 search nyc3.example.com
اینک کلاینتهای شما میتوانند به سرورهای DNS وصل شده و از آنها استفاده کنند.
با استفاده از nslookup میتوانید بررسی کنید که کلاینتها قادر به کوئری زدن به سرورهای نام هستند یا نه. این وضعیت را روی همه کلاینتهایی که در ACL با نام «trusted» ذکر شدهاند بررسی کنید. در مورد کلاینتهای CentOS، باید این ابزار را نصب کنید:
sudo yum install bind-utils
ابتدا با یک جستجوی فوروارد آغاز میکنیم
forward lookup
برای نمونه ما میتوانیم با دستور زیر یک جستجوی فوروارد برای بازیابی آدرس IP نام host1.nyc3.example.com اجرا کنیم:
nslookup host1
کوئری کردن host1 به host1.nyc3.example.com بسط مییابد، زیرا گزینه search به زیردامنه خصوصی شما تعیین شده است و کوئریهای DNS تلاش میکنند تا زیردامنه را پیش از گشتن جاهای دیگر بررسی کنند. خروجی دستور فوق به صورت زیر خواهد بود:
خروجی
Server: 127.0.0.53 Address: 127.0.0.53#53 Non-authoritative answer: Name: host1.nyc3.example.com Address: 10.128.100.101
سپس میتوانیم به بررسی جستجوهای معکوس بپردازیم.
Reverse Lookup
برای تست کردن Reverse Lookup باید آدرس IP خصوصی host1 را کوئری کنیم:
nslookup 10.128.100.101
در خروجی دستور فوق چیزی مانند زیر را باید مشاهده کنید:
خروجی
11.10.128.10.in-addr.arpa name = host1.nyc3.example.com. Authoritative answers can be found from:
اگر همه نامها و آدرسهای IP به مقادیر صحیح resolve شوند، این بدان معنی است که فایلهای زون به طور صحیحی پیکربندی شدهاند. اگر با مقادیر ناخواستهای مواجه شدید، باید اطمینان حاصل کنید که فایلهای زون روی سرور DNS اصلی را مورد بازنگری قرار دادهاید.
اینک شما موفق شدهاید سرورهای DNS داخلی را به طرز صحیحی راهاندازی کنید. در ادامه مواردی در خصوص مبحث نگهداری رکوردهای زون را ارائه میکنیم.
اینک که یک DNS داخلی عملیاتی داریم، باید رکوردهای DNS را طوری نگهداری کنیم که به درستی محیط سرور ما را بازتاب دهد.
هر زمان که یک میزبان را به محیط خود (در همان دیتاسنتر) اضافه میکنید باید آن را به DNS نیز اضافه کنید. فهرستی از مراحل این کار را در ادامه میبینید:
در نهایت فایلهای پیکربندی را تست کنید:
sudo named-checkconf sudo named-checkzone nyc3.example.com db.nyc3.example.com sudo named-checkzone 128.10.in-addr.arpa /etc/bind/zones/db.10.128
سپس BIND را مجدداً بارگذاری نمایید:
sudo systemctl reload bind9
اینک سرور اصلی شما برای استفاده از میزبان جدید پیکربندی شده است.
آدرس IP خصوصی میزبان جدید را به ACL با عنوان «trusted» اضافه کنید (named.conf.options).
ساختار پیکربندی را بررسی کنید:
sudo named-checkconf
سپس BIND را مجدداً بارگذاری کنید:
sudo systemctl reload bind9
اینک سرور ثانویه اتصالها از میزبان جدید را میپذیرد.
اگر یک میزبان را از محیط خود حذف کردهاید، یا میخواهید آن را از DNS خارج سازید، کافی است همه مواردی که در بخش فوق اضافه کردید را حذف نمایید. یعنی همه گامهای فوق را به صورت معکوس اجرا کنید.
اینک شما میتوانید رابطهای شبکه خصوصی خود را به جای آدرسهای IP با استفاده از نامشان مورد اشاره قرار دهید. این امر موجب میشود که پیکربندی سرویسها و اپلیکیشنها آسانتر شود، زیرا دیگر لازم نیست آدرسهای IP خصوصی آنها را به خاطر داشته باشید و خواندن و درک فایلها نیز آسانتر میشود. ضمناً اینک میتوانید پیکربندی خود را در یک مکان منفرد یعنی سرور DNS اصلی طوری تغییر دهید که به سرور جدیدی اشاره کند و نیاز نیست که انواع فایلهای پیکربندی مختلف را ویرایش کنید و همین امر موجب سهولت نگهداری میشود.
زمانی که DNS داخلی خود را راهاندازی کردید و فایلهای پیکربندی از FQDN های خصوصی برای تعیین اتصالهای شبکه استفاده کردند، بسیار ضروری است که سرورهای DNS به طرز صحیحی نگهداری شوند. اگر هر دوی این سرورها از کار بیفتند، سرویسها و اپلیکیشنهای شما دیگر به درستی کار نخواهند کرد. به همین دلیل است که توصیه میشود دستکم یک سرور DNS ثانویه راهاندازی شود تا به عنوان پشتیبان مورد استفاده قرار گیرد.
منبع: فرادرس
پردازش در واقع به یک برنامه در حال اجرا گفته میشود. اجرای یک پردازش میبایست به صورت ترتیبی انجام بگیرد. پردازشها به صورت نهادی تعریف میشوند که واحد پایهایِ کار پیادهسازی شده در سیستم را نشان میدهند. به بیان سادهتر برنامههای رایانهای در فایلهای متنی نوشته میشوند و هنگامی که روی سیستم عامل اجرا میشوند به پردازش تبدیل میشوند و همه وظایف اشاره شده در برنامه را به مرحله اجرا در میآورند.
زمانی که یک برنامه در حافظه بارگذاری و به یک پردازش تبدیل میشود، میتوان آن را به چهار بخش تقسیم کرد: پشته، هیپ، متن و داده. در تصویر زیر طرح سادهای از پردازش درون حافظه اصلی نمایش یافته است:
بخش پردازش | توضیح |
---|---|
پشته | شته در پردازش شامل دادههای موقتی مانند پارامترهای متد/تابع، آدرسهای بازگشتی و متغیرهای محلی است. |
هیپ | هیپ حافظهای است که به صورت دینامیک در طی زمان اجرا تخصیص مییابد. |
متن | بخش متنی پردازش شامل فعالیت جاری است که بر اساس مقدار Program Counter و محتوای رجیسترهای پردازنده نمایش مییابد. |
دادهها | در این بخش متغیرهای گلوبال و استاتیک وجود دارند. |
برنامه قطعهای از کد است که میتواند از یک خط منفرد یا میلیونها خط تشکیل یافته باشد. یک برنامه رایانهای معمولاً به وسیله برنامهنویس رایانه و به یک زبان خاص برنامهنویسی نوشته میشود. برای نمونه در ادامه برنامه سادهای به زبان C را مشاهده میکنید:
یک برنامه رایانهای مجموعهای از دستورالعملها است که هنگام اجرا، وظیفه خاصی را توسط رایانه به انجام میرساند. زمانی که یک برنامه را با یک پردازش مقایسه میکنیم، نتیجه میگیریم که پردازش، وهله دینامیکی از یک برنامه رایانهای محسوب میشود.
بخشی از برنامه رایانهای که وظیفه کاملاً تعریفشدهای را اجرا میکند به نام الگوریتم شناخته میشود. مجموعهای از برنامههای رایانهای، کتابخانهها و دادههای مرتبط به نام نرمافزار نامیده میشوند.
زمانی که یک پردازش اجرا میشود، حالتهای مختلفی را تجربه میکند. این مراحل بسته به نوع سیستم عامل متفاوت هستند و نام این مراحل نیز استاندارد خاصی ندارد.
به طور کلی یک پردازش در هر زمان یکی از حالتهای زیر را میتواند داشته باشد:
حالت | توضیح |
---|---|
آغاز (Start) | حالت اولیه یک پردازش است که در حالت آغاز یا ایجاد است. |
آماده (Ready) | در این حالت پردازش منتظر انتساب یافتن به یک پردازنده است. پردازشهای آماده در انتظار این هستند که زمان پردازنده از سوی سیستم عامل به آنها اختصاص یابد تا بتوانند اجرا شوند. پردازش پس از مرحله آغاز و یا پس از وقفهای که در آن سیستم عامل، زمان CPU را به پردازش دیگری اختصاص داده است، ممکن است وارد این حالت شوند. |
اجرا (Running) | زمانی که زمان پردازنده از سوی سیستم عامل به پردازش اختصاص یافت، پردازش وارد حالت اجرا میشود و دستورالعملهای آن از سوی پردازنده اجرا میشوند. |
انتظار (Waiting) | پردازش در صورتی که نیاز باشد منتظر منابعی مانند ورودی کاربر یا دسترسی به یک فایل بماند وارد حالت انتظار میشود. |
خاتمه یا خروج (Terminated or Exit) | زمانی که اجزای پردازش پایان مییابد یا از سوی سیستم عامل به آن پایان داده میشود، به حالت خاتمه میرود و بدین ترتیب از حافظه اصلی خارج میشود. |
بلوک کنترل پردازش نوعی ساختمان داده است که از سوی سیستم عامل برای هر پردازش نگهداری میشود. PCB به وسیله یک شناسه پردازش (PID) مشخص میشود. PCB همه اطلاعات مورد نیاز برای پیگیری روند پردازش را که شامل موارد زیر هستند شامل میشود.
اطلاعات | توضیح |
---|---|
حالت پردازش | حالت کنونی پردازش مانند این که آماده، در حال اجرا، و یا انتظار است را شامل میشود. |
مجوزهای پردازش | این اطلاعات برای فعالسازی یا غیر فعالسازی دسترسی پردازش به منابع سیستم ضروری است |
شناسه پردازش | شناسهای یکتا برای هر پردازش است که از سوی سیستم عامل تخصیص داده میشود. |
اشارهگر (Pointer) | یک اشارهگر به پردازش والد است. |
شمارنده برنامه (Program Counter) | شمارنده برنامه یک اشارهگر به آدرس دستورالعمل بعدی که باید در پردازش اجرا شود محسوب میشود. |
ثباتهای CPU | شامل ثباتها یا رجیسترهای مختلف CPU است که باید برای اجرای پردازش در حالت اجرایی نگهداری شوند. |
اطلاعات مدیریت حافظه | این اطلاعات شامل جدول page، محدودیت حافظه، جدول Segment است و به حافظه مورد استفاده از سوی سیستم عامل وابسته است. |
اطلاعات Accounting | شامل مقدار CPU مورد استفاده برای اجرای پردازش، محدودیت زمانی، شناسه اجرایی و غیره است. |
اطلاعات وضعیتهای IO | شامل فهرستی از دستگاههای ورودی/خروجی تخصیص یافته به پردازش است. |
معماری PCB | به طور کامل به نوع سیستم عامل وابسته است و در سیستمهای عامل مختلف میتواند شامل اطلاعات متفاوتی باشد. در ادامه نمودار سادهای از یک PCB را مشاهده میکنید: |
PCB پردازش در طی چرخه عمر پردازش حفظ میشود و تنها زمانی حذف میشود که پردازش خاتمه یابد.