如何在并发环境中设计与数据库的http连接(静态变量与否)

时间:2015-10-02 02:57:25

标签: java http amazon-web-services asynchronous concurrency

我使用来自亚马逊网络服务的dynamodb作为我的数据库。 AWS提供的客户端使用http来向数据库发出请求。此代码将位于服务器上,该服务器将接受来自用户的请求并将其发送到dynamodb。我有几个问题如何设计。

由于这是一个接受许多请求的服务器,我使用的是异步客户端http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/AmazonDynamoDBAsyncClient.html而不是同步,因为我不想要阻止每个请求,而是等待将来返回(更好的性能)。是否最好让这个客户端保持静态?

public class Connection {

    AmazonDynamoDBAsyncClient client;
    static DynamoDB dynamoDB;

    public Connection(){

        client = new AmazonDynamoDBAsyncClient(new ProfileCredentialsProvider());
        dynamoDB = null;

    }

    public void setConnection(String endpoint){
        client.setEndpoint(endpoint);
        dynamoDB = new DynamoDB(client);
    }


    public DynamoDB getConnection(){
        return dynamoDB;
    }

}

然后从main调用此静态变量:

public class Main{

    Connection c;
    DynamoDB con;

            public  Main() throws Exception {

                try {
          c = new Connection();
          c.setConnection("http://dynamodbserver:8000");
          con = c.getConnection(); 
          //Do stuff with the connection now
                    } catch (Exception e) {
                     System.err.println("Program failed:");
                     System.err.println(e.getMessage());
                 }

这是一个好方法吗?如果两个用户同时请求使用静态变量会发生什么(我使用的是一个名为vertx的框架,所以这个程序将在一个线程上运行,但是这个程序会有多个实例)?

2 个答案:

答案 0 :(得分:1)

您不应将连接设置为静态成员,而且您设置连接端点的方式是:

  • 非线程安全
  • 可能会导致竞争状况
  

应在AmazonDynamoDBAsyncClient时设置端点   构建然后应该在DynamoDB中使用此Async客户端   施工。另请参阅documentation

为什么不使用AWS提供的SDK dynamoDb?它将以线程安全的方式为您处理连接管理。

另外,如果您仍想推出自己的连接管理解决方案,我建议您使用Dependecy Injection框架。我强烈推荐google-guice

以下是DI通过guice的示例代码。

public class DynamoDBProvider implements Provider<DynamoDB> {
  // Notice that endpoint is set at the time of client construction and the
  // get() method provides an instance of DynamoDb.
  // In another configuration class, we define that DynamoDb will be
  // served under singleton scope, so you will have a single instance.
  private final AmazonDynamoDBAsyncClient asyncClient;

  @Inject
  public DatabaseTransactionLogProvider(
      ProfileCredentialsProvider creds,
      @Named("Endpoint") String endpoint) { 
    this.asyncClient = new AmazonDynamoDBAsyncClient(creds);
    // endpoint is a configuration so it must also be injected to the provider.
    this.setEndpoint(endPoint);
  }

  public DynamoDb get() {
    return new DynamoDB(asyncClient);
  }
}

这是确保您的连接实例作为单身人士服务的方式。

public class DynamoDBModule extends AbstractModule {

    protected void configure() {
       bind(Dynamodb.class).toProvider(DynamoDbProvider.class).in(Singleton.class);
    }
}
  

通过guice或任何其他框架学习DI将需要一些   努力,但它将在使代码可维护方面有很长的路要走   和单元可测试的。请注意利用DI的好处,你   将不得不重构您的项目,以便所有依赖   注入。

答案 1 :(得分:-1)

static会很好,因为它是由所有连接实例共享的。但是您可以通过为连接类引入单例设计模式来进一步改进代码,以便只创建一个连接实例并用于为所有请求提供服务。