2007年11月6日星期二

配置GlassFish双机集群

有两台物理计算机,主机名为host151与host164,注意GlassFish是根据主机名进行集群通信,因此在两台机各自的hosts文件中必须配置IP与主机名的映射,并保持一致。
host151作为DAS管理端,配置domain和cluster,具体步骤如下:
  1. ant -f setup-cluster.xml 安装GlassFish为cluster模式
  2. asadmin start-domain domain1 启动主域
  3. asadmin create-cluster --host host151 --port 4848 ejb-cluster 创建一个名为ejb-cluster的集群
  4. asadmin create-node-agent --host host151 --port 4848 agent151 创建一个名为agent151的节点代理,靠它来管理集群里的实例,必须单独启动
  5. asadmin create-instance --host host151 --port 4848 --nodeagent agent151 --cluster ejb-cluster instance151 创建一个名为instance151的集群实例,由agent151管理,加入ejb-cluster集群
  6. asadmin start-node-agent --syncinstances=true agent151 启动agent151,syncinstances设为true是为了同时启动集群和下面的实例instance151,缺省为false
host164的配置步骤:
  1. ant -f setup-cluster.xml
  2. asadmin create-node-agent --host host151 --port 4848 agent164 创建名为agent164的节点代理,因为host151作为集群DAS管理端,因此本机不用启动domain
  3. asadmin create-instance --host host151 --port 4848 --nodeagent agent164 --cluster ejb-cluster instance164 创建一个名为instance164的集群实例,由agent164管理,加入ejb-cluster集群,注意host和port选项是指管理主机名和端口号,不是物理主机,物理主机由所属agent决定
  4. asadmin start-node-agent --syncinstances=true agent164 启动agent164
打开host151的管理端界面,可以看到集群下面有两个实例,都已经运行。可以在集群的管理界面上部署应用程序,会自动分发到两个节点中。
EJB的客户端访问代码为了支持IIOP Load-balancing,需要做一些另外的配置,示例如下:

    public void sayHello() throws NamingException {
        Properties props = new Properties();
        props.setProperty("java.naming.factory.initial", "com.sun.enterprise.naming.SerialInitContextFactory");
        props.setProperty("java.naming.factory.url.pkgs", "com.sun.enterprise.naming");
        props.setProperty("java.naming.factory.state", "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");
        System.setProperty("com.sun.appserv.iiop.endpoints", "10.100.1.164:33700,10.100.1.151:33700");
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + ": "+getExBean(props).sayHello("Herculesx"));
        }
    }

    private ExBeanRemote getExBean(Properties props) throws NamingException {
        Context ctx = new InitialContext(props);
        ExBeanRemote exBean = (ExBeanRemote) ctx.lookup("com.xued.clusteredejb.ExBeanRemote");
        return exBean;
    }

上面的代码有两点需要注意:
  1. 想要支持IIOP Load-balancing,必须配置系统环境变量com.sun.appserv.iiop.endpoints=host1:port ,host2:port...,host是物理主机IP或主机名,port是IIOP端口号,在管理端可以看到不同实例具体的值。使用org.omg.CORBA.ORBInitialHost和org.omg.CORBA.ORBInitialPort就会关闭IIOP Load-balancing。
  2. 客户端选择不同的主机是在lookup的时候进行的,如果想每次调用都平均分配到不同主机上,就必须每次都重新lookup,这会降低一部分性能。
       

没有评论: