گام 30: کشف اندرونی سیمفونی

5.0 version
Maintained

کشف اندرونی سیمفونی

مدت مدیدی است که از سیمفونی برای توسعه‌ی اپلیکیشن‌های قدرتمند استفاده می‌کنیم اما اکثر کدی که در اپلیکیشن اجرا می‌شود، متعلق به خود سیمفونی است. چند صد خط کد در برابر هزاران خط کد.

من دوست دارم که بدانم چیزها در پشت پرده چطور کار می‌کنند و همیشه مسحور ابزارهایی می‌شده‌ام که به من در فهم چگونگی کارکرد چیزها کمک می‌کرده‌اند. اولین باری که به صورت گام‌به‌گام از یک اشکال‌زدا استفاده کردم یا اولین باری که ptrace را کشف کردم، خاطرات سحرآمیزی هستند.

آیا می‌خواهید که چگونگی کارکرد سیمفونی را بهتر بفهمید؟ زمان آن رسیده است که ببینیم سیمفونی چگونه اپلیکیشن شما را به راه می‌اندازد. به جای توصیف نظری چگونگی رسیدگی به درخواست HTTP در سیمفونی که می‌تواند کاملاً خسته‌کننده باشد، می‌خواهیم از Blackfire استفاده کنیم تا تعدادی نمایش بصری بدست آوریم و از آن برای کشف موضوعات پیچیده‌تر بهره بگیریم.

فهم اندرونی سیمفونی به کمک Blackfire

شما در حال حاضر می‌دانید که تمام درخواست‌های HTTP توسط یک مدخل خدمت‌رسانی می‌شوند: فایل public/index.php. اما بعد از آن چه می‌شود؟ چگونه کنترلرها فراخوانی می‌شوند؟

بیایید با Blackfire و از طریق افزونه‌ مرورگر Blackfire، صفحه‌ی اصلی انگلیسی را در محیط عمل‌آوری، نمایه‌سازی کنیم:

1
$ symfony remote:open

یا مستقیماً از طریق خط فرمان:

1
$ blackfire curl `symfony env:urls --first`en/

به بخش «Timeline» در نمایه بروید، شما باید چیزی مشابه این ببینید:

در timeline به روی نوار رنگی بروید تا اطلاعات بیشتری در مورد هر فراخوانی ببینید؛ شما چیزهای زیادی در مورد چگونگی کارکرد سیمفونی خواهید آموخت:

  • مدخل اصلی public/index.php است؛
  • متد Kernel::handle() به درخواست رسیدگی می‌کند؛
  • این متد، HttpKernel را فراخوانی می‌کند که تعدادی رویداد را اعزام می‌نماید.
  • اولین رویداد، RequestEvent است؛
  • متد ControllerResolver::getController() فراخوانی می‌شود تا تعیین کند که کدام کنترلر باید برای این URL فراخوانی شود؛
  • متد ControllerResolver::getArguments() فراخوانی می‌شود تا تعیین کند که چه آرگمان‌هایی باید به کنترلر داده شود (مبدل پارامتر -param converter- فراخوانی می‌شود)؛
  • متد ConferenceController::index() فراخوانی می‌شود و اکثر کد ما توسط این فراخوانی اجرا می‌شود؛
  • متد ConferenceRepository::findAll() تمام کنفرانس‌ها را از پایگاه‌داده می‌گیرد (به اتصال به پایگاه‌داده از طریق PDO::__construct() توجه کنید)؛
  • متد Twig\Environment::render() قالب را render می‌کند؛
  • رویداد‌های ResponseEvent و FinishRequestEvent اعزام می‌شوند، اما به نظر می‌رسد که هیچ شنونده‌ای واقعاً ثبت نشده است زیرا که آن‌ها خیلی سریع اجرا می‌شوند.

timeline راهی عالی برای درک چگونگی کارکرد یک کد است؛ که وقتی پروژه توسط شخص دیگری توسعه یافته باشد، بسیار سودمند است.

حالا همان صفحه را در رایانه‌ی محلی و در محیط توسعه، نمایه‌سازی کنید:

1
$ blackfire curl `symfony var:export SYMFONY_DEFAULT_ROUTE_URL`en/

نمایه را باز کنید. شما باید به بخش call graph بازهدایت شوید زیرا درخواست خیلی سریع بوده و timeline کاملاً خالی خواهد بود:

