2008年1月17日星期四

Linux上安装Oracle 10g XE

  1. 相关软件:
    Redhat Enterprise Linux 5.1
    jdk-1_5_0_14-linux-i586.bin
    oracle-xe-univ-10.2.0.1-1.0.i386.rpm
  2. 设置JAVA环境变量
    编辑/etc/profile文件,添加:
    JAVA_HOME=/usr/java/default
    CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    export  JAVA_HOME JAVA_HOME
    保存后退出重新登陆
  3. 安装oracle
    修改内核参数
    编辑/etc/sysctl.conf文件,添加:
    kernel.shmall = 2097152Erp100社区)`1p+x]&k
    kernel.shmmax = 2147483648
    1{l B:eU/t-U)v f0kernel.shmmni = 4096Erp100社区\2U/]#]*Z&P|K sk ^5s
    kernel.sem = 250 32000 100 128
    bS"^8l ^0fs.file-max = 65536Erp100社区#o(Z,GU4_�K|C"Vw`
    net.ipv4.ip_local_port_range = 1024 65000
    # /sbin/sysctl -p
    # echo 65536 > /proc/sys/fs/file-max
    编辑文件/etc/security/limits.conf ,插入 * - nofile 65536  
    重启动

    创建oracle用户
    # /usr/sbin/groupadd oinstall
    # /usr/sbin/groupadd dba
    # /usr/sbin/useradd -m -g oinstall -G dba oracle

    检查包依赖性:
    makeErp100社区&i+B6IV D*b7Y{S7dZ [
    openmotif-devel
    s@ l kk!EG.y0openmotifErp100社区Mu*tL&GN`^&N
    binutils
    K]:{#ZP ]8]u${0setarchErp100社区5_{EMcl9AF,SD
    compat-db
    ` \co1B#X%@Z-S#aD2sl%n0compat-gcc-32-c++
    l[Ri NF b Agk0compat-libstdc++
    2B.Y:q4~ A7DM L0compat-gcc
    libaio

    安装oracle包:
    # rpm -ivh oracle-xe-univ-10.2.0.1-1.0.i386.rpm
    # /etc/rc.d/init.d/oracle-xe configure
    根据提示设置8080、1521端口,还有sys和system的密码,开机是否启动等。

    编辑/etc/profile文件,添加:
    ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/
    ORACLE_SID=XE
    ORACLE_BASE=/usr/lib/oracle/xe/app/oracle/
    PATH=$PATH:$JAVA_HOME/bin:$ORACLE_HOME/bin
    export  ORACLE_HOME ORACLE_SID ORACLE_BASE
    保存后退出重新登陆

    关闭oracle
    # /etc/rc.d/init.d/oracle-xe stop
    启动oracle
    # /etc/rc.d/init.d/oracle-xe start

    创建数据库新用户
    # su - oracle
    $ sqlplus system@XE
    sqlplus> create user userName identified by password;
    sqlplus> grant dba to userName;
    sqlplus> grant unlimited tablespace to userName;

2008年1月15日星期二

JBoss 5修改EJB3连接池大小

本文所做配置根据JBoss 5.0.0beta3进行
对于EJB3远程调用连接池的配置,JBoss 5的配置文件与JBoss 4相比有些变化,步骤如下:
修改 $JBOSS_HOME/server/all/ejb3-connectors-service.xml, 初始内容如下:

   <mbean code=" org.jboss.remoting.transport.Connector"
          name="jboss.remoting:type=Connector,name=DefaultEjb3Connector,handler=ejb3">
      <attribute name="InvokerLocator">socket://${jboss.bind.address}:3873</attribute>
      <attribute name="Configuration">
         <handlers>
            <handler subsystem="AOP">org.jboss.aspects.remoting.AOPRemotingInvocationHandler</handler>
         </handlers>
      </attribute>
   </mbean>

改为:

   <mbean code="org.jboss.remoting.transport.Connector"
          name=" jboss.remoting:type=Connector,name=DefaultEjb3Connector,handler=ejb3">
      <attribute name="Configuration">
         <config>
            <invoker transport="socket">
               <attribute name="numAcceptThreads">1</attribute>
               <attribute name="maxPoolSize">1000</attribute>
               <attribute name="clientMaxPoolSize" isParam="true">1000</attribute>
               <attribute name="timeout" isParam="true">60000</attribute>
               <attribute name="serverBindAddress">${jboss.bind.address}</attribute>
               <attribute name="serverBindPort">3873</attribute>
               <attribute name="backlog">200</attribute>
            </invoker>
            <handlers>
               <handler subsystem="AOP"> org.jboss.aspects.remoting.AOPRemotingInvocationHandler</handler>
            </handlers>
         </config>
      </attribute>
   </mbean>

其中maxPoolSize,clientMaxPoolSize及 backlog根据需要调整。

2008年1月7日星期一

JDK5原子变量实践――Ejb调用自动重连

  1. ConnectorStatusPair类,需要同步两个状态,一个是进入连接队列线程数,一个是连接时间。目的是同一时间只有一个线程在重连,间隔一定时间只重连一次。

    import java.util.concurrent.atomic.AtomicReference;

    public class ConnectorStatusPair {

        private static class Pair {

            final int qLength;
            final long timeStamp;

            public Pair(int qLength, long timeStamp) {
                this.qLength = qLength;
                this.timeStamp = timeStamp;
            }
        }
        private AtomicReference<Pair> values;

        public ConnectorStatusPair(int qLength, long timeStamp) {
            values = new AtomicReference<Pair>(new Pair(qLength, timeStamp));
        }
       
        public int getQLength() {
            return values.get().qLength;
        }

        public long getTimeStamp() {
            return values.get().timeStamp;
        }

        /**
         * 原子操作加1
         * @return 更新后的值
         */
        public int incrementAndGetQLength() {
            while (true) {
                Pair oldv = values.get();
                Pair newv = new Pair(oldv.qLength + 1, oldv.timeStamp);
                if (values.compareAndSet(oldv, newv)) {
                    return newv.qLength;
                }
            }
        }

        /**
         * 原子操作减一
         * @return 更新后的值
         */
        public int decrementAndGetQLength() {
            while (true) {
                Pair oldv = values.get();
                Pair newv = new Pair(oldv.qLength - 1, oldv.timeStamp);
                if (values.compareAndSet(oldv, newv)) {
                    return newv.qLength;
                }
            }
        }

        /**
         * 原子操作比较当前时间减去values保存的时间是否大于给定的时间间隔,以毫秒计,如果为真则更新values保存的时间为当前时间
         * @param reconnectTimePeriod
         * @return 如果当前时间减去values保存的时间大于给定的时间间隔返回真,否则返回非真
         */
        public boolean compareAndSetTimeStamp(int reconnectTimePeriod) {
            while (true) {
                Pair oldv = values.get();
                long time = System.currentTimeMillis();
                if ((time - oldv.timeStamp) < reconnectTimePeriod) {
                    return false;
                }
                Pair newv = new Pair(oldv.qLength, time);
                if (values.compareAndSet(oldv, newv)) {
                    return true;
                }
            }
        }
    }

  2. Ejb3ClientProxy类,调用ejb方法,支持自动重连同步

    import com.xued.clusteredejb.ExRemote;
    import java.util.Properties ;
    import javax.naming.Context;
    import javax.naming.InitialContext ;
    import javax.naming.NamingException;
    import org.jboss.remoting.CannotConnectException ;

    public class Ejb3ClientProxy {

        private ExRemote exBean;
        private Context ctx;
        private ConnectorStatusPair connectorStatus = new ConnectorStatusPair(0, 0);

        public Ejb3ClientProxy(String hostUrl) {
            try {
                Properties props = new Properties();
                props.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
                props.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
                props.put("java.naming.provider.url", hostUrl);
                props.put("jnp.socketFactory", "org.jnp.interfaces.TimedSocketFactory ");
                props.put("jnp.timeout", "10000");
                props.put("jnp.sotimeout", "10000");
                this.ctx = new InitialContext(props);
                getExBeanInstance();
            } catch (NamingException ex) {
                System.out.println("EJB3 client initialize failed!");
            }
        }

        public String invoke(String name) {
            if (connectorStatus.getQLength() != 0) {
                return "not alive";
            }
            String res = null;
            try {
                res = exBean.invoke(name);
            } catch (CannotConnectException ex) {
                if (isNeedReconnect()) {
                    res = refreshConnection(name);
                } else {
                    res =  ex.getClass().getName() + ": " + ex.getMessage();
                }
                connectorStatus.decrementAndGetQLength ();
            } catch (Exception ex) {
                res = ex.getClass ().getName() + ": " + ex.getMessage();
            }
            return res;
        }

        private boolean isNeedReconnect(){
            return connectorStatus.incrementAndGetQLength() == 1 &&
                    connectorStatus.compareAndSetTimeStamp(60000); //间隔60秒重连一次
        }
       
       
        private void getExBeanInstance() throws NamingException {
            this.exBean = (ExRemote) this.ctx.lookup("ExBean/remote");
        }

        private String refreshConnection(String name) {
            String res;
            try {
                getExBeanInstance();
                res = exBean.invoke(name+" Server was crashed");
            } catch (NamingException ex1) {
                System.out.println("reconnect failed");
                res = "error occured";
            }
            return res;
        }
    }