DevOps
Telegram botni Render'ga joylash va uyqu rejimi bilan kurash
Bot mahalliy kompyuterda benuqson ishlaydi. Serverga chiqarilgach esa mijoz "javob bermayapti" deb yozadi. Sabab kodda emas — bepul tarifning ishlash tartibida.
Muammoning kelib chiqishi
Unutilmas Ta'm uchun tasdiqlash boti dastlab Railway'da turardi. Bir muddatdan keyin bepul soatlar tugadi va xizmat to'xtadi. Render'ga ko'chirdim — u yerda esa boshqa cheklov chiqdi.
Render bepul tarifda xizmat 15 daqiqa davomida so'rov olmasa uxlab qoladi. Keyingi so'rov kelganda u uyg'onadi, lekin bunga 30–50 soniya ketadi. Foydalanuvchi shu vaqt davomida javobsiz qoladi va odatda botni tashlab ketadi.
Polling yoki webhook
Bu tanlov joylashtirish usulini belgilaydi.
| Polling | Webhook | |
|---|---|---|
| Ishlash | Bot Telegram'dan so'raydi | Telegram botga yuboradi |
| Ochiq port | Kerak emas | Kerak, HTTPS bilan |
| Uyqu bilan | Doim faol, uxlamaydi | So'rov kelganda uyg'onadi |
| Sozlash | Oddiy | Murakkabroq |
Ko'rinishidan polling yaxshiroq — uxlab qolmaydi. Lekin Render'da Web Service turi HTTP portini ochishni talab qiladi. Agar port ochilmasa, deploy muvaffaqiyatsiz deb belgilanadi.
Men shunday qildim: polling saqlanadi, lekin yoniga kichik HTTP server qo'shiladi. Bitta jarayonda ikkalasi birga ishlaydi.
Polling va HTTP serverni birga ishlatish
import asyncio, os, logging
from aiohttp import web
from aiogram import Bot, Dispatcher
async def health(request):
return web.json_response({"status": "ok"})
async def run_web():
app = web.Application()
app.router.add_get("/", health)
app.router.add_get("/health", health)
runner = web.AppRunner(app)
await runner.setup()
port = int(os.environ.get("PORT", 10000))
await web.TCPSite(runner, "0.0.0.0", port).start()
logging.info("web on :%s", port)
async def main():
bot = Bot(token=os.environ["BOT_TOKEN"])
dp = Dispatcher()
dp.include_router(router)
await run_web()
await bot.delete_webhook(drop_pending_updates=True)
await dp.start_polling(bot)
asyncio.run(main())
Ikki muhim detal. Birinchisi — os.environ["PORT"]. Render portni o'zi beradi, uni qattiq yozib qo'ysangiz xizmat ishga tushmaydi. Ikkinchisi — delete_webhook. Agar avval webhook sozlangan bo'lsa, polling ishlamaydi va sabab tushunarsiz bo'ladi.
Keep-alive
Endi xizmatda HTTP endpoint bor. Uni muntazam "turtib" turish kerak. Buning uchun tashqi cron xizmati ishlatiladi — cron-job.org bepul va yetarli.
Sozlash oddiy: manzil sifatida https://sizning-xizmat.onrender.com/health, interval — har 10 daqiqada. 15 daqiqalik chegaradan kichik bo'lishi shart.
Nima uchun xizmatning o'zi ichidan emas: uxlab qolgan jarayon o'ziga so'rov yubora olmaydi. Turtki tashqaridan kelishi kerak.
Ikki instansiya muammosi
Deploy paytida Render eski versiyani darhol o'chirmaydi — yangisi ishga tushgunicha ikkalasi bir vaqtda ishlaydi. Polling rejimida bu xatoga olib keladi:
TelegramConflictError: terminated by other getUpdates request
Telegram bitta bot uchun faqat bitta polling ulanishiga ruxsat beradi. Yechim — Render sozlamalarida zero-downtime deploy ni o'chirish. Shunda eski jarayon avval to'xtaydi, keyin yangisi boshlanadi. Bot bir necha soniya javob bermaydi, lekin xato chiqmaydi.
Muhit o'zgaruvchilari
Token va kalitlarni kodga yozmang. Ular Render panelidagi Environment bo'limida saqlanadi va kod ularni shunday o'qiydi:
BOT_TOKEN = os.environ["BOT_TOKEN"]
ADMIN_IDS = [int(x) for x in os.environ["ADMINS"].split(",")]
FIREBASE_KEY= os.environ["FIREBASE_KEY"]
Agar token bir marta GitHub'ga tushib qolsa, uni darhol BotFather orqali bekor qiling. Commit tarixidan o'chirish yetarli emas — u allaqachon indekslangan bo'lishi mumkin.
Jurnal va nosozlik topish
Render panelida jonli jurnal bor, lekin u qayta ishga tushganda tozalanadi. Muhim hodisalarni tashqariga yozish foydali — masalan o'zingizga Telegram orqali:
async def notify_admin(bot, text):
for a in ADMIN_IDS:
try:
await bot.send_message(a, f"⚠️ {text}")
except Exception:
pass
Shunda bot ishga tushgani, xato chiqqani yoki baza bilan aloqa uzilgani haqida darhol bilasiz.
Bepul tarif chegarasi
Halol aytish kerak: bepul tarif sinov va kichik yuk uchun. Jiddiy loyihada quyidagi muammolar chiqadi:
- Uyg'onish kechikishi foydalanuvchini yo'qotadi
- Xotira cheklangan, katta kutubxonalar sig'maydi
- Doimiy disk yo'q — SQLite fayli qayta ishga tushganda yo'qoladi
- Xizmat ko'rsatish kafolati yo'q
Oxirgi punkt eng muhimi. Bepul tarifda ma'lumot bazasini fayl sifatida saqlab bo'lmaydi — u har deploydan keyin tozalanadi. Shuning uchun men holatni Firestore yoki tashqi Postgres'da saqlayman.
Xulosa
Render'da Telegram bot barqaror ishlashi mumkin, lekin uchta narsa qo'shilishi kerak: HTTP endpoint, tashqi keep-alive va tashqi ma'lumot ombori.
Mijozga xizmat ko'rsatadigan bot uchun esa pullik tarifga o'tish oxir-oqibat arzonroq tushadi — yo'qotilgan buyurtma serverdan qimmatroq.