1. वाइपर का परिचय
गो अनुप्रयोगों में एक कॉन्फ़िगरेशन समाधान की आवश्यकता को समझना
विश्वसनीय और बनाए रखने योग्य सॉफ्टवेयर बनाने के लिए, डेवलपर्स को अनुप्रयोग तार्किक से विभाजन करने की आवश्यकता होती है। इससे आप अनुप्रयोग के व्यवहार को बदले बिना अनुप्रयोग कोडबेस में परिवर्तन कर सकते हैं। एक कॉन्फ़िगरेशन समाधान इस विभाजन को संभव बनाता है, क्योंकि यह कॉन्फ़िगरेशन डेटा की बाहरीकरण को सुविधाजनक बनाता है।
विकास के साथ गो अनुप्रयोग इस तरह के सिस्टम से बहुत लाभान्वित हो सकते हैं, खासकर जब वे जटिलता में बढ़ते हैं और विभिन्न डिप्लॉयमेंट वातावरणों का सामना करते हैं, जैसे विकास, स्टेजिंग, और उत्पादन। इनमें से प्रत्येक वातावरण को डेटाबेस कनेक्शन, एपीआई कुंजी, पोर्ट संख्याएं, और अधिक के लिए विभिन्न सेटिंग्स की आवश्यकता हो सकती है। इन मानों को हार्डकोड करना समस्यात्मक और त्रुटि प्रवृत्त हो सकता है, क्योंकि यह विभिन्न कॉड पथों का पालन करने के लिए संभावनाएं बनाता है और संवेदनशील डेटा का प्रकटन के जोखिम को बढ़ाता है।
वाइपर जैसा एक कॉन्फ़िगरेशन समाधान इन चिंताओं को संबोधित करता है, जो विभिन्न कॉन्फ़िगरेशन आवश्यकताओं और प्रारूपों का समर्थन करने वाले एक समूहिक प्रक्रिया प्रदान करता है।
वाइपर का अवलोकन और उसकी भूमिका को संभालने का माध्यम
वाइपर गो अनुप्रयोगों के लिए एक व्यापक कॉन्फ़िगरेशन पुस्तकालय है, जो सभी कॉन्फ़िगरेशन आवश्यकताओं के लिए अधिकृत समाधान बनने का लक्ष्य रखता है। यह बारह-कारक अनुप्रयोग मैथोडोलोजी में निर्धारित अभ्यासों के साथ मेल खाता है, जो वातावरणों के बीच पोर्टेबिलिटी प्राप्त करने के लिए परिवर्तन की भाषा में कन्फ़िगरेशन के संचय की प्रोत्साहित करता है।
विपर कॉन्फ़िगरेशन को संभालने में प्रमुख भूमिका निभाता है जैसे:
- विभिन्न प्रारूपों जैसे JSON, TOML, YAML, HCL, और अधिक में कॉन्फ़िगरेशन फ़ाइल पढ़ें और अनमार्शल करें।
- पर्यावरण चरणों के साथ कॉन्फ़िगरेशन मानों को ओवरराइड करें, इससे बाह्य कॉन्फ़िगरेशन सिद्धांत का पालन करें।
- आवर्तनी और नए समयमें कॉन्फ़िगरेशन विकल्पों को गत
कॉन्फ़िगरेशन प्रारूप (JSON, TOML, YAML, HCL, आदि) सेट करना
Viper कई कॉन्फ़िगरेशन प्रारूपों जैसे JSON, TOML, YAML, HCL, आदि का समर्थन करता है। प्रारंभ करने के लिए, आपको नाम और प्रारूप तय करना होता है जिसे Viper को खोजना चाहिए:
v := viper.New()
v.SetConfigName("app") // बिना एक्सटेंशन के कॉन्फ़िगरेशन फ़ाइल का नाम
v.SetConfigType("yaml") // या "json", "toml", "yml", "hcl", आदि।
// कॉन्फ़िगरेशन फ़ाइल खोज पथ। अगर आपकी
// कॉन्फ़िगरेशन फ़ाइल की स्थान विभिन्न होती है तो कई पथ जोड़ें।
v.AddConfigPath("$HOME/.appconfig") // सामान्य UNIX प्रयोक्ता कॉन्फ़िग स्थान
v.AddConfigPath("/etc/appconfig/") // UNIX सिस्टम-वाइड कॉन्फ़िगरेशन पथ
v.AddConfigPath(".") // कार्यस्थल
कॉन्फ़िगरेशन फ़ाइल से पढ़ना और लिखना
Viper नमूना जानता है कि कॉन्फ़िगरेशन फ़ाइलों को कहाँ देखना है और क्या देखना है, तो आप इससे कॉन्फ़िगरेशन पढ़ने के लिए कह सकते हैं:
if err := v.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
// कॉन्फ़िग फाइल नहीं मिली; अगर चाहें तो निराश करें या अन्यथा संसाधित करें।
log.Printf("कोई कॉन्फ़िग फ़ाइल नहीं मिली। डिफ़ॉल्ट मान और/या पर्यावरण मानों का प्रयोग कर रहा है।")
} else {
// कॉन्फ़िग फ़ाइल मिल गई लेकिन एक और त्रुटि हुई
log.Fatalf("कॉन्फ़िग फ़ाइल पढ़ने में त्रुटि, %s", err)
}
}
संशोधन फिर से कॉन्फ़िग फ़ाइल में लिखने या नया बनाने के लिए, Viper कई विधियाँ प्रदान करता है। यहां यहां कैसे आप वर्तमान कॉन्फ़िगरेशन को फ़ाइल में लिखते हैं:
err := v.WriteConfig() // `v.SetConfigName` और `v.AddConfigPath` द्वारा पूर्वनिर्धारित पथ पर वर्तमान कॉन्फ़िग को लिखता है।
if err != nil {
log.Fatalf("कॉन्फ़िग फ़ाइल लिखने में त्रुटि, %s", err)
}
डिफ़ॉल्ट कॉन्फ़िगरेशन मान स्थापना
डिफ़ॉल्ट मान उनमानों के रूप में काम करते हैं जिनकी की फ़ाइल में या पर्यावरण मानों द्वारा स्थापना नहीं की गई है:
v.SetDefault("ContentDir", "content")
v.SetDefault("LogLevel", "debug")
v.SetDefault("Database.Port", 5432)
// डिफ़ॉल्ट मान के लिए एक अधिक जटिल डेटा संरचना
viper.SetDefault("Taxonomies", map[string]string{
"tag": "tags",
"category": "categories",
})
4. पर्यावरण मान और फ्लैग प्रबंधन
Viper केवल कॉन्फ़िगरेशन फ़ाइलों से सीमित नहीं है—यह पर्यावरण मानों और कमांड-लाइन फ्लैगों को भी प्रबंधित कर सकता है, जो पर्यावरण-विशेष सेटिंग के साथ काम करते समय विशेष रूप से उपयुक्त होता है।
Viper से पर्यावरण मान और फ्लैग को बाँधना
पर्यावरण मानों को बाँधना:
v.AutomaticEnv() // स्वचालित रूप से पर्यावरण मानों की खोज करता है जो Viper की कुंजियों से मेल खाते हैं।
v.SetEnvPrefix("APP") // इन्हें अन्यों से पृथक करने के लिए पर्यावरण मान उपसर्ग
v.BindEnv("port") // पोर्ट पर्यावरण मान को बाँधें (उदाहरण के लिए, APP_PORT)
// आप अपने ऐप में विभिन्न नामों के पर्यावरण मानों को मिला सकते हैं
v.BindEnv("database_url", "DB_URL") // यह Viper को "database_url" कॉन्फ़िगरेशन कुंजी के लिए DB_URL पर्यावरण मान का उपयोग करने के लिए कहता है।
pflag का उपयोग करके फ्लैग को बाँधना, जो फ्लैग विच्छेदन के लिए एक Go पैकेज है:
var port int
// pflag का उपयोग करके एक फ्लैग को परिभाषित करें
pflag.IntVarP(&port, "port", "p", 808, "ऐप्लिकेशन के लिए पोर्ट")
// एक Viper कुंजी से फ्लैग को बाँधें
pflag.Parse()
if err := v.BindPFlag("port", pflag.Lookup("port")); err != nil {
log.Fatalf("कुंजी को फ्लैग से बाँधने में त्रुटि, %s", err)
}
पर्यावरण-विशेष कॉन्फ़िगरेशन का प्रबंधन
एक ऐप्लिकेशन को अक्सर विभिन्न पर्यावरणों में (विकास, स्टेजिंग, उत्पादन, आदि) विभिन्नता से काम करने की आवश्यकता होती है। Viper कॉन्फ़िगरेशन से पर्यावरण मानों को प्राप्त कर सकता है जो कॉन्फ़िग फ़ाइल में सेटिंग्स को ओवरराइड कर सकते हैं, और विशेष पर्यावरण-स्पेसिफिक कॉन्फ़िगरेशन को संभव बनाता है:
v.SetConfigName("config") // डिफ़ॉल्ट कॉन्फ़िगरेशन फ़ाइल नाम
// पर्यावरण मानों द्वारा सेटिंग्स को ओवरराइड कर सकते हैं
// पर्यावरण टेके `APP` प्रेफ़िक्स के साथ और कुंजी के बाक़ी भाग को अपरकेस में
v.SetEnvPrefix("APP")
v.AutomaticEnv()
// उत्पादन पर्यावरण में, आप डिफ़ॉल्ट पोर्ट को ओवरराइड करने के लिए APP_PORT पर्यावरण मान का उपयोग कर सकते हैं
fmt.Println(v.GetString("port")) // यदि सेट है तो उत्पादन पर्यावरण, नहीं तो डिफ़ॉल्ट फ़ाइल या मान से आउटपुट होगा
याद रखें कि आवश्यकतानुसार, अपने ऐप्लिकेशन को Viper द्वारा लोड की गई कॉन्फ़िगरेशन द्वारा विभिन्न पर्यावरणों के बीच अंतरों को संसाधित करना हो सकता है।
5. रिमोट की/मानक संग्रह समर्थन
वाइपर, etcd, Consul, या Firestore जैसे रिमोट की/मानक संग्रह का उपयोग करके अनुप्रयोग समर्थन के लिए मजबूत समर्थन प्रदान करता है। इससे संगणना प्रणालियों में वितरित सिस्टम के बीच विविध संरचनाओं के एकीकृत कॉन्फ़िगरेशन को डायनैमिक रूप से अपडेट किया जा सकता है। इसके अलावा, वाइपर संकेतिक कॉन्फ़िगरेशन को एन्क्रिप्शन के माध्यम से सुरक्षित रूप से हैंडल करने की संभावना प्रदान करता है।
वाइपर को रिमोट की/मानक संग्रहों (etcd, Consul, Firestore, आदि) के साथ एकीकरण करना
वाइपर को रिमोट की/मानक संग्रहों के साथ उपयोग करना शुरू करने के लिए, अपने गो एप्लिकेशन में viper/remote
पैकेज का एक खाली आयात करना होगा:
import _ "github.com/spf13/viper/remote"
हम etcd के साथ एकीकरण के एक उदाहरण को देखते हैं:
import (
"log"
"github.com/spf13/viper"
_ "github.com/spf13/viper/remote"
)
func initRemoteConfig() {
viper.SetConfigType("json") // संग्रह फ़ाइल के प्रकार को सेट करें
viper.AddRemoteProvider("etcd", "http://127...1:4001", "/config/myapp.json")
err := viper.ReadRemoteConfig() // रिमोट कॉन्फ़िग पढ़ने का प्रयास करें
if err != nil {
log.Fatalf("रिमोट कॉन्फ़िग पढ़ने में विफल: %v", err)
}
log.Println("सफलतापूर्वक रिमोट कॉन्फ़िगरेशन पढ़ा गया")
}
func main() {
initRemoteConfig()
// आपका एप्लिकेशन लॉजिक यहां
}
इस उदाहरण में, वाइपर http://127...1:4001
पर चल रहे एक etcd सर्वर से जुड़ता है और /config/myapp.json
पर स्थितियों को पढ़ता है। कंसुल जैसे अन्य संग्रहों के साथ काम करते समय, "etcd"
को "consul"
से बदलें और प्रदाता-विशेष पैरामीटरों को और जैसे आवश्यकतानुसार समायोजित करें।
एन्क्रिप्टेड कॉन्फ़िगरेशन का प्रबंधन
API कुंजी या डेटाबेस क्रेडेंशियल्स जैसी संवेदनशील कॉन्फ़िगरेशन सादा पाठ में स्टोर नहीं किए जाना चाहिए। वाइपर एन्क्रिप्टेड कॉन्फ़िगरेशन को संग्रह करने और आपके अनुप्रयोग में डिक्रिप्शन करने की अनुमति देता है।
इस सुविधा का उपयोग करने के लिए, सुनिश्चित करें कि एन्क्रिप्टेड सेटिंग्स आपके की/मानक संग्रह में स्टोर किए गए हैं। फिर वाइपर का AddSecureRemoteProvider
का इस्तेमाल करें। यहां एक उदाहरण है जिसमें इसका उपयोग etcd के साथ करने के लिए:
import (
"log"
"github.com/spf13/viper"
_ "github.com/spf13/viper/remote"
)
func initSecureRemoteConfig() {
const secretKeyring = "/path/to/secret/keyring.gpg" // आपके keyring फ़ाइल का पथ
viper.SetConfigType("json")
viper.AddSecureRemoteProvider("etcd", "http://127...1:4001", "/config/myapp.json", secretKeyring)
err := viper.ReadRemoteConfig()
if err != nil {
log.Fatalf("रिमोट कॉन्फ़िग पढ़ने में असमर्थ: %v", err)
}
log.Println("सफलतापूर्वक रिमोट कॉन्फ़िगरेशन पढ़ा और डिक्रिप्ट किया गया")
}
func main() {
initSecureRemoteConfig()
// आपका एप्लिकेशन लॉजिक यहां
}
उपरोक्त उदाहरण में, AddSecureRemoteProvider
का उपयोग किया गया है, जिसमें डिक्रिप्शन के लिए आवश्यक कुंजियों को शामिल करने वाले एक जीपीजी keyring के पथ को निर्दिष्ट किया गया है।
6. कॉन्फ़िग परिवर्तन को देखना और हैंडल करना
वाइपर की शक्तिशाली विशेषताओं में से एक यह है कि यह एप्लिकेशन को बिना पुनरारंभ किए कॉन्फ़िगरेशन परिवर्तनों को निगरानी और उत्तर देने की क्षमता रखता है।
कॉन्फ़िगरेशन परिवर्तनों का निगरानी करना और पुनरायत्न करना
वाइपर, आपकी कॉन्फ़िगरेशन फ़ाइल के परिवर्तनों को देखने के लिए fsnotify
पैकेज का उपयोग करता है। आप एक दृष्टा रखने वाला सचेतक सेटअप कर सकते हैं ताकि कॉन्फ़िगरेशन फ़ाइल परिवर्तित होते ही घटनाएँ ट्रिगर हों:
import (
"log"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
)
func watchConfig() {
viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
log.Printf("कॉन्फ़िग फ़ाइल बदल गई: %s", e.Name)
// यहां आप अद्यतन की गई कॉन्फ़िगरेशन पढ़ सकते हैं यदि आवश्यक हो
// सेवाओं को पुनरारंभ करने या चर अद्यतन करने जैसी किसी कार्रवाई को करें
})
}
func main() {
viper.SetConfigName("myapp")
viper.AddConfigPath(".")
err := viper.ReadInConfig()
if err != nil {
log.Fatalf("कॉन्फ़िग फ़ाइल पढ़ने में त्रुटि, %s", err)
}
watchConfig()
// आपका एप्लिकेशन लॉजिक यहां
}
चल रहे ऐप्लिकेशन में कॉन्फ़िगरेशन अपडेट करने के ट्रिगर
चल रहे ऐप्ल