इस ब्लॉग पोस्ट श्रृंखला में, मैं AWS में बहु-किरायेदार सेवाओं के निर्माण के लिए सर्वोत्तम प्रथाओं पर चर्चा करना चाहूंगा। बहु-किरायेदार सेवाओं का निर्माण कैसे करें, इस पर मौजूदा साहित्य आमतौर पर सैकड़ों ग्राहकों के साथ SaaS अनुप्रयोगों पर लक्षित होता है (उदाहरण के लिए )।
मैं प्रत्येक प्रकार की सेवा-से-सेवा एकीकरण के लिए ब्लॉग पोस्ट की श्रृंखला को तीन भागों में विभाजित करूंगा: सिंक्रोनस, एसिंक्रोनस और बैच एकीकरण।
आंतरिक सेवाओं के लिए बहु-किरायेदारी
1.1. किरायेदार अलगाव 1.2. बहु-किरायेदार निगरानी 1.3. स्केलिंगआंतरिक सेवाओं के लिए बहु-किरायेदारी
2.1. किरायेदार-अलगाव - प्रवेश-नियंत्रण 2.2 किरायेदार-अलगाव - शोरगुल वाले पड़ोसी की समस्या 2.3 बहु-किरायेदार निगरानी 2.4 मेट्रिक्स, अलार्म, डैशबोर्ड 2.5 ऑनबोर्डिंग और ऑफबोर्डिंग एपीआई क्लाइंटAWS AppSync के साथ बहु-किरायेदारी
निष्कर्ष
मल्टी-टेनेंसी सॉफ्टवेयर की एक ही इंस्टेंस के साथ कई ग्राहकों या किरायेदारों को सेवा प्रदान करने की क्षमता है।
एक बार जब आप एक से अधिक टीमों को अपनी सेवा एपीआई पर कॉल करने की अनुमति देते हैं, तो आपकी सेवा बहु-किरायेदार बन जाती है। मल्टी-टेनेंट आर्किटेक्चर आपकी सेवाओं में अतिरिक्त जटिलता लाता है, जैसे किरायेदार अलगाव, किरायेदार-स्तरीय निगरानी और स्केलिंग।
यदि आप अपनी AWS वेब सेवा को AWS में REST , HTTP, या WebSocket API के साथ बना रहे हैं तो आप संभवतः API गेटवे का उपयोग कर रहे हैं।
संसाधन-आधारित प्राधिकरण के साथ एक ग्राहक को शामिल करना । संसाधन-आधारित पहुंच के लिए, आपको एपीआई गेटवे संसाधन नीति को अपडेट करना होगा और अपने क्लाइंट का AWS खाता जोड़ना होगा। इस पद्धति का मुख्य नुकसान यह है कि एक बार जब आप संसाधन नीति को अपडेट कर देते हैं, तो परिवर्तनों को प्रभावी करने के लिए एपीआई गेटवे चरण को फिर से तैनात करने की आवश्यकता होती है (एडब्ल्यूएस दस्तावेज़ और देखें)। हालाँकि, यदि आप सीडीके का उपयोग करते हैं तो आप नए चरणों की तैनाती को स्वचालित कर सकते हैं ( देखें)। एक अन्य नुकसान संसाधन नीति की अधिकतम लंबाई की सीमा है।
पहचान-आधारित प्राधिकरण के साथ एक ग्राहक को शामिल करना । पहचान-आधारित पहुंच नियंत्रण के लिए, आपको क्लाइंट के लिए एक IAM भूमिका बनानी होगी और भूमिका की संसाधन नीति (विश्वसनीय संबंध) को अपडेट करके क्लाइंट को इसे ग्रहण करने की अनुमति देनी होगी। आप IAM उपयोगकर्ताओं का उपयोग कर सकते हैं, लेकिन सुरक्षा की दृष्टि से IAM भूमिकाएँ बेहतर हैं। भूमिकाएँ अस्थायी क्रेडेंशियल्स के साथ प्रमाणीकरण की अनुमति देती हैं और IAM उपयोगकर्ता क्रेडेंशियल्स को संग्रहीत करने की आवश्यकता नहीं होती है। प्रति खाता 1,000 भूमिकाओं की सीमा है, लेकिन यह सीमा समायोज्य है। साथ ही, आपके एपीआई तक क्रॉस-अकाउंट एक्सेस प्राप्त करने के लिए भूमिका-आधारित पद्धति का एक और नुकसान यह है कि आपको प्रत्येक नए एपीआई क्लाइंट के लिए एक आईएएम भूमिका बनाने की आवश्यकता है। हालाँकि, भूमिका प्रबंधन को सीडीके के साथ स्वचालित किया जा सकता है ( देखें)।
AWS IAM प्राधिकरण आपको केवल API गेटवे तक पहुंच को नियंत्रित करने की अनुमति देता है (IAM नीति का उपयोग करके आप निर्दिष्ट कर सकते हैं कि AWS खाता किस API गेटवे एंडपॉइंट को कॉल कर सकता है)। आपकी सेवा के डेटा और अन्य अंतर्निहित संसाधनों तक नियंत्रण पहुंच लागू करना आपकी ज़िम्मेदारी है। अपनी सेवा के भीतर, आप कॉल करने वाले के एडब्ल्यूएस आईएएम एआरएन का उपयोग कर सकते हैं जो आगे पहुंच नियंत्रण के लिए एपीआई गेटवे अनुरोध के साथ पारित किया जाता है:
export const handler = async (event: APIGatewayEvent, context: Context): Promise<APIGatewayProxyResult> => { // IAM Principal ARN of the api caller const callerArn = event.requestContext.identity.userArn!; // .. business logic based on caller return { statusCode: 200, body: JSON.stringify({ message: `Received API Call from ${callerArn}`, }) }; };
एपीआई गेटवे में दो प्रकार के लॉग होते हैं:
आपके एपीआई क्लाइंट के अनुरोधों की निगरानी के लिए, मैं एक्सेस लॉगिंग सक्षम करने की अनुशंसा करूंगा। आप कम से कम कॉलर के AWS IAM ARN ( $context.identity.userArn
), अनुरोध पथ ( $context.path
), आपकी सेवा प्रतिक्रिया स्थिति कोड $context.status
और API कॉल विलंबता ( $context.responseLatency
) को लॉग कर सकते हैं। .
const formatObject = { requestId: '$context.requestId', extendedRequestId: '$context.extendedRequestId', apiId: '$context.apiId', resourceId: '$context.resourceId', domainName: '$context.domainName', stage: '$context.stage', path: '$context.path', resourcePath: '$context.resourcePath', httpMethod: '$context.httpMethod', protocol: '$context.protocol', accountId: '$context.identity.accountId', sourceIp: '$context.identity.sourceIp', user: '$context.identity.user', userAgent: '$context.identity.userAgent', userArn: '$context.identity.userArn', caller: '$context.identity.caller', cognitoIdentityId: '$context.identity.cognitoIdentityId', status: '$context.status', integration: { // The status code returned from an integration. For Lambda proxy integrations, this is the status code that your Lambda function code returns. status: '$context.integration.status', // For Lambda proxy integration, the status code returned from AWS Lambda, not from the backend Lambda function code. integrationStatus: '$context.integration.integrationStatus', // The error message returned from an integration // A string that contains an integration error message. error: '$context.integration.error', latency: '$context.integration.latency', }, error: { responseType: '$context.error.responseType', message: '$context.error.message', }, requestTime: '$context.requestTime', responseLength: '$context.responseLength', responseLatency: '$context.responseLatency', }; const accessLogFormatString = JSON.stringify(formatObject); const accessLogFormat = apigw.AccessLogFormat.custom(accessLogFormatString);
fields @timestamp, path, status, responseLatency, userArn | sort @timestamp desc | filter userArn like 'payment-service' | limit 20
डिफ़ॉल्ट रूप से एपीआई गेटवे द्वारा समर्थित क्लाउडवॉच मेट्रिक्स सभी अनुरोधों के लिए एकत्रित किए जाते हैं। लेकिन आप अपने एपीआई के क्लाइंट (किरायेदार) उपयोग की निगरानी करने में सक्षम होने के लिए अपने क्लाइंट नाम के अतिरिक्त आयाम के साथ कस्टम क्लाउडवॉच मेट्रिक्स प्रकाशित करने के लिए एपीआई गेटवे एक्सेस लॉग को पार्स कर सकते हैं। बहुत कम से कम, मैं प्रति-क्लाइंट क्लाउडवॉच मेट्रिक्स गणना, 4xx, 5xx, Dimension=${Client}
द्वारा विभाजित विलंबता प्रकाशित करने की अनुशंसा करता हूं। आप स्टेटस कोड और एपीआई पथ जैसे आयाम भी जोड़ सकते हैं।
2.4.1. प्रति-क्लाइंट मेट्रिक्स प्रकाशित करने के लिए मेट्रिक लॉग फ़िल्टर का उपयोग करना
आयाम Client
और Path
के साथ Count
प्रकाशित करने के लिए क्लाउडवॉच मीट्रिक लॉग फ़िल्टर का उदाहरण
new logs.MetricFilter(this, 'MultiTenantApiCountMetricFilter', { logGroup: accessLogsGroup, filterPattern: logs.FilterPattern.exists('$.userArn'), metricNamespace: metricNamespace, metricName: 'Count', metricValue: '1', unit: cloudwatch.Unit.COUNT, dimensions: { client: '$.userArn', method: '$.httpMethod', path: '$.path',},}); });
2.4.2. प्रति-क्लाइंट मेट्रिक्स प्रकाशित करने के लिए लैम्ब्डा फ़ंक्शन का उपयोग करना
वैकल्पिक विकल्प लॉग को पार्स करने, मेट्रिक्स निकालने और उन्हें प्रकाशित करने के लिए लैम्ब्डा फ़ंक्शन बनाना है। यह आपको अज्ञात क्लाइंट को फ़िल्टर करने या userArn से क्लाइंट का नाम निकालने जैसे अधिक कस्टम कार्य करने की अनुमति देता है।
const logProcessingFunction = new lambda.NodejsFunction( this, 'log-processor-function', { functionName: 'multi-tenant-api-log-processor-function', } ); new logs.SubscriptionFilter(this, 'MultiTenantApiLogSubscriptionFilter', { logGroup: accessLogsGroup, destination: new logsd.LambdaDestination(logProcessingFunction), filterPattern: logs.FilterPattern.allEvents(), });
interface ApiClientConfig { name: string; awsAccounts: string[]; rateLimit: number; burstLimit: number; } const apiClients: ApiClientConfig[] = [ { name: 'payment-service', awsAccounts: ['3','444455556666'], rateLimit: 10, burstLimit: 2, }, { name: 'order-service', awsAccounts: ['777788889999'], rateLimit: 1, burstLimit: 1, }, ];
यदि आपकी सेवा में GraphQL API है तो आप संभवतः AppSync का उपयोग करेंगे। एपीआई गेटवे के समान, आप AppSync अनुरोधों को अधिकृत करने के लिए IAM Auth का उपयोग कर सकते हैं। AppSync के पास कोई संसाधन नीति नहीं है ( देखें), इसलिए आप AppSync API पर पहुंच नियंत्रण स्थापित करने के लिए केवल भूमिका-आधारित प्राधिकरण का उपयोग कर सकते हैं। एपीआई गेटवे के समान, आप अपनी सेवा के प्रत्येक नए किरायेदार के लिए एक अलग IAM भूमिका बनाएंगे।