不知道從何時開始,當咱們聯繫一些企業的客服時,愈來愈多的聯繫和支持工做都開始由AI機器人程序代爲完成了。不管是電話下單,查詢訂單狀態,諮詢業務問題,或者其餘什麼類型的求助,這些機器人一般都能很好地完成,而一些比較「黑科技」的機器人,甚至在成功解決問題以後,咱們都沒法判斷電話那頭的究竟是人仍是程序……html
就是由於效果太好,不少企業甚至已經開始主要經過這種方式向用戶提供服務,甚至開始縮減人工客服的崗位。那麼這就可能產生一個問題:若是機器人客服的程序掛了,你的客戶該由誰來提供服務?json
若是你的智能客服是基於Amazon Lex構建的,那麼能夠考慮建立高可用性的多區域機器人,這樣就算一個區域的機器人故障,也能夠自動交由其餘區域來接待客戶,從根本上解決這種問題。session
衆多AWS客戶已經開始利用Amazon Lex機器人在電話及其餘多種渠道上加強Amazon Connect自助服務的對話體驗。藉助Amazon Lex,呼叫方(用Amazon Connect術語描述,即客戶)可以快速獲取問題的答案,幾乎不須要人工客服的介入。但這同時也給服務可用性提出了更高的要求,所以引起了新的問題:咱們該使用哪一種架構模式提高機器人可用性?在本文中,咱們將探討一種跨區域方法,經過在多個區域中部署Amazon Lex機器人以提升服務可用性。架構
架構概述編輯器
在這套解決方案中,一旦Amazon Lex出現服務可用性問題,Amazon Connect流可以將中斷影響控制在最低程度,藉此實現業務連續性。此架構模式使用如下組件:ide
之因此要在兩個區域內設置完成相同的Amazon Lex機器人,是爲了可以隨時在輔助區域中啓動該機器人,進而在主區域發生故障時及時替換。
函數
Amazon Lex的多區域模式post
隨後的兩節,主要描述集成有Amazon Lex機器人的Amazon Connect流如何在主區域發生服務故障或中斷的狀況下,快速實現恢復並使用輔助區域內的Amazon Lex正常響應客戶呼叫。測試
運行情況檢查函數將根據TEST_METHOD Lambda環境變量對兩個Amazon Lex運行時API之一進行調用(PutSession或PostText)。咱們能夠根據本身的喜愛及用例要求選擇其中一個。PutSession API調用不會產生任何額外的Amazon Lex關聯費用,但沒法測試Amazon Lex提供的天然語言理解(NLU)功能。PostTextAPI則容許咱們檢查Amazon Lex的NLU功能,且額外成本不高。ui
運行情況檢查函數會將經過測試的區域名稱,更新至DynamoDB表(lexDR)中的lexRegion列。若是主區域正常經過運行情況檢查,則lexRegion將被更新爲主區域名稱。若是運行情況檢查失敗,則該函數將基於輔助區域內的TEST_METHOD環境變量向相應的運行時API發出調用。若是測試成功,則DynamoDB表中的lexRegion列將被更新爲輔助區域;若是測試仍然失敗,則更新爲err,表明兩個區域皆已發生服務中斷。
在Amazon Connect收到的每項呼叫中,都會發出區域運行情況檢測函數調用,藉此獲取當前Amazon Connect區域中的活動Amazon Lex區域。由區域運行情況檢查函數返回的主區域將做爲最新條目,由該檢查函數寫入至DyanmoDB表。由區域檢查函數返回的可用區域內Amazon Lex機器人,將經過Get Customer Input Block配置接受Amazon Connect的調用。若是函數返回的是輔助區域,則Amazon Connect將調用輔助區域中的機器人。
部署Amazon Lex機器人
你們須要在主區域與輔助區域中建立相同的對話機器人。在本文中,咱們將us-east-1做爲主區域,us-west-2做爲輔助區域。接下來,先使用主區域us-east-1建立機器人:
對us-west-2區域重複上述步驟。如今,咱們已經在us-east-1與us-west-2中創建起可以正常運行的Amazon Lex機器人。
建立DynamoDB表
請確保當前處於us-east-1區域內。
爲Lambda函數建立IAM角色
在此步驟中,咱們將爲兩項Lambda函數建立一個AWS身份與訪問管理(AWS Identity and Access Management,簡稱IAM)角色。
{ "Version": "2012-10-17", "Statement": [{ "Sid": "VisualEditor0", "Effect": "Allow", "Action": ["dynamodb:GetItem", "dynamodb:UpdateItem"], "Resource": "arn:aws:dynamodb:us-east-1:xxxxxxxxxxxx:table/lexDR" }] }
附加如下權限策略:
部署區域檢查函數
咱們首先須要建立一項Lambda函數,用於從DynamoDB表中讀取記錄,藉此判斷哪一個Amazon Lex機器人與Amazon Connect實例處於同一區域當中。Amazon Connect或者使用此機器人的應用程序後續將調用此函數。
import json import boto3 import os import logging dynamo_client=boto3.client('dynamodb') logger = logging.getLogger() logger.setLevel(logging.DEBUG) def getCurrentPrimaryRegion(key): result = dynamo_client.get_item( TableName=os.environ['TABLE_NAME'], Key = { "connectRegion": {"S": key } } ) logger.debug(result['Item']['lexRegion']['S'] ) return result['Item']['lexRegion']['S'] def lambda_handler(event, context): logger.debug(event) region = event["Details"]["Parameters"]["region"] return { 'statusCode': 200, 'primaryCode': getCurrentPrimaryRegion(region) }
部署運行情況檢查函數
在us-east-1當中建立另外一項Lambda函數,用以實現運行情況檢查功能。
import json import boto3 import sys import os dynamo_client = boto3.client('dynamodb') primaryRegion = os.environ['PRIMARY_REGION'] secondaryRegion = os.environ['SECONDARY_REGION'] tableName = os.environ['TABLE_NAME'] primaryRegion_client = boto3.client('lex-runtime',region_name=primaryRegion) secondaryRegion_client = boto3.client('lex-runtime',region_name=secondaryRegion) def getCurrentPrimaryRegion(): result = dynamo_client.get_item( TableName=tableName, Key={ 'connectRegion': {'S': primaryRegion} } ) return result['Item']['lexRegion']['S'] def updateTable(region): result = dynamo_client.update_item( TableName= tableName, Key={ 'connectRegion': {'S': primaryRegion } }, UpdateExpression='set lexRegion = :region', ExpressionAttributeValues={ ':region': {'S':region} } ) #SEND MESSAGE/PUT SESSION ENV VA def put_session(botname, botalias, user, region): print(region,botname, botalias) client = primaryRegion_client if region == secondaryRegion: client = secondaryRegion_client try: response = client.put_session(botName=botname, botAlias=botalias, userId=user) if (response['ResponseMetadata'] and response['ResponseMetadata']['HTTPStatusCode'] and response['ResponseMetadata']['HTTPStatusCode'] != 200) or (not response['sessionId']): return 501 else: if getCurrentPrimaryRegion != region: updateTable(region) return 200 except: print('ERROR: {}',sys.exc_info()[0]) return 501 def send_message(botname, botalias, user, region): print(region,botname, botalias) client = primaryRegion_client if region == secondaryRegion: client = secondaryRegion_client try: message = os.environ['SAMPLE_UTTERANCE'] expectedOutput = os.environ['EXPECTED_RESPONSE'] response = client.post_text(botName=botname, botAlias=botalias, userId=user, inputText=message) if response['message']!=expectedOutput: print('ERROR: Expected_Response=Success, Response_Received='+response['message']) return 500 else: if getCurrentPrimaryRegion != region: updateTable(region) return 200 except: print('ERROR: {}',sys.exc_info()[0]) return 501 def lambda_handler(event, context): print(event) botName = os.environ['BOTNAME'] botAlias = os.environ['BOT_ALIAS'] testUser = os.environ['TEST_USER'] testMethod = os.environ['TEST_METHOD'] if testMethod == 'send_message': primaryRegion_response = send_message(botName, botAlias, testUser, primaryRegion) else: primaryRegion_response = put_session(botName, botAlias, testUser, primaryRegion) if primaryRegion_response != 501: primaryRegion_client.delete_session(botName=botName, botAlias=botAlias, userId=testUser) if primaryRegion_response != 200: if testMethod == 'send_message': secondaryRegion_response = send_message(botName, botAlias, testUser, secondaryRegion) else: secondaryRegion_response = put_session(botName, botAlias, testUser, secondaryRegion) if secondaryRegion_response != 501: secondaryRegion_client.delete_session(botName=botName, botAlias=botAlias, userId=testUser) if secondaryRegion_response != 200: updateTable('err') #deleteSessions(botName, botAlias, testUser) return {'statusCode': 200,'body': 'Success'}
在Environment variables部分,選擇Edit,然後添加如下環境變量:
TEST_METHOD – put_session或send_message
建立一條Amazon CloudWatch規則
爲了每5分鐘觸發一次運行情況檢查函數,咱們須要建立一條Amazon CloudWatch規則。
如今,咱們應該已經創建起lexHealthCheckRule CloudWatch規則,可以每5分鐘調用一次lexDRTest函數。這項操做將檢查主機器人的運行情況是否正常,並將結果對應更新至DynamoDB表。
建立Amazon Connect實例
隨後咱們須要建立一個Amazon Connect實例,藉此在建立lexDRTest函數的同一區域以內測試機器人的多區域模式。
將電話號碼關聯至聯繫流程
接下來,咱們須要將電話號碼關聯至聯繫流程,藉此調用並測試OrderFlowers機器人。
測試集成效果
要測試這套解決方案,能夠執行如下操做以模擬us-east-1區域發生故障的場景:
在下一次進行運行情況檢查時,解決方案將嘗試與us-east-1區域的Lex機器人進行通訊。因爲機器人別名不存在,所以沒法得到成功響應。所以,本示例隨後會呼叫輔助區域us-west-2並收到成功響應。在收到響應後,示例將使用us-west-2更新lexDR以及DynamoDB表中的lexRegion列。
接下來,全部指向us-east-1區域內Connect的後續呼叫都將與us-west-2區域內的Lex機器人進行實際交互。經過這一自動切換,能夠證實當前架構模式確實可以在發生服務故障時保障業務連續性。
在刪除機器人別名到下一次運行情況檢查之間的時段內,對Amazon Connect的呼叫都將失敗。但在運行情況檢查以後,系統將自動實現業務連續性保障。所以,每一輪運行情況檢查之間的間隔越短,則停機時間越短。咱們能夠經過編輯Amazon CloudWatch規則lexHealthCheckRule以調整每次運行情況檢查之間的間隔時長。
要讓us-east-1區域再次經過運行情況檢查,請在us-east-1中從新建立OrderFlowers機器人的別名ver_one。
資源清理
爲了不產生沒必要要的額外成本,請刪除本示例中建立的全部資源。
總結
配合Amazon Lex提供的自助服務,Amazon Connect將幫助咱們輕鬆建立便捷直觀的客戶服務體驗。本文提供一種跨區域形式的高可用性實現方法,保證可以在某一區域中的機器人或支持實現API不可用時,使用來自其餘區域的資源以繼續響應客戶呼叫。