متوجه شدید چه اتفاقی افتاد؟ نهان‌سازی HTTP فعال است و بنابراین ما در حال نمایه‌سازی از لایه‌ی نهان‌ساز HTTP در سیمفونی هستیم. از آنجایی که صفحه در نهانگاه قرار دارد، HttpCache\Store::restoreResponse() پاسخ HTTP را از نهانگاهش می‌گیرد و کنترلر هرگز فراخوانی نخواهد شد.

همانطور که در گام قبلی انجام دادیم، لایه‌ی نهان‌سازی را در public/index.php غیرفعال کرده و مجدداً تلاش کنید. می‌توانید به سرعت ببینید که نمایه بسیار متفاوت به نظر می‌رسد:

این‌ها تفاوت‌های اصلی هستند:

  • TerminateEvent، که در محیط عمل‌آوری قابل مشاهده نبود، درصد زیادی از زمان اجرا را به خود اختصاص داده است؛ دقیق‌تر نگاه کنید، می‌توانید ببینید که این رویداد، وظیفه‌ی ذخیره‌ی داده‌های نمایه‌ساز سیمفونی را در طول درخواست بر عهده دارد؛
  • در فراخوانی ConferenceController::index()، به متد SubRequestHandler::handle() که ESI را render می‌کند، توجه کنید (به همین خاطر است که ما دو فراخوانی به Profiler::saveProfile() داریم، یکی برای درخواست اصلی و یکی برای ESI).

در timeline بیشتر اکتشاف کنید؛ به بخش call graph بروید تا نمایش دیگری از همان داده‌ها را ببینید.

همانطور که همین الان کشف کردیم، اجرای کد در محیط توسعه و در محیط عمل‌آوری کاملاً متفاوت است. محیط توسعه کندتر است زیراکه نمایه‌ساز سیمفونی تلاش می‌کند تا داده‌های زیادی را برای تسهیل اشکال‌زدایی مشکلات، جمع‌آوری نماید. به این خاطر است که همواره باید در محیط عمل‌آوری نمایه‌سازی کنید، حتی در رایانه‌ی محلی.

چند آزمایش جذاب: یک صفحه‌ی خطا را نمایه‌سازی کنید، آدرس / را نمایه‌سازی کنید (که یک صفحه‌ی بازهدایت‌شونده است) یا یک منبع API. هر نمایه به شما چیز بیشتری در مورد نحوه‌ی کارکرد سیمفونی می‌گوید، چه کلاس‌ها/متدهایی فراخوانی می‌شوند، اجرای چه چیزی کم‌هزینه و اجرای چه چیزی پرهزینه است.

استفاده از افزونه‌ی اشکال‌زدایی Blackfire

به صورت پیشفرض، Blackfire تمام متد‌های فراخوانی‌شده‌ای را که به اندازه‌ی کافی قابل‌توجه نیستند، برای جلوگیری از بار زیاد و گراف‌های بزرگ حذف می‌کند. وقتی که از Blackfire به عنوان ابزار اشکال‌زدایی استفاده می‌کنید، بهتر است که تمام فراخوانی‌ها را نگه دارید. این موضوع توسط افزونه‌ی اشکال‌زدایی فراهم می‌شود.

در خط فرمان از پرچم --debug استفاده کنید:

1
2
$ blackfire --debug curl `symfony var:export SYMFONY_DEFAULT_ROUTE_URL`en/
$ blackfire --debug curl `symfony env:urls --first`en/

در محیط عمل‌آوری، برای مثال، بارگرفتن یک فایل با نام .env.local.php را خواهید دید:

این از کجا می‌آید؟ SymfonyCloud به هنگام استقرار یک اپلیکیشن سیمفونی، بهینه‌سازی‌هایی همچون بهینه‌سازی Composer autoloader را انجام می‌دهد (--optimize-autoloader --apcu-autoloader --classmap-authoritative). همچنین متغیر‌های محیط تعریف‌شده در فایل .env را نیز با تولید فایل .env.local.php بهینه می‌کند (برای جلوگیری از خواندن فایل به ازای هر درخواست):

1
$ symfony run composer dump-env prod

Blackfire ابزاری بسیار قدرتمند است که کمک می‌کند تا نحوه‌ی اجرای کد توسط PHP را درک کنیم. بهبود و افزایش کارایی، تنها یکی از راه‌های استفاده از یک نمایه‌ساز است.


  • « Previous گام 29: مدیریت کارایی
  • Next » در ادامه چه باید کرد؟

This work, including the code samples, is licensed under a Creative Commons BY-NC-SA 4.0 license.