不仅Activemq提供的jms服务,Weblogic也提供了jms服务,很多项目是部署在Weblogic中,使用其提供的jms服务也是很多企业的选择,一直没亲手试过,今天试了下,遇到的小问题还挺多,看来眼过百变不如手过一遍,下面就记录下操作步骤。构建完成后还会实现个小例子来测试下,这里主要进行点对点模式构建。
二. JMS的思想
所谓的JMS其实就是异步通信, 我们可以打个简单的比方: 现在的手机基本上普及了, 手机它有两个基本功能, 一个是打电话, 一个是发短信.
打电话是同步的, 必须要保证双方都开机才能进行通话; 而发短信则是异步的, 接收方不需要保持开机状态;
SUN公司给我们提供了一组标准被Java API用于企业级的消息处理, 通过JMS可以在Java程序之间发送和接受消息以达到交换数据的目的,
异步通信实现了程序之间的松耦合的关系.
Weblogic构建jms服务基本都是下面四个步骤(假设域已建好):
1. 新建jms服务器
2. 新建jms模块
3. 新建子部署
4. 新建资源
首先要登录Weblogic控制台(版本为weblogic 10),http://localhost:9101/console/ --------------------- 本文来自 琉璃糖 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/yuanxiaojiao0012/article/details/50685835?utm_source=copy
第一步要明白weblogic提供的jms的架构体系,通过一个简单的demo进行演示
要在AdminServer或者被管服务上创建JMS Server,。JmsServer中部署的是Jms module,在jms module可以创建异步消息的qunue和topic,以及外部访问的连接工厂,客户端是通过jndi容器的方式访问queue等对象的,所以在创建queue要指定jndi的唯一标识。
Weblogic作为Jms服务端提供Jms服务需要在Weblogic的控制台进行一些配置,主要是Jms服务器和Jms模块。Jms服务器作为Jms服务的核心提供Jms服务,也可以说是作为Jms模块的一个管理容器;Jms模块下可以进行ConnectionFactory、Topic、Queue等资源的定义,Weblogic允许我们通过JNDI对它们进行访问。
在安装的weblogic的时候再D:\Oracle\Middleware\wlserver_10.3\samples\server\examples\src\examples\jms目录下提供的jms的案例。我们就基于该案例来配置我们的weblogic的jms
一、新建jms服务器
左侧域结构->服务->消息传送->jms服务器
点击【新建】,弹出下面页面,开始填写信息,这里给jms服务器起名为JMSServer-0(默认的)
点击【下一步】,目标那选择当前服务器(AdminServer) ,将jms Server部署到AdminServer中
点击完成
点击完成
二、新建jms模块
早期weblogic可以不用构建jms模块直接新建jms连接工厂,队列等,新版本采用jms模块来组织jms连接工厂等。
左侧域结构->服务->消息传送->jms模块
点击【新建】按钮,填写名称,这里为MyJMSModule
点击【下一步】,勾选要部署的服务器AdminServer
点击【下一步】,这个页面中有一项“是否要向此jms模块中添加资源”,这个勾不勾选都可以,勾选的话在完成jms模块配置后可以立即配置资源(连接工厂,队列等),不勾选也可以稍后再配。勾选后进人下面界面:
在资源中主要是添加连接工厂、queue和topic三个资源
这里补充下分布式队列和分布式topic
不同的queue组成一个集群,形成一个分布式的队列,消息发布是发送到分布式队列中,具体是左边的queue还是右边的queue处理,由weblogic来决定,实现一个负载均衡的效果
下一步:我们新建一个连接工厂的资源
点击下一步:
点击下一步:
在创建的连接工厂是通过jndi容器提供的外部访问的,这里在创建的时候需要制定一个唯一的标志,在上面的jms 案例中使用的标志是
在D:\Oracle\Middleware\wlserver_10.3\samples\server\examples\src\examples\jms\queue案例中QueueSend.java中制定了标志的名称是
// Defines the JMS context factory.
public final static String JMS_FACTORY="weblogic.examples.jms.QueueConnectionFactory";
所以我们在配置的时候,需要将连接工厂的jndi标志设置为weblogic.examples.jms.QueueConnectionFactory
接下来点击下一步,点击完成
四:创建消息队列
点击下一步:同理这里需要制定队列jndi的标志在QueueSend.java
// Defines the queue.
public final static String QUEUE="weblogic.examples.jms.exampleQueue";
点击下一步:接下来需要将队列部署到jms module中,需要创建一个子部署
点击新建子部署
点击确定
点击完成
配置完成之后:jms module的配置如下所示
这里我们就已经把jms配置完成了,我们就可以运行案例了
首先在eclipse上创建两个java工程
QueueSend.java代码如下:
package examples.jms.queue; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Hashtable;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException; /** This example shows how to establish a connection
* and send messages to the JMS queue. The classes in this
* package operate on the same JMS queue. Run the classes together to
* witness messages being sent and received, and to browse the queue
* for messages. The class is used to send messages to the queue.
*
* @author Copyright (c) 1999,2011, Oracle and/or its affiliates. All Rights Reserved.
*/
public class QueueSend
{
// Defines the JNDI context factory.
public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory"; // Defines the JMS context factory.
public final static String JMS_FACTORY="weblogic.examples.jms.QueueConnectionFactory"; // Defines the queue.
public final static String QUEUE="weblogic.examples.jms.exampleQueue"; private QueueConnectionFactory qconFactory;
private QueueConnection qcon;
private QueueSession qsession;
private QueueSender qsender;
private Queue queue;
private TextMessage msg; /**
* Creates all the necessary objects for sending
* messages to a JMS queue.
*
* @param ctx JNDI initial context
* @param queueName name of queue
* @exception NamingException if operation cannot be performed
* @exception JMSException if JMS fails to initialize due to internal error
*/
public void init(Context ctx, String queueName)
throws NamingException, JMSException
{
qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
qcon = qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queue = (Queue) ctx.lookup(queueName);
qsender = qsession.createSender(queue);
msg = qsession.createTextMessage();
qcon.start();
} /**
* Sends a message to a JMS queue.
*
* @param message message to be sent
* @exception JMSException if JMS fails to send message due to internal error
*/
public void send(String message) throws JMSException {
msg.setText(message);
qsender.send(msg);
} /**
* Closes JMS objects.
* @exception JMSException if JMS fails to close objects due to internal error
*/
public void close() throws JMSException {
qsender.close();
qsession.close();
qcon.close();
}
/** main() method.
*
* @param args WebLogic Server URL
* @exception Exception if operation fails
*/
public static void main(String[] args) throws Exception { InitialContext ic = getInitialContext("t3://localhost:7001");
QueueSend qs = new QueueSend();
qs.init(ic, QUEUE);
readAndSend(qs);
qs.close();
} private static void readAndSend(QueueSend qs)
throws IOException, JMSException
{
BufferedReader msgStream = new BufferedReader(new InputStreamReader(System.in));
String line=null;
boolean quitNow = false;
do {
System.out.print("Enter message (\"quit\" to quit): \n");
line = msgStream.readLine();
if (line != null && line.trim().length() != 0) {
qs.send(line);
System.out.println("JMS Message Sent: "+line+"\n");
quitNow = line.equalsIgnoreCase("quit");
}
} while (! quitNow); } private static InitialContext getInitialContext(String url)
throws NamingException
{
Hashtable<String,String> env = new Hashtable<String,String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, url);
return new InitialContext(env);
} }
QueueReceive.java
package examples.jms.queue; import java.util.Hashtable;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException; /**
* This example shows how to establish a connection to
* and receive messages from a JMS queue. The classes in this
* package operate on the same JMS queue. Run the classes together to
* witness messages being sent and received, and to browse the queue
* for messages. This class is used to receive and remove messages
* from the queue.
*
* @author Copyright (c) 1999,2011, Oracle and/or its affiliates. All Rights Reserved.
*/
public class QueueReceive implements MessageListener
{
// Defines the JNDI context factory.
public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory"; // Defines the JMS connection factory for the queue.
public final static String JMS_FACTORY="weblogic.examples.jms.QueueConnectionFactory"; // Defines the queue.
public final static String QUEUE="weblogic.examples.jms.exampleQueue"; private QueueConnectionFactory qconFactory;
private QueueConnection qcon;
private QueueSession qsession;
private QueueReceiver qreceiver;
private Queue queue;
private boolean quit = false; /**
* Message listener interface.
* @param msg message
*/
public void onMessage(Message msg)
{
try {
String msgText;
if (msg instanceof TextMessage) {
msgText = ((TextMessage)msg).getText();
} else {
msgText = msg.toString();
} System.out.println("Message Received: "+ msgText ); if (msgText.equalsIgnoreCase("quit")) {
synchronized(this) {
quit = true;
this.notifyAll(); // Notify main thread to quit
}
}
} catch (JMSException jmse) {
System.err.println("An exception occurred: "+jmse.getMessage());
}
} /**
* Creates all the necessary objects for receiving
* messages from a JMS queue.
*
* @param ctx JNDI initial context
* @param queueName name of queue
* @exception NamingException if operation cannot be performed
* @exception JMSException if JMS fails to initialize due to internal error
*/
public void init(Context ctx, String queueName)
throws NamingException, JMSException
{
qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
qcon = qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queue = (Queue) ctx.lookup(queueName);
qreceiver = qsession.createReceiver(queue);
qreceiver.setMessageListener(this);
qcon.start();
} /**
* Closes JMS objects.
* @exception JMSException if JMS fails to close objects due to internal error
*/
public void close()throws JMSException
{
qreceiver.close();
qsession.close();
qcon.close();
}
/**
* main() method.
*
* @param args WebLogic Server URL
* @exception Exception if execution fails
*/ public static void main(String[] args) throws Exception { InitialContext ic = getInitialContext("t3://localhost:7001");
QueueReceive qr = new QueueReceive();
qr.init(ic, QUEUE); System.out.println("JMS Ready To Receive Messages (To quit, send a \"quit\" message)."); // Wait until a "quit" message has been received.
synchronized(qr) {
while (! qr.quit) {
try {
qr.wait();
} catch (InterruptedException ie) {}
}
}
qr.close();
} private static InitialContext getInitialContext(String url)
throws NamingException
{
Hashtable<String,String> env = new Hashtable<String,String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, url);
return new InitialContext(env);
} }
将两个java程序运行起来:就可以发送和接收消息了
运行起来之后,就可以监听jms的参数和消息设置了
接下来我们来监听weblogic的jms
第一个就是jms消息的持久化存储,消息可以存储在file中也可以存储在jdbc中,在jms Server的持久化存储中进行配置
还可以设置发生消息的最大字节数等
还可以查看消息的发送状态等信息
jms的持久化存储,把消息保存到文件中
需要新建一个持久化的存储
在jms Server配置中选择刚刚创建的文件持久化存储