2011-02-25 19 views
6

मेरे पास एक वसंत एमवीसी आराम सेवा है जो एक्सएमएल में डेटा लौटाती है। मैं इस एक्सएमएल प्रतिक्रिया को कैश करना चाहता हूं। इसे कैसे प्राप्त किया जा सकता है? एमवीसी का उपयोग कर ऐसा करना संभव है: इंटरसेप्टर?कैश HTTP प्रतिक्रिया स्प्रिंग एमवीसी आराम सेवा

उत्तर

5

आप यह काम कर सकते हैं, लेकिन मुझे लगता है कि बेहतर समाधान हैं।

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

आप सभी एक साथ अलग कैशिंग तंत्र का उपयोग करने से बेहतर संभावना है। मैं वेब सर्वर स्तर पर कैशिंग की सलाह देते हैं। यह विशेष रूप से सच है यदि आप इंटरसेप्टर स्तर में कैश करना चाहते हैं क्योंकि यह वेब सर्वर के लिए सही "अगला" है और मुझे वहां पहिया को फिर से आविष्कार करने में कोई लाभ नहीं दिख रहा है। अपाचे में कैश मॉड्यूल है। तो nginx करता है। वार्निश भी बहुत बढ़िया है।

मुझे यह भी जिक्र करना चाहिए कि आपको तब तक कैश नहीं करना चाहिए जब तक कि आपने यह निर्धारित नहीं किया है कि आपको (समय से पहले अनुकूलित करने की आवश्यकता नहीं है)। यह आपके समय और प्रयास का अपशिष्ट है। दूसरा, जब आपने यह निर्धारित किया है कि आपके पास प्रदर्शन समस्याएं हैं जिन्हें ठीक करने की आवश्यकता है (और कैशिंग सही समाधान है), तो आपको सही जगह पर सही डेटा कैश करना चाहिए।

अब, कहें कि आपने यह निर्धारित किया है कि आपके पास प्रदर्शन समस्या है और कुछ प्रकार का कैशिंग एक अच्छा समाधान है। निर्धारित करने के लिए अगली बात यह है कि कैश किया जा सकता है। यदि, प्रत्येक यूआरएल के लिए, आप एक ही डेटा वापस करते हैं, तो वेब सर्वर पर कैशिंग (अपाचे, nginx, वार्निश, आदि) स्तर आपकी सबसे अच्छी शर्त होगी।

अक्सर, आपके पास ऐसे मामले होंगे जहां दो ग्राहक एक ही यूआरएल पर क्लिक करेंगे और अलग-अलग डेटा प्राप्त करेंगे। यह फेसबुक जैसी साइट पर सबसे आसानी से देखा जाता है। जब मैं अपने दोस्त की तुलना में लॉग इन करता हूं तो मैं अलग-अलग डेटा देखता हूं। इस मामले में, आप वेब सर्वर स्तर पर कैश करने में सक्षम नहीं होंगे। आपको अपने आवेदन के अंदर कैश करने की आवश्यकता होगी। आमतौर पर इसका मतलब डेटाबेस स्तर पर कैशिंग है।

0

आवेदन स्तर पर, मैं एक सादा जावा कैश के साथ ईएचसीएच के रूप में जाऊंगा। ईएचसीएच स्प्रिंग बीन्स पर विधियों के साथ एकीकृत करने के लिए बहुत आसान है। आप @Cacheable के रूप में अपनी सेवा विधियों को एनोटेट कर सकते हैं और यह हो गया है। इसे EHCache Spring Annotations पर देखें।

HTTP स्तर पर, स्प्रिंग एमवीसी एक उपयोगी ETag filter प्रदान करता है। लेकिन मुझे लगता है कि यह बेहतर होगा अगर आप इस स्तर के कैशिंग को सर्वर स्तर पर ऐप स्तर से अधिक कॉन्फ़िगर कर सकें।

4

मैं समाधान के अनुकूलन भाग से असहमत नहीं हो सका।

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

यूएस तट-से-तट विलंबता एक अच्छे दिन पर लगभग 50ms है, इसलिए प्रत्येक कनेक्शन को 150ms जुर्माना होता है, जो कि प्रत्येक अनुरोध के लिए अधिकांश कार्यान्वयन के लिए किया जाता है।

क्लाइंट-साइड पर प्रतिक्रिया कैशिंग पूरी तरह से इस विलंबता को हटा देती है, और यदि सेवा में उनके प्रतिक्रिया पर सही शीर्षलेख हैं, तो यह मामूली है। यदि वे नहीं करते हैं, तो आपको एक कैशिंग नीति को परिभाषित करना होगा, जो कि अधिकांश भाग विशेष रूप से कठिन नहीं है।अधिकांश एपीआई कॉल या तो रीयल-टाइम हैं या नहीं।

मेरी राय में, सीईसीटी प्रतिक्रियाएं कैचिंग समयपूर्व अनुकूलन नहीं है, यह सामान्य ज्ञान है।

+0

अधिक जानकारी के उपयोगी –

-1

स्प्रिंग 3.1 के रूप में, आप @Cachable एनोटेशन का उपयोग कर सकते हैं। सशर्त कैशिंग के लिए भी समर्थन है, और कुछ अच्छे भाषण नियंत्रण के लिए @CachePut, @CacheEvict और @Caching जैसे कुछ भाई एनोटेशन भी हैं।

स्प्रिंग वर्तमान में दो अलग-अलग cache managers, एक है कि एक ConcurrentHashMap और एक कि ehcache के द्वारा समर्थित है के द्वारा समर्थित है समर्थन करता है।

आखिरकार, enable एनोटेशन के बारे में विवरण पढ़ने के लिए मत भूलना।

2

मैं इसका उपयोग करता हूं और यह शानदार गति के साथ काम करता है।

1) नियंत्रक:: सच आसान वसंत + ehcache उपयोग करने के लिए

@Cacheable("my.json") 
    @RequestMapping("/rest/list.json") 
    public ResponseEntity list(@RequestParam(value = "page", defaultValue = "0", required = false) 
           int pageNum, 
           @RequestParam(value = "search", required = false) 
           String search) throws IOException { 
    ... 
    } 

2) ehcache.xml पर इस तरह की कुछ:

<cache name="my.json" maxElementsInMemory="10000" eternal="true" overflowToDisk="false"/> 

3) वसंत कॉन्फ़िगर करें। मैं वसंत javaconf शैली का उपयोग कर रहा हूँ:

@Configuration 
@EnableCaching 
public class ApplicationConfiguration { 


    @Bean 
    public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() throws MalformedURLException { 
     EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean(); 
     ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml")); 
     return ehCacheManagerFactoryBean; 
    } 

    @Bean 
    @Autowired 
    public EhCacheCacheManager cacheManager(EhCacheManagerFactoryBean ehcache) { 
     EhCacheCacheManager ehCacheCacheManager = new EhCacheCacheManager(); 
     ehCacheCacheManager.setCacheManager(ehcache.getObject()); 
     return ehCacheCacheManager; 
    } 
} 
+2

यह काम नहीं कर सकता है किया जाएगा। ResponseEntity Serializable नहीं है और ऐप एक अपवाद – Dan

+0

फेंक देगा @Dan ResponseEntity के साथ ठीक काम करता है – hakamairi

0

वसंत कैश का उपयोग न करें जो आपको चाहिए वह नहीं है। आपको अपने सर्वर पर लोड को कम करने की आवश्यकता है, न कि अपने आंतरिक वसंत अनुप्रयोग निष्पादन को तेज करें।

कुछ HTTP से संबंधित कैशिंग रणनीतियों का उपयोग करने का प्रयास करें।

आप अपने अनुरोध

#cache expires in 3600 seconds 
cache-control: private, max-age=3600 

#hash of your content 
ETag: "e6811cdbcedf972c5e8105a89f637d39-gzip" 

# redirect caching to any HTTP header 
vary: User-Agent 

Detailed description of caching techniques

स्प्रिंग उदाहरण के लिए HTTP-एक हेडर का जोड़ सकते हैं

@RequestMapping (value = "/resource/1.pdf", produces = "application/octet-stream") 
public ResponseEntity<InputStreamResource> getAttachement (@RequestParam (value = "id") Long fileId) 
{ 
    InputStreamResource isr = new InputStreamResource(javaInputStream); 
    HttpHeaders headers = new HttpHeaders(); 
    //other headers 
    headers.setCacheControl("private, max-age=3600"); 
    return new ResponseEntity<>(irs, headers, HttpStatus.OK); 

} 
संबंधित मुद्दे