ഡെഡ് കണക്ഷനുകളില്ലാതെ ഡാറ്റാബേസുകളെ ഉണർത്തൽ
Mythex-ലെ പ്രസിദ്ധീകരിച്ച ആപ്പുകളും അവയുടെ ഡാറ്റാബേസുകളും ആരും ഉപയോഗിക്കാത്തപ്പോൾ ഉറങ്ങാൻ പോകുന്നു. ഒരു ആപ്പ് ഉണരുമ്പോൾ, എല്ലാം ഉറങ്ങിക്കിടന്നപ്പോൾ മരിച്ചുപോയ ഡാറ്റാബേസ് കണക്ഷനുകൾ വീണ്ടും ഉപയോഗിക്കാൻ ശ്രമിച്ചതിനാൽ, അതിന്റെ ആദ്യ അഭ്യർത്ഥന 10–12 സെക്കൻഡ് വരെ തടഞ്ഞുവയ്ക്കാമായിരുന്നു. ഇപ്പോൾ Spring Boot ആപ്പുകൾക്ക് ഉറക്കത്തിന് സുരക്ഷിതമായ ഡാറ്റാബേസ് ക്രമീകരണങ്ങൾ നൽകുന്നു, കൂടാതെ ഏത് സ്റ്റാക്കിലുള്ള ആപ്പുകളും ഇതേ രീതിയിൽ നിർമ്മിക്കാൻ ഏജന്റിനോട് പറയുന്നു. ഹോസ്റ്റിംഗ് പ്ലാറ്റ്ഫോമിൽ, ഉണർന്നതിന് ശേഷമുള്ള ആദ്യ അഭ്യർത്ഥന 12.7 സെക്കൻഡിൽ നിന്ന് 2.3 സെക്കൻഡായി.
ആപ്പുകളും ഡാറ്റാബേസുകളും ഉറങ്ങുന്നത് എന്തുകൊണ്ട്
പ്രസിദ്ധീകരിച്ച ഒരു Mythex ആപ്പ് കുറച്ച് നിഷ്ക്രിയ മിനിറ്റുകൾക്ക് ശേഷം സസ്പെൻഡ് ആകുന്ന ഒരു മെഷീനിലാണ് പ്രവർത്തിക്കുന്നത്, അതിന്റെ ഡാറ്റാബേസ് അഞ്ച് നിഷ്ക്രിയ മിനിറ്റുകൾക്ക് ശേഷം ഉറങ്ങുകയും അടുത്ത അഭ്യർത്ഥനയിൽ ഉണരുകയും ചെയ്യുന്ന സെർവർലെസ് Postgres ആണ്. ശാന്തമായ ഒരു ആപ്പ് വിലകുറഞ്ഞതായി നിലനിർത്തുന്നത് ഇതാണ്: ഡാറ്റാബേസ് യഥാർത്ഥത്തിൽ ഉപയോഗിച്ചതിന് നിങ്ങൾ പണം നൽകുന്നു, ഉറങ്ങുന്ന ആപ്പ് കമ്പ്യൂട്ടിന് ഒന്നും ചെലവാക്കുന്നില്ല. ബില്ലിംഗ് വശത്തെക്കുറിച്ച് ഞങ്ങൾ ഡാറ്റാബേസുകളെ അവ യഥാർത്ഥത്തിൽ ഉപയോഗിക്കുന്നതിനനുസരിച്ച് ബിൽ ചെയ്യുന്നത് എന്നതിൽ എഴുതിയിട്ടുണ്ട്.
പിടികിട്ടുന്നത്, രണ്ടും വെവ്വേറെ ഉറങ്ങുന്നു, ഒരു കണക്ഷൻ എന്താണെന്നതിനെക്കുറിച്ച് അവ യോജിക്കുന്നില്ല എന്നതാണ്.
ലക്ഷണം: ആദ്യ സന്ദർശനം മന്ദം
മിക്ക സെർവർ ആപ്പുകളും ഒരു കണക്ഷൻ പൂൾ സൂക്ഷിക്കുന്നു: ഡാറ്റാബേസ് കണക്ഷനുകളുടെ ഒരു ചെറിയ എണ്ണം തുറന്ന് തയ്യാറായി വയ്ക്കുന്നു, അതിനാൽ ഓരോ അഭ്യർത്ഥനയും പുതിയത് തുറക്കുന്നതിന്റെ ചെലവ് നൽകേണ്ടതില്ല. എപ്പോഴും പ്രവർത്തിക്കുന്ന ഒരു ആപ്പിന് ഇത് ശരിയായ രൂപകൽപ്പനയാണ്.
ഉറക്കത്തോടെ ഇവിടെ സംഭവിക്കുന്നത് ഇതാണ്:
- ആപ്പ് പ്രവർത്തിക്കുന്നു, പൂളിൽ കുറച്ച് നിഷ്ക്രിയ കണക്ഷനുകളുണ്ട്.
- ആരും സന്ദർശിക്കുന്നില്ല. ആപ്പിന്റെ മെഷീൻ സസ്പെൻഡ് ആകുന്നു — മരവിച്ച്, പൂൾ കേടുകൂടാതെ.
- ഡാറ്റാബേസ് ഉറങ്ങുകയും ഓരോ കണക്ഷന്റെയും അതിന്റെ അറ്റം ഉപേക്ഷിക്കുകയും ചെയ്യുന്നു.
- ഒരു സന്ദർശകൻ എത്തുന്നു. ആപ്പ് ഉള്ളത് പോലെ തന്നെ ഉണരുന്നു, ഡാറ്റാബേസിന് ഇനി അറിയാത്ത കണക്ഷനുകൾ ഇപ്പോഴും പിടിച്ചിരിക്കുന്നു.
- പൂൾ ആ കണക്ഷനുകളിലൊന്ന് നൽകുന്നു. അത് മരിച്ചതാണെന്ന് കണ്ടെത്താൻ — ശ്രമിച്ച് കാത്തിരുന്ന ശേഷം — അത് ഉപേക്ഷിക്കുന്നതിന് മുമ്പ് അതിന് കഴിയണം.
Spring Boot ആപ്പിൽ, ആ മരിച്ച കണക്ഷനുകൾ പരിശോധിക്കുന്നത് ആദ്യ അഭ്യർത്ഥനയെ ഏകദേശം 10 സെക്കൻഡ് തടഞ്ഞുവച്ചു, തുടർന്ന് "Connection is not available" എന്ന പിശകോടെ അത് പരാജയപ്പെട്ടു. സന്ദർശകന് സൈറ്റ് വെറുതെ ഹാങ്ങ് ആയതായി തോന്നി, പിന്നീട് ഒരു പിശക് കാണിച്ചേക്കാം.
Spring ആപ്പുകൾക്ക് ഏറ്റവും മോശം പ്രശ്നം എന്തുകൊണ്ട്
Spring Boot ഒരു ജനപ്രിയ Java ഫ്രെയിംവർക്ക് ആണ്, ഡിഫോൾട്ടായി HikariCP എന്ന കണക്ഷൻ പൂൾ ഉപയോഗിക്കുന്നു. നിഷ്ക്രിയ കണക്ഷനുകൾ എത്ര സൂക്ഷിക്കണമെന്നതുൾപ്പെടെ ക്രമീകരണങ്ങളിൽ നിന്ന് Spring ആ പൂളിനെ കോൺഫിഗർ ചെയ്യാൻ കഴിയും.
പക്ഷേ Mythex ഓരോ ആപ്പിനും അതിന്റെ ഡാറ്റാബേസ് postgresql://user:pass@host/db രൂപത്തിലുള്ള ഒരൊറ്റ DATABASE_URL ആയി നൽകുന്നു. Spring-ന് ആ ഫോർമാറ്റ് നേരിട്ട് വായിക്കാൻ കഴിയില്ല. അതിനാൽ Mythex-ൽ നിർമ്മിച്ച Spring ആപ്പുകൾ ആ URL പാഴ്സ് ചെയ്ത് കോഡിൽ സ്വന്തം പൂൾ നിർമ്മിച്ചിരുന്നു — കൈകൊണ്ട് നിർമ്മിച്ച പൂൾ Spring-ന്റെ spring.datasource.* ക്രമീകരണങ്ങളെ മുഴുവൻ അവഗണിക്കുന്നു. ശരിയായ പൂൾ ക്രമീകരണങ്ങൾ ആർക്കെങ്കിലും അറിയാമായിരുന്നാലും, അവ പ്രാബല്യത്തിൽ വരാൻ ഒരിടവുമുണ്ടായിരുന്നില്ല.
പരിഹാരം, ഭാഗം 1: Spring ഉപയോഗിക്കാവുന്ന ക്രമീകരണങ്ങൾ
ഒരു പ്രോജക്റ്റിന് ഡാറ്റാബേസ് ഉള്ളപ്പോൾ, ഇപ്പോൾ Spring നേരിട്ട് വായിക്കുന്ന എൻവയോൺമെന്റ് വേരിയബിളുകളും നൽകുന്നു:
SPRING_DATASOURCE_URL,SPRING_DATASOURCE_USERNAME,SPRING_DATASOURCE_PASSWORD—DATABASE_URL-ൽ നിന്ന് പരിവർത്തനം ചെയ്തത് (URL മറ്റൊന്ന് പറയുന്നില്ലെങ്കിൽ SSL ആവശ്യമാണ്).- ഉറക്കം കഴിഞ്ഞും നിലനിൽക്കുന്ന പൂൾ ക്രമീകരണങ്ങൾ:
| ക്രമീകരണം | മൂല്യം | കാരണം |
|---|---|---|
| കുറഞ്ഞ നിഷ്ക്രിയ കണക്ഷനുകൾ | 0 | അഭ്യർത്ഥനകൾക്കിടയിൽ ഒന്നും തുറന്നുവയ്ക്കരുത്, അതിനാൽ പഴകാൻ ഒന്നുമില്ല |
| നിഷ്ക്രിയ സമയപരിധി | 30 സെക്കൻഡ് | ഉപയോഗിക്കാത്ത കണക്ഷനുകൾ വേഗം അടയ്ക്കുക |
| പരമാവധി ആയുസ്സ് | 2 മിനിറ്റ് | പഴകുന്നതിന് മുമ്പ് ഓരോ കണക്ഷനും വിരമിപ്പിക്കുക |
| കണക്ഷൻ സമയപരിധി | 5 സെക്കൻഡ് | ഡാറ്റാബേസ് മറുപടി നൽകാൻ വൈകിയാൽ അഭ്യർത്ഥന ദീർഘനേരം തടയരുത് |
ഒരു നിഷ്ക്രിയ കണക്ഷനും തുറന്നുവയ്ക്കാത്തതിനാൽ, ഉണർന്ന ആപ്പ് മരിച്ചവയിലൂടെ കടന്നുപോകുന്നതിന് പകരം ഒരു പുതിയ കണക്ഷൻ മാത്രം തുറക്കുന്നു.
ഈ വേരിയബിളുകൾ ഉണ്ടാകുമ്പോൾ, Spring പൂൾ സ്വയം കോൺഫിഗർ ചെയ്യുന്നു, ക്രമീകരണങ്ങൾ പ്രാബല്യത്തിൽ വരുന്നു. പ്രോജക്റ്റ് സ്വയം സജ്ജമാക്കിയത് എപ്പോഴും മുൻതൂക്കം നേടുന്നു; ഇല്ലാത്തത് മാത്രമാണ് ഞങ്ങൾ നിറയ്ക്കുന്നത്. Spring അല്ലാത്ത ആപ്പുകൾ ഈ വേരിയബിളുകളെ അവഗണിക്കുന്നു.
ഏതാണ്ട് ഒന്നും ചെയ്യാതിരുന്ന വിശദാംശം
Spring എൻവയോൺമെന്റ് വേരിയബിളുകളെ അതിന്റെ ക്രമീകരണങ്ങളിലേക്ക് മാപ്പ് ചെയ്യുന്നത് തെറ്റിക്കാൻ എളുപ്പമുള്ള ഒരു നിയമം അനുസരിച്ചാണ്. minimum-idle ക്രമീകരണം SPRING_DATASOURCE_HIKARI_MINIMUMIDLE എന്ന് എഴുതണം — ഡാഷുകൾ ഒഴിവാക്കി, വാക്കുകൾ ചേർത്ത്. സ്വാഭാവികമെന്ന് തോന്നുന്ന SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE എന്ന് എഴുതിയാൽ, അത് മറ്റൊരു, നിലവിലില്ലാത്ത ക്രമീകരണത്തിലേക്ക് (minimum.idle) മാപ്പ് ചെയ്യപ്പെടുകയും നിശബ്ദമായി അവഗണിക്കപ്പെടുകയും ചെയ്യും.
അത്തരം തെറ്റ് എല്ലാ അവലോകനങ്ങളും കടന്നുപോകും, പ്രൊഡക്ഷനിൽ ഒന്നും ചെയ്യുകയുമില്ല. അതിനാൽ ഒരു ടെസ്റ്റ് മൂല്യങ്ങൾ സജ്ജമാക്കിയിട്ടുണ്ടോയെന്നും ഒരു വേരിയബിളും അടിവരയിട്ട് വേർതിരിച്ച രൂപം ഉപയോഗിക്കുന്നില്ലെന്നും പരിശോധിക്കുന്നു.
പരിഹാരം, ഭാഗം 2: മറ്റെല്ലാ സ്റ്റാക്കുകളും
Spring മാത്രമല്ല പൂൾ ഉള്ള ഫ്രെയിംവർക്ക്, എല്ലാ ഭാഷകളിലെയും എല്ലാ ലൈബ്രറികളെയും മുൻകൂട്ടി കോൺഫിഗർ ചെയ്യാൻ ഞങ്ങൾക്ക് കഴിയില്ല. അതിനാൽ നിങ്ങളുടെ ആപ്പ് എഴുതുന്ന Mythex ഏജന്റിന് — ഇപ്പോൾ ഏത് സ്റ്റാക്കിനും ഒരു സ്ഥിര നിർദ്ദേശം ലഭിക്കുന്നു: പ്രസിദ്ധീകരിച്ച ആപ്പുകളും അവയുടെ ഡാറ്റാബേസുകളും നിഷ്ക്രിയമാകുമ്പോൾ ഉറങ്ങുന്നു, അതിനാൽ തുറന്നുവച്ച കണക്ഷൻ അടുത്ത അഭ്യർത്ഥനയിൽ മരിച്ചിരിക്കാം. അത് ഇവ ചെയ്യണം:
- നിഷ്ക്രിയ ഡാറ്റാബേസ് കണക്ഷനുകളൊന്നും തുറന്നുവയ്ക്കാതിരിക്കുക, അല്ലെങ്കിൽ ഉപയോഗിക്കുന്നതിന് മുമ്പ് ഓരോന്നും പരിശോധിക്കുക,
- കണക്ഷൻ പിശകിൽ ഒരു തവണ വീണ്ടും ശ്രമിക്കുക, കൂടാതെ
- പൂൾ നിർമ്മിക്കാൻ
DATABASE_URLപാഴ്സ് ചെയ്യുന്നതിന് പകരം, എൻവയോൺമെന്റിൽ പ്ലാറ്റ്ഫോം നൽകുന്ന ഡാറ്റാബേസ് ക്രമീകരണങ്ങൾ ഉപയോഗിക്കുക.
ആ അവസാന പോയിന്റ് ഭാഗം 1-മായി ലൂപ്പ് അടയ്ക്കുന്നു: നൽകിയ ക്രമീകരണങ്ങളിൽ നിർമ്മിച്ച ആപ്പ് ഉറക്കത്തിന് സുരക്ഷിതമായ കോൺഫിഗറേഷൻ സ്വയമേവ എടുക്കുന്നു.
ഫലം
ഞങ്ങൾ പ്രസിദ്ധീകരിച്ച ആപ്പുകൾ പ്രവർത്തിപ്പിക്കുന്ന ഹോസ്റ്റിംഗ് പ്ലാറ്റ്ഫോമിൽ അളന്നപ്പോൾ, ഉണർന്നതിന് ശേഷമുള്ള ആദ്യ അഭ്യർത്ഥന 12.7 സെക്കൻഡിൽ നിന്ന് 2.3 സെക്കൻഡായി കുറഞ്ഞു.
ഞങ്ങൾ ഇതിൽ നിന്ന് പഠിച്ചത്
- ഓരോ ഉറങ്ങുന്ന ലെയറും എന്ത് നിലനിൽക്കുമെന്ന് യോജിക്കണം. മരവിച്ച ആപ്പും ഉറങ്ങുന്ന ഡാറ്റാബേസും ഓരോന്നും ന്യായമായ തീരുമാനമെടുത്തു. ഒരുമിച്ച്, ആപ്പ് ഇനി സത്യമല്ലാത്ത അവസ്ഥയുമായി ഉണർന്നു.
- എപ്പോഴും പ്രവർത്തിക്കുന്ന സെർവറുകൾക്കായി രൂപകൽപ്പന ചെയ്ത ഡിഫോൾട്ടുകൾ പൂജ്യത്തിലേക്ക് സ്കെയിൽ ചെയ്യുന്ന ആപ്പുകൾക്ക് യോജിക്കില്ല. കണക്ഷനുകൾ ചൂടോടെ നിലനിർത്തുന്നത് ചുറ്റുമുള്ളതെല്ലാം തണുക്കുന്നത് വരെ നല്ല ആശയമാണ്.
- ഫ്രെയിംവർക്കുകൾക്ക് അവരുടെ ഡാറ്റ അവരുടെ സ്വന്തം ഫോർമാറ്റിൽ നൽകുക. ഒരൊറ്റ URL ഞങ്ങൾക്ക് ലളിതമായിരുന്നു, പക്ഷേ എല്ലാ Spring ആപ്പും സ്വന്തം ക്രമീകരണങ്ങളെ അവഗണിക്കുന്ന ഒരു പൂൾ കൈകൊണ്ട് നിർമ്മിക്കാൻ അത് നിർബന്ധിച്ചു.
- ഒരു ക്രമീകരണം ഫ്രെയിംവർക്ക് വായിക്കുന്ന രീതിയിൽ തന്നെയാണോ എഴുതിയിരിക്കുന്നതെന്ന് പരീക്ഷിക്കുക. തെറ്റായ പേരിലുള്ള ശരിയായ മൂല്യം നിശബ്ദമായി ഒന്നും ചെയ്യില്ല.
Mythex-ലെ ഡാറ്റാബേസുകൾ എങ്ങനെ പ്രവർത്തിക്കുന്നു എന്നതിനെക്കുറിച്ച് പരിചയമുണ്ടെങ്കിൽ, ഡാറ്റാബേസ് ഡോക്സ് കാണുക, കൂടാതെ Postgres എന്താണെന്നതിന്റെ വിശദീകരണവും വായിക്കുക.