2012-03-01 65 views
-1

我测试了一个套接字连接程序,其中套接字连接本身是一个单独的线程,然后它将排队,另一个单独的线程用于dbprocessor将从队列中选择并运行一些sql语句。所以我注意到这里是db处理的瓶颈。我想得到一些想法是我正在做正确的架构,或者我应该改变或改进我的设计流程?哪一个适合的架构?

要求是通过套接字连接捕获数据并通过db进程运行,然后相应地存储它。

public class cServer 
{ 
private LinkedBlockingQueue<String> databaseQueue = new LinkedBlockingQueue<String>(); 

    class ConnectionHandler implements Runnable { 
     ConnectionHandler(Socket receivedSocketConn1) { 
      this.receivedSocketConn1=receivedSocketConn1; 
     } 


     // gets data from an inbound connection and queues it for databse update 

     public void run(){ 
     databaseQueue.add(message); // put to db queue 
     } 
    } 
    class DatabaseProcessor implements Runnable { 
    public void run(){ 
      // open database connection 
      createConnection(); 
      while (true){ 
       message = databaseQueue.take(); // keep taking message from the queue add by connectionhandler and here I will have a number of queries to run in terms of select,insert and updates. 
      } 
    } 

    void createConnection(){ 
     System.out.println("Crerate Connection"); 
     connCreated = new Date(); 
     try{ 
     dbconn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test1?"+"user=user1&password=*******"); 
     dbconn.setAutoCommit(false); 
     } 
     catch(Throwable ex){ 
      ex.printStackTrace(System.out); 
     } 
    } 
    } 

    public void main() 
    { 
    new Thread(new DatabaseProcessor()).start(); //calls the DatabaseProcessor 
    try 
    { 
     final ServerSocket serverSocketConn = new ServerSocket(8000);    
     while (true){ 
     try{ 
      Socket socketConn1 = serverSocketConn.accept(); 
      new Thread(new ConnectionHandler(socketConn1)).start();      
     } 
     catch(Exception e){ 
     e.printStackTrace(System.out); 
     } 
     } 
    } 
    catch (Exception e){ 
     e.printStackTrace(System.out); 
    } 

    } 

} 
+3

架构_必须由它的要求来驱动。由于您没有给出任何要求,所以确定提议的架构的适用性的唯一方法是它是否完全无法工作,或者它会如何。 – cdeszaq 2012-03-01 18:37:11

+0

您的队列在哪里/如何定义?线程安全吗?它是同步的吗? – 2012-03-01 18:50:18

+0

@alek我已经添加了类名cServer,下面是我定义队列的地方 – user837306 2012-03-01 18:57:17

回答

1

通常,您的架构听起来是正确的。您需要确保在从队列读取/写入队列时,两个线程可以正确同步。

我不确定你的意思是“瓶颈,db处理”?如果数据库处理需要很长时间,并且最终得到一个长队列,那么除了执行数据库处理的多个线程(假设当然可以并行处理)或者在数据库线程。

如果您发布了一些您认为会导致问题的特定代码,我们可以再看一下。

+0

我已经放了一些我的代码片段。你能在这里看到任何错误的设计吗?我试图通过添加一行这个新线程来生成另一个额外的数据库线程(new DatabaseProcessor())。但我最终得到错误显示我的MySQL驱动程序不存在。 – user837306 2012-03-01 18:43:25

1

这很难(阅读'不可能')来判断没有要求的架构。所以我只想做一些:

最大吞吐量: 不要使用数据库,写入平面文件,可能存储在像固态光盘一样快的东西上。

保证持久性(如果用户得到的答案不是由错误组成,数据必须安全地存储): 使整个事情成为单线程,将所有内容都保存在具有冗余光盘的数据库中。确保你有一个知道备份和恢复的称职的DBA。定期测试这些。

完成用户请求的最短时间: 您的方法似乎是合理的。

完成用户请求的最短时间+最大化吞吐量+良好持久性(这意味着什么): 您的方法看起来不错。您可能计划处理数据库请求的多个线程。但是测试你实际获得的吞吐量(更多)以及瓶颈在哪里(网络,数据库CPU,IO,锁争用...)。确保你不使用并发方法引入错误。

+0

我已添加我的代码片段。基本上套接字获取数据,然后我运行了一些SQL查询,最后存储到数据库。数据库处理确实是一个漫长的过程,涉及许多查询都涉及验证。 – user837306 2012-03-01 18:46:01

+0

考虑到这些要求,您可能会考虑一个NoSQL数据库,如Apache Cassandra,它具有非常高的吞吐量,具有持久的写入,但比平面文件(具有索引等)功能更强大,并可横向扩展到多个节点。 – DNA 2012-03-01 18:50:09

+0

@我现在正在使用mysql。那么我现在可以在这个结构上做些什么改进? – user837306 2012-03-01 18:54:03

1

对于这个简单的任务,您不需要两个线程。只需读取套接字并执行语句即可。

+0

为了避免复杂性,我们删除了2个线程,这些线程相应地处理了电子邮件和短信。因此,您是否仍然建议只使用一个线程?除此之外,我们注意到这个队列机制的好处在于,根据发送机制,传入消息的顺序保持不变。因此,插入到数据库中的消息到达的顺序如下。 – user837306 2012-03-02 13:46:58

+0

@ user837306。队列保存的顺序就是从套接字进入的顺序。这不是一个附加价值。 – EJP 2012-03-03 02:56:34

+0

我也同意这一点,让我重新看看我的团队。但除此之外,我记得我告诉过你,我们也有一条短信,另一条是电子邮件。因此,你的建议是将所有内容放在一个线程中,并保持短信和电子邮件的单独功能是你正在引导的方向。就记忆效应或性能而言,此方法与单线程之间有什么区别?我们发现这些方法的执行速度非常快,但是当队列建立时问题就开始了。 – user837306 2012-03-03 03:13:45