Monthly Archives: February 2012

tomcat里定义jndi datasource

文档在这里 
http://www.pdh.sh.cn/docs/jndi-datasource-examples-howto.html

注意事项:

1.要记得把jdbc driver的jar文件复制到tomcat的lib目录下

2.很恶心的一点: web.xml也得改 — 应用被侵入

3.更恶心的一点: 名为"jdbc/TestDB"的resource的全名将是 "java:/comp/env/jdbc/TestDB",因为tomcat会强行加上"java:/comp/env/"前缀,而且不能配置。所以,你的应用里的jndi name也得使用"java:/comp/env/jdbc/TestDB"这种全名; 如果你现有应用里的jndi name不是以"java:/comp/env/"开头的,而你又不方便改变它。。。

ubuntu下安装apache httpd + mod_proxy

1.安装httpd

sudo apt-get install apache2

2.安装mod_proxy

cd /etc/apache2/mods-available

sudo a2enmod proxy_http

3.配置一下mod_proxy

    修改/etc/apache2/sites-available/default

  

    加入

    ProxyPass / http://localhost:8781/

    ProxyPassReverse / http://localhost:8781/

    修改/etc/apache2/mods-enabled/proxy.conf

    把"deny from all" 改成 "allow from all"  #如果不改这个,浏览器就会说“You don’t have permission to access…”

memcached的一些特性

1. Memcached是用c/c++语言写的服务器程序,在linux下安装后可以用作daemon服务,这一点跟mysql很像

2. Memcached提供了一套通信协议,Memcached客户端通过这个协议与Memcached服务器进行交互。这个协议是开放的,只要遵循这个协议,任何人可以用任何语言写一个客户端

3. 系统方面

   a.Memcached就是用来占内存的,所以机器的内存越充裕越好。

   b.如果内存存取“慢”了,Memcached就会非常慢。所以,如果你的Linux用上了虚拟内存开始swap了,你的Memcached就会很弱

   c.对CPU的压力不大

   d.为了避免给网络带来压力,你的缓存项最好都是小数据

4. Memcached集群

   a.多个memcached实例一起使用即构成集群。集群的前面并没有前置任何负载均衡或者其它管理集群的东西,集群的结点之间也不会互相通信。

   b.结点之间不会复制数据,一个缓存entry只存一台机器;所以取entry时,客户端自己要知道该去哪台机取

   c.客户端存取缓存项前一般会根据key值决定去哪个结点,这个函数 node = f(key) 称为hashing函数。 最简单的策略是 node = hash(key)/size-of-node,即简单哈希后再用结点数取模

   d.基于结点数取模的寻址策略有个缺点,即在结点数增加时,几乎所有key的hashing值都会变化; 如果增加结点前某个缓存项存在A结点上,增加结点后,由于hashing值的变化,客户端可能会去到B结点读取这个缓存项,结果没读到,缓存的命中率下降。 解决办法是使用Consistent Hashing算法,使用了这种算法后,在遇到增减结点时,只有少部分key的hashing值会变化

   e.客户端还可以自己实现“权重”,即有的机器多收一点缓存,有的少收一点

5. 高级操作

  a. 支持add操作,即当key相同的缓存项不存在时,才会将客户端提交的缓存项保存

 b. 支持cas操作(Check And Set),即乐观锁。应用这种机制时,如果你上次访问某缓存后有它人更新了些缓存,那你再更新缓存就会失败

笔记:搭建memcached集群环境并通过java客户端访问它

今天在CentOS 5.7 上搭建了memcahced集群环境,并通过Xmemcached这个java client写了一个程序。步骤如下:

1.
CentOS上添加EPEL仓库,这样才能用yum安装memcached

su -c 'rpm -Uvh http://download.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm'

2.
安装memcached

yum install memcached

3.
在另一台机器上重复#1, #2,安装另一个memcached; 当然这不是必须的,你也可以在一台机上跑两个memcached实例。 具体参考memcached的参数

4.
启动memcached,即成memcached cluster

service start memcached -l 192.68.1.1 #本机ip

service start memcached -l 192.68.1.2

5.
客户端通过Xmemcached访问这个集群


http://code.google.com/p/xmemcached/搞定jar包或maven依赖

			XMemcachedClient client = new XMemcachedClient(
					AddrUtil.getAddresses("192.168.1.1:11211 192.168.1.2:11211"));

			String userId = "1";
			Object user = client.get(userId);
			if (user == null) {
				user = getNameFromDB(userId);
				client.set(userId, 5, user);
			}


			client.shutdown();

centos安装笔记

记一下安装centos时的注意事项,供以后查阅

什么是live cd?

live cd的意思是免安装版。用live cd意味着直接在光盘上跑centos

centos 5有8张cd, 我都要下吗?

不必,centos 必须的功能都在第一张盘里,下载第一张盘即可. 安装时要这样:

You can do a minimal install that just requires the first CD by performing the following two steps during the installation:

    * During the category/task selection, deselect all package categories, and choose the "Customize now" option at the bottom of screen.

    * During the customized package selection, deselect everything ( including the Base group ).

遇到错误:The CentOS disc was not found in any of your drives …

"One solution is to reboot and choose to skip the media test"

最小安装后需要添加的包

最小安装后,你会发现连"man"命令都用不了,因为此时的包实在太少。

你可能想添加的包有:

yum groupinstall base

看看哪个包里面有我要的命令,再安装这个包

yum whatprovides */ifconfig

路径设置

#非root用户把sbin纳入路径

export PATH=$PATH:/sbin

把epel纳入到yum库中

有些著名的包在标准repository里找不到,而是收录在epel里。

su -c ‘rpm -Uvh http://download.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm’

jar依赖环境下,被依赖的库中的枚举类如果调整枚举顺序会对依赖者产生什么影响?

问题:jar依赖环境下,被依赖的库中的枚举类如果调整枚举顺序会对依赖者产生什么影响? 只所以问这个问题,是因为我不确定枚举项会不会编译到依赖者bytecode的常量区里。如果会,则被依赖库的修改影响不到依赖者。

答案是:依赖者将完全参照被依赖者里的定义来行事,不存在常量区的问题。

============================场景一:先Hello,再World=============================

b.jar里面有个枚举EnumInB.java

public enum EnumInB {

    HELLO("Hello"), WORLD("World");

    private String displayText;

    private EnumInB(String displayText){
        this.displayText = displayText;
    }

    public String getDisplayText() {
        return displayText;
    }

}

a.jar依赖b.jar,且其中有个类依赖了EnumInB

让它打印一下各个枚举项的值


public class PlayEnumInB {

    public static void main(String[] args) {

        System.out.println(EnumInB.HELLO.name() + "-" + EnumInB.HELLO.getDisplayText() + "-" + EnumInB.HELLO.ordinal()); //HELLO-Hello-0
        System.out.println(EnumInB.WORLD.name() + "-" + EnumInB.WORLD.getDisplayText() + "-" + EnumInB.WORLD.ordinal()); //WORLD-World-1
    }

}

============场景二:先World, 再Hello===============================================

调整一下枚举里的顺序

这时调整一下EnumB里枚举里的顺序,并重新编译b.jar

 

    WORLD("World"), HELLO("Hello");

}

依赖者的表现

a.jar更新b.jar的版本,但不重新编译a.jar

 
        System.out.println(EnumInB.HELLO.name() + "-" + EnumInB.HELLO.getDisplayText() + "-" + EnumInB.HELLO.ordinal()); //HELLO-Hello-1
        System.out.println(EnumInB.WORLD.name() + "-" + EnumInB.WORLD.getDisplayText() + "-" + EnumInB.WORLD.ordinal()); //WORLD-World-0
   

==============场景三:Hello, World改变属性===============================================

改变一下枚举里面的成员属性

     HELLO("HelloHello"), WORLD("WorldWorld");
 }

依赖者的表现

        System.out.println(EnumInB.HELLO.name() + "-" + EnumInB.HELLO.getDisplayText() + "-" + EnumInB.HELLO.ordinal()); //HELLO-HelloHello-0
        System.out.println(EnumInB.WORLD.name() + "-" + EnumInB.WORLD.getDisplayText() + "-" + EnumInB.WORLD.ordinal()); //WORLD-WorldWorld-1
    }

}