डॉकर और जावा: एप्लिकेशन का उन्नत कंटेनरीकरण

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

Docker और Java: एप्लिकेशन कंटेनरीकरण का उन्नत स्तर

\n\n

जावा एप्लिकेशन का कंटेनरीकरण आधुनिक विकास में एक डी-फैक्टो मानक बन गया है। हालाँकि, Docker का बुनियादी ज्ञान (openjdk:11 से इमेज बनाना और कंटेनर चलाना) अब प्रोडक्शन वातावरण की आवश्यकताओं को पूरा नहीं करता है। उन्नत स्तर पर, कंटेनर के अंदर JVM के काम करने की विशेषताओं को ध्यान में रखना, इमेज के आकार को अनुकूलित करना, मेमोरी प्रबंधित करना और मॉनिटरिंग सेट करना आवश्यक है। इस लेख में, हम उन प्रमुख तकनीकों पर चर्चा करेंगे जो आपको जावा एप्लिकेशन के लिए कुशल और सुरक्षित Docker इमेज बनाने में मदद करेंगी।

\n\n

1. मल्टी-स्टेज बिल्ड: इमेज के आकार को कम करना

\n\n

क्लासिक दृष्टिकोण "एक Dockerfile - एक इमेज" अक्सर अंतिम आर्टिफैक्ट को फुला देता है। बिल्ड टूल्स (Maven, Gradle, कंपाइलर) इमेज में शामिल हो जाते हैं, जिनकी runtime में आवश्यकता नहीं होती है। समाधान मल्टी-स्टेज (multi-stage) बिल्ड है। हम प्रक्रिया को चरणों में विभाजित करते हैं: बिल्ड और रनटाइम।

\n\n

Maven का उपयोग करके Spring Boot एप्लिकेशन के लिए Dockerfile का उदाहरण:

\n\n
# बिल्ड चरण\nFROM maven:3.8.6-openjdk-17 AS builder\nWORKDIR /app\nCOPY pom.xml .\nRUN mvn dependency:go-offline -B\nCOPY src ./src\nRUN mvn clean package -DskipTests\n\n# निष्पादन चरण\nFROM eclipse-temurin:17-jre-alpine\nWORKDIR /app\nCOPY --from=builder /app/target/*.jar app.jar\nEXPOSE 8080\nENTRYPOINT ["java", "-jar", "app.jar"]
\n\n

परिणामस्वरूप, अंतिम इमेज का वजन 600+ MB के बजाय ~150 MB होता है। महत्वपूर्ण: jre इमेज ( jdk नहीं) और न्यूनतम डिस्ट्रीब्यूशन (Alpine, Slim) का उपयोग करें। Java 17+ एप्लिकेशन के लिए, jlink पर विचार करें - केवल आवश्यक मॉड्यूल के साथ कस्टम JRE बनाना।

\n\n

2. कंटेनर के अंदर काम करने के लिए JVM को कॉन्फ़िगर करना

\n\n

लंबे समय तक, JVM कंटेनर के लिए सेट मेमोरी और CPU सीमाओं को सही ढंग से निर्धारित नहीं कर पाता था। Java 8u191 और Java 10 से शुरू होकर, cgroups v1 (और Java 15 से cgroups v2) के लिए समर्थन आया। हालाँकि, केवल ऑटोमेशन पर निर्भर रहना उचित नहीं है।

\n\n

प्रोडक्शन के लिए प्रमुख पैरामीटर:

\n
    \n
  • -XX:+UseContainerSupport - कंटेनर समर्थन सक्षम करता है (Java 10+ में डिफ़ॉल्ट रूप से सक्रिय)।
  • \n
  • -XX:MaxRAMPercentage=75.0 - हीप के उपयोग को कंटेनर की उपलब्ध मेमोरी के 75% तक सीमित करता है। यह मेटास्पेस, थ्रेड स्टैक और सिस्टम प्रक्रियाओं के लिए मेमोरी छोड़ता है।
  • \n
  • -XX:ActiveProcessorCount=2 - यदि ऑटो-डिटेक्शन विफल हो जाता है, तो उपलब्ध प्रोसेसर की स्पष्ट संख्या निर्दिष्ट करता है।
  • \n
\n\n

पूर्ण ENTRYPOINT कमांड का उदाहरण:

\n\n
ENTRYPOINT ["java", \\\n    "-XX:+UseContainerSupport", \\\n    "-XX:MaxRAMPercentage=75.0", \\\n    "-XX:+ExitOnOutOfMemoryError", \\\n    "-jar", "app.jar"]
\n\n

महत्वपूर्ण: Docker वातावरण में निश्चित -Xmx और -Xms मानों से बचें। वे प्रतिकृति या स्केलिंग के दौरान कंटेनर सीमाओं में परिवर्तन के अनुकूल नहीं होते हैं।

\n\n

3. लेयर ऑप्टिमाइज़ेशन और बिल्ड कैशिंग

\n\n

Dockerfile में प्रत्येक निर्देश एक नई लेयर बनाता है। Docker उन लेयर को कैश करता है जो नहीं बदली हैं। पुनरावर्ती बिल्ड को गति देने के लिए, निर्देशों को कम बदलने वाले से अधिक बदलने वाले क्रम में व्यवस्थित करें।

\n\n

Dockerfile की सही संरचना:

\n
    \n
  1. OS निर्भरताएँ स्थापित करना (apk add, apt-get)।
  2. \n
  3. बिल्डर कॉन्फ़िगरेशन फ़ाइलें कॉपी करना (pom.xml, build.gradle)।
  4. \n
  5. निर्भरताएँ डाउनलोड करना (mvn dependency:go-offline)।
  6. \n
  7. स्रोत कोड कॉपी करना।
  8. \n
  9. बिल्ड और आर्टिफैक्ट कॉपी करना।
  10. \n
\n\n

इसके अतिरिक्त, CI/CD में docker layer caching का उपयोग किया जा सकता है। उदाहरण के लिए, GitHub Actions या GitLab CI में, बिल्ड के बीच Maven कैश को सहेजें:

\n\n
# GitLab CI के लिए उदाहरण\ncache:\n  key: ${CI_COMMIT_REF_SLUG}\n  paths:\n    - .m2/repository/\n    - .gradle/caches/
\n\n

साथ ही,

ब्लॉग

पुस्तक अनुशंसाएँ