Commit 75256457 by WeiCong

优化jms服务

parent 3fc85bd2
...@@ -9,7 +9,6 @@ import com.brilliance.eibs.util.StringUtil; ...@@ -9,7 +9,6 @@ import com.brilliance.eibs.util.StringUtil;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.math.NumberUtils; import org.apache.commons.lang.math.NumberUtils;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl; import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.PropertyValue; import org.springframework.beans.PropertyValue;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory; import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
...@@ -23,190 +22,215 @@ import org.springframework.jms.support.converter.SimpleMessageConverter; ...@@ -23,190 +22,215 @@ import org.springframework.jms.support.converter.SimpleMessageConverter;
import javax.jms.ConnectionFactory; import javax.jms.ConnectionFactory;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects;
public class JmsListeningServer extends AbsServer { public class JmsListeningServer extends AbsServer {
static final String DESTINATION_TYPE_QUEUE = "queue"; static final String DESTINATION_TYPE_QUEUE = "queue";
static final String DESTINATION_TYPE_TOPIC = "topic"; static final String DESTINATION_TYPE_TOPIC = "topic";
static final String DESTINATION_TYPE_DURABLE_TOPIC = "durableTopic"; static final String DESTINATION_TYPE_DURABLE_TOPIC = "durableTopic";
static final String DESTINATION_TYPE_SHARED_TOPIC = "sharedTopic"; static final String DESTINATION_TYPE_SHARED_TOPIC = "sharedTopic";
static final String DESTINATION_TYPE_SHARED_DURABLE_TOPIC = "sharedDurableTopic"; static final String DESTINATION_TYPE_SHARED_DURABLE_TOPIC = "sharedDurableTopic";
final static MessageConverter messageConverter = new SimpleMessageConverter(); final static MessageConverter messageConverter = new SimpleMessageConverter();
private final Map<String, DefaultMessageListenerContainer> containerCache = new HashMap<String, DefaultMessageListenerContainer>(); private final Map<String, DefaultMessageListenerContainer> containerCache = new HashMap<String, DefaultMessageListenerContainer>();
public JmsListeningServer(Context context, IServiceDef serviceDef, public JmsListeningServer(Context context, IServiceDef serviceDef,
ApacheEL elParser) { ApacheEL elParser) {
super(context, serviceDef, elParser); super(context, serviceDef, elParser);
} }
@Override @Override
public void run() { public void run() {
logger.info( LOG_FLAG + "JmsListeningServer is starting ." logger.info(LOG_FLAG + "JmsListeningServer is starting ."
+ LOG_FLAG); + LOG_FLAG);
ConnectionFactory connectionFactory; ConnectionFactory connectionFactory;
try { try {
String connectionFactoryClaz = getRequiredPropertyValue("connectionFactory"); String connectionFactoryClaz = getRequiredPropertyValue("connectionFactory");
String[] destinations = getRequiredPropertyValue("destination") String[] destinations = getRequiredPropertyValue("destination")
.split(","); .split(",");
String[] interfaceNames = getRequiredPropertyValue("interfaceName") String[] interfaceNames = getRequiredPropertyValue("interfaceName")
.split(","); .split(",");
String[] transactionNames = getRequiredPropertyValue( String[] transactionNames = getRequiredPropertyValue(
"transactionName").split(","); "transactionName").split(",");
Class<?> connectionFactoryClazz = Class Class<?> connectionFactoryClazz = Class
.forName(connectionFactoryClaz); .forName(connectionFactoryClaz);
connectionFactory = (ConnectionFactory) BeanUtils connectionFactory = (ConnectionFactory) BeanUtils
.instantiate(connectionFactoryClazz); .instantiateClass(connectionFactoryClazz);
BeanWrapper bw = new BeanWrapperImpl(connectionFactory); BeanWrapperImpl bw = new BeanWrapperImpl(connectionFactory);
Map<String, String> arguments = ((ServiceDef) this.serviceDef) Map<String, String> arguments = ((ServiceDef) this.serviceDef)
.getPropertyArguments("connectionFactory"); .getPropertyArguments("connectionFactory");
String username=null; String username = null;
String password=null; String password = null;
if (!arguments.isEmpty()) { if (!arguments.isEmpty()) {
// 连接工厂设置必要属性,动态设置 // 连接工厂设置必要属性,动态设置
for (Map.Entry<String, String> entry : arguments.entrySet()) { for (Map.Entry<String, String> entry : arguments.entrySet()) {
String propertyName = entry.getKey(); String propertyName = entry.getKey();
Object originalValue = entry.getValue(); Object originalValue = entry.getValue();
if("username".equalsIgnoreCase(propertyName)){ if ("username".equalsIgnoreCase(propertyName)) {
username=(String) originalValue; username = (String) originalValue;
}else if("password".equalsIgnoreCase(propertyName)){ } else if ("password".equalsIgnoreCase(propertyName)) {
password=(String) originalValue; password = (String) originalValue;
password=new String(Base64.decodeBase64(password)); password = new String(Base64.decodeBase64(password));
}else{ } else {
Object convertedValue = originalValue; Object convertedValue = originalValue;
convertedValue = ((BeanWrapperImpl) bw).convertForProperty(
convertedValue, propertyName); if ("hostName".equalsIgnoreCase(propertyName)) {
PropertyValue pv = new PropertyValue(propertyName, String ip = getServer(entry.getValue(), true);
convertedValue); convertedValue = bw.convertForProperty(ip, propertyName);
bw.setPropertyValue(pv); } else if ("port".equalsIgnoreCase(propertyName)) {
} String port = getServer(entry.getValue(), false);
} convertedValue = bw.convertForProperty(port, propertyName);
} } else {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); convertedValue = bw.convertForProperty(convertedValue, propertyName);
if(username!=null){ }
UserCredentialsConnectionFactoryAdapter ucfa=new UserCredentialsConnectionFactoryAdapter(); PropertyValue pv = new PropertyValue(propertyName,
ucfa.setTargetConnectionFactory(connectionFactory); convertedValue);
ucfa.setUsername(username); bw.setPropertyValue(pv);
ucfa.setPassword(password); }
factory.setConnectionFactory(ucfa); }
}else{ }
factory.setConnectionFactory(connectionFactory); DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
} if (username != null) {
factory.setMessageConverter(messageConverter); UserCredentialsConnectionFactoryAdapter ucfa = new UserCredentialsConnectionFactoryAdapter();
// 设置本地事务性 ucfa.setTargetConnectionFactory(connectionFactory);
factory.setSessionTransacted(true); ucfa.setUsername(username);
// 设置监听类型(队列/主题) ucfa.setPassword(password);
initDestinationType(factory); factory.setConnectionFactory(ucfa);
// 设置jms资源缓存级别 } else {
String cache; factory.setConnectionFactory(connectionFactory);
if (StringUtil.isEmpty(getPropertyValue("cache"))) { }
cache = "CACHE_SESSION"; factory.setMessageConverter(messageConverter);
} else { // 设置本地事务性
cache = "CACHE_" + getPropertyValue("cache").toUpperCase(); factory.setSessionTransacted(true);
} // 设置监听类型(队列/主题)
factory.setCacheLevelName(cache); initDestinationType(factory);
// 设置消费者线程数 // 设置jms资源缓存级别
String concurrency = getPropertyValue("concurrency"); String cache;
if (!StringUtil.isEmpty(concurrency)) { if (StringUtil.isEmpty(getPropertyValue("cache"))) {
factory.setConcurrency(concurrency); cache = "CACHE_SESSION";
} } else {
// 设置每个消费者处理多少消息 cache = "CACHE_" + getPropertyValue("cache").toUpperCase();
String prefetch = getPropertyValue("prefetch"); }
factory.setMaxMessagesPerTask(NumberUtils.toInt(prefetch, 5)); factory.setCacheLevelName(cache);
// 设置收取消息超时时间(毫秒) // 设置消费者线程数
String receiveTimeout = getPropertyValue("receiveTimeout"); String concurrency = getPropertyValue("concurrency");
if (!StringUtil.isEmpty(receiveTimeout)) { if (!StringUtil.isEmpty(concurrency)) {
factory.setReceiveTimeout(NumberUtils.toLong(receiveTimeout)); factory.setConcurrency(concurrency);
} }
for (int i=0;i<destinations.length;i++) { // 设置每个消费者处理多少消息
String destination=destinations[i]; String prefetch = getPropertyValue("prefetch");
if (!containerCache.containsKey(destination)) { factory.setMaxMessagesPerTask(NumberUtils.toInt(prefetch, 5));
// 设置监听端点 // 设置收取消息超时时间(毫秒)
SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint(); String receiveTimeout = getPropertyValue("receiveTimeout");
MessageListenerAdapter messageListener = new MessageListenerAdapter(); if (!StringUtil.isEmpty(receiveTimeout)) {
messageListener.setDefaultListenerMethod("handle"); factory.setReceiveTimeout(NumberUtils.toLong(receiveTimeout));
messageListener.setDelegate(new MessageHandler( }
interfaceNames[i], transactionNames[i])); for (int i = 0; i < destinations.length; i++) {
endpoint.setMessageListener(messageListener); String destination = destinations[i];
endpoint.setDestination(destination); if (!containerCache.containsKey(destination)) {
// 创建jms监听容器 // 设置监听端点
DefaultMessageListenerContainer container = factory SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();
.createListenerContainer(endpoint); MessageListenerAdapter messageListener = new MessageListenerAdapter();
// 初始化jms监听容器 messageListener.setDefaultListenerMethod("handle");
container.initialize(); messageListener.setDelegate(new MessageHandler(
// 启动jms监听容器 interfaceNames[i], transactionNames[i]));
container.start(); endpoint.setMessageListener(messageListener);
containerCache.put(destination, container); endpoint.setDestination(destination);
} // 创建jms监听容器
DefaultMessageListenerContainer container = factory
} .createListenerContainer(endpoint);
// 初始化jms监听容器
} catch (Throwable e) { container.initialize();
logger.error( LOG_FLAG + "JmsListeningServer start error." // 启动jms监听容器
+ LOG_FLAG, e); container.start();
close(); containerCache.put(destination, container);
} }
logger.info( LOG_FLAG + "JmsListeningServer start is finished." }
+ LOG_FLAG);
} } catch (Throwable e) {
logger.error(LOG_FLAG + "JmsListeningServer start error."
private void initDestinationType(DefaultJmsListenerContainerFactory factory) { + LOG_FLAG, e);
String destinationType = getPropertyValue("destinationType"); close();
boolean pubSubDomain = false; }
boolean subscriptionDurable = false;
boolean subscriptionShared = false; logger.info(LOG_FLAG + "JmsListeningServer start is finished."
if (DESTINATION_TYPE_SHARED_DURABLE_TOPIC.equals(destinationType)) { + LOG_FLAG);
pubSubDomain = true; }
subscriptionDurable = true;
subscriptionShared = true; private String getServer(String hostName, boolean isIp) {
} else if (DESTINATION_TYPE_SHARED_TOPIC.equals(destinationType)) { if (hostName.indexOf(":") == -1) {
pubSubDomain = true; return hostName;
subscriptionShared = true; }
} else if (DESTINATION_TYPE_DURABLE_TOPIC.equals(destinationType)) { Objects.requireNonNull(hostName);
pubSubDomain = true; int indexOf = hostName.indexOf("-");
subscriptionDurable = true; int index = 0;
} else if (DESTINATION_TYPE_TOPIC.equals(destinationType)) { String servers = hostName;
pubSubDomain = true; if (indexOf != -1) {
} else if (destinationType == null || "".equals(destinationType) index = Integer.parseInt(hostName.substring(indexOf + 1));
|| DESTINATION_TYPE_QUEUE.equals(destinationType)) { servers = hostName.substring(0, indexOf);
// the default: queue }
} else { String[] strings = servers.split(",");
// 给出警告,依旧使用默认队列类型作为监听模式 return isIp ? strings[index].substring(0, strings[index].indexOf(":")) : strings[index].substring(strings[index].indexOf(":") + 1);
logger.error( }
LOG_FLAG
+ "Invalid listener container 'destination-type': only " private void initDestinationType(DefaultJmsListenerContainerFactory factory) {
+ "\"queue\", \"topic\", \"durableTopic\", \"sharedTopic\", \"sharedDurableTopic\" supported." String destinationType = getPropertyValue("destinationType");
+ LOG_FLAG); boolean pubSubDomain = false;
} boolean subscriptionDurable = false;
factory.setPubSubDomain(pubSubDomain); boolean subscriptionShared = false;
factory.setSubscriptionDurable(subscriptionDurable); if (DESTINATION_TYPE_SHARED_DURABLE_TOPIC.equals(destinationType)) {
factory.setSubscriptionShared(subscriptionShared); pubSubDomain = true;
} subscriptionDurable = true;
subscriptionShared = true;
@Override } else if (DESTINATION_TYPE_SHARED_TOPIC.equals(destinationType)) {
public void close() { pubSubDomain = true;
for(Map.Entry<String, DefaultMessageListenerContainer> item: containerCache.entrySet()){ subscriptionShared = true;
DefaultMessageListenerContainer container=item.getValue(); } else if (DESTINATION_TYPE_DURABLE_TOPIC.equals(destinationType)) {
if (container != null) { pubSubDomain = true;
container.shutdown(); subscriptionDurable = true;
container = null; } else if (DESTINATION_TYPE_TOPIC.equals(destinationType)) {
} pubSubDomain = true;
} } else if (destinationType == null || "".equals(destinationType)
containerCache.clear(); || DESTINATION_TYPE_QUEUE.equals(destinationType)) {
} // the default: queue
} else {
class MessageHandler { // 给出警告,依旧使用默认队列类型作为监听模式
private String interfaceName; logger.error(
private String transactionName; LOG_FLAG
+ "Invalid listener container 'destination-type': only "
public MessageHandler(String interfaceName, String transactionName) { + "\"queue\", \"topic\", \"durableTopic\", \"sharedTopic\", \"sharedDurableTopic\" supported."
this.interfaceName = interfaceName; + LOG_FLAG);
this.transactionName = transactionName; }
} factory.setPubSubDomain(pubSubDomain);
factory.setSubscriptionDurable(subscriptionDurable);
public void handle(Object message) { factory.setSubscriptionShared(subscriptionShared);
Client client = new Client(); }
client.call(interfaceName, transactionName, new Object[] { message });
} @Override
public void close() {
} for (Map.Entry<String, DefaultMessageListenerContainer> item : containerCache.entrySet()) {
DefaultMessageListenerContainer container = item.getValue();
if (container != null) {
container.shutdown();
container = null;
}
}
containerCache.clear();
}
class MessageHandler {
private String interfaceName;
private String transactionName;
public MessageHandler(String interfaceName, String transactionName) {
this.interfaceName = interfaceName;
this.transactionName = transactionName;
}
public void handle(Object message) {
Client client = new Client();
client.call(interfaceName, transactionName, new Object[]{message});
}
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment