RESTful के साथ स्प्रिंग बूट / MVC / JavaConfig के साथ GZIP संपीड़न का उपयोग करना


96

हम RESTfulसेवाओं की श्रृंखला के लिए एनोटेशन-आधारित जावा-कॉन्फिगरेशन के साथ स्प्रिंग बूट / एमवीसी का उपयोग करते हैं और हम HTTP GZIPकुछ एपीआई प्रतिक्रियाओं पर स्ट्रीम संपीड़न को चुनिंदा रूप से सक्षम करना चाहते हैं ।

मुझे पता है कि मैं अपने नियंत्रक और ए में मैन्युअल रूप से ऐसा कर सकता हूं byte[] @ResponseBody, हालांकि हम स्प्रिंगएमवीसी इंफ्रास्ट्रक्चर (फिल्टर / आदि) पर भरोसा करना पसंद करेंगे और यह स्वचालित रूप से JSON रूपांतरण और संपीड़न (यानी विधि एक POJO लौटाता है) करेगा।

मैं रिस्पांसबॉडी या एम्बेडेड टॉमकैट उदाहरण में GZIP संपीड़न कैसे सक्षम कर सकता हूं, और एक तरह से हम केवल चुनिंदा प्रतिक्रियाओं को संकुचित कर सकते हैं?

धन्यवाद!

पुनश्च: हमारे पास वर्तमान में कोई XML आधारित कॉन्फ़िगरेशन नहीं है।


आपको GzipFilter को देखना चाहिए ।
लगभग १३:१३ बजे

2
एचटीटीपीएस के साथ HTTP संपीड़न का उपयोग न करें जब तक कि आप यह नहीं जानते कि आप क्या कर रहे हैं
नील मैकगिन

जवाबों:


189

इनमें से शेष उत्तर पुराने हैं और / या कुछ के लिए शीर्ष पर जटिल हैं जो कि सरल होना चाहिए IMO (अब के लिए gzip कितना लंबा हो गया है? जावा की तुलना में लंबे समय तक ...) डॉक्स से:

Application.properties में 1.3+

# 🗜️🗜️🗜️
server.compression.enabled=true
# opt in to content types
server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css
# not worth the CPU cycles at some point, probably
server.compression.min-response-size=10240 

ऐप्लिकेशन में। 1.2.2 - <1.3 पर

server.tomcat.compression=on
server.tomcat.compressableMimeTypes=application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css

1.2.2 से अधिक पुराना:

@Component
public class TomcatCustomizer implements TomcatConnectorCustomizer {

  @Override
  public void customize(Connector connector) {
    connector.setProperty("compression", "on");
    // Add json and xml mime types, as they're not in the mimetype list by default
    connector.setProperty("compressableMimeType", "text/html,text/xml,text/plain,application/json,application/xml");
  }
}

यह भी ध्यान दें कि यदि आप एम्बेडेड टोमैट चला रहे हैं तो यह केवल काम करेगा:

यदि आप एक गैर-एम्बेडेड टोमसैट पर तैनात करने की योजना बनाते हैं, तो आपको इसे server.xml http://tomcat.apache.org/tomcat-9.0-doc/config/http.html#Standard_mplementation में सक्षम करना होगा।

IRL उत्पादन नोट:

इसके अलावा इस सब से बचने के लिए nginx और / या haproxy के साथ Tomcat के सामने एक प्रॉक्सी / लोड बैलेंसर सेटअप का उपयोग करने पर विचार करें क्योंकि यह स्थैतिक संपत्ति और gzip MUCH को अधिक कुशलता से और आसानी से जावा / Tomcat के थ्रेडिंग मॉडल की तुलना में संभाल लेगा।

आप स्नान में बिल्ली को फेंकना नहीं चाहते हैं क्योंकि यह अनुरोधों की सेवा करने के बजाय सामान को संपीड़ित करने में व्यस्त है (या अधिक संभावना है कि थ्रेड्स खाएं / सीपीयू / हीप के चारों ओर बैठे डेटाबेस IO के इंतजार में बैठे रहें, जबकि आपका AWS बिल जो चल रहा है क्यों पारंपरिक जावा / टॉम्कट एक अच्छा विचार नहीं हो सकता है कि आप जो कर रहे हैं उसके आधार पर शुरू करें लेकिन मैं पचाता हूं ...)

Refs: https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/html/howto.html#how-to-enable-http-response-compression

https://github.com/spring-projects/spring-boot/issues/2031


