簡體   English   中英

重寫 Api 網關中的目標路徑 websocket API 私有 Z80791B3AE7002CB88C2468768ZD 集成

[英]Rewrite destination path in Api Gateway websocket API private http integration with ALB

我有一個帶有 ECS 集群的私有子網,其中沒有公共 IP 地址的服務在應用程序負載均衡器后面運行。

Application Load Balancer 也是私有的。

我有一個 API 網關,通過 HTTP 使用 VPC 鏈接與該 ALB(請參閱)集成。

我所有的微服務都像這樣工作得很好。

But now I need to add support for websockets and I need to create an API Gateway with protocol type WEBSOCKET, that has routes with HTTP integation, so that the websocket routes $connect , $disconnect , sendmessage are transformed into HTTP requests.

我遇到的問題是,為了使用私有集成,我必須指定 ALB 的 Arn,並且我不能指定 URL(請參閱)。 關於IntegrationUri

對於 HTTP API 私有集成,指定應用程序負載均衡器偵聽器、網絡負載均衡器偵聽器或 AWS Cloud Map 服務的 ARN。 如果您指定 AWS 雲 Map 服務的 ARN,則 API 網關使用 DiscoverInstances 來識別資源。 您可以使用查詢參數來定位特定資源。 要了解更多信息,請參閱 DiscoverInstances。 對於私有集成,所有資源必須歸同一個 AWS 賬戶所有。

因此,在 IntegrationUri 中,無需指定諸如https://mypublicdomain.com/My.Service/connect的內容,我可以輕松地將服務路徑添加為 URL 的一部分,而是被迫添加應用程序負載均衡器 ARN, arn:aws:myalb...

因此我不能使用 URL 路徑來讓 websocket 路由與 ALB 后面的特定服務集成

換句話說,如何將 API 網關上的 websocket 路由與私有 ALB 后面的特定服務相關聯?

PS:我曾想過使用一些帶有路徑模式條件的偵聽器規則,這些規則可以抓取所有流向 ALB 根/到所需服務的流量,但這遠非理想,因為我想基於更明顯的東西進行路由。


CloudFormation 示例:

Resources:
  websocketApiGateway:
    Type: AWS::ApiGatewayV2::Api
    Properties:
      Name: websocket-gateway
      Description: Api Gateway for websocket
      ProtocolType: WEBSOCKET
      DisableExecuteApiEndpoint: false
      RouteSelectionExpression: $request.body.action

  connectRoute:
    Type: AWS::ApiGatewayV2::Route
    Properties:
      ApiId: !Ref websocketApiGateway
      RouteKey: $connect
      AuthorizationType: NONE
      OperationName: ConnectRoute
      RouteResponseSelectionExpression: $default
      Target: !Join
        - /
        - - integrations
          - !Ref connectIntegration

  connectIntegration:
    Type: AWS::ApiGatewayV2::Integration
    Properties:
      ApiId: !Ref websocketApiGateway
      Description: Websocket $connect integration
      IntegrationType: HTTP_PROXY
      IntegrationMethod: POST
      IntegrationUri: # I cannot use something like https://mypublicdomain.com/My.Service/connect
        Fn::ImportValue: !Sub my-alb-http-listener-id
      RequestParameters:
        "integration.request.header.domainName": "context.domainName"
        "integration.request.header.stage": "context.stage"
        "integration.request.header.connectionId": "context.connectionId"
      PayloadFormatVersion: 1.0

  connectRouteResponse:
    Type: AWS::ApiGatewayV2::RouteResponse
    Properties:
      ApiId: !Ref websocketApiGateway
      RouteId: !Ref connectRoute
      RouteResponseKey: $default

UPDATE 1: Just after writing the question I thought.. If I can't route based on URI, maybe I can route at the ALB http listener based on some http header that I can set in the websocket's api gateway integration. 所以我會保留它作為一種解決方法,以防我找不到重寫 url 路徑的方法

UPDATE 2: This question is similar, but the answer is not detail enough Rewrite destination path in api gateway integration request

我並沒有真正解決它,但我有一個解決方法。

在 API 網關級別 websockets 請求被轉換為 HTTP 請求返回到 API 網關。 不理想,因為最好在內部將 http 請求發送到集成,但它可以工作並且希望它不會增加太多延遲,因為目標是相同的 api 網關。 我還添加了一些請求標頭,允許我在 web 應用程序級別提取最初位於 websocket 消息中的所需信息。

listenerRule:
  Type: AWS::ElasticLoadBalancingV2::ListenerRule
  Properties:
    Actions:
      - Type: forward
        TargetGroupArn: !Ref targetGroup
    Conditions:
      - Field: path-pattern
        PathPatternConfig: 
            Values:
              - !Sub
                - ${servicePath}*
                - servicePath: !FindInMap [microservice, settings, path]
    ListenerArn: 
      Fn::ImportValue: !Sub ${prefix}-alb-http-listener-id
    Priority: 2

現在在 api 網關我有我的 websocket 路由。 像這樣的東西

wsCommandRoute:
  Type: AWS::ApiGatewayV2::Route
  Properties:
    ApiId: !Ref wsApiGateway
    RouteKey: command
    AuthorizationType: NONE
    OperationName: CommandRoute
    RouteResponseSelectionExpression: $default
    Target: !Join
      - /
      - - integrations
        - !Ref wsCommandIntegration

wsCommandIntegration:
  Type: AWS::ApiGatewayV2::Integration
  Properties:
    ApiId: !Ref wsApiGateway
    Description: Websocket command integration
    IntegrationType: HTTP_PROXY
    IntegrationMethod: POST
    IntegrationUri:
      !Sub 
        - https://${domainName}${websocketServicePath}/ws/commands
        - domainName: !FindInMap [gateways, api, domainName]
          websocketServicePath: 
            Fn::ImportValue: !Sub ${prefix}-websocket-service-path
    RequestParameters:
      "integration.request.header.domainName": "context.domainName"
      "integration.request.header.stage": "context.stage"
      "integration.request.header.connectionId": "context.connectionId"
    PayloadFormatVersion: 1.0

wsCommandRouteResponse:
  Type: AWS::ApiGatewayV2::RouteResponse
  Properties:
    ApiId: !Ref wsApiGateway
    RouteId: !Ref wsCommandRoute
    RouteResponseKey: $default

如果有人有更好的方法,我很樂意將其標記為有效答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM