شبیه‌سازی KeepAlive در اوراکل با SQLNET.EXPIRE_TIME: راهکاری برای محیط‌های دارای فایروال و Sessionهای Idle

یکی از مشکلات رایج در محیط‌هایی که بین کلاینت و دیتابیس فایروال یا NAT وجود دارد، قطع شدن ارتباط سشن‌های Idle به‌علت Timeout است.
برای حل این مشکل، اوراکل پارامتر SQLNET.EXPIRE_TIME را معرفی کرده است. این پارامتر باعث می‌شود دیتابیس به‌صورت دوره‌ای بسته‌های کوچک (probe) ارسال کند تا مسیر ارتباطی همچنان فعال باقی بماند. این مکانیزم در واقع نوعی شبیه‌سازی TCP KeepAlive است تا فایروال‌ها ارتباط ما را قطع نکنند.

محیط تست

  • سرور دیتابیس (VMware Workstation)

    • آدرس: 192.168.188.3

    • دیتابیس: Oracle 19c (Instance: orcl)

  • کلاینت ویندوز

    • آدرس: 192.168.188.1

    • ابزار اتصال: SQL Developer (با کاربر SYS)

  • شبکه: اتصال مستقیم روی پورت 1521

تنظیم پارامتر SQLNET.EXPIRE_TIME

پارامتر در فایل sqlnet.ora در مسیر DB Home (نه Grid Home) تنظیم شد:

 

# $ORACLE_HOME/network/admin/sqlnet.ora
SQLNET.EXPIRE_TIME = 1

 

  • مقدار ۱ دقیقه صرفاً برای شبیه‌سازی در محیط تست انتخاب شد (در محیط واقعی معمولاً روی ۱۰ یا ۱۵ دقیقه قرار داده می‌شود).

  • پس از تغییر فایل، روی سرور دستور زیر اجرا شد:

 

lsnrctl reload

 

  • تا Listener تغییرات را دریافت کند.

  • توجه شود که این پارامتر فقط روی Sessionهای جدید اثر می‌گذارد؛ سشن‌های فعال قبل از تغییر، بدون بازسازی اتصال از این مکانیزم استفاده نخواهند کرد.


مانیتورینگ با tcpdump

برای مشاهده تبادل Probe و ACK بین سرور و کلاینت، از دستور زیر با اجرا توسط کاربر root استفاده شد:

 

tcpdump -i ens160 host 192.168.188.1 and port 1521 -nn -vvv -X -s0

 

خروجی نمونه

Probe و پاسخ ACK

این خروجی بصورت خلاصه شده است و متن واقعی بیشتر از این حجم دارد

 

05:32:41.416996 IP 192.168.188.3.1521 > 192.168.188.1.51965: Flags [.], length 0
05:32:41.417692 IP 192.168.188.1.51965 > 192.168.188.3.1521: Flags [.], length 0

 

  • خط اول: سرور یک probe ارسال کرده است.

  • خط دوم: کلاینت با ACK پاسخ داده است.

  • نتیجه: ارتباط زنده است.

تکرار در بازه‌های بعدی

 

05:33:42.857052 IP 192.168.188.3.1521 > 192.168.188.1.51965: Flags [.], length 0
05:33:42.858105 IP 192.168.188.1.51965 > 192.168.188.3.1521: Flags [.], length 0

 

این چرخه در هر یک دقیقه تکرار می‌شود و Session در دیتابیس پایدار می‌ماند.


بررسی Session در دیتابیس

با کوئری زیر Session کلاینت بررسی شد. از آنجا که با sql developer متصل شده بودم این جستجو را اجرا کردم:

 

select s.inst_id,
       s.status,
       s.sid||','||s.serial# sid_serial,
       s.program,
       s.osuser,
       s.username,
       s.machine,
       s.logon_time
from gv$session s
where program like 'SQL%';

 

نمونه خروجی:

 

INST_ID STATUS SID_SERIAL PROGRAM OSUSER USERNAME MACHINE LOGON_TIME
1 INACTIVE 98,60437 SQL Developer Vahid SYS vahidpc 28-SEP-2025 05:10:54

 

جمع‌بندی

  • پارامتر SQLNET.EXPIRE_TIME باعث می‌شود سرور بسته‌های KeepAlive شبیه‌سازی‌شده ارسال کند تا فایروال‌ها Session را قطع نکنند.

  • در تست حاضر، مقدار روی ۱ دقیقه تنظیم شد تا تبادلات به‌وضوح در tcpdump قابل مشاهده باشند.

  • برای اعمال تغییر، Listener با دستور reload به‌روزرسانی شد.

  • مکانیزم فقط روی سشن‌های جدید اثر دارد.

  • در خروجی tcpdump می‌توان ACKهای منظم را مشاهده کرد که نشان‌دهنده سلامت ارتباط است.

  • در صورت قطع کلاینت، به‌جای ACK، پاسخ RST یا ICMP مشاهده خواهد شد و Session خاتمه پیدا می‌کند.