1.2.2 से पुराने संस्करणों के लिए आपका दृष्टिकोण काम नहीं करेगा क्योंकि स्प्रिंग बूट TomcatConnectorCustomizerएप्लिकेशन संदर्भ में उदाहरणों की तलाश नहीं करता है; उन्हें प्रोग्रामिक रूप से पंजीकृत होना हैTomcatEmbeddedServletContainerFactory
एंडी विल्किंसन

सर उठाने के लिए धन्यवाद। मैंने इसे तब तक देना छोड़ दिया जब से यह स्थिर / गतिशील / टॉमकैट / बनाम बूट लगता है अभी भी एक मुद्दा था। इस तरह से यह होना चाहिए की तुलना में कठिन है ... Nginx रिवर्स प्रॉक्सी FTW!
जॉन कुल्विनर

3
SpringBoot में, नए गुणों server.compression.enabled कर रहे हैं = सच और server.compression.mime-प्रकार = XXX, YYY github.com/spring-projects/spring-boot/wiki/...
blacelle

2
यदि स्प्रिंग बूट के लिए हमारे पास JSON प्रतिक्रियाएं देने वाले सभी बाकी नियंत्रक हैं। क्या हम कुछ नियंत्रकों पर चुनिंदा रूप से ज़िप लगा सकते हैं?

3
आपको संपीड़न के लिए न्यूनतम प्रतिक्रिया आकार का भी उल्लेख करना चाहिए (उदाहरण: 10KB) अन्यथा यह सर्वर के लिए हर (पूर्व: 0.5KB) अनुरोध को ओवरहेड करने के लिए ओवरहेड हो जाता है। server.compression.min-response-size=10240
उस्माअमजाद

13

application.ymlकॉन्फ़िगरेशन में संस्करणों को पुन: बनाता है:

---

spring:
  profiles: dev

server:
  compression:
    enabled: true
    mime-types: text/html,text/css,application/javascript,application/json

---

इसी बग रिपोर्ट और फिक्स जहां यह बदल दिया गया था github.com/spring-projects/spring-boot/issues/2737
McLovin

12

यह मूल रूप से @ -y-wilkinson के रूप में एक ही समाधान है, लेकिन स्प्रिंग बूट 1.0 के रूप में अनुकूलित (...) विधि का एक विन्यास योग्य है। SbedletContainer पैरामीटर।

एक और बात जो ध्यान देने योग्य है, वह यह है कि टॉमकैट केवल सामग्री प्रकारों को संकुचित करता है text/html, text/xmlऔर text/plainडिफ़ॉल्ट रूप से। नीचे एक उदाहरण दिया गया है जो कम्प्रेशन का समर्थन करता है application/json:

@Bean
public EmbeddedServletContainerCustomizer servletContainerCustomizer() {
    return new EmbeddedServletContainerCustomizer() {
        @Override
        public void customize(ConfigurableEmbeddedServletContainer servletContainer) {
            ((TomcatEmbeddedServletContainerFactory) servletContainer).addConnectorCustomizers(
                    new TomcatConnectorCustomizer() {
                        @Override
                        public void customize(Connector connector) {
                            AbstractHttp11Protocol httpProtocol = (AbstractHttp11Protocol) connector.getProtocolHandler();
                            httpProtocol.setCompression("on");
                            httpProtocol.setCompressionMinSize(256);
                            String mimeTypes = httpProtocol.getCompressableMimeTypes();
                            String mimeTypesWithJson = mimeTypes + "," + MediaType.APPLICATION_JSON_VALUE;
                            httpProtocol.setCompressableMimeTypes(mimeTypesWithJson);
                        }
                    }
            );
        }
    };
}

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

2
Accept-Encoding: gzip,deflateयदि आप कर्ल का उपयोग कर रहे हैं, तो हेडर को निर्दिष्ट करके सत्यापित करने का प्रयास करें :curl -i -H 'Accept-Encoding: gzip,deflate' http://url.to.your.server
matsev

9

स्प्रिंग बूट 1.4 जावास्क्रिप्ट कंप्लीट सभी जावास्क्रिप्ट के लिए इसका उपयोग करें।

server.compression.enabled: true
server.compression.mime-types: application/json,application/xml,text/html,text/xml,text/plain,text/css,application/javascript

हम इस संपीड़न को कैसे सत्यापित करते हैं?
भार्गव

@ भार्गव अपने आपी की प्रतिक्रिया की प्रतिक्रिया हेडर देखें। इसमें शीर्षलेख शामिल होना चाहिए Content-Encoding:gzip
सुमित झा


6

