ഒരു വ്യൂ കൗണ്ട് (view count) ആണ് സന്ദർശകർ ആദ്യം വിശ്വസിക്കുന്ന സംഖ്യ. ഒരു വീഡിയോ കാണാൻ മുപ്പത് സെക്കൻഡ് വേണോ അതോ മുപ്പത് മിനിറ്റ് വേണോ എന്ന് അത് അവരെ അറിയിക്കുന്നു. TopVideoHub-ൽ ആ സംഖ്യ വളരെ വേഗത്തിൽ മാറിക്കൊണ്ടിരിക്കും. ട്രെൻഡിംഗ് ആയ ഒരു ക്ലിപ്പിന് പത്ത് മിനിറ്റിനുള്ളിൽ 40,000 വ്യൂസ് ലഭിച്ചേക്കാം. പേജിലെ കൗണ്ടർ നിശ്ചലമായാൽ, ആ പ്ലാറ്റ്ഫോം ശൂന്യമായി തോന്നും. ഉപയോക്താക്കൾ സൈറ്റ് വിട്ടുപോകും.
ആ സംഖ്യ ബ്രൗസറിൽ എത്തിക്കുക എന്നത് ലളിതമായി തോന്നാം. എന്നാൽ അതല്ല സത്യം. മിക്ക ടീമുകളും ആദ്യം പരീക്ഷിക്കുന്നത് polling ആണ്. ഇത് സെറ്റ് ചെയ്യാൻ എളുപ്പമാണ്, സ്റ്റേജിംഗ് (staging) എൻവയോൺമെന്റിൽ ഇത് നന്നായി പ്രവർത്തിക്കുകയും ചെയ്യും. എന്നാൽ സ്റ്റേജിംഗ് പലപ്പോഴും യഥാർത്ഥ സാഹചര്യങ്ങളെ പ്രതിഫലിപ്പിക്കാറില്ല.
പോളിംഗ് (Polling) എപ്പോഴാണ് നിങ്ങൾക്ക് തന്നെ ഒരു DDoS ആക്രമണമായി മാറുന്നത്
TopVideoHub ടീം ഒരു ലളിതമായ JavaScript poller നിർമ്മിച്ചു. ഇത് ഓരോ അഞ്ച് സെക്കൻഡിലും ഏറ്റവും പുതിയ വ്യൂ കൗണ്ട് ശേഖരിക്കുന്നുണ്ടായിരുന്നു. മൂന്ന് ബ്രൗസറുകൾ മാത്രം തുറന്നുള്ള ഒരു ടെസ്റ്റ് എൻവയോൺമെന്റിൽ ഇത് മികച്ച രീതിയിൽ പ്രവർത്തിച്ചു. എന്നാൽ പ്രൊഡക്ഷനിൽ (production), ഇത് പ്ലാറ്റ്ഫോമിനെ തകർത്തു കളഞ്ഞു.
ഓരോ അഞ്ച് സെക്കൻഡിലും റിഫ്രഷ് ചെയ്യുന്ന എണ്ണായിരം ഒരേസമയം കാണുന്ന കാഴ്ചക്കാർ (concurrent viewers) സെക്കൻഡിൽ 1,600 റിക്വസ്റ്റുകൾ ഉണ്ടാക്കി. ഓരോ റിക്വസ്റ്റും ഡാറ്റാബേസിലേക്ക് നേരിട്ട് ആഞ്ഞടിച്ചു. ഇതിന്റെ ഫലമായി replication lag വർദ്ധിക്കുകയും, read replicas തകരാറിലാകുകയും ചെയ്തു. കാഷെ ലെയറുകൾ (cache layers) ബൈപാസ് ചെയ്യപ്പെട്ടു. ടീം വീഡിയോ നൽകുകയല്ല, മറിച്ച് തങ്ങൾ തന്നെ ഉണ്ടാക്കിയ ഭാരം (self-inflicted load) ഡാറ്റാബേസിന് നൽകുകയായിരുന്നു.
പോളിംഗ് പ്രശ്നമുണ്ടാക്കുന്നത് വരെ അത് നിരപരാധിയാണ്. കുറഞ്ഞ ട്രാഫിക് ഉള്ള ഡാഷ്ബോർഡുകൾക്കോ അഡ്മിൻ പാനലുകൾക്കോ ഇത് കുഴപ്പമില്ല. എന്നാൽ ഒരു വൈറൽ വീഡിയോ പേജിന് ഇത് ഒരു ടിക്കിംഗ് ബോംബ് പോലെയാണ്. സെർവറിൽ നിന്ന് ബ്രൗസറിലേക്ക് ഒരു സ്ഥിരമായ കണക്ഷൻ (persistent pipe) ടീമിന് ആവശ്യമായിരുന്നു, എന്നാൽ ഒരു ഫുൾ-ഡ്യുപ്ലെക്സ് പ്രോട്ടോക്കോളിന്റെ (full-duplex protocol) സങ്കീർണ്ണത അവർക്ക് ആവശ്യമില്ലായിരുന്നു.
എന്തുകൊണ്ട് SSE വൺ-വേ പൈപ്പുകൾക്ക് (One-Way Pipes) അനുയോജ്യമാകുന്നു
സെർവർ-സെന്റ് ഇവന്റുകൾ (SSE) കൃത്യമായി ഇത്തരത്തിലുള്ള പ്രശ്നങ്ങൾ പരിഹരിക്കാനാണ് നിർമ്മിക്കപ്പെട്ടിരിക്കുന്നത്: സെർവറിന് ഡാറ്റയുണ്ട്, ബ്രൗസറിന് അത് കേൾക്കാൻ (listen) മാത്രമേ ആവശ്യമുള്ളൂ.
WebSockets-ൽ നിന്ന് വ്യത്യസ്തമായി, SSE സാധാരണ HTTP-യിലാണ് പ്രവർത്തിക്കുന്നത്. ഇത് കേൾക്കുന്നതിനേക്കാൾ വലിയ പ്രാധാന്യമുള്ള കാര്യമാണ്. നിങ്ങൾക്ക് പുതിയ പ്രോക്സി നിയമങ്ങളോ (proxy rules), അപ്ഗ്രേഡ് ഹെഡറുകളോ (upgrade headers), ലോഡ്-ബാലൻസർ ക്രമീകരണങ്ങളോ ആവശ്യമില്ല. നിങ്ങളുടെ സെർവർ HTTP/1.1 അല്ലെങ്കിൽ HTTP/2 ഉപയോഗിക്കുന്നുണ്ടെങ്കിൽ SSE പ്രവർത്തിക്കും. സ്ട്രീം വെറും ടെക്സ്റ്റ് ആയതുകൊണ്ട് ഡീബഗ്ഗിംഗ് (debugging) വളരെ എളുപ്പമാണ്. നിങ്ങൾക്ക് curl ഉപയോഗിച്ച് എൻഡ്പോയിന്റിലേക്ക് നോക്കി സംഖ്യകൾ തത്സമയം മാറുന്നത് കാണാം. ഒരു ബൈനറി സോക്കറ്റ് ഫ്രെയിം (binary socket frame) എന്തുകൊണ്ട് തെറ്റായിപ്പോയി എന്ന് ഊഹിക്കുന്നതിനേക്കാൾ ഇത് എളുപ്പമാണ്.
ബ്രൗസർ തന്നെ ബാക്കി സങ്കീർണ്ണമായ കാര്യങ്ങൾ സൗജന്യമായി ചെയ്തുതരുന്നു. കണക്ഷൻ നഷ്ടപ്പെട്ടാൽ, Last-Event-ID ഹെഡർ ഉപയോഗിച്ച് SSE തനിയെ വീണ്ടും കണക്ട് ചെയ്യും, അങ്ങനെ എവിടെ നിന്നാണ് തുടരേണ്ടതെന്ന് സെർവർക്ക് മനസ്സിലാകും. JavaScript-ലെ API വളരെ ലളിതമാണ്: ഒരു EventSource നിർമ്മിക്കുക, ഒരു onmessage ഹാൻഡ്ലർ ഘടിപ്പിക്കുക, അത്രമാത്രം.
കാഷിംഗ് (Caching) ആണ് യഥാർത്ഥ ആർക്കിടെക്ചർ
ലൈവ് കൗണ്ടറുകളിൽ സംഭവിക്കുന്ന ഏറ്റവും വലിയ ആർക്കിടെക്ചറൽ തെറ്റ്, ഓരോ ബ്രൗസർ കണക്ഷനും ഡാറ്റാബേസ് ക്വറി (query) ചെയ്യാനുള്ള കാരണമായി കാണുന്നതാണ്. 8,000 ആളുകൾ ഒരേ വീഡിയോ കാണുന്നുണ്ടെങ്കിൽ, ഓരോ രണ്ട് സെക്കൻഡിലും 8,000 ക്വറികൾ നടത്തുന്നത് ഭ്രാന്താണ്. വൈറൽ ട്രാഫിക് വന്നാൽ നിങ്ങളുടെ ഡാറ്റാബേസ് അതിനെ അതിജീവിക്കില്ല.
TopVideoHub ഇത് പരിഹരിച്ചത് PHP-യുടെ ഇൻ-മെമ്മറി ഓപ്കോഡ് (in-memory opcode) കാഷെ ആയ APCu ഉപയോഗിച്ചാണ്. ഇതിന്റെ രീതി ലളിതമാണ്. ഒരു ബാക്ക്ഗ്രൗണ്ട് പ്രോസസ്സ്—അല്ലെങ്കിൽ ഒരു ടൈമർ ഉപയോഗിച്ചുള്ള ലഘുവായ എൻഡ്പോയിന്റ്—ഓരോ രണ്ട് സെക്കൻഡിലും നിലവിലെ വ്യൂ കൗണ്ട് APCu-ലേക്ക് എഴുതുന്നു. ആയിരക്കണക്കിന് ബ്രൗസറുകൾ തുറന്നുപിടിച്ചിരിക്കുന്ന SSE എൻഡ്പോയിറ്റ്, APCu-ൽ നിന്ന് മാത്രം ഡാറ്റ വായിക്കുന്നു.
ഫലം: എത്ര കാഴ്ചക്കാർ ഉണ്ടെങ്കിലും, ഡാറ്റാബേസിന് ഓരോ രണ്ട് സെക്കൻഡിലും ഒരു തവണ മാത്രമേ റിക്വസ്റ്റ് ലഭിക്കുന്നുള്ളൂ. കാഷെ ഇവിടെ ഒരു ഷോക്ക് അബ്സോർബറായി (shock absorber) പ്രവർത്തിക്കുന്നു. APCu എന്നത് അത്ര സങ്കീർണ്ണമായ ഒന്നല്ല. ഇത് PHP-യോടൊപ്പം ലഭിക്കുന്നു, ഷെയർഡ് മെമ്മറിയിൽ (shared memory) പ്രവർത്തിക്കുന്നു, കൂടാതെ ഏത് നെറ്റ്വർക്ക് റൗണ്ട്-ട്രിപ്പിനേക്കാളും വേഗത്തിൽ ഡാറ്റ വായിക്കുന്നു. ഇടയ്ക്കിടെ മാറിക്കൊണ്ടിരിക്കുന്ന എന്നാൽ പെട്ടെന്ന് തന്നെ മാറേണ്ടതില്ലാത്ത ഒരു സംഖ്യയ്ക്ക് ഇത് അനുയോജ്യമായ ടൂളാണ്.
നിങ്ങൾ APCu ഉപയോഗിക്കുന്നില്ലെങ്കിൽ, Redis അല്ലെങ്കിൽ Memcached ഉപയോഗിച്ചാലും മതി. ഇതിന്റെ തത്വം ഒന്ന് തന്നെയാണ്: ഡാറ്റാബേസിൽ നിന്നുള്ള നേരിട്ടുള്ള റീഡ് പാത്ത് (read path) വേർതിരിക്കുക.
PHP, LiteSpeed, Cloudflare എന്നിവയെ സ്ട്രീമിംഗിനായി പ്രേരിപ്പിക്കുക
PHP വേഗത്തിൽ ജോലി തീർത്ത് നിർത്താൻ ആഗ്രഹിക്കുന്നു. വെബ് സെർവറുകൾ ഔട്ട്പുട്ട് ബഫർ (buffer) ചെയ്യാനും കൃത്യമായ ഒരു റെസ്പോൺസ് നൽകാനും ആഗ്രഹിക്കുന്നു. എന്നാൽ SSE-ക്ക് ഇതിന് വിപരീതമാണ് വേണ്ടത്: ഡാറ്റ ലഭിക്കുമ്പോൾ തന്നെ അത് അയച്ചുകൊണ്ടിരിക്കുന്ന (flushing bytes) ഒരു തുറന്ന കണക്ഷൻ. ശ്രദ്ധിച്ചില്ലെങ്കിൽ, നിങ്ങളുടെ "സ്ട്രീം" മുപ്പത് സെക്കൻഡിന് ശേഷം ഒരു വലിയ കൂട്ടമായി (single blob) എത്തും, ഇത് സ്ട്രീമിംഗിന്റെ ഉദ്ദേശ്യം തന്നെ ഇല്ലാതാക്കും.
TopVideoHub എങ്ങനെയാണ് ഈ കണക്ഷൻ തടസ്സമില്ലാതെ നിലനിർത്തിയത് എന്ന് നോക്കാം.
ഔട്ട്പുട്ട് ബഫറിംഗ് ഒഴിവാക്കുക (Kill output buffering). SSE സ്ക്രിപ്റ്റിന്റെ തുടക്കത്തിൽ, PHP ഉപയോഗിക്കുന്ന എല്ലാ ബഫറിംഗ് ലെയറുകളും ഡിസേബിൾ ചെയ്യുക. ഒരു ബഫർ ആക്റ്റീവ് ആണെങ്കിൽ ob_end_flush() വിളിക്കുക, കൂടാതെ ഹെഡറുകൾ അയച്ചതിന് ശേഷം ob_implicit_flush(true) ഉപയോഗിച്ച് ഇംപ്ലിസിറ്റ് ഫ്ലഷിംഗ് (implicit flushing) ഓഫ് ചെയ്യുക.
പ്രോക്സികളോട് ബഫറിംഗ് ഒഴിവാക്കാൻ പറയുക. X-Accel-Buffering: no എന്ന ഹെഡർ അയക്കുക. Nginx ഇത് ശ്രദ്ധിക്കുന്നുണ്ട്. LiteSpeed-ഉം ഇത് ശ്രദ്ധിക്കുന്നു. റെസ്പോൺസ് ബഫർ ചെയ്യാനോ അല്ലെങ്കിൽ ഒരു കാഷെബിൾ കട്ടയായി (cacheable lump) കംപ്രസ് ചെയ്യാനോ പാടില്ല എന്ന സന്ദേശമാണിത്.
കുറഞ്ഞ കാലാവധി നിശ്ചയിക്കുക. ഓരോ SSE കണക്ഷനും ഒരു PHP വർക്കറെ (worker) ഉപയോഗിക്കുന്നു. TopVideoHub സ്ട്രീമുകൾ 55 സെക്കൻഡിൽ പരിമിതപ്പെടുത്തുന്നു. സമയം കഴിയുമ്പോൾ, സെർവർ ഒരു അവസാന കമന്റ് അയച്ച് സ്ട്രീം ക്ലോസ് ചെയ്യുന്നു, തുടർന്ന് ബ്രൗസർ തനിയെ വീണ്ടും കണക്ട് ചെയ്യുന്നു. ഈ റീ-കണക്ഷൻ ഒരു പുതിയ വർക്കറിലേക്ക് എത്തുന്നു, ഇത് ഏതെങ്കിലും ഒരു പ്രോസസ്സ് ദീർഘനേരം തടഞ്ഞുവെക്കുന്നത് ഒഴിവാക്കുന്നു.
കണക്ഷൻ നിലനിർത്താൻ പിംഗ് (Ping) ഉപയോഗിക്കുക. ഓരോ ഇരുപത് സെക്കൻഡിലും : ping പോലുള്ള ഒരു കമന്റ് ലൈൻ അയക്കുക. SSE-യിലെ കമന്റുകൾ ബ്രൗസറിലെ മെസ്സേജ് ഹാൻഡ്ലർ അവഗണിക്കും, എന്നാൽ അവ TCP കണക്ഷൻ സജീവമായി നിലനിർത്തുന്നു. ലോഡ് ബാലൻസറുകളും (Load balancers) സിഡിഎൻകളും (CDNs) പലപ്പോഴും മുപ്പതോ അറുപതോ സെക്കൻഡിന് ശേഷം നിശബ്ദമായ കണക്ഷനുകൾ വിച്ഛേദിക്കാറുണ്ട്. ഒരു ചെറിയ ന്യൂലൈൻ (newline) ഉപയോഗിക്കുന്നത് ഇത്തരം പ്രശ്നങ്ങളിൽ നിന്ന് നിങ്ങളെ രക്ഷിക്കും.
ഉപയോക്താവിന്റെ ടാബിനെ (tab) മാനിക്കുക. ഒരു സന്ദർശകൻ ടാബ് മിനിമൈസ് ചെയ്യുകയോ മറച്ചു വെക്കുകയോ ചെയ്യുമ്പോൾ, കണക്ഷൻ അവസാനിപ്പിക്കുക. ബ്രൗസറിലെ visibilitychange നിരീക്ഷിക്കുകയും eventSource.close() വിളിക്കുകയും ചെയ്യുക. ക്ലയന്റ് ഡിസ്കണക്റ്റ് ചെയ്യുന്നത് സെർവറും തിരിച്ചറിയുകയും ലൂപ്പ് അവസാനിപ്പിക്കുകയും വേണം. PHP-യിൽ ഒരു ലൂപ്പിനുള്ളിൽ connection_aborted() ഉപയോഗിച്ച് ഇത് പരിശോധിക്കാം. പത്ത് മിനിറ്റ് മുമ്പ് പോയ ആളുകൾക്കായി 'ഗോസ്റ്റ് കണക്ഷനുകൾ' (ghost connections) വഴി വർക്കറുകളെ (workers) പാഴാക്കരുത്.
കഠിനമായ പരിധി: PHP Workers
PHP-യിലെ SSE അതിന്റെ പരിമിതികളെക്കുറിച്ച് വ്യക്തമാണ്. ഓരോ തുറന്ന SSE കണക്ഷനും ഒരു PHP വർക്കർ ഉപയോഗിക്കുന്നു. നിങ്ങളുടെ പൂളിൽ നൂറ് വർക്കറുകൾ ഉണ്ടെങ്കിൽ, നിങ്ങൾക്ക് നൂറ് സ്ട്രീമുകൾ മാത്രമേ ലഭിക്കൂ. അത്രമാത്രം. നിങ്ങൾ ഒരു Apache അല്ലെങ്കിൽ PHP-FPM പ്രോസസ് മോഡലിലാണെങ്കിൽ ഇതിന് മറ്റ് അസിങ്ക് (async) പരിഹാരങ്ങളില്ല. നിങ്ങൾക്ക് pm.max_children ക്രമീകരിക്കാം, പക്ഷേ മെമ്മറിയും CPU-യുമാണ് യഥാർത്ഥ പരിധി നിശ്ചയിക്കുന്നത്.
സാധാരണ പേജ് ലോഡുകൾക്കും, API കോളുകൾക്കും, അസറ്റ് ജനറേഷനും നിങ്ങൾ വർക്കറുകൾ ഉപയോഗിക്കുന്നുണ്ടെങ്കിൽ ഈ പരിധി വേഗത്തിൽ തിരിച്ചടിയാകും. നിങ്ങളുടെ വർക്കറുകളുടെ ഉപയോഗം (saturation) ശ്രദ്ധാപൂർവ്വം നിരീക്ഷിക്കുക. എല്ലാ വർക്കറുകളും ഇരുപത് മിനിറ്റ് നീണ്ടുനിൽക്കുന്ന സ്ട്രീമുകളിൽ കുടുങ്ങിക്കിടക്കുന്നത് കാരണം നിങ്ങളുടെ SSE എൻഡ്പോയിന്റ് ക്യൂ (queue) ആകാൻ തുടങ്ങിയാൽ, സൈറ്റ് മുഴുവൻ സ്ലോ ആകും.
കണക്കുകൾ താങ്ങാൻ കഴിയാതെ വരുമ്പോൾ, അടുത്ത ഘട്ടത്തിലേക്ക് മാറാം. Rust, Node.js അല്ലെങ്കിൽ Erlang എന്നിവ ഉപയോഗിക്കാമെങ്കിലും, സാധാരണയായി അടുത്ത ഘട്ടം Go ആണ്. Go-യിലെ goroutines ആണ് ഇതിന്റെ പ്രധാന ഘടകം. ഒരു goroutine-ന് ഏതാനും കിലോബൈറ്റുകൾ മാത്രമേ ചിലവ് വരുന്നുള്ളൂ. സാധാരണ ഹാർഡ്വെയറിൽ പോലും വലിയ പ്രയാസമില്ലാതെ പതിനായിരക്കണക്കിന് സ്ട്രീമുകൾ നിങ്ങൾക്ക് കൈകാര്യം ചെയ്യാം. അടിസ്ഥാന ലോജിക് മാറുന്നില്ല—cache-ൽ നിന്ന് വായിക്കുക, socket-ലേക്ക് എഴുതുക—എന്നാൽ റൺടൈം (runtime) ഭാരമേറിയ പ്രോസസുകളിൽ നിന്ന് ഭാരം കുറഞ്ഞ ത്രെഡുകളിലേക്ക് (lightweight threads) മാറുന്നു.
എങ്കിലും അവിടെ നിന്ന് തുടങ്ങരുത്. PHP ഉപയോഗിച്ച് നിങ്ങൾക്ക് അത്ഭുതകരമായ രീതിയിൽ മുന്നോട്ട് പോകാൻ കഴിയും. ആദ്യം ഉൽപ്പന്നം പരിശോധിക്കുക. ഡാറ്റാബേസ് ഓവർലോഡിന് പകരം വർക്കറുകൾ തീർന്നുപോകുന്നു എന്നാണ് മെട്രിക്സ് പേജ് കാണിക്കുന്നതെങ്കിൽ, നിങ്ങൾ നിലവിലുള്ള സ്റ്റാക്കിനെ (stack) മറികടന്നു എന്നാണ് അർത്ഥം. അത് ഒരു നല്ല പ്രശ്നമാണ്.
ചുരുക്കത്തിൽ
ലൈവ് കൗണ്ടറുകൾ വെറും സാങ്കേതികവിദ്യ മാത്രമല്ല. അവ നിങ്ങളുടെ ഡാറ്റാബേസിനെ ഉപയോക്താക്കളിൽ നിന്ന് സംരക്ഷിക്കുന്നതിനെക്കുറിച്ചാണ്. SSE ലളിതമാണ്, അതിനാൽ അത് ഉപയോഗിച്ച് തുടങ്ങുക. കണക്ഷൻ എണ്ണം ക്വറി എണ്ണമായി മാറാത്തതിന്, സ്ട്രീമും ഡാറ്റാബേസും തമ്മിൽ ശക്തമായ കാഷെ (cache) ഉപയോഗിക്കുക. നിങ്ങളുടെ വർക്കർ പരിധികൾ സൂക്ഷ്മമായി നിരീക്ഷിക്കുക. ലളിതമായി തുടങ്ങുക. അത് മതിയാകാത്തതുവരെ PHP മതിയാകും, അപ്പോഴേക്കും എന്തുകൊണ്ടാണ് നിങ്ങൾ ഇത് മാറ്റിവരയ്ക്കുന്നത് എന്ന് നിങ്ങൾക്ക് കൃത്യമായി അറിയാമായിരിക്കും.
നിങ്ങളുടെ അടുത്ത പ്രോജക്റ്റിനായി:
- ഡാറ്റ സർവറിൽ നിന്ന് ബ്രൗസറിലേക്ക് ഒരു വശത്തേക്ക് മാത്രം ഒഴുകുന്നുണ്ടെങ്കിൽ SSE ഉപയോഗിക്കുക.
- ഡാറ്റാബേസിന് മുന്നിൽ ഒരു കാഷെ ലെയർ (cache layer) നൽകുക. ഏതാനും സെക്കൻഡുകൾ കൂടുമ്പോൾ നടത്തുന്ന ഒരു ക്വറി ആയിരക്കണക്കിന് ക്വറികളേക്കാൾ നല്ലതാണ്.
- SSE കണക്ഷനുകൾ ഒരു മിനിറ്റിൽ താഴെയായി പരിമിതപ്പെടുത്തുക, ബ്രൗസറിനെ വീണ്ടും കണക്ട് ചെയ്യാൻ അനുവദിക്കുക.
- ടാബ് മറയ്ക്കുമ്പോൾ സ്ട്രീമുകൾ ക്ലോസ് ചെയ്യുക. ഉപയോഗശൂന്യമായ കണക്ഷനുകൾക്കായി വർക്കറുകളെ പാഴാക്കരുത്.
- PHP വർക്കർ ഉപയോഗം നിരീക്ഷിക്കുക. പരിധിയിൽ എത്തുമ്പോൾ സ്ട്രീമിംഗ് ലെയർ Go-യിലേക്ക് മാറ്റുക.
