作者:大狗 发布于: 2009-04-11 | 归类: 代码之美 | 标签: javascript | 抢沙发 »
| 浏览106次
<script type=”text/javascript”><!–
Array.prototype.strip=function(){
if(this.length<2) [this[0]]||[];
var arr=[];
for(var i=0;i
<this.length;i++){
arr.push(this.splice(i ,1));
for(var j=0;j<this.length;j++){
if(this[j]==arr[arr.length-1]){
this.splice(j ,1);
}
}
}
return arr;
}
var arr=["1","2","3","1","1"];
alert(arr.strip());
// –></script>
作者:大狗 发布于: 2009-04-11 | 归类: 代码之美 | 标签: commons-email, javamail | 抢沙发 »
| 浏览74次
今天在Apache网站上下载commons-lang jar文件时突然看到commons-email-1.1.jar这个项目jar文件,看了看user guide确实比JDK提供的好多了,简单的几行代码就实现了发邮件的功能,以前实现过一个纯JavaMail带附件发邮件功能,代码复杂不说,现在回过 头来都懒得看(主要是WEb项目注释少)。
贴上TEST代码看看,简单、清晰。只要稍加修改(邮件服务器地址、名称、密码)就可以了
简单邮件的发送:
package com.bulktree.mail;
import java.util.Date;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;
publicclass SimpleMailTest {
publicstaticvoid main(String[] args) throws EmailException {
SimpleEmail email = new SimpleEmail();
//设置发送主机的服务器地址
email.setHostName("smtp.163.com");
//设置收件人邮箱
email.addTo("bulktree@126.com","bulktree");
//发件人邮箱
email.setFrom("bulktree@163.com", "bulktree");
//如果要求身份验证,设置用户名、密码,分别为发件人在邮件服务器上注册的用户名和密码
email.setAuthentication("bulktree", "123456");
//设置邮件的主题
email.setSubject("Hello, This is My First Email Application");
//邮件正文消息
email.setMsg("I am bulktree This is JavaMail Application");
email.send();
System.out.println("The SimpleEmail send sucessful!!!");
}
}
带附件邮件发送:
package com.bulktree.mail;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.commons.mail.EmailAttachment;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.MultiPartEmail;
publicclass AttachmentMailTest {
publicstaticvoid main(String[] args) throws EmailException, MalformedURLException {
// 创建一个Email附件
EmailAttachment emailattachment = new EmailAttachment();
emailattachment.setPath("/biao_05.jpg");
// emailattachment.setURL(new URL("http://www.blogjava.net/bulktree/picture/bulktree.jpg"));
emailattachment.setDisposition(EmailAttachment.ATTACHMENT);
emailattachment.setDescription("This is Smile picture");
emailattachment.setName("bulktree");
// 创建一个email
MultiPartEmail multipartemail = new MultiPartEmail();
multipartemail.setHostName("smtp.163.com");
multipartemail.addTo("bulktree@126.com", "bulktree");
multipartemail.setFrom("bulktree@163.com", "bulktree");
multipartemail.setAuthentication("bulktree", "123456");
multipartemail.setSubject("This is a attachment Email");
multipartemail.setMsg("this a attachment Eamil Test");
//添加附件
multipartemail.attach(emailattachment);
//发送邮件
multipartemail.send();
System.out.println("The attachmentEmail send sucessful!!!");
}
}
作者:大狗 发布于: 2009-04-11 | 归类: 代码之美 | 标签: cvs, debian | 抢沙发 »
| 浏览43次
CVS想必做软件开发的都听说过,那么怎么才能让开发人员享受这一便利工具呢?当然是装个CVS服务器了。
Windows下有个CVSNT,没用过,据说问题比较多。Linux下当然简单了,Debian下更是如此。
CVS服务器的配置
CVS想必做软件开发的都听说过,那么怎么才能让开发人员享受这一便利工具呢?当然是装个CVS服务器了。
Windows下有个CVSNT,没用过,据说问题比较多。Linux下当然简单了,Debian下更是如此。
安装cvs软件包
apt-get install cvs cvsd
其中cvs是主程序软件包,cvsd是cvs的一个pserver的wrapper,能够非常方便地管理repositories和users,并 且以更安全的形式运行cvs服务。注意安装配置的时候,将cvs的主目录设为none,将cvsd的主目录设为/home/cvs(或者其它你希望的路 径)。
修改配置文件
检查一下/etc/cvsd/cvsd.conf文件,确认最后几行类似如下的形式:
RootJail /home/cvs
Repos /repos
第一行的意思就是你的cvsd的根目录,第二行是你的repositories的目录,注意这儿虽然写的是绝对路径,实际上是相对于$cvsdHome的路径,在这里就是指/home/cvs/repos。
建立repositories
如果你在配置cvsd主目录的时候选择了none,你也可以手动创建/home/cvs目录,然后执行
cvsd-buildroot /home/cvs
将cvsd根目录的文件系统建立起来。
然后是创建repositories并初始化:
mkdir /home/cvs/repos
cvs -d /home/cvs/repos init
添加用户
添加用户就很简单了,跟其它服务器程序类似,cvsd可以添加基于本地用户的虚拟用户,如下:
cvsd-passwd /home/cvs/repos cvsuser:cvsd
chown -R cvsd.cvsd /home/cvs/repos
重启服务
最后我们用/etc/init.d/cvsd restart重启cvs服务就可以使用了。
注意用户登录时还是需要使用相对路径,如:
cvs -d :pserver:cvsuser@localhost:/repos login
作者:大狗 发布于: 2009-04-11 | 归类: 代码之美 | 标签: centOS, linux, tomcat | 抢沙发 »
| 浏览188次
CentOS下安装配置Tomcat
第一步:解压缩Tomcat部署文件到 /usr/local/tomcat
<1># tar -zxf apache-tomcat-6.0.14.tar.gz
<2># mv apache-tomcat-6.0.14 /usr/local/tomcat
第二步:测试安装(注意环境变量JAVA_HOME必需提前设置)
<1>启动: # /usr/local/tomcat/bin/startup.sh
<2>关闭: # /usr/local/tomcat/bin/shutdown.sh
第三步:部署tomcat服务自动运行
(1)jsvc方式
<1>解压jsvc包(/usr/local/tomcat/bin/下)
# tar -zxf jsvc.tar.gz
<2>编译jsvc及测试(jdk安装目录:/usr/local/jdk)
# cd /usr/local/tomcat/bin/jsvc-src
# chmod +x chmod +x configure
# ./configure –with-java=/usr/local/jdk
# make
# cp jsvc ../
# cp /usr/local/tomcat/bin/jsvc-src/native/Tomcat5.sh /etc/init.d/tomcatd
<3>编辑成chkconfig可以启动的文件,见jsvc方法脚本.txt文件
# vi /etc/init.d/tomcatd
<4>添加执行用户
# useradd tomcat
<5>确保tomcat用户能够读取server.xml文件
# chmod -R +r /usr/local/tomcat/
# chmod +x tomcatd
<6>测试是否能启动
# ./tomcatd start
# ./tomcatd stop
<7>部署自动运行
# chkconfig tomcatd on
<8># service tomcatd start
# service tomcatd status
# service tomcatd stop
(2)非jsvc方式
<1>#chmod +x tomcatd
# vi /etc/init.d/tomcatd ←见非jsvc方法脚本.txt文件
<2>测试是否能启动
# ./tomcatd start
# ./tomcatd stop
<3>部署自动运行
# chkconfig tomcatd on
<4># service tomcatd start
# service tomcatd status
# service tomcatd stop
jsvc脚本
#!/bin/sh
#
# Startup Script for Tomcat6
#
# chkconfig: – 88 14
# description: Tomcat Daemon
# processname: jsvc
# pidfile: /var/run/jsvc.pid
# config:
#
# Source function library.
. /etc/rc.d/init.d/functions
#
# Adapt the following lines to your configuration
JAVA_HOME=/usr/local/jdk
CATALINA_HOME=/usr/local/tomcat
DAEMON_HOME=$CATALINA_HOME/bin
TOMCAT_USER=tomcat
# for multi instances adapt those lines.
TMP_DIR=/usr/local/tomcat/temp
PID_FILE=/var/run/jsvc.pid
CATALINA_bASE=/usr/local/tomcat
CATALINA_OPTS=
CLASSPATH=
$JAVA_HOME/lib/tools.jar:
$CATALINA_HOME/bin/commons-daemon.jar:
$CATALINA_HOME/bin/bootstrap.jar
start(){
echo starting tomcat …
$DAEMON_HOME/jsvc
-user $TOMCAT_USER
-home $JAVA_HOME
-Dcatalina.home=$CATALINA_HOME
-Dcatalina.base=$CATALINA_bASE
-Djava.io.tmpdir=$TMP_DIR
-wait 10
-pidfile $PID_FILE
-outfile $CATALINA_HOME/logs/catalina.out
-errfile ‘&1′ $CATALINA_OPTS
-cp $CLASSPATH org.apache.catalina.startup.bootstrap
}
stop(){
echo stopping tomcat …
$DAEMON_HOME/jsvc
-stop
-pidfile $PID_FILE
org.apache.catalina.startup.bootstrap
}
status() {
ps ax –width=1000 | grep “[o]rg.apache.catalina.startup.bootstrap” | awk ‘{printf $1 ” “}’ | wc | awk ‘{print $2}’ >/tmp/tomcat_process_count.txt
read line < /tmp/tomcat_process_count.txt
if [ $line -gt 0 ]; then
echo -n “tomcatd ( pid ”
ps ax –width=1000 | grep “[o]rg.apache.catalina.startup.bootstrap” | awk ‘{printf $1 ” “}’
echo “) is running…”
else
echo “Tomcat is stopped”
fi
}
case “$1″ in
start)
# Start Tomcat
start
exit $?
;;
stop)
# Stop Tomcat
stop
exit $?
;;
restart)
stop
sleep 3
start
exit $?
;;
status)
status
exit $?
;;
*)
echo “Usage: tomcatd {start|stop|restart|status}”
exit 1
;;
esac
作者:大狗 发布于: 2009-04-11 | 归类: 代码之美 | 标签: 数据库 | 抢沙发 »
| 浏览62次
首先谢谢写这篇文章的人 ^_^ 我来转载一下表示支持和尊敬!!!
舍得网支撑1亿pv/天构架,开源了
说是支持1亿pv/天,也许有点夸张,也是为了吸引您能点进来,如果您能认真看完相信也不会让您失望,当然,肯定有很多“高手”会对此会嗤之以鼻,没关系,有很多眼高手低的人总喜欢评论别人却从不会看清自己。
如果大家真想支持我、支持中国人开源项目,请把该文贴到自己的博客中或者收藏本文,记得包含文档的下载地址!!!!!!!谢谢。
我说的系统主要是构建在hibernate 之上的高效数据库缓存系统,其中包含了分布式解决方案,该系统已经应用在舍得网上了,没有发现大问题,本人也相 信该系统已经足够强大,应付数百万IP/天的应用都不是问题,我这么说肯定有人会对此表示怀疑,其实系统到底能撑多少IP/天不在于系统本身而是在于使用 该系统的人。
代码看上去很简单,其实却是两年经验的总结,整过过程也遇到了很多难点,最后一一解决了,所以也请各位珍惜他人的劳动成果。本系统非常简洁易用,主程序 baseManager.java 不到1000行代码,用“精悍”来形容绝对不为过,1000行代码却包含了数据库对象的缓存、列表和长度的缓存、按字段 散列缓存、update延时更新、自动清除列表缓存等功能,用它来实现像论坛、博客、校友录、交友社区等绝大部分应用网站都足够了。
我在理想状态下做了压力测试,在没有数据库操作的jsp页面(舍得网新首页)里可以完成2000多requests每秒(正常情况可能有 1/1000的 request有数据库查询,其余999/1000都是直接从缓存里读取),物品详情页每秒可完成3000多requests,纯静态html页面也只能 完成7000多requests/秒,我对首页进行了三个小时的压力测试,完成了24850800个requests,java一点事都没有,内存没有上 涨。按照2000个requests/秒算,一天按15小时计算,那么每天能完成3600*15*2000=1亿零8百万requests,当然这是理想 状态,实际状态就算打一折,还能完成1000万pv/天,要知道,这只是一个普通1万3千块钱买的服务器,内存4G,CPU2个,LinuxAS4系 统,apache2.0.63/resin2.1.17/jdk6.0的环境。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。现在进入正题。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
为什么要用缓存?如果问这个问题说明你还是新手,数据库吞吐量毕竟有限,每秒读写5000次了不起了,如果不用缓存,假设一个页面有100个数据库 操 作,50个用户并发数据库就歇菜,这样最多能支撑的pv也就50*3600*15=270万,而且数据库服务器累得半死,搞不好什么时候就累死了。我的这 套缓存系统比单独用memcached做缓存还要强大,相当于在memcached上再做了两级缓存,大家都知道memcached很强了,但是吞吐量还 是有限,每秒20000次get和put当遇到超大规模的应用时还是会歇菜,本地HashMap每秒可执行上百万次put和get,在这上面损耗的性能几 乎可以忽略不记了。温馨提示:能不用分布式的时候就不要用分布式,非用分布式的时候再考虑用memcached,我的缓存系统在这方面都已经实现了,改个 配置就可以了,有兴趣的可以仔细测试测试!
一般数据库缓存在我看来包含四种。第一种:单个对象的缓存(一个对象就是数据库一行记录),对于单个对象的缓存,用HashMap就可以了,稍微复 杂一点 用LRU算法包装一个HashMap,再复杂一点的分布式用memcached即可,没什么太难的;第二种:列表缓存,就像论坛里帖子的列表;第三种:长 度的缓存,比如一个论坛板块里有多少个帖子,这样才方便实现分页。第四种:复杂一点的group,sum,count查询,比如一个论坛里按点击数排名的 最HOT的帖子列表。第一种比较好实现,后面三种比较困难,似乎没有通用的解决办法,我暂时以列表缓存(第二种)为例分析。
mysql和hibernate的底层在做通用的列表缓存时都是根据查询条件把列表结果缓存起来,但是只要该表的记录有任何变化(增加/删除/修改),列表缓存要全部清除,这样只要一个表的记录经常变化(通常情况都会这样),列表缓存几乎失效,命中率太低了。
本人想了一个办法改善了列表缓存,当表的记录有改变时,遍历所有列表缓存,只有那些被影响到的列表缓存才会被删除,而不是直接清除所有列表缓存,比 如在一 个论坛版(id=1)里增加了一个帖子,那么只要清除id=1这个版对应的列表缓存就可以了,版id=2就不用清除了。这样处理有个好处,可以缓存各种查 询条件(如等于、大于、不等于、小于)的列表缓存,但也有个潜在的性能问题,由于需要遍历,CPU符合比较大,如果列表缓存最大长度设置成10000,两 个4核的CPU每秒也只能遍历完300多次,这样如果每秒有超过300个insert/update/delete,系统就吃不消了。
在前面两种解决办法都不完美的情况下,本人和同事经过几个星期的思索,总算得出了根据表的某几个字段做散列的缓存办法,这种办法无需大规模遍历,所 以 CPU符合非常小,由于这种列表缓存按照字段做了散列,所以命中率极高。思路如下:每个表有3个缓存Map(key=value键值对),第一个Map是 对象缓存A,在A中,key是数据库的id,Value是数据库对象(也就是一行数据);第二个Map是通用列表缓存b,b的最大长度一般1000左右, 在b中,key 是查询条件拼出来的String(如start=0,length=15#active=0#state=0),Value是该条件查询下 的所有id组成的List;第三个Map是散列缓存C,在C中,key是散列的字段(如根据userId散列的话,其中某个key就是 userId=109这样的String)组成的String,value是一个和b类似的HashMap。其中只有b这个Map是需要遍历的,不知道说 明白了没有,看完小面这个例子应该就明白了,就用论坛的回复表作说明,假设回复表T中假设有字段id,topicId,postUserId等字段 (topicId就是帖子的id,postUserId是发布者id)。
第一种情况,也是最常用的情况,就是获取一个帖子对应的回复,sql语句应该是象
select id from T where topicId=2008 order by createTime desc limit 0,5
select id from T where topicId=2008 order by createTime desc limit 5,5
select id from T where topicId=2008 order by createTime desc limit 10,5
的样子,那么这种列表很显然用topicId做散列是最好的,把上面三个列表缓存(可以是N个)都散列到key是topicId=2008这一个Map 中,当id是2008的帖子有新的回复时,系统自动把key是topicId=2008的散列Map清除即可。由于这种散列不需要遍历,因此可以设置成很 大,例如100000,这样10万个帖子对应的所有回复列表都可以缓存起来,当有一个帖子有新的回复时,其余99999个帖子对应的回复列表都不会动,缓 存的命中率极高。
第二种情况,就是后台需要显示最新的回复,sql语句应该是象
select id from T order by createTime desc limit 0,50
的样子,这种情况不需要散列,因为后台不可能有太多人访问,常用列表也不会太多,所以直接放到通用列表缓存b中即可。
第三种情况,获取一个用户的回复,sql语句象
select id from T where userId=2046 order by createTime desc limit 0,15
select id from T where userId=2046 order by createTime desc limit 15,15
select id from T where userId=2046 order by createTime desc limit 30,15
的样子,那么这种列表和第一种情况类似,用userId做散列即可。
第四种情况,获取一个用户对某个帖子的回复,sql语句象
select id from T where topicId=2008 and userId=2046 order by createTime desc limit 0,15
select id from T where topicId=2008 and userId=2046 order by createTime desc limit 15,15
的样子,这种情况比较少见,一般以topicId=2008为准,也放到key是topicId=2008这个散列Map里即可。
那么最后的缓存结构应该是下面这个样子:
缓存A是:
Key键(long型) Value值(类型T)
11 Id=11的T对象
22 Id=22的T对象
133 Id=133的T对象
……
列表缓存b是:
Key键(String型)
Value值(ArrayList型)
from T order by createTime desc limit 0,50 ArrayList,对应取出来的所有id
from T order by createTime desc limit 50,50 ArrayList,对应取出来的所有id
from T order by createTime desc limit 100,50 ArrayList,对应取出来的所有id
……
散列缓存C是:
Key键(String型) Value值(HashMap)
userId=2046 Key键(String型) Value值(ArrayList)
userId=2046#0,5 id组成的List
userId=2046#5,5 id组成的List
userId=2046#15,5 id组成的List
……
userId=2047 Key键(String型) Value值(ArrayList)
userId=2047#0,5 id组成的List
userId=2047#5,5 id组成的List
userId=2047#15,5 id组成的List
……
userId=2048 Key键(String型) Value值(ArrayList)
userId=2048#topicId=2008#0,5 id组成的List
userId=2048#5,5 id组成的List
userId=2048#15,5 id组成的List
……
……
总结:这种缓存思路可以存储大规模的列表,缓存命中率极高,因此可以承受超大规模的应用,但是需要技术人员根据自身业务逻辑来配置需要做散列的字 段,一般 用一个表的索引键做散列(注意顺序,最散的字段放前面),假设以userId为例,可以存储N个用户的M种列表,如果某个用户的相关数据发生变化,其余 N-1个用户的列表缓存纹丝不动。以上说明的都是如何缓存列表,缓存长度和缓存列表思路完全一样,如缓存象select count(*) from T where topicId=2008这样的长度,也是放到topicId=2008这个散列Map中。如果再配合好使用mysql的内存表和memcached,加 上F5设备做分布式负载均衡,该系统对付像1000万IP/天这种规模级的应用都足够了,除搜索引擎外一般的应用网站到不了这种规模。
再次申明:系统到底是不是强大不在系统本身而在于使用该系统的人!!!
这个缓存系统是我和同事几年经验的总结,看似简单,其实也没那么简单,把它作为开源有下面几个目的:第一,真的希望有很多人能用它;第二:希望更多 的人能 够完善和改进它;第三:希望大家能聚到一起为通用高效数据库缓存构架作出贡献,毕竟,数据库操作是各种应用最常用的操作,也是最容易产生性能瓶颈的地方。
Zip包中包含了配置方法和测试用的jsp,只要把它配置成一个web应用就可以快速调试并看到缓存的力量了,文档和下载地址是http://shedewang.com/akaladocs/api/com/akala/dbcache/core/BaseManager.html。
配置说明文件在docs/开始配置.txt里有说明。
最后啰嗦一句,如果大家真想支持我、支持中国人开源项目,请把该文贴到自己的博客中或者收藏本文,记得包含文档的下载地址!!!!!!!谢谢。thank you and Good luck。
QQ群:24561583
复制过来格式有点乱了,还是自己下载一个下来看看吧,里面有个word文档,写得比较清晰。
最新评论