در این بخش پایانی، به سراغ ابزارهای پیشرفتهای میرویم که به شما در اشکالزدایی، بهینهسازی عملکرد و کار با پایگاه داده در محیط لینوکس کمک میکنند. این مهارتها تفاوت بین یک توسعهدهنده معمولی و یک متخصص را رقم میزنند.
۱. اشکالزدایی از راه دور (Remote Debugging) 🐞
یکی از قدرتمندترین قابلیتهای اکوسیستم داتنت، امکان دیباگ کردن یک برنامه در حال اجرا روی سرور لینوکس، به صورت زنده از محیط ویژوال استودیو در ویندوز است. این یعنی میتوانید breakpoint بگذارید، مقادیر متغیرها را مشاهده کنید و خط به خط کد را روی سرور واقعی دنبال کنید.
پیشنیاز:
سرور لینوکس شما باید سرویس SSH را نصب و فعال کرده باشد.
sudo apt update && sudo apt install openssh-server
مراحل اتصال در Visual Studio:
- در ویژوال استودیو، به منوی
Debug -> Attach to Process... بروید. - در پنجره باز شده، برای
Connection type، گزینهی SSH را انتخاب کنید. - در قسمت
Connection target، آدرس IP یا نام هاست سرور لینوکس خود را وارد کرده و اطلاعات ورود (نام کاربری و رمز عبور یا کلید خصوصی) را ارائه دهید. - پس از اتصال موفق، لیستی از تمام پروسههای در حال اجرا روی سرور لینوکس به شما نمایش داده میشود.
- پروسهی مربوط به اپلیکیشن داتنت خود را پیدا کنید (معمولاً نام پروژه شما یا
dotnet). آن را انتخاب کرده و روی دکمه Attach کلیک کنید.
تمام شد! اکنون دیباگر ویژوال استودیو به پروسهی روی سرور متصل است. میتوانید در کد خود breakpoint قرار دهید و با ارسال یک درخواست به وبسایت، اجرای برنامه در آن نقطه متوقف شده و میتوانید وضعیت کامل آن را تحلیل کنید.
نکته: این قابلیت در Visual Studio Code نیز از طریق افزونهی Remote - SSH با قدرت بسیار بالایی پشتیبانی میشود و یک گردش کار (workflow) بسیار محبوب در میان توسعهدهندگان است.
۲. مانیتورینگ و تحلیل عملکرد (Performance Monitoring) 📈
چگونه بفهمیم اپلیکیشن ما روی سرور چقدر حافظه یا CPU مصرف میکند؟ اگر برنامه کند عمل کند، کجای کد گلوگاه (bottleneck) است؟ داتنت مجموعهای از ابزارهای خط فرمان عالی برای پاسخ به این سوالات فراهم کرده است. این ابزارها باید به صورت global نصب شوند:
dotnet tool install --global dotnet-counters
dotnet tool install --global dotnet-trace
dotnet tool install --global dotnet-dump
الف) dotnet-counters
یک ابزار سبک برای مشاهدهی زندهی معیارهای عملکردی برنامه.
- کاربرد: مانیتور کردن سریع و زندهی وضعیت سلامت برنامه.
- مثال: برای مشاهدهی معیارهای اصلی یک پروسه با ID مشخص (مثلاً 1234):
dotnet-counters monitor -p 1234
این دستور معیارهایی مانند cpu-usage (مصرف CPU)، working-set (حافظه کاری)، gc-heap-size (حجم حافظه مدیریت شده) و برای ASP.NET Core، تعداد requests-per-second را به صورت زنده نمایش میدهد.
ب) dotnet-trace
ابزاری برای جمعآوری اطلاعات دقیق از اجرای برنامه (profiling) برای تحلیل عمیقتر مشکلات عملکردی.
- کاربرد: پیدا کردن دلایل کندی برنامه و شناسایی متدهایی که زمان زیادی برای اجرا صرف میکنند.
- مثال: جمعآوری اطلاعات از یک پروسه و ذخیرهی آن در یک فایل:
dotnet-trace collect -p 1234 --output my-app.nettrace
فایل خروجی my-app.nettrace را میتوانید در ویژوال استودیو یا ابزار PerfView باز کرده و نمودار کامل اجرای متدها (call tree) و زمان مصرفی هرکدام را به دقت تحلیل کنید.
ج) dotnet-dump
ابزاری برای گرفتن یک تصویر لحظهای (snapshot) از حافظهی یک پروسه.
- کاربرد: تحلیل مشکلات پیچیدهی حافظه (Memory Leaks)، بنبستها (Deadlocks) و کرشهای ناگهانی.
- مثال: گرفتن یک dump از پروسه:
dotnet-dump collect -p 1234
تحلیل dump:
dotnet-dump analyze ./dump_xxxxxxxx
پس از ورود به محیط تحلیل، میتوانید از دستورات قدرتمندی مانند dumpheap -stat (برای مشاهدهی خلاصهی اشیاء در حافظه) یا clrstack (برای دیدن call stack تمام threadها) استفاده کنید تا بفهمید در لحظهی کرش، برنامه در چه وضعیتی بوده است.
۳. کار با پایگاه داده (Working with Databases) 💾
اتصال به پایگاه داده در لینوکس تفاوت چندانی با ویندوز ندارد، اما یک نکتهی بسیار مهم وجود دارد که نادیده گرفتن آن منجر به خطاهای زیادی میشود.
اتصال به SQL Server: بله، SQL Server به صورت رسمی روی لینوکس اجرا میشود و رشتهی اتصال (Connection String) شما در کد #C هیچ تغییری نمیکند. همچنین میتوانید از پایگاه دادههای محبوبی که در اکوسیستم لینوکس رایج هستند، مانند PostgreSQL یا MySQL/MariaDB استفاده کنید که توسط Entity Framework Core به خوبی پشتیبانی میشوند.
⚠️ تلهی بزرگ: حساسیت به بزرگی و کوچکی حروف (Case Sensitivity)
اکثر موتورهای پایگاه داده در لینوکس (مانند PostgreSQL) و حتی SQL Server روی لینوکس (بسته به Collation انتخابی هنگام نصب) به صورت پیشفرض Case-Sensitive هستند. این در حالی است که SQL Server روی ویندوز به صورت پیشفرض Case-Insensitive است.
این تفاوت چه مشکلی ایجاد میکند؟
فرض کنید در EF Core یک مدل به نام Product دارید و انتظار دارید به جدولی به نام Products متصل شود.
// کد شما در EF Core
public class Product {
public int Id { get; set; }
public string Name { get; set; }
}اگر در پایگاه دادهی PostgreSQL شما، نام جدول به صورت حروف کوچک (products) ساخته شده باشد، کد بالا در لینوکس با خطا مواجه خواهد شد، زیرا EF Core به دنبال جدولی به نام Products (با P بزرگ) میگردد و آن را پیدا نمیکند. این مشکل برای نام ستونها نیز صادق است.
بهترین راهکار (Best Practice):
- یک استاندارد نامگذاری برای خود تعریف کرده و هم در مدلهای #C و هم در اسکیما (schema) پایگاه داده به آن پایبند باشید. برای مثال، میتوانید تمام جداول و ستونها را با حروف کوچک یا با استاندارد snake_case (e.g., product_name) در پایگاه داده ایجاد کرده و همین استاندارد را در پیکربندی EF Core نیز اعمال کنید. این کار باعث میشود کد شما بدون هیچ مشکلی بین ویندوز و لینوکس جابجا شود.