JBoss5 Clustering Guide, 第四部分

(昨晚公司开会, 三个小时, 手机被活生生的打没电了, 更不幸的是我还没听懂几句. 真佩服manager们, 每天都能这么折腾, 不知道老板给了多少$$$, OK, 睡不着爬起来继续. 希望能尽早收工)

2.2.1 server内客户端配置
(server端缺省new InitialContext()的结果是本地JNDI,在classpath/system properties里面做手脚会影响本地JNDI, 所以在Server端调用HA-JNDI应该是ugly的, right?)

Properties p = new Properties();  
p.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
p.put(Context.URL_PKG_PREFIXES, "jboss.naming:org.jnp.interfaces");
p.put(Context.PROVIDER_URL, "localhost:1100"); // HA-JNDI port.
return new InitialContext(p);

Context.PROVIDER_URL指向的是HA-JNDI服务, 在HANamingService MBean中定义的

以上代码有时候无效, 特别是一个机器上绑定了多个IP, 运行了多个JBoss), 用下面的方法指定patition name(也不见得都有效)
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
p.put(Context.URL_PKG_PREFIXES, "jboss.naming:org.jnp.interfaces");
p.put("jnp.partitionName", "DefaultPartition"); // partition name.
return new InitialContext(p);


不要试图把jndi.properties文件放到你的部署目录, 或者编辑AS的jndi.properties文件. 这会破坏你的应用, 更个可能在是整个server遭殃. 如果你想推广你的配置, 一个方法是用别的名字部署这个文件, 然后用Properties对象加载这个文件的内容.(good idea)

[quote]以前, HANamingServiceMBean.bindAddress服务于两个功能: trunk/cluster/src/etc/hajndi-service.xml:
<!-- 绑定启动和HA-JNDI RMI地址 -->
<attribute name="BindAddress">${jboss.bind.address}</attribute>

现在分开来定义了:
<!-- Bind address of bootstrap endpoint -->
<attribute name="BindAddress">${jboss.bind.address}</attribute>
<!-- Bind address of the HA-JNDI RMI endpoint -->
<attribute name="RmiBindAddress">${jboss.bind.address}</attribute>

它们缺省是一样的, 用户可以覆盖缺省的, 可以为HA-JNDI RMI调用指定专门的网卡.

2.2.2.1从EJB和WAR里面访问HA-JNDI
如果你的客户端在EJB或者servlet里面, 最和谐的方式就是把要lookup的资源绑定到bean或者webapp的命名上下文里面(本地JNDI?) 这个绑定会会用HA-JNDI而不是本地JNDI. 下面是JMS connection Factory和queue的例子(经典用例)

在ejb-jar.xml或者web.xml里面, 定义两个resource-ref映射:
<resource-ref>
<res-ref-name>jms/ConnectionFactory</res-ref-name>
<res-type>javax.jms.QueueConnectionFactory</res-type>
<res-auth>Container</res-auth>
</resource-ref>

<resource-ref>
<res-ref-name>jms/Queue</res-ref-name>
<res-type>javax.jms.Queue</res-type>
<res-auth>Container</res-auth>
</resource-ref>

实际找的是'java:comp/env/jms/Xxxxx'

在JBoss私有部署描述文件里面(EJB是jboss.xml, WAR是jboss-web.xml)这些引用要指向HA-JNDI的URL:
<resource-ref>
<res-ref-name>jms/ConnectionFactory</res-ref-name>
<jndi-name>jnp://localhost:1100/ConnectionFactory</jndi-name>
</resource-ref>

<resource-ref>
<res-ref-name>jms/Queue</res-ref-name>
<jndi-name>jnp://localhost:1100/queue/A</jndi-name>
</resource-ref>

(这个例子怎么不用变量了? 将来绑定地址改变了这里不改的话....)
如果bean存在, 本地的HA-JNDI服务也应该存在. 这个resource-ref会自动的查找cluster内所有的node来找到JMS资源.


2.2.1.2 为什么要手工写, 为什么不把它放到jndi.properties文件里面?
一句话: conf/jndi.properties文件是控制JBossAS内部专用的.

