惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Security Affairs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
Netflix TechBlog - Medium
云风的 BLOG
云风的 BLOG
M
MIT News - Artificial intelligence
A
About on SuperTechFans
Last Week in AI
Last Week in AI
博客园 - 叶小钗
博客园 - Franky
腾讯CDC
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The GitHub Blog
The GitHub Blog
Google DeepMind News
Google DeepMind News
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
小众软件
小众软件
The Hacker News
The Hacker News
C
Cisco Blogs
C
CXSECURITY Database RSS Feed - CXSecurity.com
L
LangChain Blog
WordPress大学
WordPress大学
美团技术团队
P
Proofpoint News Feed
T
Threat Research - Cisco Blogs
AWS News Blog
AWS News Blog
S
Securelist
T
Tenable Blog
I
Intezer
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
L
LINUX DO - 热门话题
博客园 - 三生石上(FineUI控件)
Y
Y Combinator Blog
Cisco Talos Blog
Cisco Talos Blog
T
Tor Project blog
Security Latest
Security Latest
Apple Machine Learning Research
Apple Machine Learning Research
C
Cybersecurity and Infrastructure Security Agency CISA
S
Schneier on Security
L
Lohrmann on Cybersecurity
P
Privacy & Cybersecurity Law Blog
月光博客
月光博客
P
Proofpoint News Feed
Vercel News
Vercel News
Simon Willison's Weblog
Simon Willison's Weblog
G
GRAHAM CLULEY
T
The Blog of Author Tim Ferriss
F
Fortinet All Blogs
博客园 - 【当耐特】
A
Arctic Wolf
aimingoo的专栏
aimingoo的专栏

博客园 - 张皓

Stereoscopic Player 1.7.4 (SSP) 加载字幕 layout_weight体验(实现按比例显示) Linux5配置jboss环境 pager-taglib 分页扩展实例 DisplayTag1.2 扩展(自定义分页、排序、导出、页面导航) maven2 Jetty运行多模块的web application JBoss5开发web service常见问题 jboss启动常见的错误 ADO连接池 IDUdpServer研究心得 DLL内线程同步主线程研究(子线程代码放到主线程执行) DBGrid内使用CheckBox功能 子绑定控件获取父绑定项的值 - 张皓 - 博客园 IdTcpServer 用户掉线检测方法 . Net环境下消息队列(MSMQ)对象的应用[转] 消息队列(Message Queue)简介及其使用[转] 分布式事务TransactionScope小结[转] 分布式事务的点滴 调试SQL Server存储过程方法
EJB3在JBoss5内集群探究
张皓 · 2010-11-11 · via 博客园 - 张皓

EJB3JBoss5x内集群探究

本文介绍ejb3在jboss5x内集群的基本配置及注意事项,我们主要的目的是在jboss5x内集群ejb3,,然后被客户端(可以是web应用程序),不涉及到jboss http请求集群内容。具体见下:

一、             程序准备

我们准备两个项目ejb.rar、webapp.war,其中前者是ejb3项目、后者是web应用程序,主要代码如下:

ejb.rar主要代码:

接口:

package com.sample;   

@Remote

//@Local  

public interface HelloBeanItf {   

public void doSomething();    

}  

实现:

package com.sample;   

import java.io.Serializable;   

import javax.ejb.*;   

import org.jboss.annotation.ejb.Clustered;   

@Stateless  

@Clustered  

public class HelloBean implements HelloBeanItf {   

int counter = 0;   

public void doSomething() {     

 counter++;   

                   System.out.println("Stateless : Value of counter is " + counter);   

}  

}  

上面是无状态的session bean,注意标注@Clustered是必须的,如果不进行标注那么这个session bean将不会被集群。同样有状态的session bean的集群声明也是这样的,如下:

@Stateful  

@Clustered  

public class HelloBean2 implements HelloBeanItf,Serializable {   

int counter = 0;   

public void doSomething() {     

 counter++;   

                   System.out.println("Stateful : Value of counter is " + counter);   

}   

}

webapp.war主要代码:

创建index.jsp文件用以调用无状态session bean,在主要代码如下:

<%   

public void jspInit () {   

try {   

HelloBeanItf ejb = null;   

InitialContext ctx = new InitialContext();   

for(int i=0;i<10;i++){

              //ejb = (HelloBeanItf) ctx.lookup("HelloBean/local");   

ejb = (HelloBeanItf) ctx.lookup("HelloBean/remote");   

}

       }   

       catch (Exception exc) {    

               exc.printStackTrace();   

 }   

}   

ejb.doSomething();   

%>   

Stateless EJB invoked    

创建index2.jsp文件用以调用有状态session bean,在主要代码如下:

<%   

public void jspInit () {   

try {   

HelloBeanItf ejb = null;   

InitialContext ctx = new InitialContext();   

for(int i=0;i<10;i++){

               //ejb = (HelloBeanItf) ctx.lookup("HelloBean2/local");   

ejb = (HelloBeanItf) ctx.lookup("HelloBean2/remote");   

}

       }   

       catch (Exception exc) {    

               exc.printStackTrace();   

 }   

}   

ejb.doSomething();   

%>   

Stateful EJB invoked    

Classpath下添加jndi.porperties文件,具体如下:

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory

java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

java.naming.provider.url=192.168.1.2:1099, 192.168.1.3:1099

二、             配置jboss

配置jboss要稍微麻烦点,我们在三台机器上分别部署jboss名称分别为jboss1、jboss2、jboss3,对应的ip分别为192.168.1.1、192.168.1.2、192.168.1.3。配置具体步骤如下:

(1)    使jboss能通过ip访问,分别找到jboss2与jboss3安装目录下的文件jboss-home\server\all\deploy\jbossweb.sar\server.xml并打开,把

<Connector protocol="HTTP/1.1" port="8080" address="${jboss.bind.address}"  connectionTimeout="20000" redirectPort="8443" />

改为:

<Connector protocol="HTTP/1.1" port="8080" address="0.0.0.0" connectionTimeout="20000" redirectPort="8443" />

(2)    配置jvmRoute,打开jboss2及jboss3内的文件jboss-home\server\all\deploy\jbossweb.sar\server.xml,修改

<Engine name="jboss.web" defaultHost="localhost" >

jboss2改为:<Engine name="jboss.web" defaultHost="localhost" jvmRoute="jboss2">

jboss3改为:<Engine name="jboss.web" defaultHost="localhost" jvmRoute="jboss3">

(3)    设置ServerPeerID,打开jboss2及jboss3内的文件jboss-home\ server\all\deploy\messaging\ messaging-service.xml,修改

<attribute name="ServerPeerID">${jboss.messaging.ServerPeerID:0}</attribute>

jboss2改为:<attribute name="ServerPeerID">${jboss.messaging.ServerPeerID:2}</attribute>

jboss3改为:<attribute name="ServerPeerID">${jboss.messaging.ServerPeerID:3}</attribute>

三、             部署

我们把ejb分别部署到jboss2和jboss3内,使它们进行集群。把web客户端部署到jboss1内用以访问ejb,具体如下:

(1)    复制ejb.jar到jboss2的jboss-home\server\all\farm下,使用all进行部署是因为all内包含所有的服务,集群服务及jboss cache服务都是我们所需的,放入farm内是为了当几个jboss集群后它们将自动完成部署ejb到各自的farm目录内,不过这个功能偶尔会部署失败,可以手工copy一份。当然我们也可以手工把ejb分别复制jboss2、jboss3的jboss-home\server\all\deploy目录下,集群效果一样。

(2)    分别进入jboss2、jboss3主机上控制台进入jboss安装目录使用 run.bat –c all -b 0.0.0.0 命令启动jboss。

当然我们也可以分别用run.bat –c all -b 192.168.1.2 run.bat –c all -b 192.168.1.3分别启动

(3)    部署webapp.war到jboss1的目录jboss-home\server\default\deploy下,并启动jboss1

(4)    部署webapp.war到jboss2的目录jboss-home\server\all\deploy下,用以跟jboss1的web客户端做比对。

四、             运行分析

(1)    运行jboss1内的web客户端

在浏览器上输入http://192.168.1.1/webapp/index.jsp,后我们观察下jboss2、jboss3的控制台

