Computer >> कंप्यूटर >  >> प्रोग्रामिंग >> Ruby

रेल अनुप्रयोगों पर रूबी में HTTP कैशिंग

कैशिंग का वर्णन करने का एक सामान्य तरीका कुछ डेटा संग्रहीत करना है ताकि हम इसे बाद में जल्दी से प्राप्त कर सकें। कभी-कभी, इसका अर्थ है गणना किए गए डेटा को संग्रहीत करना ताकि इसे फिर से गणना करने की आवश्यकता न हो, लेकिन यह डेटा को फिर से लाने से बचने के लिए स्थानीय रूप से संग्रहीत करने का भी उल्लेख कर सकता है। आपका कंप्यूटर लगातार ऐसा करता है, क्योंकि आपका ऑपरेटिंग सिस्टम रैम में बार-बार एक्सेस किए जाने वाले डेटा को रखने की कोशिश करता है ताकि इसे फिर से हार्ड ड्राइव या एसएसडी से प्राप्त न करना पड़े।

इसी तरह, आपका ब्राउज़र पहले से डाउनलोड किए गए संसाधनों का पुन:उपयोग करने का प्रयास करता है। पहली बार किसी नई वेबसाइट पर जाने पर आपने शायद इसे स्वयं देखा होगा। आरंभिक लोड में अधिक समय लगता है क्योंकि आपके ब्राउज़र को सब कुछ को नीचे खींचना होता है इसकी जरूरत है, सभी छवियों, जावास्क्रिप्ट और स्टाइलशीट सहित। एक मजेदार तथ्य यह है कि जब आप सीएनएन होमपेज को नए सिरे से डाउनलोड करते हैं, तो आपका ब्राउज़र मूल डूम गेम की तुलना में 1993 के आसपास अधिक डेटा प्राप्त करता है। जिज्ञासु के लिए, इस ब्लॉग पोस्ट को लिखते समय, सीएनएन मेरी मशीन पर सिर्फ 3 एमबी से अधिक डाउनलोड करता है, से संपीड़ित ~15MB, और वह है एक विज्ञापन अवरोधक सक्षम होने के साथ, जबकि मूल डूम इंस्टॉलर ~2.2MB था।

इस डेटा को कैश करने के लिए ब्राउज़र के लिए सर्वर के साथ कुछ समन्वय होना चाहिए। ब्राउज़र को यह जानने की जरूरत है कि वह क्या कैश कर सकता है और कितने समय तक; अन्यथा, सर्वर के पास एक नया संस्करण उपलब्ध होने पर यह आपको पुरानी सामग्री दिखा सकता है। इस लेख में, हम देखेंगे कि यह क्लाइंट-सर्वर कैशिंग समन्वय कैसे किया जाता है और इसे बदलने के लिए रेल क्या प्रदान करता है।

यद्यपि ध्यान इस बात पर है कि रूबी ऑन रेल्स इसे कैसे संभालता है, वास्तविक तंत्र HTTP विनिर्देशों का हिस्सा है। दूसरे शब्दों में, हम यहां जिस कैशिंग के बारे में बात कर रहे हैं, वह इंटरनेट के बुनियादी ढांचे में बेक की गई है, जो इसे आधुनिक वेबसाइटों और ढांचे के विकास की आधारशिला बनाती है। विभिन्न ढांचे, जैसे रेल, सिंगल-पेज एप्लिकेशन (एसपीए), और यहां तक ​​​​कि स्थिर साइटें, सभी इन तंत्रों का उपयोग प्रदर्शन को बेहतर बनाने में मदद के लिए कर सकते हैं।

HTTP अनुरोध-प्रतिक्रिया

आप शायद अनुरोध-प्रतिक्रिया जीवनचक्र से परिचित हैं, कम से कम उच्च स्तर पर:आप किसी वेबसाइट पर एक लिंक पर क्लिक करते हैं, आपका ब्राउज़र उस सामग्री के लिए सर्वर को एक अनुरोध भेजता है, और सर्वर उस सामग्री को वापस भेजता है (ध्यान दें कि मैं मैं यहाँ बहुत सारी जटिलताओं को जान-बूझकर दिखा रहा हूँ)।

आइए इस आगे-पीछे के लेन-देन में भेजे जा रहे वास्तविक डेटा में थोड़ा खुदाई करें। प्रत्येक HTTP संदेश में एक हेडर और एक बॉडी होती है (<head> . के साथ भ्रमित नहीं होना चाहिए और <body> एचटीएमएल टैग)। अनुरोध शीर्षलेख सर्वर को बताता है कि आप किस पथ तक पहुंचने का प्रयास कर रहे हैं और किस HTTP विधि का उपयोग करना है (उदाहरण के लिए, प्राप्त/पुट/पैच/पोस्ट)। यदि आवश्यक हो, तो आप अपने ब्राउज़र के डेवलपर टूल या कमांड-लाइन टूल, जैसे curl का उपयोग करके इन शीर्षलेखों में खुदाई कर सकते हैं :

