JMS + jboss EAP 6.2 示例

简介: .Net中如果需要消息队列功能,可以很方便的使用微软自带的MSMQ,对应到Java中,这个功能就是JMS(Java Message Service). 下面以Jboss EAP 6.2环境,介绍一下基本的用法: JMS有二种基本的使用模式, 一种是点对点模式(即“一条”消息只能从“一个”发送方传输到“一个”接收方) - 这种模式下,发送方、接收方不必同时在线,消息在未取回走,一直存放在队列中。

.Net中如果需要消息队列功能,可以很方便的使用微软自带的MSMQ,对应到Java中,这个功能就是JMS(Java Message Service). 下面以Jboss EAP 6.2环境,介绍一下基本的用法:

JMS有二种基本的使用模式,

一种是点对点模式(即“一条”消息只能从“一个”发送方传输到“一个”接收方) - 这种模式下,发送方、接收方不必同时在线,消息在未取回走,一直存放在队列中。

另一种是发布/订阅模式,即一条消息(该模式下,称为“主题”),被一个发送方发送后,如果有多个接收方订阅了,这些接收方都能收到消息 - 这种模式下,发布者和订阅都必须同时在线,否则接收不到消息。

本文主要演示“点对点”模式的基本使用

 

一、jboss上创建相应的用户

JMS要求用户安全认证,即不允许随便谁都向队列里发送/接收,先在Jboss里创建一个用户。

%JBOSS_HOME%/bin/add-user.sh (mac/linux机环境,如果是windows,则是add-user.bat)

执行这个命令后,会出现文字交互界面,参考下图:

将创建一个msgUser的用户,提示:jboss eap 6.2安全性比较高,要求用户的密码满足复杂性要求(比如: Password1! ),如果太简单的密码,将创建失败

输完密码后,会提示该用户是否加入某个组,这里输入组名:guest (后面创建queue时会用到),参考下图:

注:上图中最后一个加密字符串,最好记录一下,某些应用要求安全认证时,需要在配置中配置该串(本文中暂时用不到)

创建完成后,实质上是在%JBOSS_HOME%/standalone/configuration的application-roles.propertiesapplication-users.properties这二个文件中加了一些内容:

msgUser=5f7e011c53bb155cf99b9eeffccdad4d (这是application-users.properties中增加的内容)

msgUser=guest (这是application-roles.properties中增加的内容)

 

二、在jboss中创建队列

把%JBOSS_HOME%/standalone/configuration下的standalone.xml先改个名,然后把standalone-full.xml改成standalone.xml,启动jboss (即:要以standalone-full.xml中的内容做为配置启动jboss)

a)  图形界面方式

进入jboss的管理控制台,找到Profile -> Subsystems -> Messageing -> Destinations -> 查看 (参考下图)

默认情况,应该没有任何Queue

点击“添加”,Name这里输入myQueue(这个可以随便改),JNDI Names这里输入 java:jboss/exported/queue/mytest (最后面的mytest可以随便改,前面的部分建议不要改)

这样就创建一个Queue,到目前为止,还没看到跟安全认证相关的设置,切换到Seurity Settings面板

可以看到,默认情况下,创建的Queue允许"guest"角色 "发送"消息(Send这里是true)、"接收"消息(Consume这里是true),这就是为什么我们在第一步,要把msgUser这个用户加入guest组的原因

 

b) standalone.xml 配置方式

其实刚才的操作,最后的结果就是在standalone.xml中生成了如下代码:

        <subsystemxmlns="urn:jboss:domain:messaging:1.4">

          ...

                <security-settings>

                    <security-setting match="#">

                        <permission type="send" roles="guest"/>

                        <permission type="consume" roles="guest"/>

                    </security-setting>

                </security-settings> 

      ...

                <jms-destinations>

                    <jms-queue name="myQueue">

        //注:这一行建议也手动加上,对于单纯向Queue发送消息而言,加不加效果一样,

        //但是对于Message-drive-bean不加,偶尔会发现无法从queue/mytest接收到消息

                        <entry name="queue/mytest"/>  

                        <entryname="java:jboss/exported/queue/mytest"/>

                        <durable>true</durable>

                    </jms-queue>

                </jms-destinations>

            </hornetq-server>

        </subsystem>

熟悉这个结构后,可以直接在standalone.xml中修改

 

c) 单独在deployments目录下部署 xxx-jms.xml (注:必须是以-jms.xml结尾的文件) 

内容如下:

<?xmlversion="1.0"encoding="UTF-8"?>

<messaging-deploymentxmlns="urn:jboss:messaging-deployment:1.0"><hornetq-server><jms-destinations><jms-queuename="fred"><entryname="jms/queue/fred"/><entryname="java:jboss/exported/jms/queue/fred"/></jms-queue></jms-destinations></hornetq-server></messaging-deployment>

注:经实际测试,建议所有内容都写在一行上,不加要其它任何空格或Tab字符,否则部署会失败(jboss EAP 6.1+版本对xml的校验极严格,哪怕是不可见字符,只要有一个字符校验失败,整个部署将失败)

另外:该方式部署的queue,在管理控制界面上看不到,但是代码可访问 

 

三、编写测试代码

3.1 jndi.properties

要连接到队列,必然需要一些相关的参数,比如:队列地址、用户名、密码、连接“字符串”等,如果硬编码在java代码中,显然不好,我们可以在src目录下,新建一个jndi.properties文件,内容参考下图:

java.naming.factory.initial=org.jboss.naming.remote.client.InitialContextFactory

java.naming.provider.url=remote\://localhost\:4447

java.naming.security.principal=msgUser

java.naming.security.credentials=Password1!

lookup.connectionfactory.name=jms/RemoteConnectionFactory

lookup.destination.name=queue/mytest

前面java开头是的必须的,后面的二行,是我自己加的(当然大家也可以自行添加任何需要的属性)

 

3.2 编写测试代码

(以下代码是在jboss-quickstart示例代码的基础上修改而来的)

 1 package org.jboss.as.quickstarts.jms;
 2 
 3 import java.util.Hashtable;
 4 
 5 import javax.jms.Connection;
 6 import javax.jms.ConnectionFactory;
 7 import javax.jms.Destination;
 8 import javax.jms.JMSException;
 9 import javax.jms.MessageConsumer;
10 import javax.jms.MessageProducer;
11 import javax.jms.Session;
12 import javax.jms.TextMessage;
13 import javax.naming.Context;
14 import javax.naming.InitialContext;
15 import javax.naming.NamingException;
16 
17 
18 
19 public class JbossJMSTest {
20 
21     public static void main(String[] args) throws NamingException, JMSException {
22 
23         final String lOOKUP_CONNECTION_FACTORY_NAME = "lookup.connectionfactory.name";
24         final String lOOKUP_DESTINATION_NAME = "lookup.destination.name";
25 
26         ConnectionFactory connectionFactory = null;
27         Connection connection = null;
28         Session session = null;
29         MessageProducer producer = null;
30         MessageConsumer consumer = null;
31         Destination destination = null;
32         TextMessage message = null;
33         Context context = null;
34 
35         try {
36             // 创建上下文(默认会从应用的classpath下加载jndi.properties做为环境参数)
37             context = new InitialContext();
38 
39             // 把环境参数取出来,后面会用到
40             Hashtable<String, String> env = (Hashtable<String, String>) context
41                     .getEnvironment();
42 
43             // 查找连接工厂
44             connectionFactory = (ConnectionFactory) context.lookup(env
45                     .get(lOOKUP_CONNECTION_FACTORY_NAME));
46 
47             // 查找目标队列
48             destination = (Destination) context.lookup(env
49                     .get(lOOKUP_DESTINATION_NAME));
50 
51             // 创建连接
52             connection = connectionFactory.createConnection(
53                     env.get(Context.SECURITY_PRINCIPAL),
54                     env.get(Context.SECURITY_CREDENTIALS));
55 
56             // 创建会话
57             session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
58 
59             // 创建生产者(即发送者)
60             producer = session.createProducer(destination);
61 
62             // 创建消费者(即接收者)
63             consumer = session.createConsumer(destination);
64 
65             // 开始连接
66             connection.start();
67 
68             // 发送消息
69             message = session.createTextMessage("菩提树下的杨过,欢迎使用JMS!");
70             producer.send(message);
71 
72             // 接收消息
73             message = (TextMessage) consumer.receive(5000);
74 
75             // 打印消息
76             System.out.println(message.getText());
77 
78         } catch (NamingException e) {
79             e.printStackTrace();
80         } catch (JMSException e) {
81             e.printStackTrace();
82         } finally {
83             // 释放资源
84             if (context != null) {
85                 context.close();
86             }
87 
88             if (connection != null) {
89                 connection.close();
90             }
91 
92         }
93     }
94 
95 }
JbossJMSTest

 