jboss2

jboss3

Stateless : Value of counter is 1

Stateless : Value of counter is 1

Stateless : Value of counter is 2

Stateless : Value of counter is 2

Stateless : Value of counter is 3

Stateless : Value of counter is 1

Stateless : Value of counter is 2

Stateless : Value of counter is 3

Stateless : Value of counter is 4

Stateless : Value of counter is 5

再刷新一次如下:

jboss2

jboss3

Stateless : Value of counter is 3

Stateless : Value of counter is 4

Stateless : Value of counter is 4

Stateless : Value of counter is 5

Stateless : Value of counter is 5

Stateless : Value of counter is 6

Stateless : Value of counter is 7

Stateless : Value of counter is 8

Stateless : Value of counter is 9

Stateless : Value of counter is 10

第一次访问时我们循环了10次,发现在jboss上分别运行了5次,这就达到了负载均衡的目的。第二次访问了我们看jboss内counter是的规律是11223344…这说明jboss1内产生了两个HelloBean 的实例进行轮训访问,而jboss2内只有一个HelloBean 的实例,这完全符合无状态session bean的特性,至于为什么jboss2内有两个实例,还未搞清楚,有待探究。

然后我们在浏览器内输入http://192.168.1.1/webapp/index2.jsp,后我们观察下jboss2、jboss3的控制台

jboss2

jboss3

Stateful : Value of counter is 1

Stateful : Value of counter is 2

Stateful : Value of counter is 3

Stateful : Value of counter is 4

Stateful : Value of counter is 5

Stateful : Value of counter is 6

Stateful : Value of counter is 7

Stateful : Value of counter is 8

Stateful : Value of counter is 9

Stateful : Value of counter is 10

再刷新一次如下:

jboss2

jboss3

Statefu l: Value of counter is 1

Stateful : Value of counter is 2

Stateful : Value of counter is 3

Stateful : Value of counter is 4

Stateful : Value of counter is 5

Statefu l: Value of counter is 6

Stateful : Value of counter is 7

Stateful : Value of counter is 8

Stateful : Value of counter is 9

Stateful : Value of counter is 10

如再连续刷新两次发现输入跟上面一样。第一次访问时我们循环了10次,发现在jboss3上分别运行了10次产生了一个HelloBean2实例,第二次jboss2上运行10次产生了一个HelloBean2实例,这样我们可以看出,每次访问时集群会随机给我们找一个ejb服务,而每次访问都会产生一个新的session bean实例,这完全符合有状态session bean的特性。

(2)    关闭jboss3,我们按照上一步操作进行,发现访问正常进行,所有的请求都在jboss2上响应了,这样我们就达到了故障转移的目的。

(3)    以同样的方式重新启动jboss3,我们分别通过http://192.168.1.2/webapp/index.jsphttp://192.168.1.2/webapp/index2.jsp,进行访问,不难发现所有的请求都在jboss2上得到了响应,这是因为如果如果jboss内的web客户端访问集群ejb时,如果要访问的ejb集群本机也参与的话那么群集只返回本机的ejb,当然如果本机的ejb挂掉的话集群是可以随机分配其它jboss内的ejb的。

(4)    我们可以把HelloBeanItf 的注解改为@Local,把index.jsp、index2.jsp内的 ctx.lookup("HelloBean2/remote");  改为 ctx.lookup("HelloBean2/local");然后按照之前方式重新部署,我们发现只能通  http://192.168.1.2/webapp/index.jsphttp://192.168.1.2/webapp/index2.jsp进行访问,而且请求全部在jboss2上响应,这也符合Local的session bean的特性。

五、讨论

通过上面的测试我们可以想象,我们可以构造这样一个集群系统,在一个jboss内构建对外的web客户端来访问其它多个集群后的ejb服务的系统是完全可行的,这样要求这个对外web客户端的jboss不能参与ejb的集群。这种方式看上去有点类似于apache+mod_jk+jboss的http集群,但本质上是不太一样的。这两种方式的集群到底哪个更优本人还未进行过测试,希望以后能有机会亲自测试体验下。以上是我对jboss内集群ejb的一些探究,不足与错误忘大家指点。