Discord bot არის დიდხანს მცხოვრები პროცესი, რომელიც ერთ websocket-ს ღიად ინახავს. თავად websocket თითქმის არაფერი ღირს: heartbeat ორმოცდაათიოდე წამში ერთხელ და ის მოვლენები, რომლებზეც გამოიწერე. slash-ბრძანებების bot ოცდაათ სერვერში 80-150 MB რეზიდენტულ მეხსიერებას და ბირთვის რამდენიმე პროცენტს იყენებს, რაც ნიშნავს, რომ ნებისმიერ ჰოსტზე ყველაზე პატარა გეგმაც უკვე ზედმეტად დიდია.
რაც ღირს, ის cache-ია. ყველა მთავარი ბიბლიოთეკა ინახავს იმის ასლს, რაც ნახა - guild-ებს, არხებს, როლებს, წევრებს, შეტყობინებებს, presence-ებს - რათა შენმა კოდმა ისინი ქსელური მოთხოვნის გარეშე წაიკითხოს. ეს cache შენს წარმატებას მიჰყვება და არა შენს კოდს, სწორედ ამიტომ ვარდება bot, რომელიც ათ სერვერში კარგად მუშაობდა, ოთხასში ერთი ხაზის შეცვლის გარეშე. მეორე, რაც ღირს, აუდიოა, რადგან მუსიკის bot სინამდვილეში ტრანსკოდირების სერვისია ჩატის ინტერფეისით.
ეს პოსტი იმაზეა, როგორ გამიჯნო ისინი, სანამ არასწორისთვის გადაიხდი.
რას ინახავს bot მეხსიერებაში სინამდვილეში#
დაშალე რიცხვი და ის მისტიკური აღარ იქნება. ტიპურ bot-ზე რეზიდენტული სიმრავლე ოთხი რამაა:
| კომპონენტი | ტიპური ღირებულება | იზრდება |
|---|---|---|
| Runtime და ბიბლიოთეკები | 60-120 MB (Node), 50-90 MB (Python) | თითქმის არაფერზე |
| Guild-ების, არხებისა და როლების cache | 1-10 MB რამდენიმე ასეულ guild-ზე | სერვერების რაოდენობაზე |
| წევრებისა და მომხმარებლების cache | ასეულობით ბაიტიდან რამდენიმე KB-მდე თითოეულზე | წევრებზე, თუ მათ cache-ავ |
| შეტყობინებების cache | 200 შეტყობინება არხზე ნაგულისხმევად discord.js-ში | არხები გამრავლებული აქტივობაზე |
| ხმა, თითო აქტიურ ნაკადზე | 30-80 MB plus რეალური CPU | ერთდროულ მსმენელებზე |
| შენი საკუთარი state | რასაც ცვლადში ჩადებ | ჩვეულებრივ, ჩუმად, სამუდამოდ |
წევრების cache არის მთელი პასუხი დიდ სერვერებში მყოფ ნებისმიერ bot-ზე. bot-ს guild-ებში, რომლებიც ჯამში ასი ათასი წევრია, ჩართული წევრების cache-ით და გაშვებისას chunk-ად დაყოფილი guild-ებით, შეუძლია დაამატოს რამდენიმე ასეული მეგაბაიტი, სანამ რამე სასარგებლოს გააკეთებს. იმავე bot-ს, წევრების cache-ის გამორთვით, იქვე რჩება, საიდანაც დაიწყო.
ბოლო სტრიქონი მეტ ყურადღებას იმსახურებს, ვიდრე იღებს. ყველაფერი, რაც dictionary-ში შეინახე, რადგან მონაცემთა ბაზა ზედმეტად მოგეჩვენა, მეხსიერების გაჟონვაა გეგმით. cooldown-ის map-ები user ID-ით, ბოლო შეტყობინებების Map anti-spam შემოწმებისთვის, სიმღერების რიგის მასივი თითო guild-ზე: ყველა მათგანი შეუზღუდავია, თუ არ შეზღუდე. ყველა კოლექციას, რომელიც შენს კოდს ეკუთვნის, დაუწესე ზღვარი და გამოდევნა, ან შეეგუე, რომ პროცესი იზრდება, სანამ კონტეინერი არ გააჩერებს.
Intent-ები შენს კოდზე ადრე წყვეტს მეხსიერებას#
Gateway intent-ები არის გამოწერა, რომელსაც დაკავშირებისას აცხადებ. ისინი აკონტროლებს, რას გიგზავნის Discord, და რასაც გიგზავნის, ბიბლიოთეკა სწორედ იმას ინახავს cache-ში. მათი სწორად დაყენება ზომის შერჩევის ყველაზე მაღალეფექტური გადაწყვეტილებაა და ერთ ხაზს ითხოვს.
სამი intent პრივილეგირებულია, რაც ნიშნავს, რომ ისინი Developer Portal-შიც უნდა ჩართო და კოდშიც, ხოლო 100-ზე მეტ სერვერში მყოფი bot უნდა იყოს ვერიფიცირებული, რომ ისინი შეინარჩუნოს:
GUILD_MEMBERS- წევრების შესვლა, გასვლა და განახლებები. ეს არის ის, რაც მეხსიერებას ავსებს. მის გარეშე შენი bot წევრების სიას საერთოდ არ იღებს.GUILD_PRESENCES- ონლაინ სტატუსი და აქტივობა ყოველი guild-ის ყოველი წევრისთვის. ძალიან ძვირია და თითქმის არასდროს არის საჭირო. თუ ის ჩართე იმისთვის, რომ გენახა, ვინ არის ონლაინ, თითქმის ნამდვილად არ გჭირდებოდა.MESSAGE_CONTENT- იმ შეტყობინებების ტექსტი, რომლებშიც შენი bot პირდაპირ მოხსენიებული არ არის. საჭიროა prefix ბრძანებებისთვის, slash ბრძანებებისთვის არ არის საჭირო.
bot, რომელიც მთლიანად slash ბრძანებებზეა აგებული, GUILDS-ს და ძალიან ცოტა სხვა რამეს საჭიროებს. prefix ბრძანებებიდან slash ბრძანებებზე გადასვლა ამიტომ მეხსიერების ოპტიმიზაციაცაა და არა მხოლოდ ინტერფეისის ცვლილება, და ის MESSAGE_CONTENT-ის ვერიფიკაციის ტვირთსაც გიხსნის.
Cache-ის შემცირება#
ორივე მთავარ ბიბლიოთეკას შეუძლია cache-ის ცალსახად შეზღუდვა. გააკეთე ეს მანამ, სანამ დაგჭირდება და არა out-of-memory გაჩერების შემდეგ.
discord.js v14-ში makeCache ადგენს ზღვრებს თითო manager-ზე, ხოლო sweepers ტაიმერით ასუფთავებს:
const { Client, GatewayIntentBits, Options } = require("discord.js");const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages], makeCache: Options.cacheWithLimits({ ...Options.DefaultMakeCacheSettings, MessageManager: 25, PresenceManager: 0, GuildMemberManager: { maxSize: 50, keepOverLimit: (member) => member.id === member.client.user.id, }, }), sweepers: { ...Options.DefaultSweeperSettings, messages: { interval: 3600, lifetime: 1800 }, },});keepOverLimit ხაზი დეკორაცია არ არის. ბიბლიოთეკას საკუთარი guild წევრი სჭირდება თავისი უფლებების გასაგებად, ამიტომ მკაცრი ზღვარი ამ გამონაკლისის გარეშე უფლებების შემოწმებას ისე ამტვრევს, რომ მიზეზის მოძებნა რთულია. დოკუმენტაცია ასევე ჩამოთვლის რამდენიმე manager-ს, რომელთა შეზღუდვა საერთოდ არ შეიძლება - მათ შორის guild-ები, არხები და როლები - რადგან ბიბლიოთეკის დანარჩენი ნაწილი ვარაუდობს, რომ ისინი სრულია. შეზღუდე შეტყობინებები, წევრები და presence-ები; სტრუქტურულ cache-ებს ნუ შეეხები.
discord.py-ში ეკვივალენტი კლიენტის constructor-ზეა:
import discordintents = discord.Intents.default()intents.message_content = Falseintents.members = Falseintents.presences = Falseclient = discord.Client( intents=intents, max_messages=None, # default is 1000, None disables chunk_guilds_at_startup=False, member_cache_flags=discord.MemberCacheFlags.none(),)chunk_guilds_at_startup არის ის, რასაც ხალხი ხედავს გვიან. members intent-ის ჩართვისას ის ნაგულისხმევად true-ა და ბიბლიოთეკა ყოველი guild-ის სრულ წევრთა სიას კავშირის წამსვე ითხოვს. რამდენიმე ასეულ დიდ სერვერში მყოფ bot-ზე ეს გრძელი, მეხსიერებაჭამი გაშვებაა, რომელიც ყოველ restart-ზე ხდება. გამორთე და ის წევრები, რომლებიც მართლა გჭირდება, მოიტანე guild.fetch_member(id)-ით.
ორივე ცვლილების შემდეგ უყურე მეხსიერების გრაფიკს კონსოლში ერთი დღე და ნუ ენდობი პირველ ჩვენებას. გაშვების მეხსიერება არ არის მდგრადი მდგომარეობის მეხსიერება, და Node განსაკუთრებით სიამოვნებით იზრდება იმ heap ზღვრისკენ, რომელიც მას ჰგონია, სანამ garbage collector სერიოზულად შეუდგება მუშაობას. რატომ კვდება შენი Node აპლიკაცია 2 GB-ზე 4 GB გეგმაზე განმარტავს ამ ზღვარს და როგორ დააყენო ის შეგნებულად.
მუსიკისა და ხმის bot-ები სხვა ცხოველია#
მუსიკის bot არ არის ჩატ bot ფუნქციით. ის აუდიო მილსადენია და ზომის წესები სრულიად სხვაა.
ყოველი ერთდროული ნაკადი მოიცავს წყაროს მოტანას, დეკოდირებას, 48 kHz სტერეოზე გადაყვანას, Opus-ში კოდირებას, დაშიფვრას და წამში 50 პაკეტის გაგზავნას. პრაქტიკაში ეს ნიშნავს მინიმუმ ერთ ffmpeg პროცესს ნაკადზე, ხშირად yt-dlp პროცესს, რომ წყარო ჯერ გადაწყვიტოს, და ნატიურ Opus encoder-ს. Node-ის მხარეს @discordjs/voice-ს ასევე სჭირდება დაშიფვრის პაკეტი და Opus ბიბლიოთეკა, დაყენებული მასთან ერთად; Python-ის მხარეს გჭირდება ffmpeg path-ში და PyNaCl ხმისთვის.
დაახლოებითი ბიუჯეტი:
| ერთდროული ნაკადები | მეხსიერება ბაზისურ bot-ზე დამატებით | CPU |
|---|---|---|
| 1 | 30-80 MB | ბირთვის 5-15% |
| 5 | 150-400 MB | ბირთვის 0.3-0.8 |
| 20 | 0.6-1.5 GB | 1.5-3 ბირთვი, plus მკვეთრი ზრდა |
ორი პრაქტიკული შედეგი. პირველი: მუსიკის bot-ზე CPU ილევა და არა მეხსიერება, ხოლო გაზიარებულ გეგმაზე CPU მკაცრი შეზღუდვაა იმ წილამდე, რომელიც იყიდე. შეზღუდული event loop უარესია, ვიდრე ნელი: ის gateway heartbeat-ს აყოვნებს, Discord დადასტურებებს აღარ იღებს და ბიბლიოთეკა თავიდან უკავშირდება. bot, რომელიც „შემთხვევით წყდება, როცა რამდენიმე ადამიანი მუსიკას უკრავს“, თითქმის ყოველთვის CPU-შიმშილშია და არა ქსელის პრობლემის მქონე.
მეორე: წყაროს გადაწყვეტა yt-dlp-ით არის მკვეთრი, გაუთვალისწინებელი ხარჯი, რომელსაც დაკვრასთან კავშირი არ აქვს და თუ cache-ის უშვებ, დისკზე წერს. 5 GB გეგმაზე ის ივსება უფრო სწრაფად, ვიდრე ელოდები. დააყენე cache საქაღალდე, რომლის გასუფთავებაც შეგიძლია, ან cache საერთოდ გამორთე.
მუსიკის bot, რომელიც ერთ-ორ guild-ს ემსახურება, კარგადაა 1-2 GB-ზე სრულ ბირთვთან ერთად. საჯარო მუსიკის bot ათეულობით ერთდროული ნაკადით გაცილებით დიდზე უნდა იყოს და, პატიოსნად, საკუთარ მანქანას იმსახურებს.
Sharding და სად მრავლდება მეხსიერება#
Discord ითხოვს bot-ის shard-ებად დაყოფას, როგორც კი ის 2,500-ზე მეტ guild-შია. gateway გეუბნება, რამდენი shard სურს: გააგზავნე GET /gateway/bot შენი token-ით და წაიკითხე shards ველი. ამ ზღვარს ქვემოთ sharding პრობლემის გადაწყვეტაა, რომელიც შენ არ გაქვს.
როგორ მოქმედებს sharding მეხსიერებაზე, მთლიანად ბიბლიოთეკაზეა დამოკიდებული და ეს დეტალია, რომელიც ხალხს ეჭირება:
- discord.js `ShardingManager` ყოველ shard-ზე ცალკე Node პროცესს ქმნის. თითოეული პროცესი სრული bot-ია საკუთარი runtime-ით, საკუთარი ბიბლიოთეკის ინსტანციით და საკუთარი cache-ით. თექვსმეტი shard ბაზისური მეხსიერების თექვსმეტმაგია და shard-ებს შორის კომუნიკაცია manager-ის გავლით უნდა წავიდეს
broadcastEval-ით. ბიუჯეტი გულუხვად გამოყავი. - discord.py-ის `AutoShardedClient` ყველა shard-ს ერთ პროცესში უშვებს ერთ event loop-ზე, ამიტომ runtime-ის ღირებულება ერთხელ იხდება და cache-ები გაზიარებულია. მეხსიერება მონაცემებს მიჰყვება და არა shard-ების რაოდენობას.
ორივე შემთხვევაში sharding წერტილია, სადაც bot იაფი პროცესი აღარ არის და ინფრასტრუქტურა ხდება. თუ იქით მიდიხარ, გაზიარებული state ჯერ მეხსიერებიდან გამოიტანე, რადგან როგორც კი ერთზე მეტი პროცესია, ცვლადში არაფერი აღარ არის საიმედო.
სად მიდის მონაცემები#
პატარა bot-ის ნაგულისხმევი JSON ფაილია და ის მუშაობს, სანამ არ შეწყვეტს. ორი ჩავარდნის რეჟიმი, ორივე გავრცელებული:
- მთელი ფაილის ჩაწერა ყოველ ცვლილებაზე. რამდენიმე ასეულ კილობაიტზე და ჩაწერაზე თითო ბრძანებაზე ეს კარგადაა; რამდენიმე მეგაბაიტზე ის ყოველ ინტერაქციაზე შესამჩნევ შეფერხებად იქცევა, რადგან event loop დაბლოკილია სერიალიზაციისას.
- შუა ჩაწერისას მოკვლა. პროცესი, რომელიც
open-სა დაclose-ს შორის გაჩერდა, დამოკლებულ ფაილს ტოვებს და bot ვეღარ ამოდის. ყოველთვის ჩაწერე დროებით ფაილში იმავე საქაღალდეში დაrename-ით ჩააყენე ადგილზე, რაც ატომურია ნებისმიერ ჭკვიან ფაილურ სისტემაზე.
გადადი SQLite-ზე, როცა ფაილი მოუხერხებელი ხდება, რაც უმეტესი bot-ისთვის დაახლოებით იმ წერტილია, როცა გინდა მოთხოვნა და არა ყველაფრის ჩატვირთვა. SQLite ერთი ფაილია, სერვერს არ საჭიროებს და bot-ის ჩაწერის მოცულობას შეუმჩნევლად ართმევს თავს. გადადი ქსელურ მონაცემთა ბაზაზე, როცა ერთზე მეტი პროცესი გაქვს, როცა ორი რამ ერთდროულად წერს ან როცა მონაცემები მეხსიერებაში კომფორტულად აღარ ეტევა.
ჰოსტინგის მხარეს აპლიკაციის გეგმები მოიცავს ორ მონაცემთა ბაზის სლოტს, რომლებიც პანელში იქმნება და host-ს, მომხმარებელსა და პაროლს გიგენერირებს. უფრო დიდი ან ცალკე მასშტაბირებადი საცავისთვის არსებობს დამოუკიდებელი PostgreSQL და MongoDB ხაზები. Postgres თუ MongoDB პატიოსანი შედარებაა, ხოლო connection pool-ები და ზღვრები ფარავს შეცდომას, რომელსაც უმეტესი bot პირველად უშვებს: კავშირს ყოველი ბრძანებისთვის ხსნის და სერვერს ამოწურავს.
რასაც არ უნდა აირჩევდე, token და კავშირის სტრიქონი repository-ში არ ეკუთვნის. ჩადე ისინი გარემოს ცვლადებში Startup ტაბზე - გარემოს ცვლადები და საიდუმლოებები განმარტავს, რატომ და რა გააკეთო იმ დღეს, როცა ერთ-ერთი გაჟონავს.
გეგმის ზომები რეალური bot-ებისთვის#
აპლიკაციის ჰოსტინგის კიბე საორიენტაციოდ. ყველა დონეს ერთი და იგივე პანელი აქვს, ამიტომ აქ ფუნქციებზე არაფერია.
| Bot | მეხსიერება | CPU | გონივრული დონე |
|---|---|---|---|
| Slash ბრძანებები, 50 guild-ზე ნაკლები | 150-250 MB | 0.2 ბირთვზე ნაკლები | 1 GB, 0.5 vCPU |
| მოდერაცია ან ლოგირება, რამდენიმე ასეული guild | 300-700 MB | 0.2-0.5 ბირთვი | 2 GB, 1 vCPU |
| ეკონომიკა ან დონეები მონაცემთა ბაზით | 400 MB - 1 GB | 0.3-0.7 ბირთვი | 2-4 GB |
| მუსიკა, 1-3 ერთდროული ნაკადი | 400-800 MB | 0.5-1 ბირთვი | 2 GB, 1 vCPU |
| მუსიკა, 10+ ერთდროული ნაკადი | 1.5-3 GB | 2-3 ბირთვი | 6-8 GB, 2-3 vCPU |
| Sharded, 2,500+ guild (discord.js) | 250-400 MB თითო shard-ზე | 0.2 ბირთვი თითო shard-ზე | გაზომე, შემდეგ გაამრავლე |
დისკი იშვიათად არის შეზღუდვა, მაგრამ ერთ დახედვას იმსახურებს. discord.js პროექტი ხმის მხარდაჭერით 150-250 MB node_modules-ს ჩამოიტანს; Python-ის ვირტუალური გარემო ჩვეულებრივ უფრო მცირეა. დააყენე npm ci --omit=dev-ით, რომ build-ის dependency-ები არ მოჰყვეს. დისკის რეალური რისკია მუსიკის bot, რომელიც აუდიოს cache-ავს, და bot, რომელიც ლოგის ფაილს ბრუნვის გარეშე წერს; ორივე 5 GB გეგმას რამდენიმე თვეში ჩუმად ავსებს.
დაიწყე პატარათი. bot ჰოსტინგში ყველაზე ადვილად ზომაში მისადაგებადი დატვირთვაა უკან, რადგან მეხსიერების გრაფიკი კონსოლში ზუსტად გეუბნება, სად ხარ ზღვართან შედარებით, ხოლო დონის შეცვლა ზღვარს იმ სერვერზე ცვლის, რომელიც უკვე გაქვს და არა მის თავიდან აგებას.
ონლაინ დარჩენა: restart-ები, crash loop-ები და deploy-ები#
რისთვისაც ხალხი ჰოსტინგს ყიდულობს, არის ის, რომ bot ხვალაც მუშაობს. სამი დეტალი წყვეტს, ასე იქნება თუ არა.
დაუმუშავებელი rejection პროცესს კლავს. თანამედროვე Node-ში დაუმუშავებელი promise rejection პროცესს ნაგულისხმევად წყვეტს. დაამუშავე, ჩაწერე და დარწმუნდი, რომ ლოგირება გასვლამდე ხდება:
process.on("unhandledRejection", (error) => { console.error("unhandled rejection:", error);});process.on("SIGTERM", async () => { await client.destroy(); process.exit(0);});SIGTERM-ის დაჭერა და კლიენტის განადგურება უფრო მნიშვნელოვანია, ვიდრე ჩანს: bot, რომელიც websocket-ის დახურვის გარეშე მოკლეს, მის შემდეგ ერთ წუთამდე ონლაინ ჩანს, რაც restart-ს გაცილებით გრძელ გათიშვად აჩენს, ვიდრე ის იყო. გრაციოზული გამორთვა და health check-ები ზოგად შაბლონს შეიცავს.
მეხსიერების ზღვრის მიღწევა გრაციოზული მოვლენა არ არის. კონტეინერის ზღვარზე kernel პროცესს აჩერებს და ის სუფთად იწყება, swap-ში დატოვების ნაცვლად. ეს კარგი ნაგულისხმევია - bot-ის swap-ი restart-ზე უარესია - მაგრამ ნიშნავს, რომ შეუზღუდავი cache იჩენს თავს, როგორც იდუმალი restart ყოველ რამდენიმე საათში და არა ნელი დაცემა.
Crash loop შეიმჩნევა. watcher ორ-ორ წუთში ამოწმებს სერვერს, რომელიც გაითიშა ან რომლის uptime უკან წავიდა; შენ მიერ მოთხოვნილი restart-ები არ ითვლება. საათში სამი მოულოდნელი restart გაფრთხილებას სერვერის გვერდზე აჩენს და ავტომატურად ხსნის ticket-ს, ექვსი კი შეჩერებამდე მიდის. ეს პოლიტიკა არსებობს, რადგან bot, რომელიც ყოველ ოცი წამში თავიდან იწყება, gateway-ს ურტყამს და identify კვოტას წვავს, და ღირს ამის ცოდნა, სანამ შუაღამით ცვლილებას deploy-ავ და დაიძინებ. რატომ იწყება შენი გეიმ სერვერი განუწყვეტლივ თავიდან თავად ციკლის დიაგნოსტიკას ფარავს.
Deploy-ები მეორე ნახევარია. GitHub repository-ის მიბმა ორ გადამრთველს გაძლევს: pull ყოველ start-ზე და deploy push-ზე, რომელიც თავიდან მხოლოდ იმ სერვერს იწყებს, რომელიც უკვე მუშაობდა. ორივე ღირს bot-ზე, რადგან ალტერნატივა ფაილების SFTP-ით ატვირთვაა და დავიწყება, რომელი ვერსიაა ცოცხალი. სახელმძღვანელო არის Node.js აპლიკაციის deploy GitHub-იდან და Python-ზეც იმავენაირად მოქმედებს.
FAQ#
რამდენი RAM სჭირდება Discord bot-ს?
slash-ბრძანებების bot-ს რამდენიმე ათეულ სერვერში 150-250 MB სჭირდება, ამიტომ ყველაზე პატარა ხელმისაწვდომი გეგმა უკვე გულუხვია. მეხსიერება კითხვად მხოლოდ მაშინ იქცევა, როცა წევრებს cache-ავ, შეტყობინებებს cache-ავ, აუდიოს უკრავ ან state-ს ცვლადებში ინახავ. სანამ მეტს იყიდი, ერთი კვირა გაზომე მდგრადი მდგომარეობა.
რატომ იყენებს ჩემი bot მეტ მეხსიერებას, რაც მეტ სერვერზე შედის?
იმიტომ, რომ ბიბლიოთეკა ინახავს იმას, რასაც gateway აგზავნის, და gateway მეტს აგზავნის, როცა მეტია. გამოსავალი თითქმის ყოველთვის intent-ები და cache-ის ზღვრებია და არა უფრო დიდი გეგმა: გამორთე GUILD_PRESENCES, გამორთე წევრების chunking გაშვებისას და შეზღუდე შეტყობინებების cache.
უნდა გავყო თუ არა ჩემი bot shard-ებად?
არა, სანამ Discord არ მოითხოვს, რაც 2,500 guild-ზე მეტია. ჰკითხე gateway-ს, რა უნდა, GET /gateway/bot-ით და ნუ გამოიცნობ. ადრეული sharding პროცესებს, სირთულეს და discord.js-ში გამრავლებულ მეხსიერების ანგარიშს ამატებს სარგებლის გარეშე.
შემიძლია რამდენიმე bot ერთ გეგმაზე გავუშვა?
ტექნიკურად ორი პროცესი ერთ კონტეინერში ეტევა, მაგრამ ეს ცრუ დაზოგვაა: ისინი მეხსიერების ზღვარს და CPU შეზღუდვას იზიარებენ და ერთი crash-loop-ში მყოფი bot მეორესაც ჩამოაგდებს. ცალკე პატარა გეგმები დაზიანების რადიუსს მცირეს ინახავს და გრაფიკებს წაკითხვადს ხდის.
VDS ჯობია bot-ისთვის?
თუ ექვს-შვიდ პატარა სერვისს უშვებ, შეიძლება უფრო იაფი იყოს, რადგან მეხსიერება მათ შორის ერთიანდება. ერთი-ორი bot-ისთვის ეს მეტ სამუშაოს ნიშნავს, ვიდრე ზოგავს. VDS თუ გეიმ პანელი გადაკვეთის წერტილს სწორად გადის.
რატომ ჭედავს ჩემი მუსიკის bot, როცა რამდენიმე ადამიანი იყენებს?
CPU. ყოველი ნაკადი ტრანსკოდირებაა, გეგმაზე CPU მკაცრი შეზღუდვაა იმ წილამდე, რომელიც იყიდე, და როცა event loop შიმშილობს, აუდიო პაკეტები გვიან გადის და gateway heartbeat მათთან ერთად ასევე გვიან. უყურე CPU გრაფიკს, სანამ ეს ხდება; თუ ის შენს ზღვარზეა მიჯაჭვული, ეს არის შენი პასუხი.




კომენტარები
სრულიად ანონიმურად: ანგარიშის, ელფოსტის და cookie-ის გარეშე. ინახება მხოლოდ სახელი, ტექსტი და დრო - სხვა არაფერი. ბმულების რაოდენობა ლიმიტირებულია.