我目前有两个客户端(Producer / Consumer),我正在尝试通过JMS发送一个大文件。我成功生成并将文件发送到JMS服务器没有任何问题。问题是当我尝试使用消息时,我得到以下异常:
Aug 24, 2012 11:25:37 AM client.Client$1 onException
SEVERE: Connection to the Server has been lost, will retry in 30 seconds. weblogic.jms.common.LostServerException: java.lang.Exception: weblogic.rjvm.PeerGoneException: ; nested exception is:
weblogic.socket.MaxMessageSizeExceededException: Incoming message of size: '10000080' bytes exceeds the configured maximum of: '10000000' bytes for protocol: 't3'
<Aug 24, 2012 11:25:37 AM CDT> <Error> <Socket> <BEA-000403> <IOException occurred on socket: Socket[addr=127.0.0.1/127.0.0.1,port=7001,localport=51764]
weblogic.socket.MaxMessageSizeExceededException: Incoming message of size: '10000080' bytes exceeds the configured maximum of: '10000000' bytes for protocol: 't3'.
weblogic.socket.MaxMessageSizeExceededException: Incoming message of size: '10000080' bytes exceeds the configured maximum of: '10000000' bytes for protocol: 't3'
at weblogic.socket.BaseAbstractMuxableSocket.incrementBufferOffset(BaseAbstractMuxableSocket.java:174)
at weblogic.rjvm.t3.MuxableSocketT3.incrementBufferOffset(MuxableSocketT3.java:351)
at weblogic.socket.SocketMuxer.readFromSocket(SocketMuxer.java:983)
at weblogic.socket.SocketMuxer.readReadySocketOnce(SocketMuxer.java:922)
我认为这与我在WebLogic中的MaxMessage大小设置有关,而不是代码问题(但我当然可能是错的)。这是我的最大消息大小的settigns
我不确定为什么我会收到此异常,因为此协议的最大邮件大小大于异常所声称的...任何想法?
我也尝试过添加服务器启动参数-Dweblogic.MaxMessageSize = 200000000,但无济于事。
以下是我设置MessageListener和消息使用者本身的一些代码。
public boolean setClient(MessageListener listener) {
try {
Properties parm = new Properties();
parm.setProperty("java.naming.factory.initial",
"weblogic.jndi.WLInitialContextFactory");
parm.setProperty("java.naming.provider.url", iProps.getURL());
parm.setProperty("java.naming.security.principal", iProps.getUser());
parm.setProperty("java.naming.security.credentials",
iProps.getPassword());
ctx = new InitialContext(parm);
final QueueConnectionFactory connectionFactory = (QueueConnectionFactory) ctx
.lookup(iProps.getConFactory());
connection = connectionFactory.createQueueConnection();
((WLConnection) connection)
.setReconnectPolicy(JMSConstants.RECONNECT_POLICY_ALL);
((WLConnection) connection).setReconnectBlockingMillis(30000L);
((WLConnection) connection).setTotalReconnectPeriodMillis(-1L);
session = connection.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE);
queue = (Queue) ctx.lookup(iProps.getQueue());
// The following code in the switch statement is the only code that
// differs for the producer and consumer.
switch (cType)
{
case PRODUCER: {
producer = (WLMessageProducer) session
.createProducer(queue);
// Setting to send large files is done in WebLogic
// Administration Console.
// Set
producer.setSendTimeout(60000L);
break;
}
case CONSUMER: {
consumer = session.createConsumer(queue);
if (listener != null) {
consumer.setMessageListener(listener);
}else{
log.warning("A Message listener was not set for the consumer, messages will not be acknowledged!");
}
break;
}
default:
log.info("The client type " + cType.toString()
+ " is not currently supported!");
return false;
}
connection.setExceptionListener(new ExceptionListener() {
@Override
public void onException(JMSException arg0) {
Logger log2 = new MyLogger().getLogger("BPEL Client");
if (arg0 instanceof LostServerException) {
log2.severe("Connection to the Server has been lost, will retry in 30 seconds. "
+ arg0.toString());
} else {
log2.severe(arg0.toString());
}
}
});
shutdownListener = new ShutdownListener(connection, session, producer, consumer);
connection.start();
log.info("Successfully connected to " + iProps.getURL());
return true;
} catch (JMSException je) {
log.severe("Could not connect to the WebLogic Server, will retry in 30 seconds. "
+ je.getMessage());
try {
Thread.sleep(30000L);
} catch (InterruptedException e) {
log.warning(e.toString());
}
return setClient(listener);
} catch (Exception e) {
log.severe("Could not connect to the WebLogic Server, will retry in 30 seconds. "
+ e.toString());
try {
Thread.sleep(30000L);
} catch (InterruptedException ie) {
log.warning(ie.toString());
}
return setClient(listener);
}
}
这是MessageListener:
public class ConsumerListener implements MessageListener {
private Logger log;
private File destination;
private Execute instructions;
public ConsumerListener(Execute instructions, File destination) {
this.instructions = instructions;
this.destination = destination;
log = new MyLogger().getLogger("BPEL Client");
}
@Override
public void onMessage(Message arg0) {
try {
if (arg0.getJMSRedelivered()) {
log.severe("A re-delivered message has been received, and it has been ignored!"
+ arg0.toString());
} else {
try {
if (arg0 instanceof TextMessage) {
consumeMessage((TextMessage) arg0);
} else if (arg0 instanceof BytesMessage) {
consumeMessage((BytesMessage) arg0);
} else {
log.warning("Currently, only TextMessages and BytesMessages are supported!");
}
} catch (JMSException e) {
log.severe(e.toString());
} catch (IOException e) {
log.severe(e.toString());
} catch (Throwable t) {
log.severe(t.toString());
}
}
} catch (JMSException e) {
log.severe(e.toString());
}
}
/**
* Unwraps the JMS message received and creates a file and a control file if
* there are instructions present.
*
* @param textMessage
* JMS message received to be consumed.
* @throws JMSException
* @throws IOException
*/
protected void consumeMessage(TextMessage textMessage) throws JMSException,
IOException {
// ***All properties should be lowercase. for example fileName
// should be
// filename.***
String fileName = textMessage.getStringProperty("filename");
if (fileName == null || fileName.isEmpty()) {
fileName = textMessage.getStringProperty("fileName");
}
if (fileName != null && !fileName.isEmpty()) {
// Check if the
// file name is equal to the shutdown file. If it
// is, shutdown the consumer. This is probably not a good way to
// do this, as the program can no longer be shutdown locally!
// We have a file in the queue, need to create the file.
createFile(destination.getAbsolutePath() + "\\" + fileName,
textMessage.getText());
log.info("Done creating the file");
String inst = textMessage.getStringProperty("instructions");
// If there are instructions included, then create the
// instruction file, and route the message based on this file.
if (inst != null && !inst.isEmpty()) {
// We need to rout the file.
log.info("Instructions found, executing instructions");
String[] tokens = fileName.split("\\.");
String instFileName = "default.ctl";
if (tokens.length == 2) {
instFileName = tokens[0] + ".ctl";
}
File controlFile = createFile(destination.getAbsolutePath()
+ "\\" + instFileName, inst);
Control control = new Control(controlFile);
instructions.execute(control);
log.info("Done executing instructions");
} else {
log.info("No instructions were found");
}
log.info("Done consuming message: " + textMessage.getJMSMessageID());
}
}
/**
* Unwraps the JMS message received and creates a file and a control file if
* there are instructions present.
*
* @param bytesMessage
* The bytes payload of the message.
* @throws JMSException
* @throws IOException
*/
protected void consumeMessage(BytesMessage bytesMessage)
throws JMSException, IOException {
// ***All properties should be lowercase. for example fileName
// should be
// filename.***
log.info("CONSUME - 1");
String fileName = bytesMessage.getStringProperty("filename");
if (fileName == null || fileName.isEmpty()) {
fileName = bytesMessage.getStringProperty("fileName");
}
if (fileName != null && !fileName.isEmpty()) {
// Check if the
// file name is equal to the shutdown file. If it
// is, shutdown the consumer. This is probably not a good way to
// do this, as the program can no longer be shutdown locally!
// We have a file in the queue, need to create the file.
byte[] payload = new byte[(int) bytesMessage.getBodyLength()];
bytesMessage.readBytes(payload);
createFile(destination.getAbsolutePath() + "\\" + fileName, payload);
log.info("Done creating the file");
String inst = bytesMessage.getStringProperty("instructions");
// If there are instructions included, then create the
// instruction file, and route the message based on this file.
if (inst != null && !inst.isEmpty()) {
// We need to rout the file.
log.info("Instructions found, executing instructions");
String[] tokens = fileName.split("\\.");
String instFileName = "default.ctl";
if (tokens.length == 2) {
instFileName = tokens[0] + ".ctl";
}
File controlFile = createFile(destination.getAbsolutePath()
+ "\\" + instFileName, inst);
Control control = new Control(controlFile);
instructions.execute(control);
log.info("Done executing instructions");
} else {
log.info("No instructions were found");
}
log.info("Done consuming message: "
+ bytesMessage.getJMSMessageID());
}
}
/**
* Creates a file with the given filename (this should be an absolute path),
* and the text that is to be contained within the file.
*
* @param fileName
* The filename including the absolute path of the file.
* @param fileText
* The text to be contained within the file.
* @return The newly created file.
* @throws IOException
*/
protected File createFile(String fileName, String fileText)
throws IOException {
File toCreate = new File(fileName);
FileUtils.writeStringToFile(toCreate, fileText);
return toCreate;
}
/**
* Creates a file with the given filename (this should be an absolute path),
* and the text that is to be contained within the file.
*
* @param fileName
* The filename including the absolute path of the f ile.
* @param fileBytes
* The bytes to be contained within the file.
* @return The newly created file.
* @throws IOException
*/
protected File createFile(String fileName, byte[] fileBytes)
throws IOException {
File toCreate = new File(fileName);
FileUtils.writeByteArrayToFile(toCreate, fileBytes);
return toCreate;
}
}
答案 0 :(得分:8)
您还必须从WLS控制台增加最大邮件大小,如所有托管服务器的屏幕截图所示。
然后执行重启,问题就会解决。
此外,还有第二种替代解决方案。根据{{3}}:
调整MessageMaximum限制
如果推送到使用者的消息的聚合大小大于当前协议的最大消息大小(默认大小为10 MB,并且是基于每个WebLogic Server实例使用控制台配置的,并且基于每个客户端使用Dweblogic.MaxMessageSize命令行属性),消息传递失败。
在客户端设置最大邮件大小
在发送和接收大邮件时,除了WebLogic Server实例之外,您可能还需要配置WebLogic客户端。要在客户端上设置最大邮件大小,请使用以下命令行属性:
<强> -Dweblogic.MaxMessageSize 强>
注意:此设置适用于传递到客户端的所有WebLogic Server网络数据包,而不仅仅是与JMS相关的数据包。
<强>编辑:强>
可以通过以下一项或多项操作解决此问题。
应用 weblogic.MaxMessageSize 属性的
- 配置系统属性-Dweblogic.MaxMessageSize
- 使用管理员和所有托管服务器的WLS控制台增加最大邮件大小。 WLS控制台中的步骤是:server / Protocols / General
- 从WLS控制台增加最大邮件大小。 WLS控制台中的步骤是:队列/配置/阈值和配额/最大邮件大小
程序
保留setDomainEnv文件的备份。停止所有服务器。在每个setDomainEnv文件中添加-Dweblogic.MaxMessageSize = yourValue,更具体地说,在EXTRA_JAVA_PROPERTIES行中添加。然后首先启动ADMIN,当ADMIN处于RUNNING状态时,启动MANAGED服务器。
我希望这会有所帮助。
答案 1 :(得分:0)
在我的情况下,设置-Dweblogic.MaxMessageSize解决了这个问题。我的问题是消息大小的最大限制应该是多少?我们只是不能继续增加 邮件大小以解决此问题。有没有办法优化此值 还有其他一些价值观吗?