|
2007年1月3日
作者 cctvx1 关键字:ActiveMQ,实践
一.安装ActiveMQ
首先去http://activemq.apache.org/download.html 下载最新版本4.1.0release (http://activemq.apache.org/activemq-410-release.html), 解压apache-activemq-4.1-incubator.zip(或者apache-activemq-4.1-incubator.tar.gz)目录如下: +bin (windows下面的bat和unix/linux下面的sh) +conf (activeMQ配置目录,包含最基本的activeMQ配置文件) +data (默认是空的) +docs (index,replease版本里面没有文档,-.-b不知道为啥不带) +example (几个例子 +lib (activemMQ使用到的lib) -apache-activemq-4.1-incubator.jar (ActiveMQ的binary) -LICENSE.txt -NOTICE.txt -README.txt -user-guide.html
你可以使用bin\activemq.bat(activemq) 启动,如果一切顺利,你就会看见类似下面的信息 (细节可能不一样,比如路径,或者jmx,jdbc信息)
ACTIVEMQ_HOME: D:\java\framework_and_lib\activemq\apache-activemq-4.1-incubator\ bin\.. Loading message broker from: xbean:activemq.xml INFO BrokerService - ActiveMQ null JMS Message Broker (localho st) is starting INFO BrokerService - For help or more information please see: http://incubator.apache.org/activemq/ INFO ManagementContext - JMX consoles can connect to service:jmx:r mi:///jndi/rmi://localhost:1099/jmxrmi INFO JDBCPersistenceAdapter - Database driver recognized: [apache_derby _embedded_jdbc_driver] INFO DefaultDatabaseLocker - Attempting to acquire the exclusive lock to become the Master broker INFO DefaultDatabaseLocker - Becoming the master on dataSource: org.ap ache.derby.jdbc.EmbeddedDataSource@1d840cd INFO JournalPersistenceAdapter - Journal Recovery Started from: Active Jou rnal: using 5 x 20.0 Megs at: D:\java\framework_and_lib\activemq\apache-activemq -4.1-incubator\activemq-data\journal INFO JournalPersistenceAdapter - Journal Recovered: 0 message(s) in transa ctions recovered. INFO TransportServerThreadSupport - Listening for connections at: tcp://P-SUW EI:61616 WARN MulticastDiscoveryAgent - brokerName not set INFO TransportConnector - Connector default Started INFO TransportServerThreadSupport - Listening for connections at: stomp://P-S UWEI:61613 INFO TransportConnector - Connector stomp Started INFO NetworkConnector - Network Connector default Started INFO BrokerService - ActiveMQ JMS Message Broker (localhost, I D:P-SUWEI-1207-1170916242296-1:0) started
*。几个小提示 1. 这个仅仅是最基础的ActiveMQ的配置,很多地方都没有配置因此不要直接使用这个配置用于生产系统 2. 有的时候由于端口被占用,导致ActiveMQ错误,ActiveMQ可能需要以下端口1099(JMX),61616(默认的TransportConnector) 3. 如果没有物理网卡,或者MS的LoopBackAdpater Multicast会报一个错误
二. 测试你的ActiveMQ 由于ActiveMQ是一个独立的jms provider,所以我们不需要其他任何第三方服务器就可以马上做我们的测试了.编译 example目录下面的程序 ProducerTool/ConsumerTool 是JMS参考里面提到的典型应用,Producer产生消息,Consumer消费消息 而且这个例子还可以加入参数帮助你测试刚才启动的本地ActiveMQ或者是远程的ActiveMQ
ProducerTool [url] broker的地址,默认的是tcp://localhost:61616 [true|flase] 是否使用topic,默认是false [subject] subject的名字,默认是TOOL.DEFAULT [durabl] 是否持久化消息,默认是false [messagecount] 发送消息数量,默认是10 [messagesize] 消息长度,默认是255 [clientID] durable为true的时候,需要配置clientID [timeToLive] 消息存活时间 [sleepTime] 发送消息中间的休眠时间 [transacte] 是否采用事务
ConsumerTool [url] broker的地址,默认的是tcp://localhost:61616 [true|flase] 是否使用topic,默认是false [subject] subject的名字,默认是TOOL.DEFAULT [durabl] 是否持久化消息,默认是false [maxiumMessages] 接受最大消息数量,0表示不限制 [clientID] durable为true的时候,需要配置clientID [transacte] 是否采用事务 [sleepTime] 接受消息中间的休眠时间,默认是0,onMeesage方法不休眠 [receiveTimeOut] 接受超时
我们这样可以使用: java -classpath .\apache-activemq-4.1-incubator.jar;example\bin ProducerTool tcp://192.168.3.142:61616 test.mysubject java -classpath .\apache-activemq-4.1-incubator.jar;example\bin ConsumerTool tcp://192.168.3.142:61616 test.mysubject
当然你可以使用上面的参数进行更复杂的测试,持久,事务
如果出现下面的信息,恭喜你,你的ActiveMQ已经能够工作了 Connecting to URL: tcp://192.168.3.142:61616 Publishing a Message with size 255 to queue: TOOL.DEFAULT Using non-durable publishing Sleeping between publish 0 ms Sending message: Message: 0 sent at: Thu Feb 08 15:05:34 CST 2007 ... Sending message: Message: 1 sent at: Thu Feb 08 15:05:34 CST 2007 ... 。。。。。。。。
Connecting to URL: tcp://192.168.3.142:61616 Consuming queue: test.mysubject Using non-durable subscription Received: Message: 0 sent at: Thu Feb 08 14:51:34 CST 2007 ... Received: Message: 1 sent at: Thu Feb 08 14:51:34 CST 2007 ... 。。。。
三.小结 我们已经下载,启动,并且用程序测试了我们的ActiveMQ,而后面将在这个能跑得ActiveMQ进一步的走下去,一步一步展示ActiveMQ的高级特性。
作者cctvx1 关键字:ActiveMQ,实践 一.ActiveMQ是什么? ActiveMQ is the most popular and powerful open source Message Bus. 引用ActiveMQ官方网站
ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,尽管JMS规范出台 已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位。 下面是它的特性列表 (详细的特性清单请参考http://activemq.apache.org/features.html) 1.多种语言和协议编写客户端 语言: Java, C, C++, C#, Ruby, Perl, Python, PHP 应用协议: OpenWire,Stomp REST,WS Notification,XMPP,AMQP 2.完全支持JMS1.1和J2EE 1.4规范 (持久化,XA消息,事务) 3.对Spring的支持,ActiveMQ可以很容得内嵌到使用Spring的系统里面去,而且也支持Spring2.0的特性 4.通过了常见J2EE服务器(如 Geronimo,JBoss 4, GlassFish,WebLogic)的测试,其中通过JCA 1.5 resource adaptors的配置, 可以让ActiveMQ可以自动的部署到任何兼容J2EE 1.4 商业服务器上 5.支持多种传送协议:in-VM,TCP,SSL,NIO,UDP,JGroups,JXTA 6.支持通过JDBC和journal提供高速的消息持久化 7.从设计上保证了高性能的集群,客户端-服务器,点对点 8.支持Ajax 9.支持与Axis的整合 10.可以很容易得调用内嵌JMS provider,进行测试 二.ActiveMQ的竞争者 1.其他开源 JMS provider(资料来自 java-source.net) : jbossmq(jboss 4) jboss messaging (jboss 5) joram-4.3.21 2006-09-22 openjms-0.7.7-alpha-3.zip December 26, 2005 mantamq 官网暂时无法访问 ubermq 官网暂时无法访问 SomnifugiJMS 2005-7-27 开源的JMS Provider大部分都已经停止发展了,剩下的几个都是找到了东家,和某种J2EE 服务器挂钩, 比如jboss mq 与jboss,joram与jonas(objectweb组织),ActiveMQ 与Geronimo(ASF APACHE基金组织), 而在这3个之间,从网络底层来看,只有ActiveMQ使用了NIO,单从这个角度来看ActiveMQ在性能上会有 一定的优势
2.商业JMS provider IBM WebSphere MQ BEA WebLogic JMS Oracle AQ NonStop Server for Java Message Service(JMS) Sun Java System Message Queue Sonic jms TIBCO Enterprise For JMS iLinkMQ (国内) 现在的商业J2EE 应用服务器大部分都会有JMS Provider的实现,毕竟应用服务器都已经花费不薄,也不在乎 在里面送一个JMS Provider了,当然还是有独立的比如IBM WebSphere MQ,Sonic JMS ,前者肯定是商用MQ (这个概念不仅仅是JMS Provier了,只能说JMS 只是它提供的一个应用)中间的巨无霸了。 从这点来看,ActiveMQ明显的竞争者并不多,因为它是作为独立的开源JMS Provider出现的,很容易被用于多种结构设计中, 使用ActiveMQ作为默认JMS Provider的开源项目有ServiceMix,Geronimo. (待续) P.S Monday, February 5, 2007 Apache ActiveMQ graduates from the incubator Apache ActiveMQ has now graduated to become a top level project (TLP) at Apache! Its new site is now hosted at http://activemq.apache.org/. Many thanks to all those in the Incubator and ActiveMQ communities for making this happen!
主要就是正则表达式的运用,除了mod_rewrite之外还有一个urlrewritefilter 下面是一个测试二级域名映射规则
RewriteEngine On RewriteCond %{HTTP_HOST} ^[^www.]+.test.ecom$ Rewriterule ^(.+) %{HTTP_HOST}$1 [C] Rewriterule ^([^www.]+)\.test\.ecom(.*) /shop_$1$2 Rewriterule ^www.test.ecom(.*) /$1 [nc,PT] RewriteRule /shop_(.+)/pic/(.*)$ /pic/$2 [nc,PT] RewriteRule /shop_(.+)/js/(.*)$ /js/$2 [nc,PT] RewriteRule /shop_(.+)/css/(.*)$ /css/$2 [nc,PT] RewriteRule /shop_(.+)/(.+).do?(\.*)$ /$2.do?domainName=$1&%{QUERY_STRING} [L,nc]
RewriteLog "logs/rewrite.log" RewriteLogLevel 3
关键字段: RewriteCond 表示如果条件满足则使用下面的Rewriterule Rewriterule 就是采用具体的正则表达式来匹配 Rewriterule 后面还可以带有参数
见apache参考 http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html
- '
chain|C ' (chained with next rule) This flag chains the current rule with the next rule (which itself can be chained with the following rule, and so on). This has the following effect: if a rule matches, then processing continues as usual - the flag has no effect. If the rule does not match, then all following chained rules are skipped. For instance, it can be used to remove the ``.www '' part, inside a per-directory rule set, when you let an external redirect happen (where the ``.www '' part should not occur!).
- '
cookie|CO= NAME:VAL:domain[:lifetime[:path]]' (set cookie) This sets a cookie in the client's browser. The cookie's name is specified by NAME and the value is VAL. The domain field is the domain of the cookie, such as '.apache.org', the optional lifetime is the lifetime of the cookie in minutes, and the optional path is the path of the cookie
- '
env|E= VAR:VAL' (set environment variable) This forces an environment variable named VAR to be set to the value VAL, where VAL can contain regexp backreferences ($N and %N ) which will be expanded. You can use this flag more than once, to set more than one variable. The variables can later be dereferenced in many situations, most commonly from within XSSI (via <!--#echo var="VAR"--> ) or CGI ($ENV{'VAR'} ). You can also dereference the variable in a later RewriteCond pattern, using %{ENV:VAR} . Use this to strip information from URLs, while maintaining a record of that information.
- '
forbidden|F ' (force URL to be forbidden) This forces the current URL to be forbidden - it immediately sends back a HTTP response of 403 (FORBIDDEN). Use this flag in conjunction with appropriate RewriteConds to conditionally block some URLs.
- '
gone|G ' (force URL to be gone) This forces the current URL to be gone - it immediately sends back a HTTP response of 410 (GONE). Use this flag to mark pages which no longer exist as gone.
- '
handler|H =Content-handler' (force Content handler) Force the Content-handler of the target file to be Content-handler. For instance, this can be used to simulate the mod_alias directive ScriptAlias , which internally forces all files inside the mapped directory to have a handler of ``cgi-script ''.
- '
last|L ' (last rule) Stop the rewriting process here and don't apply any more rewrite rules. This corresponds to the Perl last command or the break command in C. Use this flag to prevent the currently rewritten URL from being rewritten further by following rules. For example, use it to rewrite the root-path URL ('/ ') to a real one, e.g., '/e/www/ '.
- '
next|N ' (next round) Re-run the rewriting process (starting again with the first rewriting rule). This time, the URL to match is no longer the original URL, but rather the URL returned by the last rewriting rule. This corresponds to the Perl next command or the continue command in C. Use this flag to restart the rewriting process - to immediately go to the top of the loop. Be careful not to create an infinite loop!
- '
nocase|NC ' (no case) This makes the Pattern case-insensitive, ignoring difference between 'A-Z' and 'a-z' when Pattern is matched against the current URL.
- '
noescape|NE ' (no URI escaping of output) This flag prevents mod_rewrite from applying the usual URI escaping rules to the result of a rewrite. Ordinarily, special characters (such as '%', '$', ';', and so on) will be escaped into their hexcode equivalents ('%25', '%24', and '%3B', respectively); this flag prevents this from happening. This allows percent symbols to appear in the output, as in
RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE]
which would turn '/foo/zed ' into a safe request for '/bar?arg=P1=zed '.
- '
nosubreq|NS ' (not for internal sub-requests) This flag forces the rewriting engine to skip a rewriting rule if the current request is an internal sub-request. For instance, sub-requests occur internally in Apache when mod_include tries to find out information about possible directory default files (index.xxx files). On sub-requests it is not always useful, and can even cause errors, if the complete set of rules are applied. Use this flag to exclude some rules. To decide whether or not to use this rule: if you prefix URLs with CGI-scripts, to force them to be processed by the CGI-script, it's likely that you will run into problems (or significant overhead) on sub-requests. In these cases, use this flag.
- '
proxy|P ' (force proxy) This flag forces the substitution part to be internally sent as a proxy request and immediately (rewrite processing stops here) put through the proxy module. You must make sure that the substitution string is a valid URI (typically starting with http:// hostname) which can be handled by the Apache proxy module. If not, you will get an error from the proxy module. Use this flag to achieve a more powerful implementation of the ProxyPass directive, to map remote content into the namespace of the local server.
Note: mod_proxy must be enabled in order to use this flag.
- '
passthrough|PT ' (pass through to next handler) This flag forces the rewrite engine to set the uri field of the internal request_rec structure to the value of the filename field. This flag is just a hack to enable post-processing of the output of RewriteRule directives, using Alias , ScriptAlias , Redirect , and other directives from various URI-to-filename translators. For example, to rewrite /abc to /def using mod_rewrite , and then /def to /ghi using mod_alias :
RewriteRule ^/abc(.*) /def$1 [PT] Alias /def /ghi
If you omit the PT flag, mod_rewrite will rewrite uri=/abc/... to filename=/def/... as a full API-compliant URI-to-filename translator should do. Then mod_alias will try to do a URI-to-filename transition, which will fail.
Note: You must use this flag if you want to mix directives from different modules which allow URL-to-filename translators. The typical example is the use of mod_alias and mod_rewrite .
- '
qsappend|QSA ' (query string append) This flag forces the rewrite engine to append a query string part of the substitution string to the existing string, instead of replacing it. Use this when you want to add more data to the query string via a rewrite rule.
- '
redirect|R [=code]' (force redirect) Prefix Substitution with http://thishost[:thisport]/ (which makes the new URL a URI) to force a external redirection. If no code is given, a HTTP response of 302 (MOVED TEMPORARILY) will be returned. If you want to use other response codes in the range 300-400, simply specify the appropriate number or use one of the following symbolic names: temp (default), permanent , seeother . Use this for rules to canonicalize the URL and return it to the client - to translate ``/~ '' into ``/u/ '', or to always append a slash to /u/ user, etc. Note: When you use this flag, make sure that the substitution field is a valid URL! Otherwise, you will be redirecting to an invalid location. Remember that this flag on its own will only prepend http://thishost[:thisport]/ to the URL, and rewriting will continue. Usually, you will want to stop rewriting at this point, and redirect immediately. To stop rewriting, you should add the 'L' flag.
- '
skip|S =num' (skip next rule(s)) This flag forces the rewriting engine to skip the next num rules in sequence, if the current rule matches. Use this to make pseudo if-then-else constructs: The last rule of the then-clause becomes skip=N , where N is the number of rules in the else-clause. (This is not the same as the 'chain|C' flag!)
- '
type|T =MIME-type' (force MIME type) Force the MIME-type of the target file to be MIME-type. This can be used to set up the content-type based on some conditions. For example, the following snippet allows .php files to be displayed by mod_php if they are called with the .phps extension:
RewriteRule ^(.+\.php)s$ $1 [T=application/x-httpd-php-source]
ConcurrentModificationException 一个不该犯的低级错误,今天的代码突然抛了一个concurrentModificationException错误, Iterator的一个基本概念没有掌握导致的这个错误,就是在Iterator的实现类 比如Hashtable里面的内部类 private class Enumerator<T> implements Enumeration<T>, Iterator<T>
会在next,或者remove的时候检查当前集合是否会在修改状态,如果是的话 就会抛出 ConcurrentModificationException,而他自己remove则是使用了同步的方法 而且同步了modCount;expectedModCount;
public T next() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); return nextElement(); }
public void remove() { if (!iterator) throw new UnsupportedOperationException(); if (lastReturned == null) throw new IllegalStateException("Hashtable Enumerator"); if (modCount != expectedModCount) throw new ConcurrentModificationException();
synchronized(Hashtable.this) { Entry[] tab = Hashtable.this.table; int index = (lastReturned.hash & 0x7FFFFFFF) % tab.length;
for (Entry<K,V> e = tab[index], prev = null; e != null; prev = e, e = e.next) { if (e == lastReturned) { modCount++; expectedModCount++; if (prev == null) tab[index] = e.next; else prev.next = e.next; count--; lastReturned = null; return; } } throw new ConcurrentModificationException(); } } } 而自己在next的同时,修改了这个集合,导致了这个错误的出现
Spring 官方已经提到这个错误了
http://www.springframework.org/docs/reference/xsd-config.html#xsd-config-integration-resin
A.3.3.1. XML parsing errors in the Resin v.3 application server
If you are using the XSD-style for Spring 2.0 XML configuration and deploying to v.3 of Caucho's Resin application server, you will need to set some configuration options prior to startup so that an XSD-aware parser is available to Spring. Please do read this resource
而resin给出来的参考就是他默认不是使用xerces和xalan作为xml和xslt的默认解析器
正是由于他默认不是采用以上作为xml,xstl的解析器,导致了在resin下面 使用spring 2.0 新xsd配置方式会报错误
(主要就是xml中的attribute和propertie 他取不到)
解决的方法就是让resin使用xerces和xalan作为xml和xslt的默认解析器
配置:
在resin.conf的<web-app>或者<server>节点下添加
<!-- xml --> <system-property javax.xml.parsers.DocumentBuilderFactory= "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl"/> <system-property javax.xml.parsers.SAXParserFactory= "org.apache.xerces.jaxp.SAXParserFactoryImpl"/> <!-- xslt --> <system-property javax.xml.transform.TransformerFactory= "org.apache.xalan.processor.TransformerFactoryImpl"/>
然后把相应的jar加入%RESIN_HOME%/lib 目录,这里需要说明的是我在测试activemq的时候
加入xerces和xalan后,他包其他class无法找到,感觉好像是默认的web-app目录下的jar无效了,我暂时直接加入系统classpath解决的
这点不知道是不是我自己的平台问题。
经过测试 resin 3.0.22+spring 2.0+activemq xsd配置方式ok了,
ps. ^.^ 以前的resin下面项目没有用2.0配置,自己也学习到了新东西
|