不应该自己写这个文件, 并且部署到classpath里面, 这样会干扰server内部.
直接后果是本地JNDI树上绑定不到, 又跑到HA-JNDI上面去了.

2.2.1.3 我怎么知道绑到HA-JNDI的东西对不对?
到JMX-console, 对jboss:service=JNDIView mbean执行list操作. 在结果的最后那嘎达, 看到"HA-JNDI Namespace"? 一般来说, 这里是空的. 如果这里有不希望出现的东西, 很可能就是你的classpath里面有jndi.properties. 这里有个"不能从cluster里面删除node的例子"[url]http://www.jboss.com/index.html?module=bb&op=viewtopic&t=104715[/url]
(这小子就这样出名了)

2.2.2 在服务器外面跑的客户端
(俺们在用的c/s模式, web和ejb分开部署的也算)
JNDI客户端需要知道HA-JNDI的状态. 你可以指定一组在cluster里面跑HA-JNDI的node列表, 放到jndi.properties的java.naming.provider.url属性. (知道上面一节出错的根源了? 有很多人把client/server写在一起, 打包的时候又没能很好分开. 真有人力挺这种项目结构啊....那可不是吹得)

每个server node用IP:port,中间用逗号分隔. 参见2.2.3
[code]java.naming.provier.url=server1:1100,server2:1100,server3:1100,server4:1100[/code]
在初始化的时候, JNP客户端会尝试一个一个的检测列表里面的每个node, 找到第一个可用的node就从它那下载stub(这个应该是naming服务的stub, 具体的lookup动作就像ejb的方法, 还要被loadbalance和failover).

[quote]在lookup过程中, 没有load balance. 仅仅遍历列表, 抓到活的就用.
[b]HA-JNDI服务器列表仅仅是个子集就够用了[/b](会自动发现其它的node?)[/quote]

下载回来的smart proxy包含了活动nodes列表和负载均衡的逻辑, 会自动的对naming请求均衡负载, 并且失败转移.

进一步说, 每次JNDI调用到服务器上, 拦截器里面的nodes列表会更新, 如果有变化的话. (这个好像前面说过了, 有点像版本管理)

如果这个java.naming.provider.url属性是空的,或者里面的列表都不能访问, 客户端会尝试在网络上组播来发现HA-JNDI服务(自动发现, 彪悍啊) 配置参见2.2.3
[b]别高兴的太早: 客户端和服务器端的网段必须能够传播多播报文(不是广播? 很烂的交换机下很可能不work)[/b]

[quote]自动发现的缺省组播地址是230.0.0.4,端口1102[/quote]

会用到属性:
java.naming.provider.url(这节就讲它了, 不翻了): Provides a list of IP addresses and port numbers for HA-JNDI provider nodes in the cluster. The client tries those providers one by one and uses the first one that responds.

jnp.disableDiscovery: true/false禁用自动发现.

jnp.partitionName: 如果网络里面有别的cluster分区, 这个用来只接收你希望加入的分区. 不用自动发现就不需要了. 缺省为空, 自动找到第一个响应的服务器, 不管对方是个什么分区.(这个特性很操蛋, 太容易出错了. 应该是空对空吧比较合适吧)

jnp.discoveryTimeout: 自动发现的超时. Default is 5000 ms.

jnp.discoveryGroup: 组播地址. Default is 230.0.0.4. 要跟服务器端的HA-JNDI服务配置一样.

jnp.discoveryPort: 自动发现的组播端口. Default is 1102. 必须跟服务器端的AutoDiscoveryPort一致.

jnp.discoveryTTL: 组播发现包的TTL (time-to-live). 表示包可以跨越的网关数hops. a multicast packet can be allowed to propagate before networking equipment should drop the packet. 它不是个时间!

(如果你的客户是个稳定的局域网, 就偷懒用自动发现吧. 如果客户环境未知, 还是老老实实用JNLP servlet去维护这个列表(不知道server有没有自动完成这个功能), 或者双管齐下)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值