# curl -v honeybadger.io
...
> GET / HTTP/1.1
> Host: honeybadger.io
> User-Agent: curl/7.64.1
> Accept: */*

आउटपुट का यह पहला भाग अनुरोध शीर्षलेख है। हम एक GET जारी कर रहे हैं करने के लिए honeybadger.io . इसके बाद सर्वर ने क्या भेजा ("प्रतिक्रिया शीर्षलेख"):

>
< HTTP/1.1 301 Moved Permanently
< Cache-Control: public, max-age=0, must-revalidate
< Content-Length: 39
< Content-Security-Policy: frame-ancestors 'none'
...
< Content-Type: text/plain

प्रतिक्रिया में HTTP कोड शामिल होता है (उदा., 200 सफलता के लिए या 404 के लिए नहीं मिला)। इस उदाहरण में, यह एक स्थायी रीडायरेक्ट (301) है क्योंकि कर्ल http . से संपर्क करने का प्रयास कर रहा है यूआरएल, जो सुरक्षित https . पर रीडायरेक्ट करता है URL.प्रतिक्रिया शीर्षलेख में सामग्री प्रकार भी शामिल है, जो text/plain है यहाँ, लेकिन कुछ अन्य सामान्य विकल्प हैं text/html , text/css , text/javascript , और application/json

प्रतिक्रिया निकाय हेडर का अनुसरण करता है। हमारे मामले में, शरीर खाली है क्योंकि एक 301 रीडायरेक्ट को शरीर की आवश्यकता नहीं है। अगर हमने curl -v https://www.honeybadger.io . के साथ फिर से कोशिश की , आपको यहां मुखपृष्ठ सामग्री दिखाई देगी, ठीक वैसे ही जैसे आप किसी ब्राउज़र में स्रोत देख रहे थे।

यदि आप स्वयं इसका प्रयोग करना चाहते हैं तो यहां दो युक्तियां दी गई हैं:

  1. केवल कर्ल के साथ प्रतिक्रिया शीर्षलेख दिखाने के लिए (उदाहरण के लिए, कोई अनुरोध शीर्षलेख या प्रतिक्रिया निकाय नहीं), -I का उपयोग करें विकल्प, जैसा कि curl -I localhost:3000 में है ।
  2. डिफ़ॉल्ट रूप से, रेल विकास के माहौल में कैश नहीं करता है; आपको rails dev:cache चलाने की आवश्यकता हो सकती है पहले।

कैश-कंट्रोल HTTP हैडर

जहां तक ​​कैशिंग की बात है, हम जिस मुख्य हेडर की परवाह करते हैं, वह है Cache-Control शीर्षलेख। यह निर्धारित करने में मदद करता है कि कौन सी मशीनें हमारे रेल सर्वर से प्रतिक्रिया को कैश कर सकती हैं और जब वह कैश्ड डेटा समाप्त हो जाता है। Cache-Control के अंदर शीर्षलेख, कई फ़ील्ड हैं, जिनमें से अधिकांश वैकल्पिक हैं। हम यहां कुछ सबसे प्रासंगिक प्रविष्टियों के माध्यम से जाएंगे, लेकिन अधिक जानकारी के लिए, आप आधिकारिक HTTP विनिर्देश w3.org पर देख सकते हैं।

बुनियादी आउट-ऑफ़-द-बॉक्स रेल प्रतिक्रिया शीर्षलेख से एक नमूना यहां दिया गया है:

< Content-Type: text/html; charset=utf-8
< Etag: W/"b41ce6c6d4bde17fd61a09e36b1e52ad"
< Cache-Control: max-age=0, private, must-revalidate

अधिकतम-आयु

max-age फ़ील्ड एक पूर्णांक है जिसमें प्रतिक्रिया मान्य होने वाले सेकंड की संख्या होती है। डिफ़ॉल्ट रूप से, एक दृश्य के लिए एक रेल प्रतिक्रिया में यह 0 पर सेट होगा (यानी, प्रतिक्रिया तुरंत समाप्त हो जाती है, और ब्राउज़र को हमेशा एक नया संस्करण मिलना चाहिए)।

सार्वजनिक/निजी

public . सहित या private हेडर सेट में किन सर्वरों को प्रतिक्रिया को कैश करने की अनुमति है। यदि शीर्षलेख में private शामिल है , इसे केवल अनुरोध करने वाले क्लाइंट (उदाहरण के लिए, ब्राउज़र) द्वारा कैश किया जाना है, न कि किसी अन्य सर्वर से जो इसे प्राप्त करने के लिए गुजरा हो, जैसे कि सामग्री वितरण नेटवर्क (सीडीएन) या प्रॉक्सी। यदि शीर्षलेख में public शामिल है , तो इन मध्यस्थ सर्वरों को प्रतिक्रिया को कैश करने की अनुमति है। रेल प्रत्येक शीर्षलेख को private . पर सेट करती है डिफ़ॉल्ट रूप से।

अत्यावश्यक-पुनरीक्षित करें

रेल्स must-revalidate भी सेट करते हैं डिफ़ॉल्ट रूप से फ़ील्ड। इसका अर्थ यह है कि क्लाइंट को यह पुष्टि करने के लिए सर्वर से संपर्क करना चाहिए कि इसका कैश्ड संस्करण उपयोग किए जाने से पहले अभी भी मान्य है। यह निर्धारित करने के लिए कि कैश्ड संस्करण मान्य है, क्लाइंट और सर्वर ईटैग का उपयोग करते हैं।

ईटैग

ईटैग एक वैकल्पिक HTTP शीर्षलेख है जो सर्वर द्वारा तब जोड़ा जाता है जब यह क्लाइंट को प्रतिक्रिया भेजता है। आमतौर पर, यह प्रतिक्रिया पर ही किसी प्रकार का चेकसम होता है। जब क्लाइंट (यानी, आपके ब्राउज़र) को इस संसाधन के लिए फिर से अनुरोध करने की आवश्यकता होती है, तो इसमें If-None-Match में इसे प्राप्त एटैग (यह मानते हुए कि इसकी पिछली प्रतिक्रिया कैश की गई है) शामिल है। HTTP हेडर। सर्वर तब 304 . के साथ प्रतिसाद दे सकता है HTTP कोड ("संशोधित नहीं") और एक खाली बॉडी। इसका मतलब है कि सर्वर पर संस्करण नहीं बदला है, इसलिए क्लाइंट को इसके कैश्ड संस्करण का उपयोग करना चाहिए।

ईटैग दो प्रकार के होते हैं:मजबूत और कमजोर (एक कमजोर टैग को W/ से दर्शाया जाता है। उपसर्ग)। वे उसी तरह व्यवहार करते हैं, लेकिन एक मजबूत ईटीएजी का मतलब है कि संसाधन की दो प्रतियां (सर्वर पर संस्करण और स्थानीय कैश में एक) 100% बाइट-फॉर-बाइट समान हैं। कमजोर ईटैग, हालांकि, इंगित करते हैं कि दो प्रतियां बाइट-दर-बाइट समान नहीं हो सकती हैं, लेकिन कैश्ड संस्करण का अभी भी उपयोग किया जा सकता है। इसका एक सामान्य उदाहरण है रेल्स का csrf_meta_tags सहायक, जो एक टोकन बनाता है जो लगातार बदलता रहता है; इस प्रकार, भले ही आपके आवेदन में एक स्थिर पृष्ठ हो, क्रॉस-साइट-अनुरोध-जालसाजी (सीएसआरएफ) टोकन के कारण रीफ्रेश होने पर यह बाइट-फॉर-बाइट समान नहीं होगा। रेल डिफ़ॉल्ट रूप से कमजोर ईटैग का उपयोग करती है।

रेल में Etags

रेल स्वचालित रूप से विचारों पर ईटैग को संभालती है। इसमें आउटगोइंग हेडर में ETag शामिल है और इसमें आने वाले ETag हेडर की जांच करने के लिए मिडलवेयर है और 304 लौटाता है (संशोधित नहीं) कोड जब उपयुक्त हो। विशेष रूप से, हालांकि, क्योंकि रेल गतिशील रूप से विचार उत्पन्न करता है, इससे पहले कि वह उस दृश्य के लिए ईटीएजी को समझ सके, उसे अभी भी सभी प्रतिपादन कार्य करना होगा। इसका मतलब यह है कि भले ही ईटैग मेल खाते हों, आप केवल उस समय और बैंडविड्थ की बचत कर रहे हैं, जो पूरे नेटवर्क में डेटा भेजने में लगता है, जैसा कि व्यू कैशिंग जैसी किसी चीज के विपरीत है, जहां कैश्ड संस्करण होने पर आप रेंडरिंग चरण को पूरी तरह से छोड़ सकते हैं। हालाँकि, रेल जनरेट किए गए ETag को बदलने के लिए कुछ तरीके प्रदान करता है।

बासी?

ETag को बदलने से हमेशा बदलते CSRF टोकन को दूर करने का एक तरीका stale? के साथ है ActionController में सहायक . यह आपको सीधे ETag (या तो मजबूत या कमजोर) सेट करने की अनुमति देता है। हालांकि, आप इसे केवल एक ऑब्जेक्ट पास कर सकते हैं, जैसे कि एक ActiveRecord मॉडल, और यह ऑब्जेक्ट के updated_at के आधार पर ETag की गणना करेगा। टाइमस्टैम्प या अधिकतम updated_at . का उपयोग करें अगर आप कोई संग्रह पास करते हैं:

class UsersController < ApplicationController
  def index
    @users = User.includes(:posts).all

    render :index if stale?(@users)
  end
end

पृष्ठ को कर्ल से मारकर, हम परिणाम देख सकते हैं:

# curl -I localhost:3000 -- first page load
ETag: W/"af9ae8f2d66b9b6c4d0513f185638f1a"
# curl -I localhost:3000 -- reload (change due to CSRF token)
ETag: W/"f06158417f290334f47ea2124e08d89d"

-- Add stale? to controller code

# curl -I localhost:3000 -- reload
ETag: W/"04b9b99835c359f36551720d8e3ca6fe" -- now using `@users` to generate ETag
# curl -I localhost:3000 -- reload
ETag: W/"04b9b99835c359f36551720d8e3ca6fe" -- no change

यह हमें उस पर अधिक नियंत्रण देता है जब क्लाइंट को फिर से पूरा पेलोड डाउनलोड करना होता है, लेकिन उसे अभी भी सर्वर से हर बार जांचना पड़ता है। यह निर्धारित करने के लिए कि इसका कैश अभी भी मान्य है या नहीं। क्या होगा अगर हम उस चेक को पूरी तरह से छोड़ना चाहते हैं? यह वह जगह है जहां max-age हेडर में फ़ील्ड आता है।

समाप्त_इन और http_cache_forever

रेल हमें ActionController . में कुछ सहायक तरीके प्रदान करती है max-age को समायोजित करने के लिए फ़ील्ड:expires_in और http_cache_forever . वे दोनों काम करते हैं कि आप उनके नाम के आधार पर क्या उम्मीद करेंगे:

class UsersController < ApplicationController
  def index
    @users = User.includes(:posts).all

    expires_in 10.minutes
  end
end
# curl -I localhost:3000
Cache-Control: max-age=600, private

रेल ने max-age सेट किया है 600 (सेकंड में 10 मिनट) तक और must-revalidate . को हटा दिया खेत। आप private भी बदल सकते हैं public: true . पास करके फ़ील्ड नामित तर्क।

http_cache_forever ज्यादातर expires_in . के आसपास सिर्फ एक आवरण है जो max-age सेट करता है 100 साल तक और एक ब्लॉक लेता है:

class UsersController < ApplicationController
  def index
    @users = User.includes(:posts).all

    http_cache_forever(public: true) do
      render :index
    end
  end
end
# curl -I localhost:3000
Cache-Control: max-age=3155695200, public

इस प्रकार की अत्यंत-दीर्घकालिक-कैशिंग यही कारण है कि रेल की संपत्ति में एक "फिंगरप्रिंट" जोड़ा जाता है, जो फ़ाइल की सामग्री का हैश है और फ़ाइल नाम बनाता है, जैसे कि packs/js/application-4028feaf5babc1c1617b.js . अंत में "फिंगरप्रिंट" फ़ाइल की सामग्री को फ़ाइल के नाम से प्रभावी ढंग से जोड़ता है। यदि सामग्री कभी बदलती है, तो फ़ाइल नाम बदल जाएगा। इसका अर्थ है कि ब्राउज़र इस फ़ाइल को हमेशा के लिए सुरक्षित रूप से कैश कर सकते हैं क्योंकि अगर यह कभी बदलता है, तो एक छोटे से तरीके से भी, फिंगरप्रिंट बदल जाएगा; जहां तक ​​ब्राउज़र का संबंध है, यह एक पूरी तरह से अलग फ़ाइल है जिसे डाउनलोड करने की आवश्यकता है।

क्षेत्रों का प्रभाव

अब जबकि हमने कुछ कैशिंग विकल्पों को शामिल कर लिया है, मेरी सलाह थोड़ी अजीब लग सकती है, लेकिन मेरा सुझाव है कि आप इस आलेख में किसी भी तरीके का उपयोग करने से बचने का प्रयास करें! ईटैग और एचटीटीपी कैशिंग के बारे में जानना अच्छा है, और रेल हमें विशिष्ट समस्याओं के समाधान के लिए कुछ विशिष्ट उपकरण प्रदान करता है। चेतावनी, हालांकि, और यह एक बड़ी बात है, यह सभी कैशिंग आपके आवेदन के बाहर होती है और इसलिए, काफी हद तक आपके नियंत्रण से बाहर है। यदि आप रेल में व्यू कैशिंग या निम्न-स्तरीय कैशिंग का उपयोग कर रहे हैं, जैसा कि इस श्रृंखला के पहले के हिस्सों में शामिल किया गया है, और अमान्यता के मुद्दों का सामना करते हैं, तो आपके पास विकल्प हैं; आप touch कर सकते हैं मॉडल, अपडेट किए गए कोड को पुश करें, या यहां तक ​​कि Rails.cache . तक पहुंचें यदि आपको करना है तो सीधे कंसोल से, लेकिन HTTP कैशिंग के साथ नहीं। व्यक्तिगत रूप से, मुझे Rails.cache.clear चलाने के बजाय बहुत कुछ करना होगा उत्पादन में एक समस्या का सामना करना पड़ता है जहां उपयोगकर्ताओं के लिए साइट तब तक टूट जाती है जब तक कि वे अपना ब्राउज़र कैश साफ़ नहीं कर देते (आपकी ग्राहक सेवा टीम आपको इसके लिए भी प्यार करेगी)।

निष्कर्ष

यह रेल में कैशिंग पर श्रृंखला का अंत है; उम्मीद है, यह उपयोगी और जानकारीपूर्ण था। कैशिंग के लिए मेरी सलाह इस प्रकार है:जितना हो सके उतना कम करें, लेकिन जितना आपको करना है उतना करें। यदि आप प्रदर्शन समस्याओं का अनुभव करते हैं, तो उन तरीकों की तलाश शुरू करें जो अक्सर हिट होते हैं; शायद, उन्हें याद किया जा सकता है। अनुरोधों में बने रहने के लिए मूल्य की आवश्यकता है? हो सकता है कि अत्यधिक उपयोग की जाने वाली विधि कुछ निम्न-स्तरीय कैशिंग का उपयोग कर सके। या, शायद, यह कोई विशेष तरीका नहीं है; यह सिर्फ उन सभी नेस्टेड पार्टिकल्स के माध्यम से क्रंच कर रहा है, जो चीजों को धीमा कर रहे हैं; इस मामले में, शायद देखें स्तर कैशिंग मदद कर सकता है। इनमें से प्रत्येक मुद्दे को लक्षित करने के लिए रेल हमें "तेज चाकू" देता है, और हमें केवल यह जानना होगा कि उनका उपयोग कब करना है।


  1. रूबी डेवलपर्स के लिए डेटा संरचनाओं का अवलोकन

    डेटा संरचना क्या है? डेटा संरचना डेटा को व्यवस्थित और एक्सेस करने का एक विशिष्ट तरीका है । उदाहरणों में शामिल हैं: सरणी बाइनरी ट्री हैश विभिन्न डेटा संरचनाएं अलग-अलग कार्यों में उत्कृष्ट होती हैं। उदाहरण के लिए, यदि आप शब्दकोश (शब्द और परिभाषा), या फ़ोन बुक (व्यक्ति का नाम और संख्या) जैसा दिखन

  1. रूबी के साथ कमांड-लाइन एप्लिकेशन (सीएलआई) कैसे बनाएं?

    बहुत से लोग भूल जाते हैं कि रूबी ऐसे काम कर सकती है जो वेब एप्लिकेशन नहीं हैं। इस लेख में, मैं आपको दिखाना चाहता हूं कि इसका समाधान करने में मदद के लिए एक कमांड-लाइन एप्लिकेशन कैसे बनाया जाए! यहां कुछ कमांड-लाइन एप्लिकेशन दिए गए हैं जिनसे आप परिचित हो सकते हैं: psql rails bundler gem git कम

  1. रूबी ऑन रेल्स क्या है और यह क्यों उपयोगी है?

    रूबी ऑन रेल्स (कभी-कभी RoR) सबसे लोकप्रिय ओपन-सोर्स वेब एप्लिकेशन फ्रेमवर्क है। इसे रूबी प्रोग्रामिंग भाषा के साथ बनाया गया है। आप अनुप्रयोगों को बनाने में मदद करने के लिए रेल का उपयोग कर सकते हैं, सरल से जटिल तक, रेल के साथ आप क्या हासिल कर सकते हैं इसकी कोई सीमा नहीं है! ढांचा क्या है? फ़्रेम