首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java和mysql高并发瓶颈解决方案

Java和mysql高并发瓶颈解决方案
EN

Stack Overflow用户
提问于 2017-06-23 18:33:15
回答 2查看 652关注 0票数 0

我们正在开发一个车辆跟踪系统,在该系统中,几个GPS设备继续使用Tcp连接将它们的GPS位置发送到服务器。Tcp通信器对GPS位置进行解码,并将数据插入数据库,在插入之前,我们会进行一些选择和更新,但我所做的全部工作都是使用准备好的语句。现在,TCP通信器的一个线程在创建线程后为一个设备request.Immediately提供服务--我们从池中获得一个连接。在解码GPS数据之后,我们对每个数据执行多个选择、更新和插入。随着设备数量的增加,到Mysql数据库的并发连接的数量也在增加。我们现在预计会有30到5万台设备在传输数据,下面的每一个minute.Currently都是整个tcp通信器的代码片段。我知道最终我们将面临两个插入瓶颈的数据库。克服这种情况的最佳解决方案是什么?Java也能处理这么多并发性吗?

代码语言:javascript
复制
public class comm8888 {
    HikariDataSource connectionPool = null;
    private Socket receivedSocketConn1;
    ConnectionHandler(Socket receivedSocketConn1) {
      this.receivedSocketConn1=receivedSocketConn1;
    }
    Connection dbconn = null;
    public void run() { // etc
     DataOutputStream w = null;
     DataInputStream r = null;  
     String message="";
     receivedSocketConn1.setSoTimeout(60000);
       dbconn = connectionPool.getConnection();
     dbconn.setAutoCommit(false);
     try {
         w = new DataOutputStream(new BufferedOutputStream(receivedSocketConn1.getOutputStream()));
         r = new DataInputStream(new BufferedInputStream(receivedSocketConn1.getInputStream()));
         while ((m=r.read()) != -1){
             //multiple prepared based sql select,update and insert here.
         }
     }
     finally{
        try {
            if ( dbconn != null ) {
              dbconn.close();
            }
        }
        catch(SQLException ex){
             ex.printStackTrace();
        }
        try{
           if ( w != null ){
                w.close();
                r.close();
                receivedSocketConn1.close();
            }
        }
        catch(IOException ex){
           ex.printStackTrace(System.out);
        }
      }
   }
}


    public static void main(String[] args) {
      new comm8888();
    }
    comm8888() {
      try {

          HikariConfig config = new HikariConfig();
                config.setJdbcUrl("jdbc:mysql://localhost:3306/testdata"); 
                config.setUsername("****"); 
                config.setPassword("****");      
                config.setMaximumPoolSize(20);      
          connectionPool = new HikariDataSource(config); // setup the connection pool           
       }
          catch (Exception e) {
                e.printStackTrace(System.out);
         }
          try 
          {
                   final ServerSocket serverSocketConn = new ServerSocket(8888);                
                   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);

          }

    }
} 
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-06-23 19:36:07

从评论转到这里来解释更多。

代码语言:javascript
复制
dbconn = connectionPool.getConnection();
...
while (...) {
   // dbconn is held for up to 60 seconds which is not scalable
} 

因此,您可以在实际需要做些什么以避免长时间的db连接时获得一个dbConn。

代码语言:javascript
复制
while (...) {
    // got some more data to process - now get a dbConn 
    dbconn = connectionPool.getConnection();
    // do inserts, etc.
    // commit and release the connection!
} 

另一种方法是通过发布到队列或调用REST服务来完全卸载与数据库的交互。

代码语言:javascript
复制
while (...) {
    // got some more data to process
    // publish the data to a JMS queue
    // or post the data to a REST endpoint
    // there is no database interaction here at all!
} 

然后,消息使用者或REST端点处理数据并插入/更新db。这些消息/请求中的每一个都是小的,因此db连接只能从池借用几毫秒(最多几毫秒)。处理JMS消息/POST请求的服务器集群可以独立于最初接收原始套接字数据的服务器进行缩放。

票数 1
EN

Stack Overflow用户

发布于 2017-06-23 18:53:08

一个问题是,如果设备数量增加,每个设备都试图连接db,这是不可扩展的解决方案。一种方法是一批一批地处理.Store队列中的所有消息,直到它达到批处理大小为止,然后插入,因为batch.It将保存网络,因为您不是一个接一个地插入记录。

如果您需要进一步的可扩展解决方案,那么可以使用nosql解决方案或主主复制多节点拓扑来支持大流量和可用性。

对于select和update,您可以使用合并查询,该查询需要在使用时进行分析,如果存在,case.Merge查询将更新,如果不存在,将进行插入。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44727922

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档