Spark Streaming:自定义接收器:数据源:Websphere Message Queue

时间:2016-01-29 22:35:09

标签: apache-spark ibm-mq spark-streaming custom-receiver

我正在尝试在Spark流中为WSMQ数据源实现Customer接收器。我按照here提供的示例。

后来我在this Github repository跟随了示例。

我遇到了三个问题:

1:错误(程序运行一段时间后出现此错误)

java.net.ConnectException: Connection refused
    at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
    at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:739)
    at org.apache.kafka.common.network.Selector.poll(Selector.java:238)
    at org.apache.kafka.clients.NetworkClient.poll(NetworkClient.java:192)
    at org.apache.kafka.clients.producer.internals.Sender.run(Sender.java:191)
    at org.apache.kafka.clients.producer.internals.Sender.run(Sender.java:122)
    at java.lang.Thread.run(Thread.java:745)
  1. 即使我在创建会话时使用了此代码,程序也不会从WSMQ中删除消息

    MQQueueSession qSession = (MQQueueSession) qCon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
    
  2. 我需要在Custom Receiver Spark API中实现可靠的Receiver。它说:

    要实现可靠的接收器,您必须使用存储(多条记录)来存储数据。这种存储风格是一个阻塞调用,只有在所有给定记录都存储在Spark中之后才会返回。如果接收方配置的存储级别使用复制(默认情况下启用),则此复制在复制完成后返回。因此,它确保数据可靠地存储,并且接收器现在可以适当地确认源。这确保了当接收器在复制数据的过程中出现故障时不会导致数据 - 缓冲的数据将不会被确认,因此稍后将被源重新发送。

  3. 我不知道如何处理商店(多条记录)?

    我无法弄清楚为什么会发生这些错误以及如何实现可靠的Receiver

    以下是代码:

    public class JavaConnector extends Receiver<String> {
    
        String host = null;
        int port = -1;
        String qm=null;
        String qn=null;
        String channel=null;
        transient Gson gson=new Gson();
        transient MQQueueConnection qCon= null;
        String topic=null;
    
        Enumeration enumeration =null;
        private static MQQueueReceiver receiver = null;
    
    
        public JavaConnector(String host , int port, String qm, String channel, String qn) {
            super(StorageLevel.MEMORY_ONLY_2());
            this.host = host;
            this.port = port;
            this.qm=qm;
            this.qn=qn;
            this.channel=channel;
    
    
        }
    
        public void onStart()  {
            // Start the thread that receives data over a connection
            new Thread()  {
                @Override public void run() {
                    try {
                        initConnection();
                        receive();
                    }
                    catch (JMSException ex)
                    {
                        ex.printStackTrace();
                    }
                    catch (Exception ex)
                    {
                        ex.printStackTrace();
                    }
                }
            }.start();
        }
    
        public void onStop() {
    
            // There is nothing much to do as the thread calling receive()
            // is designed to stop by itself isStopped() returns false
    
        }
    
        /** Create a MQ connection and receive data until receiver is stopped */
        private void receive() throws InterruptedException {
            System.out.print("Started receiving messages from MQ");
    
    
            try {
    
                JMSTextMessage receivedMessage= null;
                int cnt =0;
    
                //JMSTextMessage receivedMessage = (JMSTextMessage) receiver.receive(10000);
    
                boolean flag=false;
                while (!isStopped() && enumeration.hasMoreElements()&&cnt<50 )
                {
    
                    receivedMessage= (JMSTextMessage) enumeration.nextElement();
                    receivedMessage.acknowledge();
                    String userInput = receivedMessage.getText();
    
                        ArrayList<String> list = new ArrayList<String>();
                        list.add(userInput);
                        Iterator<String> itr = list.iterator();
                        store(itr);
                    cnt++;
    
                }
                /*while (!isStopped() && receivedMessage !=null)
                {
    
                   // receivedMessage= (JMSTextMessage) enumeration.nextElement();
                    String userInput = receivedMessage.getText();
    
                    store(userInput);
            receivedMessage.acknowledge();
    
                }*/
    
                // Restart in an attempt to connect again when server is active again
                //restart("Trying to connect again");
    
                stop("No More Messages To read !");
                qCon.close();
                System.out.println("Queue Connection is Closed");
    
            }
            catch(Exception e)
            {      Thread.sleep(100);
                System.out.println("WRONG"+e.toString());
                e.printStackTrace();
                restart("Trying to connect again");
            }
            catch(Throwable t) {
                Thread.sleep(100);
                System.out.println("WRONG-1"+t.toString());
                // restart if there is any other error
                restart("Error receiving data", t);
            }
    
    
    
        }
    
        public void initConnection() throws JMSException,InterruptedException {
            try {
                MQQueueConnectionFactory conFactory = new MQQueueConnectionFactory();
                conFactory.setHostName(host);
                conFactory.setPort(port);
                conFactory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
                conFactory.setQueueManager(qm);
                conFactory.setChannel(channel);
                conFactory.setMsgBatchSize(100);
    
    
                qCon = (MQQueueConnection) conFactory.createQueueConnection();
                MQQueueSession qSession = (MQQueueSession) qCon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
                MQQueue queue = (MQQueue) qSession.createQueue(qn);
                MQQueueBrowser browser = (MQQueueBrowser) qSession.createBrowser(queue);
                qCon.start();
                //receiver = (MQQueueReceiver) qSession.createReceiver(queue);
                enumeration= browser.getEnumeration();
    
    
            } catch (Exception e) {
                Thread.sleep(1000);
            }
        }
    
        @Override
        public StorageLevel storageLevel() {
            return StorageLevel.MEMORY_ONLY_2();
        }
    

1 个答案:

答案 0 :(得分:1)

最后我能够解决这个问题。 解决方案1:蒸汽上下文试图写入Kafka,因为kafka已关闭并且它给了我IO错误。这对我来说很愚蠢。 :)

解决方案2:我应该使用MessageListener,QueueBrowser用于读取它实际上不消息的消息。