简体   繁体   English

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

[英]How to design http connection to database in concurrent environment (static variable or not)

I am using dynamodb from amazon web services as my database. 我正在使用来自Amazon Web Services的dynamodb作为数据库。 The client providd by AWS uses http to make the requests to the database. 由AWS提供的客户端使用http向数据库发出请求。 This code will be on a server which will accept requests from users and send it over to dynamodb. 此代码将在服务器上,该服务器将接受来自用户的请求并将其发送到dynamodb。 I had a few questions how to design this then. 我当时有几个问题,如何设计。

Since this is a server accepting many requests I am using the async client http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/AmazonDynamoDBAsyncClient.html instead of the sync because I don't want for every request to block and instead I will wait for a future to return (better performance). 由于这是一台接受许多请求的服务器,因此我正在使用异步客户端http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/AmazonDynamoDBAsyncClient.html而不是同步,因为我不这样做不想阻止每个请求,而是我将等待将来的返回(更好的性能)。 Is it best to make this client static? 最好使此客户端静态?

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;
    }

}

Then to call this static variable from main: 然后从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());
                 }

Is this a good approach? 这是一个好方法吗? What will happen if two users are requesting to use the static variable at the same time (I am using a framework called vertx so this program will run on a single thread, but there will be multiple instances of this program)? 如果两个用户同时请求使用静态变量(我使用的是vertx框架,那么该程序将在单个线程上运行,但是该程序会有多个实例)会发生什么?

You should not set the connection as static member, Also the way you are setting endpoints of your connection is: 您不应将连接设置为静态成员,另外,设置连接端点的方式是:

  • not thread safe 不是线程安全的
  • may lead to race condition 可能导致比赛状况

Endpoints should be setup at the time of AmazonDynamoDBAsyncClient construction and then this Async client should be used in the DynamoDB construction. 应在构建AmazonDynamoDBAsyncClient时设置端点,然后在DynamoDB构建中使用此异步客户端。 Please also refer to the documentation . 另请参阅文档

Why don't you use the SDK provided with AWS for dynamoDb ? 您为什么不将AWS 随附的SDK用于dynamoDb It will take care of connection management for you in a thread safe manner. 它将以线程安全的方式为您管理连接管理。

On a side note, If you still want to roll out your own solution for connection management, I would recommend that you use a Dependecy Injection framework. 附带说明一下,如果您仍然想推出自己的连接管理解决方案,我建议您使用Dependecy Injection框架。 I would highly recommend google-guice . 我强烈推荐google-guice

Here is the sample code of DI through guice. 这是通过guice进行DI的示例代码。

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);
  }
}

This is how you ensure your connection instance is served as singleton. 这是确保连接实例用作单例的方式。

public class DynamoDBModule extends AbstractModule {

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

Learning DI through guice or any other framework will require some effort but it will go aa long way in making your code maintainable and unit testable. 通过guice或其他任何框架学习DI都需要付出一些努力,但要使代码可维护和可单元测试将大有帮助。 Please be aware to utilize the benefits of DI, you will have to refactor your project so that all depedencies are injected. 请注意,要利用DI的好处,您将必须重构项目,以便注入所有缺陷。

static would be good since it is shared by all connection instance. 静态将是一件好事,因为它由所有连接实例共享。 but you can further improve the code by introducing singleton design pattern for connection class so that only one connection instance will be created and used for serve all the requests. 但是您可以通过为连接类引入单例设计模式来进一步改进代码,以便仅创建一个连接实例并将其用于满足所有请求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM