2016-08-24 76 views
0

我不确定以下情况的最佳解决方案是:在写入数据库时​​使用java读取tcp流

我的Java程序永久从tcp-stream中读取数据。同时,将这些数据保存到数据库是必要的。应该写入数据库的数据量可能有所不同

我已经阅读了很多关于消息队列系统等等。详细地说,我的解决方案会考虑使用LinkedBlockingQueue。从而,有两个线程: 一个)启动,其将执行从TCP流 b读取)开始一个消费者威胁,这将从流中(解析)数据写入到数据库

生产者威胁在(示例 - )的代码看起来像以下:

Main.java

public static void main(String[] args) { 
     LinkedBlockingQueue queue = new LinkedBlockingQueue(50); 
     Producer producer = new Producer(queue); 
     Consumer consumer = new Consumer(queue, producer); 

Produer.java

public class Producer implements Runnable { 
    private LinkedBlockingQueue queue; 
    private boolean running; 

    public Producer(LinkedBlockingQueue queue) { 
     this.queue = queue; 
     running = true; 
    } 

@Override 
    public void run() { 
    //read TCP-Stream here and save parsed messages to queue 
    } 
    public boolean isRunning() { 
     return running; 
    } 

Consumer.java

public class Consumer implements Runnable { 
    private Producer producer; 
    private LinkedBlockingQueue queue; 

    public Consumer(LinkedBlockingQueue queue, Producer producer) { 
     this.queue = queue; 
     this.producer = producer; 
    } 
    @Override 
    public void run() { 
     //insert data into database here 
     if(producer.isRunning()) { 
      //while producer is running, data needs to be inserted to database 
     } 
    } 

这是您会推荐使用的解决方案吗?或者你知道更好的解决方案吗?

谢谢!

+0

是的,这几乎是一种标准方法。你也可以看看ExecutorService。复制[生产者/消费者线程使用队列](http://stackoverflow.com/questions/2332537/producer-consumer-threads-using-a-queue)(因为代码不是特定于tcp /数据库)。 –

+0

我没有看到两个线程的原因。我会一起做。没有收获。 – EJP

回答

2

你自己的建议非常好。

最终你试图解决的是back pressure的问题,即如果你的数据接收速度比你写的数据库更快。这可能仅仅是因为有大量数据到达或者仅仅是因为你的目的地暂时不可用。无论哪种方式,这是你需要处理的情况。

在您提出的解决方案中,这由内存中的暂存区域(=您的队列)处理。只要你有足够的内存,并且你不会太在意停电的数据,那么内存策略对你来说就可以正常工作。突发事件将被Java应用程序中越来越多的内存吸收。本身并不是一个问题,但请记住,当您的队列最终耗尽时,JVM GC将启动并从JVM堆中再次释放内存。但从外部看,即从操作系统的角度来看,内存可能永远不会被释放。 JVM将内存释放回操作系统是非常非常保守的。再次,在大多数情况下,这不是问题。

如果您有更严格的需求,那么您需要考虑更“健壮”的临时区域而不是RAM,例如本地磁盘。根据我的经验,您提出的解决方案适合95%的用例。

+0

TCP将通过对发件人施加压力自动处理背压。应用程序无需参与此操作。 – EJP

+0

@EJP。我只是比你有更广泛的“背压”定义,而不仅仅是低层网络的东西。 – peterh

+0

不,我们有相同的定义,我只是没有看到应用程序涉及它的任何需要。如果你有两个线程和一个队列,你将不得不限制队列,以免内存不足,所以你最终会得到TCP反压,同时你没有做任何有用的事情,你已经只是读了很多你还没有处理过的数据。重点是什么? – EJP

相关问题