Apache spark Spark流:自定义接收器:数据源:Websphere消息队列
我正在尝试在Spark streaming中实现WSMQ数据源的客户接收器。我遵循提供的示例 后来,我在一次会议上学习了这个例子 我收到三个问题: 1:错误(程序运行一段时间后出现此错误)Apache spark Spark流:自定义接收器:数据源:Websphere消息队列,apache-spark,ibm-mq,spark-streaming,custom-receiver,Apache Spark,Ibm Mq,Spark Streaming,Custom Receiver,我正在尝试在Spark streaming中实现WSMQ数据源的客户接收器。我遵循提供的示例 后来,我在一次会议上学习了这个例子 我收到三个问题: 1:错误(程序运行一段时间后出现此错误) 即使我在创建会话时使用了此代码,程序也不会从WSMQ中删除消息 MQQueueSession qSession = (MQQueueSession) qCon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); 我需要实现一个可靠的接收器,在定制接收器
MQQueueSession qSession = (MQQueueSession) qCon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
接收器
,在定制接收器sparkapi中进行了解释。它说:
要实现可靠的接收器,必须使用存储(多条记录)来存储数据。这种存储风格是一种阻塞调用,只有在所有给定记录都存储在Spark中之后才会返回。如果接收器配置的存储级别使用复制(默认情况下已启用),则此调用将在复制完成后返回。因此,它确保数据被可靠地存储,并且接收器现在可以适当地确认源。这确保当接收器在复制数据中间失败时不会产生数据——缓冲的数据将不被确认,因此稍后将被源怨恨。接收器
代码如下:
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();
}
public类JavaConnector扩展接收器{
字符串host=null;
int端口=-1;
字符串qm=null;
字符串qn=null;
字符串通道=空;
瞬态Gson Gson=新Gson();
瞬态MQQueueConnection qCon=null;
字符串主题=null;
枚举=空;
专用静态MQQueueReceiver=null;
公共JavaConnector(字符串主机、int端口、字符串qm、字符串通道、字符串qn){
超级(仅限存储级内存_2());
this.host=host;
this.port=端口;
这个。qm=qm;
这个。qn=qn;
这个通道=通道;
}
public void onStart(){
//启动通过连接接收数据的线程
新线程(){
@重写公共无效运行(){
试一试{
initConnection();
接收();
}
捕获(JMEX)
{
例如printStackTrace();
}
捕获(例外情况除外)
{
例如printStackTrace();
}
}
}.start();
}
公共void onStop(){
//除了调用receive()的线程之外,没有什么可做的
//被设计为自行停止,isStopped()返回false
}
/**创建MQ连接并接收数据,直到接收器停止*/
private void receive()引发InterruptedException{
System.out.print(“开始从MQ接收消息”);
试一试{
JMSTextMessage receivedMessage=null;
int-cnt=0;
//JMSTextMessage receivedMessage=(JMSTextMessage)receiver.receive(10000);
布尔标志=假;
而(!isStopped()&&enumeration.hasMoreElements()&&cnt最终我能够解决这个问题。
解决方案1:热气腾腾的上下文试图写入卡夫卡,因为卡夫卡已经关闭,它给了我IO错误。我太傻了。:)
解决方案2:我应该使用MessageListener,QueueBrowser用于读取消息,但实际上并不使用消息
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();
}