jai deep
jai deep

Reputation: 11

Marklogic Rest API Transactions Issues with Load Balancer

We are using MarkLogic Rest Api in order to send/update the data on to marlogic database server. Also we are using transactions for multi-statement commit/rollback. So when we pass the request via a load balancer to marklogic to get the transaction id and associate that transaction id with the subsequent requests and finally we are trying to commit the request with the same transaction id but load balancer throws a error Bad request (Load Balancer doesn't recognize the request as it fails).

  1. We are creating a transactions by calling http://host:port/version/transactions API via POST method and this will return transaction id in the Location response header.
  2. Then we will associate a transaction id with the document insert/update via eval (http://host:port/version/eval) service api.
  3. After that commit a transaction created by making a POST request to the /transactions service, send a POST request to the /transactions/{txid} service with a URL of the form: http://host:port/version/transactions/txid?result=outcome

How to get the session cookie from load balancer ? How to pass that to subsequent requests via c# code ?

Upvotes: 1

Views: 251

Answers (2)

Mads Hansen
Mads Hansen

Reputation: 66781

You need to enable Session Affinity (or session stickiness) in your load balancer for the SessionID cookie, and ensure that it is maintained and used by the (c#) client.

For your ELB, an example is provided in the Resources Declaration section of the MarkLogic Server on Amazon Web Services (AWS) Guide

ElasticLoadBalancer is the Load Balancer for all of the ASGs. For details on the AWS::ElasticLoadBalancing::LoadBalancer type, see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-elb.html.

ElasticLoadBalancer:
    Type: 'AWS::ElasticLoadBalancing::LoadBalancer'
    DependsOn:
      - VpcStack
      - ElbSecurityGroup
    Properties:
      AppCookieStickinessPolicy:
        - CookieName: SessionID
          PolicyName: MLSession
      SecurityGroups:
        - !Ref ElbSecurityGroup
      Subnets:
        - !GetAtt [VpcStack, Outputs.PublicSubnet1Id]
        - !If [MultiZone, !GetAtt [VpcStack, Outputs.PublicSubnet2Id], !Ref 'AWS::NoValue']
        - !If [MultiZone, !GetAtt [VpcStack, Outputs.PublicSubnet3Id], !Ref 'AWS::NoValue']
      ConnectionDrainingPolicy:
        Enabled: 'true'
        Timeout: '60'
      CrossZone: 'true'

Transaction Management When Using a Load Balancer

This section applies only to client applications that use multi-statement transactions and interact with a MarkLogic Server cluster through a load balancer. For additional general-purpose load balancer guidelines, see Connecting Through a Load Balancer.

When you use a load balancer, it is possible for requests from your application to MarkLogic Server to be routed to different hosts, even within the same session. This has no effect on most interactions with MarkLogic Server, but operations that are part of the same multi-statement transaction need to be routed to the same host within your MarkLogic cluster. This consistent routing through a load balancer is called session affinity.

Most load balancers provide a mechanism that supports session affinity. This usually takes the form of a session cookie that originates on the load balancer. The client acquires the cookie from the load balancer, and passes it on any requests that belong to the session. The exact steps required to configure a load balancer to generate session cookies depends on the load balancer. Consult your load balancer documentation for details.

To the load balancer, a session corresponds to a browser session, as defined in RFC 2109 (https://www.ietf.org/rfc/rfc2109.txt). However, in the context of a Java Client API application using multi-statement transactions, a session corresponds to a single multi-statement transaction.

The Java Client API leverages a session cookie to preserve host affinity across operations in a multi-statement transaction in the following way. This process is transparent to your application; the information is provided to illustrate the expected load balancer behavior.

  1. When you create a transaction using DatabaseClient.openTransaction, the Java Client API receives a transaction id from MarkLogic and, if the load balancer is properly configured, a session cookie from the load balancer. This information is cached in the Transaction object.
  2. Each time you perform a Java Client API operation that includes a Transaction object, the Java Client API attaches the transaction id and the session cookie to the request(s) it sends to MarkLogic. The session cookie causes the load balancer to route the request to the same host in your MarkLogic cluster that created the transaction.
  3. When MarkLogic receives a request, it ignores the session cookie (if present), but uses the transaction id to ensure the operation is part of the requested transaction. When MarkLogic responds, the load balancer again adds a session cookie, which the Java Client API caches on the Transaction object.
  4. When you commit or roll back a transaction, any cookies returned by the load balancer are discarded since the transaction is no longer valid. This effectively ends the session from the load balancer's perspective because the Java Client API will no longer pass the session cookie around.

Any Java Client API operation that does not include a Transaction object will not include a session cookie (or transaction id) in the request to MarkLogic, so the load balancer is free to route the request to any host in your MarkLogic cluster.

Upvotes: 0

ehennum
ehennum

Reputation: 7335

The general pattern for configuring the load balancer is documented here:

https://docs.marklogic.com/guide/rest-dev/transactions#id_42381

Questions on configuring a specific load balancer are best directed to the vendor or community for that load balancer.

On an unrelated note, the eval endpoint should be used only as a convenience during development and not in production because of the security risk.

As an alternative, consider either installing a main module and using the invoke endpoint or using the out-of-the-box documents endpoint.

Hoping that helps,

Upvotes: 0

Related Questions