JBoss EAP应用服务器部署方法和JBoss 开发JMS消息服务小例子
一、download JBoss-EAP-6.2.0GA: http://jbossas.jboss.org/downloads
JBoss Enterprise Application Platform(JBoss EAP)作为Redhat公司的商业产品是一个更加关注企业级特性和稳定性的实用部署版为了与JBoss Application Server(JBoss AS) 为了使这两个产品有差异化避免用户混淆因此
RedHat公司在2013年4月将JBoss AS正式更名为WildFly改名后的首个版本为WildFly 8,将接棒JBoss AS 7。RedHat公司表示,新版本不仅是名称上的变化,还带来了如下改进:
1.启动超快
2.模块化设计
3.非常轻量,内存占用非常少
4.更优雅的配置、管理方式
5.严格遵守Java EE7和OSGi规范
目前最新版本是8.1.0.Final http://download.jboss.org/wildfly/8.1.0.Final/wildfly-8.1.0.Final.zip
JBoss AS 7 : http://download.jboss.org/jbossas/7.1/jboss-as-7.1.1.Final/jboss-as-7.1.1.Final.zip
二、安装JBoss EAP 将下载的ZIP包解压到一个目录中例如:E:\jboss-eap-6.2
(1) JBOSS7 启动:
以standalone模式运行服务器:
/bin/standalone.sh (Unix / Linux)
\bin\standalone.bat (Windows)
如果你需要允许远程和本地都能连接jboss,那么将启动时指定-b参数 standalone.bat -b 0.0.0.0
或者通过修改配置文件的方式:
standalone.bat --server-config standalone-full.xml启动时指定配置文件默认是standalone.xml配置信息。
domain模式运行服务器:
/bin/domain.sh (Unix / Linux)
\bin\domain.bat (Windows)
(2) JBOSS7 停止:
/bin/jboss-cli.bat --connect --command=:shutdown 或者ctrl + c 组合键
/bin/jboss-cli.sh --connect --command=:shutdown 或者ctrl + c 组合键
三、启动JBoss EAP 6.2:
启动成功后访问:http://127.0.0.1:8080/ 进入JBoss EAP 6欢迎页面如下图
四、为JBoss EAP 添加一个管理员用户操作如下:
添加用户成功后访问:http://127.0.0.1:9990/console 弹出验证用户对话框,输入上一步中添加的用户名和密码。
验证成功后进入JBoss EAP后台管理页面:
五、接下配置JBoss JMS消息中间件:
(1)首先需要添加一个应用型用户操作如下:
JMS有两种模式 P2P,PUB/SUB
①P2P模型
在P2P模型中,有下列概念:消息队列(Queue)、发送者(Sender)、接收者(Receiver)。每个消息都被发 送到一个特定的队列,接收者从队列中获取消息。队列保留着消息,直到它们被消费或超时。每个消息只有一个消费者 (Consumer)(即一旦被消费,消息就不再在消息队列中)发送者和接收者之间在时间上没有依赖性,也就是说当发送者发送了消息之后,
不管接收者有没有正在运行,它不会影响到消息被发送到队列。接收者在成功接收消息之后需向队列应答成功如果你希望发送的每个消息都应该被成功处理 的话,那么你需要P2P模型。
适用场合:想让接收者进行且只进行一次处理组件之间进行同步通信
②Pub/Sub模型
在Pub/Sub模型中,有下列概念: 主题(Topic)、发布者(Publisher)、订阅者(Subscriber)。
客户端将消息发送到主题。多个发布者将消息发送到Topic,系统将这些消息传递给多个订阅者。
每个消息可以有多个消费者发布者和订阅者之间有时间上的依赖性 。针对某个主题(Topic)的订阅者,
它必须创建一个订阅之后,才能消费发布者的消息,而且,为了消费消息,订阅者必须保持运行的状态。
当然,为了缓和这种严格的时间相关性,JMS允许订阅者创建一个可持久化的订阅。这样,即使订阅者
没有被激活(运行),它也能接收到发布者的消息。如果你希望发送的消息可以不被做任何处理、
或者被一个消费者处理、或者可以被多个消费者处理 的话,
那么可以采用Pub/Sub模型(也就是说发布者不关心有多少侦听者)。
关于时间的依赖性二种模型的实现结果:
对于p2p 模型的每个消息只能有一个消费者 如果我们定义二个消息接受者的Bean那么只能有一端会接收到消息。
当你把部署在Jboss中的消息接收Bean去掉以后,然后发送消息 此时消息在队列中,
一旦你重新部署他会立刻就接收到刚刚发送的消息 所以它没有时间的依赖性,
pub/sub 模型可以有多个消费者 在这个模型中如果我们定义多个接收消息的Bean当我们
在客户端发送消息的时候二个bean都会接收到消息,所以他有多个消费者
但是如果你把Jboss部署中的消息接收bean去掉之后,发送消息。然后在重新部署,
那么消息也无法接收到 ,所以说他有时间的依赖性。
(2)在JBoss EAP console后台管理页面中创建queue消息队列,参考下图步骤:
进入jboss的管理控制台,找到Profile -> Subsystems -> Messageing -> Destinations -> view
这样就创建一个Queue,到目前为止,还没看到跟安全认证相关的设置,切换到Seurity Settings面板
可以看到,默认情况下,创建的Queue允许"guest"角色 "发送"消息(Send这里是true)、"接收"消息(Consume这里是true),这就是为什么我们在第一步,要把添加的Jmsqueue这个用户加入guest组的原因了。
如果熟悉配置文件也可以通过直接编辑配置文件的方式配置queue消息队列:
E:\jboss-eap-6.2\standalone\configuration\standalone-full.xml找到
节点
在中间加入以下内容:
- <hornetq-server>
- <jms-destinations>
- <jms-queue name="testQueue">
- <entry name="java:jboss/exported/jms/queue/test"/>
- <durable>true</durable>
- </jms-queue>
- </jms-destinations>
- </hornetq-server>
(3)编写测试代码: P2P模式:消息生产者代码如下:
- package com.runsun;
- import java.util.concurrent.CountDownLatch;
- import java.util.concurrent.TimeUnit;
- import java.util.logging.Logger;
- import java.util.Properties;
- import javax.jms.Connection;
- import javax.jms.ConnectionFactory;
- import javax.jms.Destination;
- import javax.jms.MessageProducer;
- import javax.jms.Session;
- import javax.jms.TextMessage;
- import javax.naming.Context;
- import javax.naming.InitialContext;
- /**
- *
Description:JMS客户端消息生产者
- */
- public class JMSProducer {
- private static final Logger log = Logger.getLogger(JMSProducer.class.getName());
- private static final String DEFAULT_MESSAGE = "这是第一条JMS信息.....";
- private static final String DEFAULT_CONNECTION_FACTORY = "jms/RemoteConnectionFactory";
- private static final String DEFAULT_DESTINATION = "jms/queue/test";
- private static final String DEFAULT_MESSAGE_COUNT = "1";
- private static final String DEFAULT_USERNAME = "Jmsqueue";
- private static final String DEFAULT_PASSWORD = "queue@123";
- private static final String INITIAL_CONTEXT_FACTORY = "org.jboss.naming.remote.client.InitialContextFactory";
- private static final String PROVIDER_URL = "remote://localhost:4447";
- public static void main(String[] args) throws Exception {
- Context context=null;
- Connection connection=null;
- try {
- // 设置上下文的JNDI查找
- log.info("设置JNDI访问环境信息也就是设置应用服务器的上下文信息!");
- final Properties env = new Properties();
- env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);// 该KEY的值为初始化Context的工厂类,JNDI驱动的类名
- env.put(Context.PROVIDER_URL, PROVIDER_URL);// 该KEY的值为Context服务提供者的URL.命名服务提供者的URL
- env.put(Context.SECURITY_PRINCIPAL, DEFAULT_USERNAME);
- env.put(Context.SECURITY_CREDENTIALS, DEFAULT_PASSWORD);//应用用户的登录名,密码.
- // 获取到InitialContext对象.
- context = new InitialContext(env);
- log.info("初始化上下文,'JNDI驱动类名','服务提供者URL','应用用户的账户','密码'完毕.");
- log.info("获取连接工厂!");
- ConnectionFactory connectionFactory = (ConnectionFactory) context.lookup(DEFAULT_CONNECTION_FACTORY);
- log.info("获取目的地!");
- Destination destination = (Destination) context.lookup(DEFAULT_DESTINATION);
- // 创建JMS连接、会话、生产者和消费者
- connection = connectionFactory.createConnection(DEFAULT_USERNAME, DEFAULT_PASSWORD);
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer producer = session.createProducer(destination);
- connection.start();
- int count = Integer.parseInt(DEFAULT_MESSAGE_COUNT);
- // 发送特定数目的消息
- TextMessage message = null;
- for (int i = 0; i < count; i++) {
- message = session.createTextMessage(DEFAULT_MESSAGE);
- producer.send(message);
- log.info("message:"+message);
- log.info("message:"+DEFAULT_MESSAGE);
- }
- // 等待30秒退出
- CountDownLatch latch = new CountDownLatch(1);
- latch.await(30, TimeUnit.SECONDS);
- } catch (Exception e) {
- log.severe(e.getMessage());
- throw e;
- } finally {
- if (context != null) {
- context.close();
- }
- // 关闭连接负责会话,生产商和消费者
- if (connection != null) {
- connection.close();
- }
- }
- }
- }
运行代码控制台输出内容:
查看JBoss EAP 管理后台页面:
在运行两次:
P2P模式:消息消费者代码如下:
- package com.runsun;
- import java.util.Properties;
- import java.util.concurrent.CountDownLatch;
- import java.util.concurrent.TimeUnit;
- import java.util.logging.Logger;
- import javax.jms.Connection;
- import javax.jms.ConnectionFactory;
- import javax.jms.Destination;
- import javax.jms.MessageConsumer;
- import javax.jms.Session;
- import javax.jms.TextMessage;
- import javax.naming.Context;
- import javax.naming.InitialContext;
- public class JMSConsumer {
- private static final Logger log = Logger.getLogger(JMSConsumer.class.getName());
- private static final String DEFAULT_CONNECTION_FACTORY = "jms/RemoteConnectionFactory";
- private static final String DEFAULT_DESTINATION = "jms/queue/test";
- private static final String DEFAULT_USERNAME = "Jmsqueue";
- private static final String DEFAULT_PASSWORD = "queue@123";
- private static final String INITIAL_CONTEXT_FACTORY = "org.jboss.naming.remote.client.InitialContextFactory";
- private static final String PROVIDER_URL = "remote://localhost:4447";
- public static void main(String[] args) throws Exception {
- ConnectionFactory connectionFactory = null;
- Connection connection = null;
- Session session = null;
- MessageConsumer consumer = null;
- Destination destination = null;
- TextMessage message = null;
- Context context = null;
- try {
- final Properties env = new Properties();
- env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
- env.put(Context.PROVIDER_URL, PROVIDER_URL);
- env.put(Context.SECURITY_PRINCIPAL, DEFAULT_USERNAME);
- env.put(Context.SECURITY_CREDENTIALS, DEFAULT_PASSWORD);
- context = new InitialContext(env);
- connectionFactory = (ConnectionFactory) context.lookup(DEFAULT_CONNECTION_FACTORY);
- destination = (Destination) context.lookup(DEFAULT_DESTINATION);
- connection = connectionFactory.createConnection(DEFAULT_USERNAME, DEFAULT_PASSWORD);
- session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- consumer = session.createConsumer(destination);
- connection.start();
- // 等待30秒退出
- CountDownLatch latch = new CountDownLatch(1);
- while (message == null) {
- log.info("开始从JBOSS端接收信息-----");
- message = (TextMessage) consumer.receive(5000);
- latch.await(1, TimeUnit.SECONDS);
- }
- log.info("接收到的消息的内容:" + message.getText());
- } catch (Exception e) {
- log.severe(e.getMessage());
- throw e;
- } finally {
- if (context != null) {
- context.close();
- }
- if (connection != null) {
- connection.close();
- }
- }
- }
- }
运行代码:
Pub/Sub模式测试代码:
编辑standalone-full.xml加入如下的代码:
- package com.runsun;
- import java.util.Properties;
- import java.util.concurrent.CountDownLatch;
- import java.util.concurrent.TimeUnit;
- import javax.jms.JMSException;
- import javax.jms.Session;
- import javax.jms.TextMessage;
- import javax.naming.Context;
- import javax.naming.InitialContext;
- import javax.naming.NamingException;
- public class JMSSub {
- private static final String DEFAULT_USERNAME = "Jmsqueue";
- private static final String DEFAULT_PASSWORD = "queue@123";
- private static final String INITIAL_CONTEXT_FACTORY = "org.jboss.naming.remote.client.InitialContextFactory";
- private static final String PROVIDER_URL = "remote://localhost:4447";
- /**
- * @param args
- * @throws NamingException
- * @throws JMSException
- * @throws InterruptedException
- */
- public static void main(String[] args) throws NamingException, JMSException, InterruptedException {
- final Properties env = new Properties();
- env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
- env.put(Context.PROVIDER_URL, System.getProperty(Context.PROVIDER_URL, PROVIDER_URL));
- env.put(Context.SECURITY_PRINCIPAL, System.getProperty("username", DEFAULT_USERNAME));
- env.put(Context.SECURITY_CREDENTIALS, System.getProperty("password", DEFAULT_PASSWORD));
- InitialContext context = new InitialContext(env);
- javax.jms.ConnectionFactory cf = (javax.jms.ConnectionFactory)context.lookup("jms/RemoteConnectionFactory");
- javax.jms.Connection connection = cf.createConnection(DEFAULT_USERNAME, DEFAULT_PASSWORD);
- boolean transacted = false;
- javax.jms.Session session = connection.createSession(transacted, Session.AUTO_ACKNOWLEDGE);
- javax.jms.Topic topic = session.createTopic("testTopic");
- javax.jms.MessageConsumer consumer = session.createConsumer(topic);
- consumer.setMessageListener(new javax.jms.MessageListener() {
- public void onMessage(javax.jms.Message message)
- {
- try {
- TextMessage tm = (TextMessage)message;
- System.out.println("received message content: "+tm.getText().toString());
- System.out.println("getJMSDestination: "+tm.getJMSDestination());
- System.out.println("getJMSReplyTo: "+tm.getJMSReplyTo());
- System.out.println("getJMSMessageID: "+tm.getJMSMessageID());
- System.out.println("getJMSRedelivered: "+tm.getJMSRedelivered());
- } catch (JMSException e) {
- e.printStackTrace();
- }
- }
- });
- connection.start();
- //等待30秒退出
- CountDownLatch latch = new CountDownLatch(1);
- latch.await(100, TimeUnit.SECONDS);
- }
- }
- package com.runsun;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.util.Properties;
- import javax.jms.JMSException;
- import javax.jms.Session;
- import javax.jms.TextMessage;
- import javax.naming.Context;
- import javax.naming.InitialContext;
- import javax.naming.NamingException;
- public class JMSPub {
- private static final String DEFAULT_USERNAME = "Jmsqueue";
- private static final String DEFAULT_PASSWORD = "queue@123";
- private static final String INITIAL_CONTEXT_FACTORY = "org.jboss.naming.remote.client.InitialContextFactory";
- private static final String PROVIDER_URL = "remote://localhost:4447";
- public static void main(String[] args) throws NamingException, JMSException, IOException {
- final Properties env = new Properties();
- env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
- env.put(Context.PROVIDER_URL, System.getProperty(Context.PROVIDER_URL, PROVIDER_URL));
- env.put(Context.SECURITY_PRINCIPAL, System.getProperty("username", DEFAULT_USERNAME));
- env.put(Context.SECURITY_CREDENTIALS, System.getProperty("password", DEFAULT_PASSWORD));
- InitialContext context = new InitialContext(env);
- javax.jms.ConnectionFactory cf = (javax.jms.ConnectionFactory)context.lookup("jms/RemoteConnectionFactory");
- javax.jms.Connection connection = cf.createConnection(DEFAULT_USERNAME, DEFAULT_PASSWORD);
- boolean transacted = false;
- javax.jms.Session session = connection.createSession(transacted, Session.AUTO_ACKNOWLEDGE);
- /**
- * 在standalone-full.xml中找到 节点
- * 在此节点下找到节点增加
- *
- */
- javax.jms.Topic topic = (javax.jms.Topic)context.lookup("jms/topic/test");
- javax.jms.MessageProducer producer = session.createProducer(topic);
- BufferedReader msgStream = new BufferedReader(new InputStreamReader(
- System.in));
- String line = null;
- boolean quitNow = false;
- do {
- System.out.print("输入要发送的消息:(数字0退出)");
- line = msgStream.readLine();
- if (line != null && line.trim().length() != 0) {
- TextMessage textMessage = session.createTextMessage();
- textMessage.setText(line);
- producer.send(textMessage);
- quitNow = line.equalsIgnoreCase("0");
- }
- } while (!quitNow);
- }
- }
运行JMSSub:
订阅者已经在监听消息:
接下来运行JMSPub消息发布者:
JMSPub控制台:
JMSub控制台: