1、什么是ActiveMQ

 ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完全支持JMS1.1和J2EE .4规范的 JMS Provider实现,尽管JMS规范出台已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位。
主要特点:
  ). 多种语言和协议编写客户端。语言: Java, C, C++, C#, Ruby, Perl, Python, PHP。应用协议: OpenWire,Stomp REST,WS Notification,XMPP,AMQP
  ). 完全支持JMS1.1和J2EE .4规范 (持久化,XA消息,事务)。
  .) 对Spring的支持,ActiveMQ可以很容易内嵌到使用Spring的系统里面去,而且也支持Spring2.0的特性。
  .) 通过了常见J2EE服务器(如 Geronimo,JBoss , GlassFish,WebLogic)的测试,其中通过JCA 1.5 resource adaptors的配置,可以让ActiveMQ可以自动的部署到任何兼容J2EE 1.4 商业服务器上。
  ). 支持多种传送协议:in-VM,TCP,SSL,NIO,UDP,JGroups,JXTA。
  ). 支持通过JDBC和journal提供高速的消息持久化。
  ). 从设计上保证了高性能的集群,客户端-服务器,点对点。
  ). 支持Ajax。
  ). 支持与Axis的整合。
  ). 可以很容易得调用内嵌JMS provider,进行测试。

2、JMS介绍:

 )、JMS的全称是Java Message Service,即Java消息服务。用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。

 )、它主要用于在生产者和消费者之间进行消息传递,生产者负责产生消息,而消费者负责接收消息。把它应用到实际的业务需求中的话我们可以在特定的时候利用生产者生成一消息,并进行发送,对应的消费者在接收到对应的消息后去完成对应的业务逻辑。

3、ActiveMQ的两种消息形式。

   )、对于消息的传递有两种类型。
    a)、一种是点对点的,即一个生产者和一个消费者一一对应。
    b)、另一种是发布/订阅模式,即一个生产者产生消息并进行发送后,可以由多个消费者进行接收。   )、JMS定义了五种不同的消息正文格式,以及调用的消息类型,允许你发送并接收以一些不同形式的数据,提供现有消息格式的一些级别的兼容性。
    a)、 StreamMessage -- Java原始值的数据流。
    b)、 MapMessage--一套名称-值对。
    c)、 TextMessage--一个字符串对象。
    d)、 ObjectMessage--一个序列化的 Java对象。
    e)、 BytesMessage--一个字节的数据流。

4、ActiveMQ的安装。官方网址:http://activemq.apache.org/

由于ActiveMQ是java开发的,所以需要先安装jdk(注意:安装jdk,需要jdk1.7以上版本)的哦。这里使用的是apache-activemq-5.12.0-bin.tar.gz版本的。

开始进行解压缩操作。

 [root@localhost package]# ls
apache-activemq-5.12.-bin.tar.gz apache-activemq-5.12.-bin.zip apache-tomcat-7.0..tar.gz IK Analyzer 2012FF_hf1 IK Analyzer 2012FF_hf1.rar jdk-7u55-linux-i586.tar.gz solr-4.10..tgz.tgz zookeeper-3.4..tar.gz
[root@localhost package]# tar -zxvf apache-activemq-5.12.-bin.tar.gz -C /home/hadoop/soft/

解压缩完以后进入bin目录。开始进行启动操作。

启动:[root@localhost bin]# ./activemq start

停止:[root@localhost bin]# ./activemq stop

查看状态:[root@localhost bin]# ./activemq status

 [root@localhost soft]# cd apache-activemq-5.12./
[root@localhost apache-activemq-5.12.]# ls
activemq-all-5.12..jar bin conf data docs examples lib LICENSE NOTICE README.txt webapps webapps-demo
[root@localhost apache-activemq-5.12.]# ll
total
-rwxr-xr-x. root root Aug activemq-all-5.12..jar
drwxr-xr-x. root root Sep : bin
drwxr-xr-x. root root Sep : conf
drwxr-xr-x. root root Sep : data
drwxr-xr-x. root root Sep : docs
drwxr-xr-x. root root Sep : examples
drwxr-xr-x. root root Sep : lib
-rw-r--r--. root root Aug LICENSE
-rw-r--r--. root root Aug NOTICE
-rw-r--r--. root root Aug README.txt
drwxr-xr-x. root root Sep : webapps
drwxr-xr-x. root root Sep : webapps-demo
[root@localhost apache-activemq-5.12.]# cd bin/
[root@localhost bin]# ls
activemq activemq-diag activemq.jar env linux-x86- linux-x86- macosx wrapper.jar
[root@localhost bin]# ./activemq start
INFO: Loading '/home/hadoop/soft/apache-activemq-5.12.0//bin/env'
INFO: Using java '/home/hadoop/soft/jdk1.7.0_55/bin/java'
INFO: Starting - inspect logfiles specified in logging.properties and log4j.properties to get details
INFO: pidfile created : '/home/hadoop/soft/apache-activemq-5.12.0//data/activemq.pid' (pid '')
[root@localhost bin]# ./activemq status
INFO: Loading '/home/hadoop/soft/apache-activemq-5.12.0//bin/env'
INFO: Using java '/home/hadoop/soft/jdk1.7.0_55/bin/java'
ActiveMQ is running (pid '')
[root@localhost bin]#

然后你可以访问后台管理界面,账号和密码默认都是admin的。访问地址:http://192.168.110.142:8161/admin

Home是当前的欢迎页,Queues是点到点形式,Topics是发布订阅模式,Subscribers话题消息的发布与订阅,Connections客户端链接,Network当前网络的链接状态,Scheduled计划任务,Send可以测试发送消息。

5、ActiveMQ的使用方法,JMS消息发送模式。
aaarticlea/png;base64,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ErBHWLFihdatWydJqq6unpQ6I5GITj755LTLBwIBSVszw3/961/Tuubss8/WYYcdNq74hhMKhXThhRdq7dq1amtr0+9+97tJrR8AAGBPUFpaqvvuu0/nnXee1q1bp9NPP10333yz/H6/rr/+ep111llavXq1zj//fN1zzz3KyckZtq5bbrlFr776qiwWi371q19p/vz5251/6KGHRh09+6Mf/Sjl8ZaWlpTnZs2aNemjFQbQ35z+SCRgjzAwN2yfffbRrFmzJqXORCKhjRs3jvm6eDye9nXBYHC735955hn94he/GPW6fffdN+XxF198URdccIHWrl2rwsJC/fCHP0wrDgAAAOzI6/XqD3/4gy644ALV1NQoEolIkrKzs3XzzTfrlFNOUU1NjS6//HL99re/TVnHvffeq4cfflhms1nXXnutPv/5z+9Q5gc/+IHOOuuslNeffvrpSiQS+tOf/rTDuWOOOUalpaU7fJE/5phjhn1M9DeRDhIJmPbee+89vf7665KkE044YdLqdTqdWrFixQ7Hk8mkli5dqi984QsqLS0dsY5QKKS3335bX/nKV9Jq0+FwjJgIGUhQpCqzceNGnXnmmaqvr1d5ebluu+02FRYWptUuAADYcy1cuHDGXnvt1bh06dLEVMeyK3K5XLrzzju1atWq7RYhLCws1K9//Wtdf/31+t73vjfs9fPmzVNOTo4uueQSHXzwwSnL+Hw++Xy+lOdMJpOysrI0e/bslOczMjKGPZcK/U2kg/1G9nB+v9+QlPIL8XRxxhln6L333pu0+g488EDdfPPNw56/8847dffdd2vOnDm6//77R5wT9stf/lJPPPGEDjroIN10000Tiisej+tzn/ucpB3/nq+++qp++tOfKhKJ6JBDDtEVV1wx4vC66WAgS75y5Ure5wAAmAC/33+nYRjfMJvNTyeTySdzc3NfffXVV/vGcP207G/29fUpI2P0+7KGYWxbCDESiWj//feXtLV/5nQ6JW0dhepyuUas5+9//7tqa2t3OH7XXXcpKytLp59++g7nlixZIo/Hs8N03CVLloxragP9ze3tyf1NRiRgWnv66ae3JRGys7NTrmZrGIZ6enokSTabbdQ6rVbriOdPPfVUvfDCC/roo4909dVX68Ybb0xZbtWqVdvevL/2ta+N2u54RCIR3XLLLXr66adltVp15ZVX6pvf/OZOaQsAAExfJpOp0DCM75pMpu92dXV1+P3+Z00m05NdXV0v1dbWxqY6vo9bbW2tvve97+miiy7SV7/61R3Opzo21NFHH53yuNvt1tKlS3c4/sADD+hf//pXymvi8biWLFmS8lwgEBj23GSgv7lnIpGAaauxsVG33HKLJOnzn/+8fve736VMJGzYsGHbPLG///3vE27XbrfrV7/6lU4++WS99NJLevLJJ3eYhxaPx/Xzn/9cyWRSp5xyir70pS+NWOdwHzSjle/q6lJnZ6ekrQmQBx54QA888MAO5b/4xS/q+9///pjaAAAAeyaTyeSVdLphGKe7XK5gdXX1cyaT6UmTybR8xYoVkamO7+OwfPlyNTc369JLL9W//vUvXXzxxduNThi8HeRwhiuTSKSeQVJfX69PfepTuuuuu7Yd27hxo44++mgdcMABuvXWW3e4Zt9990058uCee+6R2+3e7hj9TYwFiQRMS/F4XJdffrkikYh8Pp+uueaalEmEnaWyslLf/e539dFHH6Vc/+COO+7Q+vXr9ZnPfGbEOXMDxrqoY6rywWBwh8UbB7S2to6pfgAAgH4uk8n0bUnfNgwj4vf7lxmG8WRWVtZf3n777dQdj2ngggsukNvt1m9/+1s98cQTWrdunW666aYdtnkcy3SO9vb2YddIiEQiamlp0X777bfd8YFdyebOnTum+FMt3Eh/E2Oxx83lwPam65y1K6+8UsuWLVNmZqZuu+22YVeVlbYfkTDe52GsGdxNmzYpmUyqsLBQ2dnZKcssWrRIV1111Zjqfe+993TTTTfpww8/lNls1hlnnKFzzjlHZrN5TPVMByP9zbGDPsMwDnv33XdfmupAAGBXV11d/RWTybRM3JBLx3OSnpR0nzT9+pvS1nUBLr/8csViMR1xxBG6+uqrJf2nHzKeREJubq5eeeWV7c6tWbNGJ5100uQF3q+ioiLlNIqR0N/8D9ZIAKaRSCSimpoamc1mXXfddR/LF8rxbAMpSc3NzcOeG8sKtw0NDbr99tu1fPlySVv3Nb766qtVXV09rriwx8mQ9HNJJBIAYBQmk+kLog+dLsNkMhmGYUx1HDvNgQceqLvuuku33367Lrnkkp3Wjs1m07nnnrvdsbq6Oi1fvlxFRUXDrklwxx13yO1268QTT9zuuGEYuvPOO0dcFHwo+psYjDdBTDt2u1233XabVqxYoS9/+csfa9uDV9/9ODQ0NOiee+7RX/7yFyUSCZnNZp144ok677zzhh3psKfZEzPEY+H3+38u6SqTyUQSAQDG5uqVK1f+fKqD+Dj4/f47JZ2TRtGIyWR6PplMPmm32//yj3/8I9R//f07NcAptvfee+uOO+5IeW4so1aTyeSw52bNmrXddISWlhadccYZkqSLLrpo2K3E77jjDuXm5u4wlWHTpk268847h91ScjD6m0iFRAKmpfz8fB166KFav379qMPABmfJB7azGcmbb7457LmPax2GDz74QI888oheeuml7RbkSSaTeuihh/TQQw+NeL3ZbNY///nPnR0mAACY/oKS/izpSZPJ9Nc9ZbHFdI131OpIXn75ZV1//fXq7OzUt7/97WGTCENt2LBBv/3tb5WTk6NVq1ZJkubMmTNsefqbGAmJBExrhmEoHo+nXX4sZQf09f1nG2WLxTLm69MVjUb18ssva+nSpfq///u/bcdHWmchlZ3xgQYAAPYo7ZKeNZvNT3Z2dr68J27/ONiSJUv06U9/WosXL95hnYDJWmyxp6dH//u//6sHH3xQa9askbR1ukMwGBxxTa0jjjhCknTVVVfJMAy9/vrrkrZ+yV+4cKFOOOGE7crT30S6SCRgWpszZ86ob+ATXWyxt7d328+Dt/2ZLLW1tXrkkUf0wgsvKBLZmuTPzMxUb2+vzGaznn/++THVxyKEAABgrAzDaJb0lKQnc3NzX3v11Vf7RrtmTxAKhfTHP/5R999/vx566CHNmzdvUutvamrStddeqxUrVuxwwysajeq5554bc52ptoOkv4mxIpEATFAoFJK09c02MzNz0us3m81atmyZYrGYFixYoMMPP1yHHXaYDjrooElvCwAAYKi+vr5r99prr/OXLl2aGL30nuWDDz6QYRiy2+2qqqqa9PqLiopkMplksVh0+OGH6/jjj9dpp52WMhmQjuG+4NPfxFiRSAAmqL29XZKUm5u7U+qvqKjQ7373OxUXF6u0tHS7c4Zh6MYbb9wp7QIAAEjS+++/v/n999+f6jB2SQPPy6JFi1JufzgZiy3+4he/UHZ2dlpTC+644w51d3fr4osvTrtdif4mxo5EAjBBA3PAiouLd1obn/rUp1IeNwxDjz/++E5rFwAAAMP74IMPJEn77LNPyvOTsVaA2+1Ou+xAv3Cs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du12u+677z5deOGFWrlypZYtW7bXPLRIJKKf/exnikajuuiii3TCCSf0WWdv/2j6K9/c3KympiZJuxIgzz//vJ5//vm9yn/lK1/R97///QG1AQAAxiaTyeSRdJlhGJdlZGS0zJ49+zWTybTMZDKtWL16dSjZ8e0LK1asUG1trebNm6ePPvpIP/rRj3aPTpC0x3aQvemtTGdn/BkklZWVOvzww/XLX/5y97GKigp961vf0rHHHquHHnpor2vmzJkTd1HFZ555Rm63e49j9DcxECQSMCpFIhHdeuutCoVCysnJ0Z133tnnkLLhVlpaqu9+97vatGlT3KFhTzzxhDZv3qwvfelLfc6Zixnooo7xyre0tOy1eGPMzp07B1Q/AABAlwyTyXSBpAsMwwh5vd7lhmEsS0tL+/MHH3wQv+MxClx//fVyu916+OGHtXTpUm3cuFH333//Xts8xltPqzcNDQ29rpEQCoVUV1eno446ao/jsV3JDjrooAHFH2/hRvqbGAgSCRiV7rzzTn3yySdKTU3VggULlJWVNaLt9ZXBveyyy/Y6tm3bNkm7RkOcffbZca+bNWuWbr/9dkmJ/xNau3at7r//fn366acym826/PLLdfXVV8tsNid0/Wjk9XqNZMcAABiVbvd6vbcnO4j9jF3SWSaT6az29nZ5vd7XJC1LdlAj5cILL9T48eN16623au3atXr44Yd1xx13jEhblZWVknZN233llVf2Ov/ss8/q2WefjXttRUVFr+uAlZSU7J5GQX8TA0EiAaNOKBRSWVmZzGaz7r777oQWUByqwWwDKUm1tbW9nhvICrdVVVV6/PHHtWLFCkm79jW+4447NHv27EHFhTGnIxqNfpzsIADgQBCNRj82m80doh+dCMNkMhmGMXpz+scdd5x++ctf6vHHH9ctt9wyYu3YbDZdc801exzbsmWLVqxYoYKCgl7XJHjiiSfkdrt1/vnn73HcMAw9+eSTfS4K3hP9TXTHGyBGHbvdrscee0yrV6/WV7/61X3a9qpVq+RyufZZe1VVVXrmmWf05z//WZ2dnTKbzTr//PN17bXXKj09fZ/FsT9bs2bNvpvTAgAY9f71r3+9Kik12XHsS16v90lJVydQNGQymV6PRqPL7Hb7n//+97/7u65fNKIBJtnMmTP1xBNPxD03kHUHotFor+eKi4v3mI5QV1en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e7muXbt6Pb5582aNGzdOhw4dUnR0tF566aUrXgsND0ECACAgdOrUKa5jx47pCQkJNVvFyo8tWbJER48elSS99NJLeuqpp6o8NyIiQtOmTVNBQYG2bt2qpUuX6v7779ctt9xSX+UCsMjtt9/+q1tvvfVkQkJCmdW1XIuaNGmi9957T/v3779sEcLo6Gj95S9/0axZs/T8889X2b9Dhw6KiorShAkT1KdPH6/ntGjRQi1atPDaZrPZFBoaqptuuslre3BwcJVt3jRq1EitW7eusv348eOS5PWc48eP6w9/+INOnDihNm3aaNGiRYqOjjY9NhoOggQAQEAICwtbnpmZ2cHhcHwn6a9NmjRZkJqaet7quqxSUFCgNWvWSLr4rVJ1IUI5u92uSZMmaefOnSopKdGKFSs0Y8aMui4VgMWCg4OnZGZm/nvXrl3XeTyeNU2bNk1NTU29YHVdVrtw4YKCgy9+nIqMjPS6k0GXLl303//939WuK/Pb3/5WGzZsUJMmTaod75tvvlFmZmal48XFxQoNDdXy5cu99svPz6+yzZsHHnhADzzwgNc2t9utHj16SFKlxyJSU1P1+uuv68SJE3rooYc0efLkah/nQMNGkAAACBg2m80uqaOk+Ly8vNkOhyPTbrd/fO7cubmZmZn5VtdXnzZv3lwxBXf48OGm+91www3q3bu3EhMTtXnzZk2ZMkWhoaEV7eVTXYcOHarx48d7vca8efMqtiNLS0vzes6hQ4e0cuVK7dq1S7m5uWrUqJFuu+02PfHEE1W+wbVybMDf2Wy2aMMwRttsttF5eXm5Dofjc5vNtiYvLy8lMzOzxOr66ltmZqaef/55jR8/Xg8++GCldm/Hfql///5ejzdr1kwJCQmVjq9YsUK7d+/22sftdmvhwoVe286ePVtlmy+4XC7NnTtX69atU1hYmKZMmaInnniizsbDtYEgAQAQkGwXvx66xePxTG3SpMkbsbGxx202W4LNZnsnLS0t2+r66tqePXskXZySe+edd9ao71133aXExES53W7t27dPDofDp7WtXLlS8+fPv2yLsby8PO3YsUM7duzQI488ounTp9fJYo9Wjg00FDabrbmk4YZhDG/SpEl+bGzsBpvNtsZmsyWnpaW5rK6vPiQnJ+v06dOaOHGidu/erVdeeaVidoJ0ccebK6nqnLIy70+QnDhxQt26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hYWFeuWVV0yPK13cBnLBggVq1aqVYmJiLmszDKNie1ygHEECAAABauzYsdq2bZuOHTumN954Qx6PR3379vV6rsvl0syZMyuer/3jH/9Y6c2mJN12220VH+adTqccDsdl7cuWLVNubq7XMR577DGtXbtWJSUleuuttxQfH3/ZTgnlcnJylJGRoR49elwzYwMITHv37pUk3XHHHV7bfbFWQLNmzUyf++mnn0pSjYMESerWrZvX44ZhVFwXKEeQAABAgAoPD9d//Md/aPTo0Tp16pQmT56sdevWqV+/fmrbtq3Cw8OVk5Oj3bt3a/369crJyZEkPfrooxXbjv1Sv379lJKSIkl6+eWXNXbsWN1xxx0qKirShg0btGbNGrVp00bff/99pb6dO3fWww8/rKSkJKWmpuqZZ57RkCFDdOuttyooKEhZWVnatm2bNmzYoCeffLLSh3krxwYQeDweT8WChLGxsV7P8dVii2acPXtW+fn56tSpU62v4U1tdl9gjQT/R5AAAEAA+/Wvf60PP/xQ06dP186dO7V7927t3r3b67mRkZH64x//qKFDh8pms3k95+677674QJ6Xl6dZs2Zd1j548GAFBwd7/TAvSVOmTFFBQYG++eYbHTp0SNOmTat0js1mU6tWra6psQEEnoMHD6qwsFDBwcH613/9V6vLqQhSc3NztXLlSvXs2VNt27a1uCr4K4IEAAACXHR0tBYvXqwdO3YoOTlZ//u//6vs7GwVFxdLuvht1Pjx4/XII4+YmmI7Y8YMde7cWf/zP/+jY8eOyePxqF27dho8eLD69eunefPmVdm3fJZESkqK/va3v+ngwYPKy8tTWFiYbrzxRsXGxurxxx/Xbbfdds2NDSCw7NixQ5J06623Kiws7KqvV1Zmbi3L1157TU2aNKn4s8fj0ZdffqmFCxfKbrcrJydH8+bN07x589SyZUvdfffduvvuuxUXF6ePP/7YJ7UCBAkAAECSdOedd+rOO++s+PM777yjTz75RB6PR99//73p53TtdruefPJJPfnkk17bx48fr/Hjx1fZ32az6cEHH9SDDz5Ysx/A4rEBBJadO3dKqnp9hOqcP39eoaGhly3Q+OWXX0rSZSGBNwMHDpTL5dL27du1Y8cObd68WadPn1ZQUJAmT56sPn36aOvWrUpJSdG2bduUkJCghIQERUREqGfPnrr33nt1/fXXq3HjxqZq9Xg8NVo0EoGBIAEAAHj18ssv66efftKXX36ptWvXKiQkRC+//LLXlckBIJAUFxdX7Nhw++2317j/zJkzlZiYqLCwMIWFham0tLRiFpi37Xg3bNig7777TidPnlRmZqaysrJkGIakiwHqvffeq1GjRlVsQdm3b1/17dtXxcXF+vrrr5WSkqKvv/5aW7Zs0ZYtWxQcHKzu3bvrxRdfNPX4gy8WjYR/IUgAAABe2e12zZo1S6+++qq2bt2qTz75RN99951GjBihzp07Kzw8XIcPH74mng0GgPpUVFSk3r17a9u2bbWakdChQwclJSWppKREJSUlkqTQ0FB169ZNzz33XKXzT548qdWrV0u6OHPqxhtvVOfOnRUXF6devXqpefPmXseJiIhQnz591KdPHxUVFenLL79UcnKy/vnPf2r//v1q2bLlFWtlsUV4432lJABAQHA4HNMkTZU03el0TrO2mmubw+EwpJqtwO0vysrKFB8frzVr1nhtD8S/E39S/obf6XTyvhB1wp/vnx6Px+ssrWPHjkmSbrrppmr7l5WVVfwvLCysyhlfubm52rlzp/7lX/5Fbdq0UWRk5FXVnZubq5MnT15xh4fPPvtMdru9xo821LZfQxPI909mJAAAgGoFBQVp0qRJ6t27tz755BNt375dbrdb0sUFCgEgUFX1wf9KAUK5oKAgBQUFXfG85s2b6+GHH65JaVe8XlWzGC41cODAWl2/tv3QcBAkAAAAU7p3767u3bvLMAzl5OTIMAxdf/31VpcFAADqGUECAACoEZvNphYtWlhdBgAAsAjLLgMAAAAAANMIEgAAAAAAgGkECQAAAAAAwDSCBAAAAAAAYBpBAgAAAAAAMI0gAQAAc7IlqaioyOo6AJ8pLCwsf5ltZR3we9w/4XcC/f5JkAAAgDkHJCkjI8PqOgCfueT3eb+VdcDvcf+E3wn0+ydBAgAAJthsthWSNHv2bDmdzku/iQAanMLCQjmdTsXHx0uSDMNYYXFJ8GPcP+FPuH9eZLO6AACAdRwOxzRJUyVNdzqd06yt5ppndzgcn0vqZ3UhgI/9zel0Pi7JsLoQ+C3un/BXAXv/ZEYCAADmeJxO5+OGYYyU9JUC9JlI+I1sSV8ZhjHS6XT+uwLwTTDqFfdP+BPun5KCrS4AAIAGxLNnz55lkpZZXQgANDDcPwE/wowEAAAAAABgGkECAAAAAAAwjSABAAAAAACYRpAAAAAAAABMI0gAAAAAAACmESQAAAAAAADTCBIAAAAAAIBpBAkAAAAAAMA0ggQAAAAAAGAaQQIAAAAAADCNIAEAAAAAAJhGkAAAAAAAAEwjSAAAAAAAAKYRJAAAAAAAANMIEgAAAAAAgGkECQAAAAAAwDSCBAAAAAAAYBpBAgAAAAAAMC3Y6gJwTbB37dp1hGEYwyR1lNTC6oKAWsqWdMBms61IS0v7UJLH6oIAAAAAf8OMBNgdDsfnhmF8IKmXCBHQsLWQ1MswjA8cDsd6cY8DAAAAfI4ZCQHu55kI/W6++WZNnDhR7du3V1RUlNVlAbVSVFSkjIwMzZ49W5mZmf8WGxs7fM+ePcusrgsAAADwJ3xbF+B+fpxBEydOVGxsLCECGrSoqCjFxsZqwoQJkiSbzTbM4pIAAAAAv0OQgI6S1L59e6vrAHzmkt/nTlbWAQAAAPgjggS0kMRMBPiVRo0alb9kzQ8AAADAxwgSAAAAAACAaQQJAAAAAADANIIEAAAAAABgGkECAAAAAAAwjSABAAAAAACYRpAAAAAAAABMI0gAAAAAAACmESQAAAAAAADTCBIAAAAAAIBpBAkAAAAAAMA0ggQAAAAAAGAaQQICXnZ2tqZMmaIpU6bU2RinTp3SrFmz9Pnnn9fZGG63W3FxcYqLi6uzMQAAAACAIAEBIysrS0VFRZWOFxYWKikpSUlJSXU2dmpqqtasMKy0bgAACNFJREFUWaOFCxd6rcFXPB6PPB5PnV0fAAAAAAgSEDD+/Oc/6/7779f69evrfexBgwapTZs2Onv2rFauXFnv4/9STk6OZsyYIZfLZXUpAAAAABqYYKsLAOpDWlqaDh8+LEmKjY31yTVdLpeGDh1q+vyzZ89KkpYvX64vvvjCVJ9nn31WDz/8cK3qq0pBQYGee+45HTp0SNnZ2VqwYIFPrw8AAADAvxEkICCUzwK444471Lp1a59cs6ysTMePH69xP7fbbbpffn7+ZX9ev3693nzzzSv269q1q9fjmzdv1rhx43To0CFFR0frpZdeMlUHAAAAAJQjSIDfS09P19atWyVJgwcP9tl1GzdurLS0tErHPR6PEhISdNdddykmJqbaaxQUFGjnzp164IEHTI3ZqFGjaoOQ8oDC2znHjx/XH/7wB504cUJt2rTRokWLFB0dbWpcAAAAAChns7oAWMvhcBiSvH4g9hcjRoxQenq6z65377336t13362y/b333tMHH3ygdu3aafny5YqMjKzy3LffflufffaZ7rvvPs2ZM+eq6nK73erRo4ekyv+eqampev311+VyufTQQw9p8uTJioqKuqrxrnXlszKcTif3uWo4HI5pkqZKmu50OqdZWw0AAAAaAmYkwK+tW7euIkQIDw+XzVb5M6VhGDp//rwkKSIi4orXDAsLq7b9mWee0aZNm3TkyBFNnz5d8fHxXs/bv3+/1q5dK0l65JFHrjhubbhcLs2dO1fr1q1TWFiYpkyZoieeeKJOxgIAAAAQGAgS4LdOnjypuXPnSpJ69uypBQsWeA0Sjh07pgEDBkiSvvnmm6seNzIyUu+8846GDh2qlJQUrVmzpuL65dxut6ZNmyaPx6Nhw4bp/vvvr/aa/fv3r1EN5efn5eXp3Llzki4GICtWrNCKFSsqnX/PPffohRdeqNEYAAAAAAITQQL8ktvt1qRJk+RyudSiRQvNmDHDa4hQV26++WaNHj1aR44c8br+wZIlS3T06FF1795dzz///BWvV9NFHb2dn5+fX2nxxnI//fRTja4PAAAAIHARJMAvzZgxQ99++61CQkI0a9YsXXfddXU6XnUzBoYPH17p2A8//CDp4myIgQMHeu3XpUsXTZ06VZL5NSzS09M1Z84cHThwQHa7XSNGjNCoUaNkt9tN9fdH5euAAAAAAPANggT4HZfLpYyMDNntds2cObPKrRB9qTbbQErS6dOnq2yryY4KWVlZWrx4sZKTkyVJMTExmj59umJjY2tVFwLOBY/Hs8fqIgAAANAwECTA70RGRmrRokVKS0tT796963Xs1NRUNW7cuN7Gy8rK0tKlS7Vx40aVlZXJbrdryJAhGjNmjMLDw+utjmsZuzYAAAAAvkWQAL90ww03qG/fvjp69Kiefvrpas81jP+b+V6+fWJ1tm/fXmVbfa3DsHfvXq1evVopKSkqKyurOO7xeLRq1SqtWrWq2v52u127du2q6zIBAAAA+CGCBPg1wzDkdrtNn1+Tc8tduHCh4nVQUFCN+5tVXFysLVu2KCEhQfv27as4Hh0dXaPZB7V9DAMAAAAAJIIE+Ll27dpdcaHCS7d/NLuo4aVKS0srXgcH+/4/qczMTK1evVqbNm2Sy+WSJIWEhKi0tFR2u12JiYk1ul59rBkBAAAAwH8F7lLugI8UFBRIuvjhPiQkxOfXt9vtSkpKksvlUqdOnfTqq69q06ZNPh8HAAAAAMxgRgJwlXJyciRJTZs2rZPrt23bVgsWLFCrVq0UExNzWZthGIqPj6+TcQEAAADAG4IE4CqVrznQqlWrOhujW7duXo8bhqFPP/20zsYFAAAAgF8iSACu0t69eyVdXI+hvtVm9wXWSAAAAABwNVgjAbgKpaWl+uKLLyRJcXFxFlcDAAAAAHWPIAG4CsnJyTp79qwiIiLUq1cvq8sBAAAAgDrHow3wO263Wz169KhV35pM+09MTNTcuXMlSYMGDVJkZGStxrwaHo9H/fv3r/dxAQAAAAQuggT4pebNm9f5GElJScrPz1fLli01cuTIOh+vKuWLPQIAAABAfSBIgN8JDQ3V5s2b63yc0tJSbd++XWPHjrVkNoLEYosAAAAA6h9BAlBLISEhWrJkiex2a5Yaee2112o1dm37AQAAAIBEkABcFSs/kA8cOLBe+wEAAACAxK4NAAAAAACgBggSAAAAAACAaQQJAAAAAADANIIEAAAAAABgGkECAAAAAAAwjSABAAAAAACYRpAAAAAAAABMI0hAtiQVFRVZXQfgM4WFheUvs62sAwAAAPBHBAk4IEkZGRlW1wH4zCW/z/utrAMAAADwR0FWFwBr3XjjjcGSHjtw4IDatWunxo0bKzQ01OqygFopLCzUvn37FB8fr9zcXBmG8dapU6f2WF0XAAAA4E9sVhcAy9kdDsfnkvpZXQjgY39zOp2PSzKsLgQAAADwJ8xIgHHy5MlPWrZs+YPNZmsqqZGkSKuLAmopW9IuwzDe2rNnz0QRIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACA9P8BIJrlnMPnXVsAAAAASUVORK5CYII=" alt="" />
注意:
1)、在点对点或队列模型下,一个生产者向一个特定的队列发布消息,一个消费者从该队列中读取消息。这里,生产者知道消费者的队列,并直接将消息发送到消费者的队列。这种模式被概括为:只有一个消费者将获得消息。生产者不需要在接收者消费该消息期间处于运行状态,接收者也同样不需要在消息发送时处于运行状态。每一个成功处理的消息都由接收者签收。
2)、发布者/订阅者模型支持向一个特定的消息主题发布消息。0或多个订阅者可能对接收来自特定消息主题的消息感兴趣。在这种模型下,发布者和订阅者彼此不知道对方。这种模式好比是匿名公告板。这种模式被概括为:多个消费者可以获得消息,在发布者和订阅者之间存在时间依赖性。发布者需要建立一个订阅(subscription),以便客户能够购订阅。订阅者必须保持持续的活动状态以接收消息,除非订阅者建立了持久的订阅。在那种情况下,在订阅者未连接时发布的消息将在订阅者重新连接时重新发布。

6、JMS应用程序接口。

 )、ConnectionFactory 接口(连接工厂)
用户用来创建到JMS提供者的连接的被管对象。JMS客户通过可移植的接口访问连接,这样当下层的实现改变时,代码不需要进行修改。 管理员在JNDI名字空间中配置连接工厂,这样,JMS客户才能够查找到它们。根据消息类型的不同,用户将使用队列连接工厂,或者主题连接工厂。
)、Connection 接口(连接)
连接代表了应用程序和消息服务器之间的通信链路。在获得了连接工厂后,就可以创建一个与JMS提供者的连接。根据不同的连接类型,连接允许用户创建会话,以发送和接收队列和主题到目标。
)、Destination 接口(目标)
目标是一个包装了消息目标标识符的被管对象,消息目标是指消息发布和接收的地点,或者是队列,或者是主题。JMS管理员创建这些对象,然后用户通过JNDI发现它们。和连接工厂一样,管理员可以创建两种类型的目标,点对点模型的队列,以及发布者/订阅者模型的主题。
)、MessageConsumer 接口(消息消费者)
由会话创建的对象,用于接收发送到目标的消息。消费者可以同步地(阻塞模式),或异步(非阻塞)接收队列和主题类型的消息。
)、MessageProducer 接口(消息生产者)
由会话创建的对象,用于发送消息到目标。用户可以创建某个目标的发送者,也可以创建一个通用的发送者,在发送消息时指定目标。
)、Message 接口(消息)
是在消费者和生产者之间传送的对象,也就是说从一个应用程序创送到另一个应用程序。一个消息有三个主要部分:
消息头(必须):包含用于识别和为消息寻找路由的操作设置。
一组消息属性(可选):包含额外的属性,支持其他提供者和用户的兼容。可以创建定制的字段和过滤器(消息选择器)。
一个消息体(可选):允许用户创建五种类型的消息(文本消息,映射消息,字节消息,流消息和对象消息)。
消息接口非常灵活,并提供了许多方式来定制消息的内容。
)、Session 接口(会话)
表示一个单线程的上下文,用于发送和接收消息。由于会话是单线程的,所以消息是连续的,就是说消息是按照发送的顺序一个一个接收的。会话的好处是它支持事务。如果用户选择了事务支持,会话上下文将保存一组消息,直到事务被提交才发送这些消息。在提交事务之前,用户可以使用回滚操作取消这些消息。一个会话允许用户创建消息生产者来发送消息,创建消息消费者来接收消息。

7、如何使用java操作activeMQ呢,把ActiveMQ依赖的jar包添加到工程中。

使用maven工程,则添加jar包的依赖:

 <dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.11.</version>
</dependency>

然后你就可以愉快得开发了。是不是很开森呢。

8、ActiveMQ点对点模式(point-to-point)。

ActiveMq的点对点生产者。

 package com.taotao.activemq;

 import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQTextMessage;
import org.junit.Test; /**
*
* @ClassName: ActiveMqMain.java
* @author: biehl
* @since: 2019年9月15日 下午4:44:57
* @Copyright: ©2019 biehl 版权所有
* @version: 0.0.1
* @Description:
*/
public class ActiveMqMain { // activeMq得点对点生产者
@Test
public void queueProducer() throws JMSException {
// 1、创建一个连接工厂对象ConnectionFactory对象。需要指定mq服务得ip以及端口号61616。
String brokerURL = "tcp://192.168.110.142:61616";
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerURL);
// 2、使用ConnectionFactory创建一个连接Connection对象。
Connection connection = connectionFactory.createConnection();
// 3、开启连接。调用Connection对象得start方法。
connection.start();
// 4、使用Connection对象创建一个Session对象。
// 参数一是否开启事务,一般不开启事务,保证数据得最终一致性,可以使用消息队列实现数据最终一致性。如果第一个参数为true,第二个参数自动忽略
// 参数二是消息得应答模式。两种模式,自动应答和手动应答。一般使用自动应答。
boolean transacted = false;// 不开启事务
int acknowledgeMode = Session.AUTO_ACKNOWLEDGE;//
Session session = connection.createSession(transacted, acknowledgeMode);
// 5、使用Session对象创建一个Destination对象。两种形式queue、topic。现在应该使用queue。
String queueName = "queue1";// 当前消息队列得名称
Queue queue = session.createQueue(queueName);
// 6、使用Session对象创建一个Producer对象。
// interface Queue extends Destination。destination是一个接口。
MessageProducer producer = session.createProducer(queue);
// 7、创建一个TextMessage对象。
// 创建TextMessage方式一
// TextMessage textMessage = new ActiveMQTextMessage();
// textMessage.setText("hello activeMq......");
// 方式二
TextMessage textMessage = session.createTextMessage("hello activeMq......");
// 8、发送消息。
producer.send(textMessage);
// 9、关闭资源。
producer.close();// 关闭producer
session.close();// 关闭session
connection.close();// 关闭connection
} }

ActiveMQ的点对点消息生产成功以后,可以在ActiveMQ提供的web界面可以看到一些信息。

activeMq的点对点消费者。

 package com.taotao.activemq;

 import java.io.IOException;

 import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQTextMessage;
import org.junit.Test; /**
*
* @ClassName: ActiveMqMain.java
* @author: biehl
* @since: 2019年9月15日 下午4:44:57
* @Copyright: ©2019 biehl 版权所有
* @version: 0.0.1
* @Description:
*/
public class ActiveMqMain { // activeMq的点对点生产者
@Test
public void queueProducer() throws JMSException {
// 1、创建一个连接工厂对象ConnectionFactory对象。需要指定mq服务得ip以及端口号61616。
String brokerURL = "tcp://192.168.110.142:61616";
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerURL);
// 2、使用ConnectionFactory创建一个连接Connection对象。
Connection connection = connectionFactory.createConnection();
// 3、开启连接。调用Connection对象得start方法。
connection.start();
// 4、使用Connection对象创建一个Session对象。
// 参数一是否开启事务,一般不开启事务,保证数据得最终一致性,可以使用消息队列实现数据最终一致性。如果第一个参数为true,第二个参数自动忽略
// 参数二是消息得应答模式。两种模式,自动应答和手动应答。一般使用自动应答。
boolean transacted = false;// 不开启事务
int acknowledgeMode = Session.AUTO_ACKNOWLEDGE;//
Session session = connection.createSession(transacted, acknowledgeMode);
// 5、使用Session对象创建一个Destination对象。两种形式queue、topic。现在应该使用queue。
String queueName = "queue1";// 当前消息队列得名称
Queue queue = session.createQueue(queueName);
// 6、使用Session对象创建一个Producer对象。
// interface Queue extends Destination。destination是一个接口。
MessageProducer producer = session.createProducer(queue);
// 7、创建一个TextMessage对象。
// 创建TextMessage方式一
// TextMessage textMessage = new ActiveMQTextMessage();
// textMessage.setText("hello activeMq......");
// 方式二
TextMessage textMessage = session.createTextMessage("hello activeMq......");
// 8、发送消息。
producer.send(textMessage);
// 9、关闭资源。
producer.close();// 关闭producer
session.close();// 关闭session
connection.close();// 关闭connection
} // activeMq的点对点消费者
@Test
public void queueConsumer() throws JMSException {
// 1、创建一个连接工厂ConnectionFactory 对象
String brokerURL = "tcp://192.168.110.142:61616";
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerURL);
// 2、使用连接工厂对象创建一个连接
Connection connection = connectionFactory.createConnection();
// 3、开启连接
connection.start();
// 4、使用连接对象创建一个Session对象
boolean transacted = false;// 关闭事务
int acknowledgeMode = Session.AUTO_ACKNOWLEDGE;// 自动响应
Session session = connection.createSession(transacted, acknowledgeMode);
// 5、使用Session创建一个Destination,Destination应该和消息的发送端一致的。
String queueName = "queue1";
Queue queue = session.createQueue(queueName);
// 6、使用Session创建一个Consumer对象。
MessageConsumer consumer = session.createConsumer(queue);
// 7、向Consumer对象中设置一个MessageListener对象,用来接受消息。
// 匿名内部类,new 接口,后面加上{},相当于实现了这个接口的实现类。然后创建这个实现类的对象listener。
MessageListener listener = new MessageListener() { @Override
public void onMessage(Message message) {
// 接受事件的。当消息到达就可以在这里接受到消息了的。
// 8、取出消息的内容。
if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
// 9、打印消息内容。
try {
String text = textMessage.getText();
System.out.println(text);
} catch (JMSException e) {
e.printStackTrace();
}
}
}
};
consumer.setMessageListener(listener); // 关闭资源以前,系统等待,等待接受消息。
/*while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}*/ // 等待键盘输入。才回接着向下执行的。
try {
System.in.read();
} catch (IOException e) {
e.printStackTrace();
} // 10、关闭资源。
consumer.close();// 关闭consumer
session.close();// 关闭session
connection.close();// 关闭connection
} }

执行了activeMq的点对点消费者。可以在界面看到变化。可以看到有一个消费者,然后生产了7条消息,7条消息进队和7条消息出队。

9、ActiveMQ发布订阅模式(publish/subscribe)。

消费者有两种消费方法(这里使用异步消费):
  a、同步消费。通过调用消费者的receive方法从目的地中显式提取消息。receive方法可以一直阻塞到消息到达。

  b、异步消费。客户可以为消费者注册一个消息监听器,以定义在消息到达时所采取的动作。

    实现MessageListener接口,在MessageListener()方法中实现消息的处理逻辑。

 package com.taotao.activemq;

 import java.io.IOException;

 import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic; import org.apache.activemq.ActiveMQConnectionFactory;
import org.junit.Test; /**
* Active的发布订阅模式
*
* @ClassName: ActiveMqTopics.java
* @author: biehl
* @since: 2019年9月19日 上午10:51:14
* @Copyright: ©2019 biehl 版权所有
* @version: 0.0.1
* @Description:
*/
public class ActiveMqTopics { // 发布订阅模式,生产者。topic生产者生产消息默认不持久化客户端的。
@Test
public void topicProducer() {
try {
// 1、创建一个连接工厂对象。需要指定mq服务的ip地址以及端口号61616
String brikerURL = "tcp://192.168.110.142:61616";
// 创建ConnectionFactory接口对象,实现类ActiveMQConnectionFactory
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brikerURL); // 2、创建Connection连接
Connection connection = connectionFactory.createConnection(); // 3、开启连接,调用Connection的start方法。
connection.start(); // 4、创建Session,使用Connection对象创建一个session
// 参数一是否开启事务,一般不开启事务,保证数据得最终一致性,可以使用消息队列实现数据最终一致性。如果第一个参数为true,第二个参数自动忽略
boolean transacted = false;
// 参数二是消息得应答模式。两种模式,自动应答和手动应答。一般使用自动应答。
int acknowledgeMode = Session.AUTO_ACKNOWLEDGE;
Session session = connection.createSession(transacted, acknowledgeMode); // 5、创建Destination,应该使用topic,区别于点对点的queue
String topicName = "topic01";
Topic topic = session.createTopic(topicName); // 6、创建一个Producer对象
// interface Topic extends Destination.
// Destination是一个接口,Topic接口继承Destination这个接口。
MessageProducer producer = session.createProducer(topic); // 7、创建一个TextMessage对象
String message = null;
TextMessage textMessage = null;
for (int i = ; i < ; i++) {
message = i + " ActiveMQ topics......";
textMessage = session.createTextMessage(message); // 8、发送消息
producer.send(textMessage);
} // 9、关闭资源
producer.close();// 关闭producer
session.close();// 关闭session
connection.close();// 关闭connection
} catch (JMSException e) {
e.printStackTrace();
}
} // 发布订阅模式,消费者必须一直等待生产者生产的消息,因为发布订阅模式不持久化。
@Test
public void topicConsumer() {
try {
// 1、创建一个连接工厂对象
String brokerURL = "tcp://192.168.110.142:61616";
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerURL); // 2、使用连接工厂对象创建一个连接
Connection connection = connectionFactory.createConnection(); // 3、开启连接
connection.start(); // 4、使用连接对象创建一个Session对象
// 参数一是否开启事务,一般不开启事务,保证数据得最终一致性,可以使用消息队列实现数据最终一致性。如果第一个参数为true,第二个参数自动忽略
boolean transacted = false;
// 参数二是消息得应答模式。两种模式,自动应答和手动应答。一般使用自动应答。
int acknowledgeMode = Session.AUTO_ACKNOWLEDGE;
Session session = connection.createSession(transacted, acknowledgeMode); // 5、使用session创建destination,注意,destination应该和消息的发送端一致的。
String topicName = "topic01";
Topic topic = session.createTopic(topicName); // 6、使用session创建一个consumer对象
MessageConsumer consumer = session.createConsumer(topic); // 7、向Consumer对象中设置一个MessageListener对象,用来接受消息。
// 匿名内部类,new 接口,后面加上{},相当于实现了这个接口的实现类。然后创建这个实现类的对象listener。
MessageListener listener = new MessageListener() {
// 接受事件的。当消息到达就可以在这里接受到消息了的。
// 8、取出消息的内容。
@Override
public void onMessage(Message message) {
if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
// 9、打印消息内容。
try {
String text = textMessage.getText();
System.out.println(text);
} catch (JMSException e) {
e.printStackTrace();
}
}
}
};
consumer.setMessageListener(listener); // 启动三次,模拟是三个消费者
System.out.println("消费者1.......");
// System.out.println("消费者2.......");
// System.out.println("消费者3......."); // 等待键盘输入。才回接着向下执行的。
try {
System.in.read();
} catch (IOException e) {
e.printStackTrace();
} // 9、关闭资源
consumer.close();// 关闭producer
session.close();// 关闭session
connection.close();// 关闭connection
} catch (JMSException e) {
e.printStackTrace();
} } }

执行了activeMq的发布订阅模式。可以在界面看到变化。可以看到有三个消费者,然后生产了201条消息,201条消息进队和603条消息出队。

10、ActiveMQ与Spring整合如下所示:

在pom.xml配置文件中引入自己的依赖的jar包。

 <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>

在配置文件applicationContext-activemq.xml里面配置ConnectionFactory。如下所示:

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms-4.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->
<bean id="targetConnectionFactory"
class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL"
value="tcp://192.168.110.142:61616" />
</bean> <!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory"
class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory"
ref="targetConnectionFactory" />
</bean>
</beans>

开始配置生产者的spring配置。

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms-4.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <!-- 、真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->
<bean id="targetConnectionFactory"
class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL"
value="tcp://192.168.110.142:61616" />
</bean> <!-- 、Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory"
class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<!-- 给属性targetConnectionFactory传值 -->
<property name="targetConnectionFactory"
ref="targetConnectionFactory" />
</bean> <!-- 、开始配置生产者配置 -->
<!-- 配置生产者 -->
<!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->
<bean id="jmsTemplate"
class="org.springframework.jms.core.JmsTemplate">
<!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->
<!-- 给属性connectionFactory传值 -->
<property name="connectionFactory" ref="connectionFactory" />
</bean> <!-- 、配置消息的Destination对象 -->
<!-- 点对点模式 -->
<!-- 这个是队列目的地,点对点的。 -->
<bean id="queueDestination"
class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg>
<!-- 给ActiveMQQueue构造参数传递一个值为queue -->
<value>queue</value>
</constructor-arg>
</bean> <!-- 发布订阅模式 -->
<!-- 这个是主题目的地,一对多的。 -->
<bean id="topicDestination"
class="org.apache.activemq.command.ActiveMQTopic">
<!-- 给ActiveMQTopic构造参数传递一个值为topic -->
<constructor-arg value="topic" />
</bean> </beans>

生产者测试代码如下所示:

可以根据之前的消费者测试一下,消息的消费。

 package com.taotao.activemq;

 import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage; import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator; /**
*
* @ClassName: SpringActiveMQ.java
* @author: biehl
* @since: 2019年9月19日 下午7:01:43
* @Copyright: ©2019 biehl 版权所有
* @version: 0.0.1
* @Description:
*/
public class SpringActiveMQ { // 使用spring与activemq整合,是哟个jmsTemplate发送消息
@Test
public void jmsTemplateProducer() {
// 1、初始化spring容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"classpath:/spring/applicationContext-activemq.xml");
// 2、从容器中获得jmsTemplate对象。根据类型获取到bean的对象
JmsTemplate jmsTemplate = applicationContext.getBean(JmsTemplate.class);
// 3、从容器中获得Destination对象。根据名称获取到bean的对象
Destination destination = (Destination) applicationContext.getBean("queueDestination"); // 4、发送消息
jmsTemplate.send(destination, new MessageCreator() { @Override
public Message createMessage(Session session) throws JMSException {
// 定义一个消息
String message = "hello activeMq......";
// 发送消息
TextMessage textMessage = session.createTextMessage(message);
return textMessage;
}
});
} }

效果如下所示:

开始配置消费者的spring配置。

  1)、注意:那么消费者是通过Spring为我们封装的消息监听容器MessageListenerContainer实现的,它负责接收信息,并把接收到的信息分发给真正的MessageListener进行处理。每个消费者对应每个目的地都需要有对应的MessageListenerContainer。
  2)、对于消息监听容器而言,除了要知道监听哪个目的地之外,还需要知道到哪里去监听,也就是说它还需要知道去监听哪个JMS服务器,这是通过在配置MessageConnectionFactory的时候往里面注入一个ConnectionFactory来实现的。
  3)、所以在配置一个MessageListenerContainer的时候有三个属性必须指定:
    a、一个是表示从哪里监听的ConnectionFactory
    b、一个是表示监听什么的Destination;
    c、一个是接收到消息以后进行消息处理的MessageListener。
  4)、常用的MessageListenerContainer实现类是DefaultMessageListenerContainer。

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms-4.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <!-- 、真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->
<bean id="targetConnectionFactory"
class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL"
value="tcp://192.168.110.142:61616" />
</bean> <!-- 、Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory"
class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<!-- 给属性targetConnectionFactory传值 -->
<property name="targetConnectionFactory"
ref="targetConnectionFactory" />
</bean> <!-- 、配置消息的Destination对象。接受消息的目的地。 -->
<!-- 点对点模式 -->
<!-- 这个是队列目的地,点对点的。 -->
<bean id="queueDestination"
class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg>
<!-- 给ActiveMQQueue构造参数传递一个值为queue -->
<value>queue</value>
</constructor-arg>
</bean> <!-- 发布订阅模式 -->
<!-- 这个是主题目的地,一对多的。 -->
<bean id="topicDestination"
class="org.apache.activemq.command.ActiveMQTopic">
<!-- 给ActiveMQTopic构造参数传递一个值为topic -->
<constructor-arg value="topic" />
</bean> <!-- 、配置消息接收者 -->
<!-- 配置一个监听器 -->
<bean id="activeMqMessageListener"
class="com.taotao.search.listener.ActiveMqMessageListener" /> <!-- 配置监听容器 -->
<bean
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<!-- 属性设置 -->
<!-- 一个是表示从哪里监听的ConnectionFactory -->
<property name="connectionFactory" ref="connectionFactory" />
<!-- 一个是表示监听什么的Destination -->
<property name="destination" ref="queueDestination" />
<!-- 一个是接收到消息以后进行消息处理的MessageListener -->
<property name="messageListener" ref="activeMqMessageListener" />
</bean> </beans>

然后可以写消息监听器,用来监听生产者生产的消息,以便实现自己的业务逻辑。

 package com.taotao.search.listener;

 import java.text.SimpleDateFormat;
import java.util.Date; import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage; /**
* 接受ActiveMQ发送的消息.
*
* @ClassName: ActiveMqMessageListener.java
* @author: biehl
* @since: 2019年9月19日 下午7:55:24
* @Copyright: ©2019 biehl 版权所有
* @version: 0.0.1
* @Description:
*/
public class ActiveMqMessageListener implements MessageListener { @Override
public void onMessage(Message message) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
System.out.println("监听生产者生产的消息,消费者进行消息消费.......");
// 消息到了onMessage就接受到了消息
if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
try {
String text = textMessage.getText();
System.out.println(sdf.format(new Date()) + " : " + text);
} catch (JMSException e) {
e.printStackTrace();
}
}
} }

由于这里只是简单的测试,如果是正式项目的话,直接加载这个配置文件,然后就可以进行消息的监听消费,我这里只是加载一下这个配置文件即可。

 package com.taotao.search.service;

 import java.io.IOException;

 import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; /**
*
* @ClassName: ActiveMqConsumer.java
* @author: biehl
* @since: 2019年9月19日 下午8:10:55
* @Copyright: ©2019 biehl 版权所有
* @version: 0.0.1
* @Description:
*/
public class ActiveMqConsumer { // 启动spring容器。就可以实现监听生产者发送消息,消费者消费小的目的地。
public static void main(String[] args) {
// 初始化spring容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"classpath:/spring/applicationContext-activemq.xml");
System.out.println("spring容器加载完毕,开始监听生产者生产的消息.......");
try {
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
}
}

实现效果如下所示:

控制台打印如下所示,只要你生产消息,这里就可以进行消息的消费。

待续......

ActiveMQ的安装与使用。的更多相关文章

  1. activemq的安装与使用

    一.activemq的安装 环境:CentOS 6.JDK8 1. 确保系统已安装了可用的jdk版本2. 从网上下载 Linux 版的 ActiveMQ( apache-activemq-5.11.1 ...

  2. ActiveMQ的安装与配置

    ActiveMQ的安装与配置详情 (1)ActiveMQ的简介 MQ: (message queue) ,消息队列,也就是用来处理消息的,(处理JMS的).主要用于大型企业内部或与企业之间的传递数据信 ...

  3. 170516、ActiveMQ 的安装与使用(单节点)

    ActiveMQ 的安装与使用(单节点)IP: 192.168.4.101环 境: CentOS 6.6 . JDK71. 安装 JDK 并配置环境变量(略)JAVA_HOME=/usr/local/ ...

  4. activemq的安装使用

    近期有项目中用到消息队列,JMS规范中实现最好的开源框架就是activemq.所以选择它(当然这是我老大决定的,像我这样的刚入职场的小菜鸟考虑问题还不太全面)作为消息队列数据传输.公司有有成型的消息队 ...

  5. 淘淘商城项目_同步索引库问题分析 + ActiveMQ介绍/安装/使用 + ActiveMQ整合spring + 使用ActiveMQ实现添加商品后同步索引库_匠心笔记

    文章目录 1.同步索引库问题分析 2.ActiveM的介绍 2.1.什么是ActiveMQ 2.2.ActiveMQ的消息形式 3.ActiveMQ的安装 3.1.安装环境 3.2.安装步骤 4.Ac ...

  6. Dubbo入门到精通学习笔记(八):ActiveMQ的安装与使用(单节点)、Redis的安装与使用(单节点)、FastDFS分布式文件系统的安装与使用(单节点)

    文章目录 ActiveMQ的安装与使用(单节点) 安装(单节点) 使用 目录结构 edu-common-parent edu-demo-mqproducer edu-demo-mqconsumer 测 ...

  7. Active-MQ的安装

    (1)首先就是下载软件 wget http://archive.apache.org/dist/activemq/apache-activemq/5.9.0/apache-activemq-5.9.0 ...

  8. 分布式架构实战--ActiveMQ的安装与使用(单节点)

    具体内容请参考样例代码和视频教程: http://www.roncoo.com/course/view/85d6008fe77c4199b0cdd2885eaeee53 IP:192.168.4.10 ...

  9. ActiveMQ——activemq的安装详情,修改密码

    1.安装 下载 http://activemq.apache.org/download-archives.html, [推荐]ActiveMQ 5.13.4 Release与jdk1.7搭配(其它版本 ...

随机推荐

  1. 《机器学习基石》---Linear Models for Classification

    1 用回归来做分类 到目前为止,我们学习了线性分类,线性回归,逻辑回归这三种模型.以下是它们的pointwise损失函数对比(为了更容易对比,都把它们写作s和y的函数,s是wTx,表示线性打分的分数) ...

  2. (十)c#Winform自定义控件-横向列表

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  3. 腾讯PCG(后台开发) 牛客网视频面试 一面

    腾讯视频面试 作为一个小渣渣记录一下,腾讯是我一直想进的公司,但其实准备的时间不是很长,也不是科班还是存在很大的劣势,记录一下找工作的经历. 首先说一下,这是我第一次视频面试,还是蛮紧张的.不过面试官 ...

  4. 【转】python爬虫之腾讯视频vip下载

    本文转自如下:作者:jia666666 原文:https://blog.csdn.net/jia666666/article/details/82466553 版权声明:本文为博主原创文章,转载请附上 ...

  5. java JVM原理讲解和调优和gc

  6. gradle引jar包,引工程

    gradle引jar包有直接引mvn仓库的,也有引本地的,引本地jar包需要: compile files("xxxxxx.jar")

  7. Spring学习之旅(一)--初始Spring

    之前从博客.视频断断续续的学到了 Spring 的相关知识,但是都是一个个碎片化的知识.刚好最近在读 <Sprign实战(第四版)>,所以借此机会重新整理下Spring 系列的内容. Sp ...

  8. python 35 多线程

    目录 多线程 1. 线程 2. 线程vs进程 3. 开启线程的两种方法. 4. 线程的特性 5. 线程的相关方法 6. join 阻塞 7. 守护线程 daemon 8. 互斥锁 多线程 1. 线程 ...

  9. ionic App 解决android端在真机上 tab处于顶部的Bug

    在app.js 页面中添加以下代码 .config(function($stateProvider, $urlRouterProvider,$ionicConfigProvider) { $ionic ...

  10. 怎样才算精通Linux

    1.掌握至少50个以上的常用命令(包括grep.awk.sed.ps.find等等吧,熟练使用,基础的选项不用man) 2.熟悉Gnome/KDE等X-windows桌面环境操作 3.掌握.tgz.. ...