接上一部分.
一, 需求:
每隔5分钟从photo表中把状态为I的图片用base64加密发送到ODM系统,同时把图片状态更改为P.
每隔2小时,把状态为P的图片进行重发.
每隔5分钟从ODM系统获取图片处理的状态,如何成功更新状态为A,失败更新为E,相应记录异常原因.
二, 架构:
我们的消息传递是通过JMS实现的,连接设置如下:
图片是通过base64处理的,使用dom4j生成相应的消息格式
备注: 经过base64处理后文件会加大33.3%
三, 准备工作:
1), wlclient-12.1.3.jar(通过weblogic生成)
2), 发送message的格式样例
3), 所需的URL及相应的queue
4),确认是否有访问权限(telnet address port)
四, 实现步骤:
1), 数据库端实现. 查询图片与更新图片状态的2个功能
2), java端根据传入的参数生成message, 发送到已配置好的jms服务器
3), 把相应的java工程代码打包成SendPhoto_0.0.1.jar
4), 编写shell脚本.
i: 获取数据库链接
ii: 获取图片相关信息
iii: 调用SendPhoto_0.0.1.jar发送图片
参数: job_id, creation_time, path_photo, ........
5), java端连接JMS获取信息,打印图片相应的信息(job_id,doc_id, status, err_code)
6), 把相应的java工程代码打包成PhotoStatus_0.0.1.jar
7), 编写shell脚本.
i: 获取数据库链接
ii: 调用PhotoStatus_0.0.1.jar获取图片处理结果信息
iii: 根据打印信息调用相应的存储过程更新图片状态
8), 编写crontab 每5分钟执行一次脚本
备注: 代码存于网盘/darren/projects/odm
五, 问题汇总:
1), JMS的queue中未收到message.
可能原因:地址及queue是否正确; message格式是否正确,节点要一致; JMS监听是否开启.
2),message中没有base64的图片信息
可能原因: 图片确实不存在; 图片名称中有空格或特殊字符导致参数紊乱,无法找到图片.
3), message中job_id过长,导致ODM组处理异常以致无任何返回值.
4), message短时间内大批量重复发送,导致JMS崩溃.
描述: JMS中设置了对message的achive的时间为1h, 短时间大批量的重复文件,超出JMS处理范围引发瘫痪. 解决方案是对于没有回应的message,延长重复时间至2h(之前为5m),当JMS achive完成后再重发就不会有类似问题.
5). 手动shell脚本可以执行,但是用了crontab无法执行.
原因: shell脚本中调用jar包没有写全路径,导致无法找到jar包
6), 工程中对于有处理异常的消息没有及时突出,导致卡顿,无法进行下一个消息的发送
解决方案:无论何种异常,要及时记录异常信息及相应退出
7), message的生成跟发送放在同一个工程里,这会导致重用性低.
六, 部分代码
发送图片:
// step1: read args and generate message object
GXDMessage message = parseArgs(args);
log.info("start pusher: "+message.getFileName());
// step2: read configure property file and prepare to connect to odm
final QueueUtilsConfiguration config = MQPusher
.loadProperties(ApplicationConstant.CONFIG_PATH);
// step3: connect to odm server and send message
MQPusher.sendPicture(config, message);
cod of method : sendPicture
/**
* send picture to scintilla message queue
*
* @param config : the configure of server
* @param message: gxd message
*/
public static void sendPicture(QueueUtilsConfiguration config,
GXDMessage message) {
JMSHelper jmsHelper = null;
try {
//step 1: initialize class JMSHelper
jmsHelper = new JMSHelper(config.getInitialContextFactory(),
config.getProviderUrl(), config.getJndiConnFactory(),
config.getMqHostUser(), config.getMqHostPw(),
config.getJndiQueue());
} catch (Exception ne) {
log.error("send message failed. Details:" + e.getMessage());
System.exit(1);
}
try {
//step2: covert object to odm message.
String msg = XMLBuilder.BuildXMLDoc(message).asXML();
//step3: send message
jmsHelper.send(msg.getBytes());
//step 4: close queue, session and connect.
jmsHelper.close();
} catch (JMSException e) {
log.error("sending message failed. Details:" + e.getMessage());
System.exit(1);
} catch (NamingException e) {
log.error("close session and conection failed. Details:"
+ e.getMessage());
System.exit(1);
}
}
code of watcher :
// load properties
final QueueUtilsConfiguration config = MQWatcher
.loadProperties(ApplicationConstant.CONFIG_PATH);
// receive message
MQWatcher.receive(config);