PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

स्प्रिंग, हाइबरनेट और C3P0 के साथ बहु-किरायेदार वेब ऐप में कनेक्शन पूलिंग प्रबंधित करें

आप 3 अलग-अलग रणनीतियों के बीच चयन कर सकते हैं जो कनेक्शन मतदान को प्रभावित करेंगे। किसी भी स्थिति में आपको MultiTenantConnectionProvider . का कार्यान्वयन प्रदान करना होगा . आपके द्वारा चुनी गई रणनीति निश्चित रूप से आपके कार्यान्वयन को प्रभावित करेगी।

MultiTenantConnectionProvider.getAnyConnection() के बारे में सामान्य टिप्पणी

getAnyConnection() हाइबरनेट द्वारा मेटाडेटा एकत्र करने और सत्र फ़ैक्टरी सेटअप करने के लिए आवश्यक है। आमतौर पर एक बहु-किरायेदार वास्तुकला में आपके पास एक विशेष/मास्टर डेटाबेस (या स्कीमा) होता है जिसका उपयोग किसी भी किरायेदार द्वारा नहीं किया जाता है। यह एक तरह का टेम्प्लेट डेटाबेस (या स्कीमा) है। यह ठीक है अगर यह विधि इस डेटाबेस (या स्कीमा) से कनेक्शन लौटाती है।

रणनीति 1 :प्रत्येक टैनेंट का अपना डेटाबेस होता है। (और इसलिए यह स्वयं का कनेक्शन पूल है)

इस मामले में, प्रत्येक टैनेंट का अपना कनेक्शन पूल होता है जिसे C3PO द्वारा प्रबंधित किया जाता है और आप MultiTenantConnectionProvider का कार्यान्वयन प्रदान कर सकते हैं। AbstractMultiTenantConnectionProvider . पर आधारित

प्रत्येक टैनेंट का अपना C3P0ConnectionProvider . होता है , तो आपको केवल selectConnectionProvider(tenantIdentifier) . में करना होगा सही वापस करना है। आप उन्हें कैश करने के लिए एक मानचित्र रख सकते हैं और आप C3POConnectionProvider को कुछ इस तरह से आलसी-प्रारंभ कर सकते हैं:

private ConnectionProvider lazyInit(String tenantIdentifier){
    C3P0ConnectionProvider connectionProvider = new C3P0ConnectionProvider();
    connectionProvider.configure(getC3POProperties(tenantIdentifier));
    return connectionProvider;
}

private Map getC3POProperties(String tenantIdentifier){
    // here you have to get the default hibernate and c3po config properties 
    // from a file or from Spring application context (there are good chances
    // that those default  properties point to the special/master database) 
    // and alter them so that the datasource point to the tenant database
    // i.e. : change the property hibernate.connection.url 
    // (and any other tenant specific property in your architecture like :
    //     hibernate.connection.username=tenantIdentifier
    //     hibernate.connection.password=...
    //     ...) 
}

रणनीति 2 :प्रत्येक टैनेंट की अपनी स्कीमा होती है और एक ही डेटाबेस में उसका अपना कनेक्शन पूल होता है

यह मामला ConnectionProvider . के संबंध में पहली रणनीति के समान है कार्यान्वयन क्योंकि आप AbstractMultiTenantConnectionProvider . का भी उपयोग कर सकते हैं अपने MultiTenantConnectionProvider . को लागू करने के लिए बेस क्लास के रूप में

कार्यान्वयन रणनीति 1 के लिए सुझाए गए कार्यान्वयन के समान है, सिवाय इसके कि आपको c3po कॉन्फ़िगरेशन में डेटाबेस के बजाय स्कीमा को बदलना होगा

रणनीति 3 :एक डेटाबेस में प्रत्येक टैनेंट की अपनी स्कीमा होती है, लेकिन एक साझा कनेक्शन पूल का उपयोग करें

यह मामला थोड़ा अलग है क्योंकि प्रत्येक टैनेंट समान कनेक्शन प्रदाता का उपयोग करेगा (और इसलिए कनेक्शन पूल साझा किया जाएगा)। मामले में:कनेक्शन प्रदाता को कनेक्शन के किसी भी उपयोग से पहले उपयोग करने के लिए स्कीमा सेट करना होगा। यानी आपको MultiTenantConnectionProvider.getConnection(String tenantIdentifier) लागू करना होगा (यानी AbstractMultiTenantConnectionProvider द्वारा प्रदान किया गया डिफ़ॉल्ट कार्यान्वयन काम नहीं करेगा)।

Postgresql के साथ आप इसके साथ कर सकते हैं:

 SET search_path to <schema_name_for_tenant>;

या उपनाम का उपयोग कर रहे हैं

 SET schema <schema_name_for_tenant>;

तो यह है आपका getConnection(tenant_identifier); ऐसा दिखेगा:

@Override
public Connection getConnection(String tenantIdentifier) throws SQLException {
    final Connection connection = getAnyConnection();
    try {
        connection.createStatement().execute( "SET search_path TO " + tenanantIdentifier );
    }
    catch ( SQLException e ) {
        throw new HibernateException(
                "Could not alter JDBC connection to specified schema [" +
                        tenantIdentifier + "]",
                e
        );
    }
    return connection;
}

उपयोगी संदर्भ यहाँ है (आधिकारिक दस्तावेज़)

अन्य उपयोगी लिंक C3POConnectionProvider.java

आप अपने कार्यान्वयन में रणनीति 1 और रणनीति 2 को जोड़ सकते हैं। आपको वर्तमान टैनेंट के लिए सही कनेक्शन गुण/कनेक्शन url खोजने का एक तरीका चाहिए।

संपादित करें

मुझे लगता है कि रणनीति 2 या 3 के बीच चुनाव ट्रैफ़िक और आपके ऐप पर किरायेदारों की संख्या पर निर्भर करता है। अलग कनेक्शन पूल के साथ:एक किरायेदार के लिए उपलब्ध कनेक्शन की मात्रा बहुत कम होगी और इसलिए:यदि किसी वैध कारण से एक किरायेदार को अचानक कई कनेक्शन की आवश्यकता होती है तो इस विशेष किरायेदार द्वारा देखा गया प्रदर्शन काफी कम हो जाएगा (जबकि अन्य किरायेदार नहीं होगा प्रभावित)।

दूसरी ओर, रणनीति 3 के साथ, अगर किसी वैध कारण से एक किरायेदार को अचानक कई कनेक्शन की आवश्यकता होती है:प्रत्येक किरायेदार द्वारा देखा गया प्रदर्शन कम हो जाएगा।

सामान्य तौर पर, मुझे लगता है कि रणनीति 2 अधिक लचीली और सुरक्षित है:प्रत्येक किरायेदार एक निश्चित मात्रा में कनेक्शन का उपभोग नहीं कर सकता है (और यदि आपको इसकी आवश्यकता है तो यह राशि प्रति किरायेदार कॉन्फ़िगर की जा सकती है)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. लंबी बाइनरी (कच्चे डेटा) तारों को संग्रहित करना

  2. पोस्टग्रेज़ यूयूआईडी जेडीबीसी काम नहीं कर रहा है

  3. आईडी के आधार पर लाखों पंक्तियों को हटाने का सबसे अच्छा तरीका

  4. मैं postgresql फ़ंक्शन या ट्रिगर से कुछ http अनुरोध कैसे भेज सकता हूं?

  5. माउंटेन लायन पोस्टग्रेज कनेक्ट नहीं हो सका