运行结果:

最后附加上pom.xml内容:

 1 <?xml version="1.0"?>
 2 
 3 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 5     <modelVersion>4.0.0</modelVersion>
 6 
 7     <groupId>cnblogs</groupId>
 8     <artifactId>helloworld-jms</artifactId>
 9     <version>1.0</version>
10     <packaging>jar</packaging>
11 
12     <properties>
13         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
14     </properties>
15 
16     <dependencies>
17         <dependency>
18             <groupId>org.jboss.as</groupId>
19             <artifactId>jboss-as-jms-client-bom</artifactId>
20             <version>7.2.0.Final-redhat-8</version>
21             <type>pom</type>
22         </dependency>
23     </dependencies>
24 
25 </project>
pom.xml

示例源代码下载:helloworld-jms.zip

目录
相关文章
|
安全 Java 应用服务中间件
JBOSS EAP实战(2)-集群、NGINX集成、队列与安全
JBOSS HTTP的Thread Group概念 JBOSS是一个企业级的J2EE APP Container,因此它和任何一种成熟的企业级中间件一样具有Thread Group的概念。
1680 0
|
关系型数据库 MySQL Java
JBOSS EAP实战(1)
JBOSS的诞生 1998年,在硅谷SUN公司的SAP实验室,一个年轻人正坐在电脑前面思考,然后写着什么东西。不,他没有在写程序,他在写辞呈。他正在做出人生的一个重大决定:他要辞掉在SUN的这份工作,投身到open source的开发。
1760 0
|
Java 应用服务中间件 API
Jboss EAP:native management API学习
上一节已经学习了CLI命令行来控制JBOSS,如果想在程序中以编码方式来控制JBOSS,可以参考下面的代码,实际上在前面的文章,用代码控制Jboss上的DataSource,已经有所接触了,API与CLI是完全等价的,一个是人工敲指令,一个是代码控制,二者最终的效果一致。
1274 0
|
应用服务中间件 数据安全/隐私保护 运维
jboss CLI 命令行接口学习(适用JBOSS EAP 6.2+)
一、确认CLI所使用的端口 以domain模式为例,查看domain controller(也就是master主机)上的host.xml 1 2 3 4 5 6 7 8 其中native.
1454 0
|
Oracle 关系型数据库 Java
jboss EAP 6.2+ 通过代码控制JNDI数据源
通过Jboss提供的API,可以操控JBoss,效果跟在管理控制台手动操作完全一样,下面是示例代码: 一、pom.xml添加依赖项 org.jboss.as jboss-as-controller-client 7.
1079 0
|
Java 应用服务中间件 数据安全/隐私保护
jboss eap 6.2+ 版本中 加密datasource密码等敏感信息
默认情况下,在jboss eap 6.2+ 管理控制台创建datasource后,会在standalone.xml(独立模式)或host.xml(域模式)中以明文保存相关敏感信息。 这会给服务器留下安全隐患,不过官方已经考虑到了这一点,给出了vault机制来进行加密,步骤如下:   1.
1250 0
|
应用服务中间件 安全 网络安全
jboss eap 6.3 域(Domain)模式配置
jboss提供了二种运行模式:standalone(独立运行模式)、domain(域模式),日常开发中,使用standalone模式足已;但生产部署时,一个app,往往是部署在jboss集群环境中的,如果所有jboss server均采用standalone模式,会给运维带来极大的工作量,需要每台jboss server上逐一部署/更新,显然不适合。
1354 0
|
负载均衡 应用服务中间件 Linux
jboss eap 6.3 集群(cluster)配置
接上一篇继续,Domain模式解决了统一管理多台jboss的问题,今天我们来学习如何利用mod_cluster来实现负载均衡、容错。 mod_cluster是jboss的一个开源集群模块(基于apache 2.
1482 0
|
Java 应用服务中间件 Apache
jboss eap 6.3 集群(cluster)-Session 复制(Replication)
本文算是前一篇的后续,java web application中,难免会用到session,集群环境中apache会将http请求智能转发到其中某台jboss server。假设有二个jboss server:Server A,Server B,Session值在Server A上。
1286 0