टॉमकैट में Enabeling GZip ने मेरे स्प्रिंग बूट प्रोजेक्ट में काम नहीं किया। मैंने यहां पाए जाने वाले CompressingFilter का इस्तेमाल किया ।

@Bean
public Filter compressingFilter() {
    CompressingFilter compressingFilter = new CompressingFilter();
    return compressingFilter;
}

@ user1127860 tnx यह काम करता है लेकिन फिर भी इस फ़िल्टर को और कॉन्फ़िगर करने के लिए? मैं वसंत बूट का उपयोग करता हूँ और खिचड़ी भाषा में इनमैट पैरामेट्स जोड़ने के लिए कहते हैं। web
स्प्रिंग

5

GZIP संपीड़न को सक्षम करने के लिए, आपको एम्बेडेड टोमैट उदाहरण के कॉन्फ़िगरेशन को संशोधित करने की आवश्यकता है। ऐसा करने के लिए, आप EmbeddedServletContainerCustomizerअपने जावा कॉन्फ़िगरेशन में सेम घोषित करते हैं और फिर TomcatConnectorCustomizerइसके साथ पंजीकरण करते हैं।

उदाहरण के लिए:

@Bean
public EmbeddedServletContainerCustomizer servletContainerCustomizer() {
    return new EmbeddedServletContainerCustomizer() {
        @Override
        public void customize(ConfigurableEmbeddedServletContainerFactory factory) {
            ((TomcatEmbeddedServletContainerFactory) factory).addConnectorCustomizers(new TomcatConnectorCustomizer() {
                @Override
                public void customize(Connector connector) {
                    AbstractHttp11Protocol httpProtocol = (AbstractHttp11Protocol) connector.getProtocolHandler();
                    httpProtocol.setCompression("on");
                    httpProtocol.setCompressionMinSize(64);
                }
            });
        }
    };
}

उपलब्ध विभिन्न संपीड़न कॉन्फ़िगरेशन विकल्पों के बारे में अधिक जानकारी के लिए टॉमकैट प्रलेखन देखें ।

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

यदि यह आपकी आवश्यकताओं को पूरा नहीं करता है, तो मेरा मानना ​​है कि आपको अपने नियंत्रक में संपीड़न करना होगा और एक gzip सामग्री-एन्कोडिंग हेडर के साथ एक बाइट [] प्रतिक्रिया वापस करनी होगी।


1
एप्लिकेशन को सेटिंग में डालने के विकल्प के आपके उत्तर के बीच क्या अंतर है। server.compression.enabled = true server.compression.mime-types = application / json, application / xml, text / html, text / xml, text / plain, application / javascript, text / css
lukassass

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

बस यह साझा करना चाहता हूं कि मेरे मामले में टॉमकैट एक लोड बैलेंसर के पीछे है जो https प्राप्त करता है और http के रूप में tomatat के लिए अनुरोध को रोकता है। जब मैं application.properties समाधान प्रतिक्रिया का उपयोग करता हूं तो यह gzip नहीं है, लेकिन जब मैं कनेक्टर पर प्रोग्रामेटिक समाधान का उपयोग करता हूं तो मुझे मिलता है। https अनुरोध के साथ gzip प्रतिक्रिया LB
lukass77

मामले में एक और सवाल मैं application.properties समाधान का उपयोग करता हूं .. और 8081 और 8082 बंदरगाहों पर 2 से अधिक कनेक्टर्स को परिभाषित करता हूं .. क्या सभी कनेक्टरों को या केवल 8080 कनेक्टर को अपग्रेडेशन करता है?
1

मैं इसे देखता हूं, कंप्रेशर केवल पोर्ट 8080 पर लागू होता है, भले ही आप अधिक कनेक्टर खोलते हों .., मुझे लगता है कि इस पर बग को स्प्रिंग बूट के लिए खुला होना चाहिए? .., इसलिए मेरे लिए केवल काम समाधान प्रत्येक कनेक्टर के लिए प्रोग्रामेटिक कॉन्फ़िगरेशन था; आवेदन नहीं।
समर्थक

0

मेरे स्प्रिंग बूट + स्प्रिंग डेटा प्रोजेक्ट में भी यही समस्या थी, जब मुझे इनवाइट किया गया था @RepositoryRestResource

समस्या MIME प्रकार लौटा दी गई है; जो है application/hal+jsonserver.compression.mime-typesसंपत्ति में इसे जोड़ने से मेरे लिए यह समस्या हल हो गई।

आशा है कि यह किसी और की मदद करता है!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.