Quantcast
Channel: IT社区推荐资讯 - ITIndex.net
Viewing all 15843 articles
Browse latest View live

致一位正为报考大学选择专业而迟疑的高中生

$
0
0

致一位正为报考大学选择专业而迟疑的高中生

 

XX同学:

 

刚刚收到你的来信,很为你的向学精神而高兴。我是牟平人,属烟台地区,36年前从家乡考到西南政法大学学习法律,所以我们是老乡,很为家乡有你这样的学子感到自豪。

 

我知道,高考的专业选择是一件令人纠结的事情。你喜欢哲学,但是担心将来就业困难,又不愿意学习金融专业,于是想考虑选择中文或法律专业。我个人对于哲学或中文专业的情况不是特别了解,不过,就一般情况而言,一个人如果学习的是自己所特别喜欢的专业,往往就能够焕发出强大的学习动力,从而在大学期间取得优异的成绩,为今后攻读更高的学位奠定基础。假如将来是博士毕业,那么,通常属于本科毕业生要担心的专业就业困难就不是问题了。在一个较为理想的层次上考虑,哲学专业培养的是学生的一种理性地探索知识与道德问题的能力,它要通过对于古希腊以来伟大哲学家思想的不断领略、理解与温习,激发每一个学习者思考人类基本问题的思维能力和创造性。所以,虽然这个专业难以成为一种特别功利性的饭碗学问,但是,如果你真正热爱它,持之以恒地研究与思考,很可能成为未来一个好学者甚至思想家的起航港。

 

当然,这更像是一只美好的梦想。任何国家里,专门的哲学家都是凤毛麟角的(虽然我们国家在大学里“吃哲学饭”的人也不少)。不过,就今天的教育模式而言,越来越多的人本科毕业之后还是要读硕士学位;在本科读书期间,也有不少同学辅修另一个学士学位。我的课堂上就有来自其他专业的同学辅修法学学位。因此,我的建议是,如果你报考的是综合性大学,也许无需过于看重特定专业将来的就业情况,尊重自己的兴趣是特别重要的。进入大学之后还有很多的再选择机会。

 

至于你就法学专业提出的那些问题,简短的篇幅实在不容易给出有价值的答案。我只是说,很多人把法学专业的学习误解为一种对于法律条文的记诵之学,这实在是大错特错的。在某种意义上,法学跟哲学有太多的相似点。它注重对人性、人际关系以及合理的社会秩序的理解,注重秩序与自由的紧张关系,注重法律与其他社会现象诸如伦理、文化之间的互动。单单一个死刑是否应当废除的问题,就隐含着多么大的哲学、伦理学和人文的意义!所以,真正成就一个合格的法律家,四年的本科学习是远远不够的,这甚至需要终生的努力。

 

你让我推荐一本法律书,我想也许最合适你读的是意大利伟大的法律思想家贝卡利亚的《犯罪与刑罚》,篇幅不大,但是把法学与哲学融为一体,是一本了不起的经典。你可以在网上搜索一下,或许能够得到购买的相关信息。

 

希望上面说的这些对你能够有点帮助,也祝你成功!

 

贺卫方

2014年7月14日

 


  青春就应该这样绽放   游戏测试:三国时期谁是你最好的兄弟!!   你不得不信的星座秘密

网页字体设置你了解吗?

$
0
0

以前做项目的时候就依葫芦画瓢的设置 { font-family:arial,”microsoft yahei”,simsun,sans-self; } 等类似的字体,然而当更多的设备和系统出现后,以前这样的设置已不能满足网页在各设备上的显示需求。

就拿最简单的宋体(simsun)来说吧,在Windows系统下显示是一个比较容易阅读的字体,然而在Mac上简直无法直视,如下图给出一个优化前后页面的对比效果:

字体优化前后对比图

因此,出于种种原因,促使我不得不去对字体做一个相应的了解。

对于网站字体设置,本文给出以下意见:

移动端项目:

font-family:Tahoma,Arial,Roboto,”Droid Sans”,”Helvetica Neue”,”Droid Sans Fallback”,”Heiti SC”,sans-self;

 

pc端(含Mac)项目:

font-family:Tahoma,Arial,”Helvetica Neue“,”Hiragino Sans GB”,Simsun,sans-self;

 

移动和pc端项目:

font-family:Tahoma,Arial,Roboto,”Droid Sans”,”Helvetica Neue”,”Droid Sans Fallback”,”Heiti SC”,”Hiragino Sans GB”,Simsun,sans-self;

 

首先说说字体的种类,字体分为五大种类,然而各设备的支持情况也个不相同,如,

各移动设备系统支持情况:

五大类字体安卓4.0IOS6.0WP8
sans-serif(无衬线)支持支持支持
serif(衬线)支持支持支持
monospace(等宽)支持支持支持
fantasy(梦幻)不支持支持不支持
cuisive(草体)不支持不支持不支持

 

当然目前这只是移动设备各系统的支持情况,然而pc端个浏览器的支持情况也各不相同,如:

五大类字体IE系列ChromeFirefox
sans-serif(无衬线)支持不支持不支持
serif(衬线)支持支持支持
monospace(等宽)支持支持支持
fantasy(梦幻)支持支持支持
cuisive(草体)不支持不支持不支持

 

下面介绍下个系统的默认字体和常用字体:

系统默认西文字体默认中文字体其他常用西文字体其他常用中文字体
Windows宋体宋体Tahoma、Arial、Verdana、Georgia微软雅黑、黑体
Android 4.0以下Droid SansDroid Sans FallbackArial无宋体、无微软雅黑
Android 4.0及以上RobotoRobotoArial无宋体、无微软雅黑
iOSHelvetica NeueHeiti SC (黑体)Tahoma(v7.0)、Arial、Verdana、GeorgiaSTHeiti(v7.0)、无宋体、无微软雅黑
Mac OS X 10.6以下Helvetica NeueSTHeiti (华文黑体)Tahoma、Arial、Verdana、Georgia宋体、无微软雅黑
Mac OS X 10.6及以上Helvetica NeueHiragino Sans GB  (冬青黑体简体中文)Tahoma、Arial、Verdana、Georgia宋体、无微软雅黑

参考资料: iOS6字体列表iOS7字体列表Mac OS X  10.6字体列表Mac OS X 10.7字体列表 等,在看了一些资料之后,对系统和浏览器下的字体就有了一个基本的认识。

有很多同学看到上面这些表格里面的结论,可能就会想到:可以只设置西文字体不设置中文字体。

只设置西文字体不设置中文字体是否可以?答案当然是不可以。因为上面这些系统和浏览器的默认字体也仅仅是是一个理想状态下的设置,这些默认字体仅限于浏览器或系统最初的默认字体。现在的手机都支持字体更换,对于浏览器而已也是如此,现在的浏览器都支持用户自己设置字体。因此,只设置西文字体而忽略中文字体设置是存在一定的危险性的。

 

对于现在Adroid系统的各种字体app,如:字体管家、字体管理等。如果用户自己下载相关的app字体软件将字体改掉,这种情况下,我们该如何处置?

如果用户将默认的系统字替换掉,那我们就只能用其他的中文字体来代替现实,然而就目前而言,移动端的中文字体非常少(几乎是唯一性),因此,本人还没有找到相应的解决办法,后期找到方法再分享出来。

如果代码审查时你忘记了拿近视眼镜

$
0
0

你身处在一个卓越开明的开发团队,你被安排了一整天的时间,什么都不干,只做代码审查。然而,在活动开始两小时前,你发现自己把近视眼镜忘家里了,整个早上你看到的都是模糊的影像和颜色。你该怎么办?

正确的做法是,回家取你的眼镜,因为步行十分钟就能到家,然后今天会跟往常一样愉快的度过。但是,如果说,是你在早上准备离家上班时,发现一群凶猛好斗的大黄蜂在放眼镜的抽屉里筑起了蜂巢,挡住了你拿眼镜的途径,而且它们看起来很不喜欢被打搅。那你怎么办呢?

另一个正确的做法,很显然,是假装你带了隐形眼镜,免得让自己很尴尬。而且你知道自己有不看任何代码细节、只看大概就能说出很多让人钦佩的意见的能力。

代码审查 例一

ex1

我们都认可代码责任应该绝对的分离。任何类都应该只做它自己职责范围内的事情。但是,你的这个 UserCreator很可能有点过了。如果这个 UserCreator对象只做这一点事,那其实 Users对象自己就应该创建自己。另外一点不好的是,创建一个简单的 Users,你还需要在成堆的小文件中找出它的创建者对象,不宜操作,也不宜理解。

代码审查 例二

ex2

看看这些一大堆的方法函数,却伪装成一个类,我可以看到,从技术上讲,这些方法都是在各自做自己的事情。虽然没有任何的文字信息提示或暗示,我也能猜出你没有很好的给这个类写测试程序。如果给我一杯浓咖啡、一个下午时间,我想我可以分析出中间这20行的代码是用来判断应该给哪个用户发送邮件,但我还是希望你将这部分代码放到 def users_to_send_emails_to函数里,免得我再去动脑子。

代码审查 例三

ex3

很好,在这个类里,你的方法都非常的简洁短小,这是一个进步。然而,你做的是有点过了。虽然Ruby解释器并不在意你的代码逻辑在每个只有一行的方法间来回跳跃,但人脑解释器会在意。也许有人会喜欢上下翻屏看代码,但如果换成我,让我在手臂上记下哪个方法应该调用哪个方法,那我更喜欢将这些小方法组合到一起。

代码审查 例四

ex4

可以看出,你非常关心这个类是否被放在了合适的命名空间里。非常好,使用命名空间是个好事。但在这个文件里,你嵌套了6层。看起来你试图在一个小小的地方里装下太多的东西。你要么应该想想不要分那么多层(是的,我可以看到这里有两个辅助类,应该放到它们自己的空间里,但如果把它放到其它地方会有不好吗?),要么拆分一些代码,放到自己的根空间下。

代码审查 例五

ex5

非常详细的注释,佩服!这段代码需要好几个章节的文字来辅助理解,佩服!

代码审查 例六

ex6

仔细看一下这第二个方法。如果一个方法需要8个参数才能让它知道干什么事情、如何干事情,那么,这个 方法有点太累了。请重构它,从它的肩膀上消减一些负担,拿走一些压力。把它一分为二(或更多),或者,也许将一些参数当成类的初始化参数,可能会更有意义些。这8个参数你会同时都用到吗?所以,不要期望你的方法这样。

所以,这就是当你忘了拿近视眼镜、或直视太阳太久时做代码审查的方法。如果你有丰富的编程经验,我相信你也能举出很多有趣的例子。有人可能会反对,说这些只是一些小事情,还有很多更重要的事情需求考虑。然而,清爽、简洁、良好格式的代码是你需要的,如果你不去用心控制好你的代码结构,它终究会给你带来烦恼。

请阅读全文: 如果代码审查时你忘记了拿近视眼镜

本文由 外刊IT评论网( www.vaikan.com)原创发表
文章地址: 如果代码审查时你忘记了拿近视眼镜
[英文原文: Code review without your glasses ]

你也许会喜欢这些文章:

  1. 事后诸葛亮:如何写出没有bug的软件
  2. 代码审查不是用来……
  3. 谷歌是如何做代码审查的
  4. 你们公司做代码审查吗?
  5. 代码审查和不良编程习惯




vps安全设置

$
0
0

适合新手及才接触VPS的朋友们看一下,主要是关于VPS安全方面相关内容的

禁止ROOT登陆 保证安全性;

使用DDoS deflate简单防攻击;

iftop Linux流量监控工具;

每日自动备份VPS到FTP空间;

升级LNMP的NGINX到最新版。

一、修改SSH端口

vi /etc/ssh/sshd_config

找到其中的#Port 22(第13行),去掉#,修改成Port 3333

使用如下命令,重启SSH服务,注:以后用新端口登陆。

service sshd restart

二、禁止ROOT登陆

先添加一个新帐号vpsmm,可以自定义:

useradd vpsmm

给vpsmm帐号设置密码:

passwd vpsmm

仍旧是修改/etc/ssh/sshd_config文件,第39行:#PermitRootLogin yes,去掉前面的#,并把yes改成no,然后,重启SSH服务。以后,先使用vpsmm登陆,再su root即可得到ROOT管理权限。

login as: vpsmm
vpsmm@ip password:*****
Last login: Tue Nov 22 14:39:58 2010 from 1.2.3.4
su root
Password:*********** #注这里输入ROOT的密码

三、使用DDos deflate简单防落CC和DDOS攻击

使用netstat命令,查看VPS当前链接确认是否受到攻击:

netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n

IP前面的数字,即为连接数,如果说正常网站,几十到一百都属于正常连接,但出现几百,或上千的就可以垦定这个IP与你的VPS之间可能存在可疑连接现象。

可以使用iptables直接BAN了这个IP的永久访问:

iptables -A INPUT -s 12.34.56.78 -j DROP

今天介绍给大家一种方法,是使用软件DDos deflate来自动检测并直接BAN掉的方法,首先我们要确认一下iptables服务状态,默认CENTOS就安装的,不看也行。

service iptables status

安装DDos deflat:

wget http://www.inetbase.com/scripts/ddos/install.sh
chmod +x install.sh
./install.sh

安装后需要修改/usr/local/ddos/ddos.conf,主要是APF_BAN=1要设置成0,因为要使用iptables来封某些可疑连接,注意EMAIL_TO=“root”,这样BAN哪个IP会有邮件提示:

##### Paths of the script and other files
PROGDIR="/usr/local/ddos"
PROG="/usr/local/ddos/ddos.sh"
IGNORE_IP_LIST="/usr/local/ddos/ignore.ip.list"  //IP地址白名单
CRON="/etc/cron.d/ddos.cron"    //定时执行程序
APF="/etc/apf/apf"
IPT="/sbin/iptables"
##### frequency in minutes for running the script
##### Caution: Every time this setting is changed, run the script with --cron
#####          option so that the new frequency takes effect
FREQ=1   //检查时间间隔,默认1分钟
##### How many connections define a bad IP? Indicate that below.
NO_OF_CONNECTIONS=150     //最大连接数,超过这个数IP就会被屏蔽,一般默认即可
##### APF_BAN=1 (Make sure your APF version is atleast 0.96)
##### APF_BAN=0 (Uses iptables for banning ips instead of APF)
APF_BAN=1        //使用APF还是iptables。推荐使用iptables,将APF_BAN的值改为0即可。
##### KILL=0 (Bad IPs are'nt banned, good for interactive execution of script)
##### KILL=1 (Recommended setting)
KILL=1   //是否屏蔽IP,默认即可
##### An email is sent to the following address when an IP is banned.
##### Blank would suppress sending of mails
EMAIL_TO="root"   //当IP被屏蔽时给指定邮箱发送邮件,推荐使用,换成自己的邮箱即可
##### Number of seconds the banned ip should remain in blacklist.
BAN_PERIOD=600    //禁用IP时间,默认600秒,可根据情况调整

四、使用iftop查看详细网络状况

安装IFTOP软件:

yum -y install flex byacc  libpcap ncurses ncurses-devel libpcap-devel
wget http://www.ex-parrot.com/pdw/iftop/download/iftop-0.17.tar.gz
tar zxvf iftop-0.17.tar.gz
cd iftop-0.17
./configure
make && make install

安装后,使用iftop运行,查看网络情况。TX,发送流量;RX,接收流量;TOTAL,总流量;Cumm,运行iftop期间流量;peak,流量峰值;rates,分别代表2秒、10秒、40秒的平均流量。

快捷键:h帮助,n切换显示IP主机名,s是否显示本机信息,d是否显示远端信息,N切换端口服务名称,b切换是否时数流量图形条。

五、每日备份你的VPS上传到FTP空间

六、升级LNMP中的NGINX到最新版

现在最新版是0.8.53,如果以后出新版,只要更新版本号就可以,在SSH里运行:

wget http://www.nginx.org/download/nginx-0.8.53.tar.gz
tar zxvf nginx-0.8.53.tar.gz
cd nginx-0.8.53
./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module  --with-http_sub_module
make
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old
cd objs/
cp nginx /usr/local/nginx/sbin/
/usr/local/nginx/sbin/nginx -t
kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`
/usr/local/nginx/sbin/nginx -v
cd ..
cd ..
rm -rf nginx-0.8.53
rm -rf nginx-0.8.53.tar.gz

七、常用netstat命令:

1.查看所有80端口的连接数

netstat -nat|grep -i "80"|wc -l

2.对连接的IP按连接数量进行排序

netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n

3.查看TCP连接状态

netstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn
netstat -n | awk '/^tcp/ {++S[$NF]};END {for(a in S) print a, S[a]}'
netstat -n | awk '/^tcp/ {++state[$NF]}; END {for(key in state) print key,"\t",state[key]}'
netstat -n | awk '/^tcp/ {++arr[$NF]};END {for(k in arr) print k,"\t",arr[k]}'
netstat -n |awk '/^tcp/ {print $NF}'|sort|uniq -c|sort -rn
netstat -ant | awk '{print $NF}' | grep -v '[a-z]' | sort | uniq -c

4.查看80端口连接数最多的20个IP

netstat -anlp|grep 80|grep tcp|awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -nr|head -n20
netstat -ant |awk '/:80/{split($5,ip,":");++A[ip[1]]}END{for(i in A) print A,i}' |sort -rn|head -n20

5.用tcpdump嗅探80端口的访问看看谁最高

tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F"." '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -nr |head -20

6.查找较多time_wait连接

netstat -n|grep TIME_WAIT|awk '{print $5}'|sort|uniq -c|sort -rn|head -n20

7.找查较多的SYN连接

netstat -an | grep SYN | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -nr | more
作者:tiancaimvp 发表于2014-7-16 0:40:59 原文链接
阅读:0 评论:0 查看评论

Linux已经完全统治了这个世界:反对开源社区愚不可及

$
0
0

原文来自: http://readwrite.jp/archives/9977

无论一个企业多强大,它都不存在和开源社区抗衡的实力

十年前,Unix占有最快的计算机世界排名前10位的五席,以及超级计算机市场的44%。现在怎么样了呢?以往那些凭借着处理能力地位难以撼动的Unix已经被 Linux取代了其位置,别说世界上最快的计算机前十名,就是前50名也没有UNIX的影子。

社区:隐藏的性能助推器


人们并不都是很清楚的意识到社区的有效性。1999年,SUN公司的首席执行官Scott Makuneri对Linux性能做了如下的攻击。
【linux就和Windows操作系统一样,用在设备或客户端上太庞大,在服务器上也没有足够的扩展性。我不明白为什么人们从世界各地继续付钱给MS,Linux也是如此】


我们不能说他没有先见之明,在1999年的时候,Linux并不在世界上最快的排名500名之列,Sun Solaris的性能更是遥遥领先于Linux。

然而,Sun Solaris无法战胜的是Linux社区。

SUN公司历史上有众多的创新值得夸耀,但只是作为一个公司无论你多么伟大,你毕竟只是一个公司。今天没有一个公司能有足够的拥有丰富的经验的工程师来实现大型的技术架构。





而现在,Linux已经占据了世界前500名超级计算机的97%,Unix只有2%(不包括Solaris)。


活跃​​的社区活动给开源项目带来了许多优势。

1. 采用开源项目是好的
2. 采用开源项目是安全的
3. 采用开源项目能创造更多的市场
4. 采用开源项目的成果比竞争对手要更好

社区不仅降低了由于闭源导致问题的风险,同时在StackOverflow和GitHub上充实了技术信息。与开源技术相关的开发者的数量的增多,提 高了开源技术的市场渗透率。进而促进了第三方社区的形成,这是一个永恒的周期。这是在一个公司内无法完成的。

性能问题也随着关联项目的增多而更容易解决。如Linux受到RedHat,IBM,惠普和甲骨文,甚至于SUN的关注而在性能上得到飞快的提高。出于各种原因,它们对Linux贡献代码做了改进。结果是,Linux不仅功能增加了,性能也得到改善。性能问题也随着关联项目的增多而更容易解决。如Linux受到RedHat,IBM,惠普和甲骨文,甚至于SUN的关注而在性能上得到飞快的提高。出于各种原因,它们对Linux贡献代码做了改进。结果是,Linux不仅功能增加了,性能也得到改善。


打赌2014年社区的发展

这就是为什么我对于开源项目OpenStack和Hadoop,以及其他开源项目报乐观态度的原因。性能和未来的潜力等等,Linux这十多年的经历过的种种问题仍然存在。但是只要有集中了社区的关注,这只不过是时间问题罢了。
当然也有进展不顺的例子。比如 OpenStack由于缺乏领导力,这个cloud社区在进入市场时蹒跚前行。但是如果能够解决领导力的问题,一个活跃的OpenStack的社区将支持其继续发展。

作者:robertsong2004 发表于2014-7-15 22:39:42 原文链接
阅读:49 评论:0 查看评论

避免全表扫描的sql优化

$
0
0
/**
http://www.2cto.com/database/201201/116117.html
**/
对查询进行优化,应尽量避免全表扫描,首先应考虑在where 及order by 涉及的列上建立索引:
 
 .尝试下面的技巧以避免优化器错选了表扫描:
 
·   使用ANALYZE TABLE tbl_name为扫描的表更新关键字分布。
 
·   对扫描的表使用FORCE INDEX告知MySQL,相对于使用给定的索引表扫描将非常耗时。
 
           SELECT * FROM t1, t2 FORCE INDEX (index_for_column)
 
            WHERE t1.col_name=t2.col_name;
 
·   用--max-seeks-for-key=1000选项启动mysqld或使用SET max_seeks_for_key=1000告知优化器假设关键字扫描不会超过1,000次关键字搜索。
 
 
 
 
 
 1. 应尽量避免在where 子句中对字段进行null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,
 
      如:
 
      select id from t where num is null
 
     NULL对于大多数数据库都需要特殊处理,MySQL也不例外,它需要更多的代码,更多的检查和特殊的索引逻辑,有些开发人员完全没有意识到,创建表时NULL是默认值,但大多数时候应该使用NOT NULL,或者使用一个特殊的值,如0,-1作为默  认值。
 
     不能用null作索引,任何包含null值的列都将不会被包含在索引中。即使索引有多列这样的情况下,只要这些列中有一列含有null,该列    就会从索引中排除。也就是说如果某列存在空值,即使对该列建索引也不会提高性能。 任何在where子句中使用is null或is not null的语句优化器是不允许使用索引的。
 
 
 
      此例可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
 
      select id    from t where num=0
 
 2. 应尽量避免在where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
 
 
 
   MySQL只有对以下操作符才使用索引:<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE。 可以在LIKE操作中使用索引的情形是指另一个操作数不是以通配符(%或者_)开头的情形。例如,“SELECT id FROM t WHERE col LIKE 'Mich%';”这个查询将使用索引,但“SELECT id FROM t WHERE col  LIKE '%ike';”这个查询不会使用索引。
 
 
 
 3. 应尽量避免在where 子句中使用or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,
 
    如:
 
    select id from t where num=10 or num=20
 
    可以这样查询:select id from t where num=10 union all select id from t where num=20
 
 
 
 4 .in 和not in 也要慎用,否则会导致全表扫描,
 
    如:
 
   select id from t where num in(1,2,3)
 
   对于连续的数值,能用between 就不要用in 了:
 
   select id from t where num between 1 and 3
 
 
 
  5.下面的查询也将导致全表扫描:
 
       select id from t where name like '%abc%' 或者
 
       select id from t where name like '%abc' 或者
 
       若要提高效率,可以考虑全文检索。
 
      而select id from t where name like 'abc%' 才用到索引
 
 
 
 7. 如果在where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推 迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:
 
    select id from t where num=@num
 
   可以改为强制查询使用索引:select id from t with(index(索引名)) where num=@num
 
 
 
 8.应尽量避免在where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。
 
 如:
 
  select id from t where num/2=100
 
应改为:
 
 select id from t where num=100*2
 
 
 
9. 应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。
 
如:
 
select id from t where substring(name,1,3)='abc'--name
select id from t where datediff(day,createdate,'2005-11-30')=0--‘2005-11-30’生成的id 应改为:
 
 
 
select id from t where name like 'abc%'
select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'
10.不要在where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
 
 
 
11.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。
 
 
 
12.不要写一些没有意义的查询,
 
如需要生成一个空表结构:
 
 select col1,col2 into #t from t where 1=0
 
这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:create table #t(...)
 
 
 
13.很多时候用exists 代替in 是一个好的选择:
 
select num from a where num in(select num from b)
 
用下面的语句替换:
 
select num from a where exists(select 1 from b where num=a.num)
 
 
 
14.并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。
 
 
 
15.索引并不是越多越好,索引固然可以提高相应的select 的效率,但同时也降低了insert 及update 的效率,因为insert 或update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。
 
 
 
16.应尽可能的避免更新clustered 索引数据列,因为clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新clustered 索引数据列,那么需要考虑是否应将该索引建为clustered 索引。
 
 
 
17.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
 
 
 
18.尽可能的使用varchar/nvarchar 代替char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
 
 
 
19.任何地方都不要使用select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。
 
 
 
20.尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。21.避免频繁创建和删除临时表,以减少系统表资源的消耗。
 
 
 
22.临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。
 
 
 
23.在新建临时表时,如果一次性插入数据量很大,那么可以使用select into 代替create table,避免造成大量log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。
 
 
 
24.如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先truncate table ,然后drop table ,这样可以避免系统表的较长时间锁定。
 
 
 
25.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。26.使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。
 
 
 
27.与临时表一样,游标并不是不可使用。对小型数据集使用FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。
 
 
 
28.在所有的存储过程和触发器的开始处设置SET NOCOUNT ON ,在结束时设置SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送DONE_IN_PROC 消息。
 
 
 
29.尽量避免大事务操作,提高系统并发能力。
 
 
 
30.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。


已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



Wireshark 入门详解

$
0
0

目录:

一、 background 二、 how it works 三、包抓取方式 四、 filter in Wireshark
  •   Capture filter例子
  • 抓取所有本主机发送的报文,本机为2.2.2.2
  • 抓取与主机1.1.1.1.的1033端口的所有通信
  • 抓取所有的tcp RST报文
五、 Wireshark的安装 六、 Wireshark的实用功能
  • l Follow tcp stream
  • l Statistics
  • l Flow graph
  • l Tcp stream graph
七、 Wireshark的扩展
  •  ip地理信息扩展
八、让Wireshark支持自定义协议
  •  Wireshark中的协议解析器模块
  • l Lua编写协议解析插件
  1.  Lua为何物
  2. Wireshark与lua的关系
  3. 使用lua编写自定义协议解析器
九、附录

一、background

Wireshark是一款支持多平台的包抓取分析开源软件,前身是ethereal。 Wireshark基于libpcap on unix-like,winpcap on windows。Tcpdump同样基于libpcap实现。Libpcap来自于BPF,下图是BPF的一个结构图: wireshark-1

二、how it works

wireshark-2

三、How packets capture

当前Wireshark支持以下三种包抓取方式: 1. 网络适配器上实时抓取; 2. 远程主机抓取; 3. pipe方式抓取; 这里主要介绍下远程主机的抓取方式,此功能依赖于libpcap/winpcap提供的rpcapd.程序: wireshark-3 首先服务器端建立侦听 wireshark-4 然后客户端连接到服务器端 wireshark-5wireshark-6 现在能看见远程主机网卡上的流量了 wireshark-7 Packet由libpcap抓取之后通过管道传送到wireshark,由此远程抓包只是流量重定向而已。

四、filter in Wireshark

Wireshark中提供了两种filter: 1. Capture filter; 2. Display filter; 其中capture filter来自于libpcap,语法如下  [direction] [[type] value] [proto] Direction: src dst Type: host net port Proto: ether tcp udp arp ... Capture filter在libpcap实现,只有满足过滤器的包之后才会送往应用程序。 l  Capture filter例子
  • 抓取所有本主机发送的报文,本机为2.2.2.2
src host 2.2.2.2
  • 抓取与主机1.1.1.1.的1033端口的所有通信
host 1.1.1.1 && port 1033
  • 抓取所有的tcp RST报文
tcp[13]&4==4 || tcp[13]&4==14       #tcp的flag在偏移13字节的地方,占据1字节 Display filter来自于Wireshark,用于对捕获包的显示过滤。Wireshark利用此filter还是实现了coloring rules,statistics等功能。

五、Wireshark install

Wireshark依赖于libpcap/winpcap,于是在应用程序安装之前,首先安装此库。

六、Wireshark utility

  •  Follow tcp stream
Wireshark将通信抽象成流的概念,按照Wireshark的解释,流是“The stream content is displayed in the same sequence as it appeared on the network”,就是一个序列号下来的通信,主要针对tcp通信 wireshark-8 红方表示发送方,蓝方表示回送方
  • Statistics
可以按照协议,按照endpoint,按照packet length进行统计显示 wireshark-9
  •  Flow graph
将网络通信以时序图的方式展现出来 wireshark-10
  •  Tcp stream graph

七、Wireshark extension

  •   ip地理信息扩展
maxmind是一个在线ip地理信息提供商GeoIP,http://www.maxmind.com,它提供了一个离线数据库文件,Wireshark加载此文件,可以在显示捕获包的同时显示该包中的IP的地理信息; wireshark-11wireshark-12

八、让Wireshark支持自定义协议

  •  Wireshark中的协议解析器模块
源码下的epan目录
  • Lua编写协议解析插件
Init.lua文件 Lua为何物 wireshark-13 Wireshark与lua的关系
  1.  wireshark内置了lua解释器
  2.  Lua作为wireshark的扩展通道,为wireshark提供支持自定义的协议解析的能力
a) 侦听时分析 b) 显示时分析 3. Wireshark通过init.lua进入其他的lua程序 使用lua编写自定义协议解析器 1. 步骤 a)   定义协议 b)  定义解析函数 c)   在全局解析函数table中加入解析规则

九、附录

最初的libpcap论文:http://www.tcpdump.org/papers/bpf-usenix93.pdf Capture filter语法:http://www.Wireshark.org/docs/wsug_html_chunked/ChCapCaptureFilterSection.html Wireshark提供了display filter功能,该语法介绍如下:http://www.Wireshark.org/docs/wsug_html_chunked/ChWorkBuildDisplayFilterSection.html Wiki上对于GeoIP的说明:http://wiki.Wireshark.org/HowToUseGeoIP GeoIP的下载页面:http://dev.maxmind.com/geoip/legacy/downloadable/ 本文由网友李文博提供。希望大家加入我们,一起成长。

笔记本电池续航骤减25% 想省电千万别装Chrome!

$
0
0

如果你的笔记本电池经常偷偷“跑电”,我们建议你好好检查一下自己所安装的软件——尤其是浏览器,它们很可能就是电量提前耗尽的罪魁祸首。

《福布斯》杂志日前刊文指出,Windows版谷歌Chrome浏览器目前存在一个严重的、能极大加速损耗电池电量的问题——在多数情况下,该问题甚至可导致笔记本电脑减少25%的续航时间。

笔记本电池续航骤减25% 想省电千万别装Chrome!

Windows系统的核心有一个固定的“系统时脉”,通常情况下,这个周期是15.6毫秒,系统核心会在每秒钟询问处理器大约64次,以查看当前是否有任务需要执行。在系统没有向处理器发出请求的时候,处理器处于省电工作状态,频率、电压都会大大降低,这是笔记本节能技术的基本原理。

然而,透过工具可以发现,当Chrome处在运行状态时,电脑处理器会以每毫秒一次的频率收到频繁请求。换而言之,处理器过去每一秒只会被唤醒64次,而安装Chrome浏览器后,处理器每秒则会被唤醒1000次!这样以来,处理器的省电功能将形同虚设——不管有没有任务需要执行,它都会处于全速工作状态。

微软曾经表示,当系统时脉达到每周期1000毫秒时,能耗会最多增加能耗25%,这将大大缩短笔记本的续航时间。同时,改变系统时脉还会带来诸多其它问题,因为操作系统核心要统筹管理所有应用,不过,问题出现在系统层面,大多数用户很难发现这些问题。


一致性HASH算法

$
0
0

一致性 hash 算法( consistent hashing )

张亮

consistent hashing 算法早在 1997 年就在论文  Consistent hashing and random trees 中被提出,目前在cache 系统中应用越来越广泛;

1 基本场景

比如你有 N 个 cache 服务器(后面简称 cache ),那么如何将一个对象 object 映射到 N 个 cache 上呢,你很可能会采用类似下面的通用方法计算 object 的 hash 值,然后均匀的映射到到 N 个 cache ;

hash(object)%N

一切都运行正常,再考虑如下的两种情况;

1 一个 cache 服务器 m down 掉了(在实际应用中必须要考虑这种情况),这样所有映射到 cache m 的对象都会失效,怎么办,需要把 cache m 从 cache 中移除,这时候 cache 是 N-1 台,映射公式变成了 hash(object)%(N-1) ;

2 由于访问加重,需要添加 cache ,这时候 cache 是 N+1 台,映射公式变成了 hash(object)%(N+1) ;

1 和 2 意味着什么?这意味着突然之间几乎所有的 cache 都失效了。对于服务器而言,这是一场灾难,洪水般的访问都会直接冲向后台服务器;

再来考虑第三个问题,由于硬件能力越来越强,你可能想让后面添加的节点多做点活,显然上面的 hash 算法也做不到。

  有什么方法可以改变这个状况呢,这就是 consistent hashing...

2 hash 算法和单调性

   Hash 算法的一个衡量指标是单调性( Monotonicity ),定义如下:

  单调性是指如果已经有一些内容通过哈希分派到了相应的缓冲中,又有新的缓冲加入到系统中。哈希的结果应能够保证原有已分配的内容可以被映射到新的缓冲中去,而不会被映射到旧的缓冲集合中的其他缓冲区。

容易看到,上面的简单 hash 算法 hash(object)%N 难以满足单调性要求。

3 consistent hashing 算法的原理

consistent hashing 是一种 hash 算法,简单的说,在移除 / 添加一个 cache 时,它能够尽可能小的改变已存在 key 映射关系,尽可能的满足单调性的要求。

下面就来按照 5 个步骤简单讲讲 consistent hashing 算法的基本原理。

3.1 环形hash 空间

考虑通常的 hash 算法都是将 value 映射到一个 32 为的 key 值,也即是 0~2^32-1 次方的数值空间;我们可以将这个空间想象成一个首( 0 )尾( 2^32-1 )相接的圆环,如下面图 1 所示的那样。

circle space

图 1 环形 hash 空间

3.2 把对象映射到hash 空间

接下来考虑 4 个对象 object1~object4 ,通过 hash 函数计算出的 hash 值 key 在环上的分布如图 2 所示。

hash(object1) = key1;

… …

hash(object4) = key4;

object

图 2 4 个对象的 key 值分布

3.3 把cache 映射到hash 空间

Consistent hashing 的基本思想就是将对象和 cache 都映射到同一个 hash 数值空间中,并且使用相同的 hash算法。

假设当前有 A,B 和 C 共 3 台 cache ,那么其映射结果将如图 3 所示,他们在 hash 空间中,以对应的 hash 值排列。

hash(cache A) = key A;

… …

hash(cache C) = key C;

cache

图 3 cache 和对象的 key 值分布

 

说到这里,顺便提一下 cache 的 hash 计算,一般的方法可以使用 cache 机器的 IP 地址或者机器名作为 hash输入。

3.4 把对象映射到cache

现在 cache 和对象都已经通过同一个 hash 算法映射到 hash 数值空间中了,接下来要考虑的就是如何将对象映射到 cache 上面了。

在这个环形空间中,如果沿着顺时针方向从对象的 key 值出发,直到遇见一个 cache ,那么就将该对象存储在这个 cache 上,因为对象和 cache 的 hash 值是固定的,因此这个 cache 必然是唯一和确定的。这样不就找到了对象和 cache 的映射方法了吗?!

依然继续上面的例子(参见图 3 ),那么根据上面的方法,对象 object1 将被存储到 cache A 上; object2 和object3 对应到 cache C ; object4 对应到 cache B ;

3.5 考察cache 的变动

前面讲过,通过 hash 然后求余的方法带来的最大问题就在于不能满足单调性,当 cache 有所变动时, cache会失效,进而对后台服务器造成巨大的冲击,现在就来分析分析 consistent hashing 算法。

3.5.1 移除 cache

考虑假设 cache B 挂掉了,根据上面讲到的映射方法,这时受影响的将仅是那些沿 cache B 逆时针遍历直到下一个 cache ( cache C )之间的对象,也即是本来映射到 cache B 上的那些对象。

因此这里仅需要变动对象 object4 ,将其重新映射到 cache C 上即可;参见图 4 。

remove

图 4 Cache B 被移除后的 cache 映射

3.5.2 添加 cache

再考虑添加一台新的 cache D 的情况,假设在这个环形 hash 空间中, cache D 被映射在对象 object2 和object3 之间。这时受影响的将仅是那些沿 cache D 逆时针遍历直到下一个 cache ( cache B )之间的对象(它们是也本来映射到 cache C 上对象的一部分),将这些对象重新映射到 cache D 上即可。

 

因此这里仅需要变动对象 object2 ,将其重新映射到 cache D 上;参见图 5 。

add

图 5 添加 cache D 后的映射关系

4 虚拟节点

考量 Hash 算法的另一个指标是平衡性 (Balance) ,定义如下:

平衡性

  平衡性是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都得到利用。

hash 算法并不是保证绝对的平衡,如果 cache 较少的话,对象并不能被均匀的映射到 cache 上,比如在上面的例子中,仅部署 cache A 和 cache C 的情况下,在 4 个对象中, cache A 仅存储了 object1 ,而 cache C 则存储了object2 、 object3 和 object4 ;分布是很不均衡的。

为了解决这种情况, consistent hashing 引入了“虚拟节点”的概念,它可以如下定义:

“虚拟节点”( virtual node )是实际节点在 hash 空间的复制品( replica ),一实际个节点对应了若干个“虚拟节点”,这个对应个数也成为“复制个数”,“虚拟节点”在 hash 空间中以 hash 值排列。

仍以仅部署 cache A 和 cache C 的情况为例,在图 4 中我们已经看到, cache 分布并不均匀。现在我们引入虚拟节点,并设置“复制个数”为 2 ,这就意味着一共会存在 4 个“虚拟节点”, cache A1, cache A2 代表了cache A ; cache C1, cache C2 代表了 cache C ;假设一种比较理想的情况,参见图 6 。

virtual nodes

图 6 引入“虚拟节点”后的映射关系

 

此时,对象到“虚拟节点”的映射关系为:

objec1->cache A2 ; objec2->cache A1 ; objec3->cache C1 ; objec4->cache C2 ;

因此对象 object1 和 object2 都被映射到了 cache A 上,而 object3 和 object4 映射到了 cache C 上;平衡性有了很大提高。

引入“虚拟节点”后,映射关系就从 { 对象 -> 节点 } 转换到了 { 对象 -> 虚拟节点 } 。查询物体所在 cache 时的映射关系如图 7 所示。

map

图 7 查询对象所在 cache

 

“虚拟节点”的 hash 计算可以采用对应节点的 IP 地址加数字后缀的方式。例如假设 cache A 的 IP 地址为202.168.14.241 。

引入“虚拟节点”前,计算 cache A 的 hash 值:

Hash(“202.168.14.241”);

引入“虚拟节点”后,计算“虚拟节”点 cache A1 和 cache A2 的 hash 值:

Hash(“202.168.14.241#1”);  // cache A1

Hash(“202.168.14.241#2”);  // cache A2

5 小结

Consistent hashing 的基本原理就是这些,具体的分布性等理论分析应该是很复杂的,不过一般也用不到。

http://weblogs.java.net/blog/2007/11/27/consistent-hashing 上面有一个 java 版本的例子,可以参考。

http://blog.csdn.net/mayongzhan/archive/2009/06/25/4298834.aspx 转载了一个 PHP 版的实现代码。

http://www.codeproject.com/KB/recipes/lib-conhash.aspx C语言版本

 

 

一些参考资料地址:

http://portal.acm.org/citation.cfm?id=258660

http://en.wikipedia.org/wiki/Consistent_hashing

http://www.spiteful.com/2008/03/17/programmers-toolbox-part-3-consistent-hashing/

  http://weblogs.java.net/blog/2007/11/27/consistent-hashing

http://tech.idv2.com/2008/07/24/memcached-004/

http://blog.csdn.net/mayongzhan/archive/2009/06/25/4298834.aspx

 



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



Adobe与Google共同推出一款开源中日韩文字体

$
0
0

Adobe 和 Google 共同发布了一款针对中文、日文、韩文的开源字体,包括 65535 个象形文字,是目前东亚文字最大的字体之一。目前这款字体在 Google Fonts 和 Adobe 字体库已经可以免费获取。

两公司市场部门出于不同的考虑,对这款字体的命名不同,Adobe 称之为 Source Han Sans,而 Google 把它作为 Noto Pan-Unicode的一部分,叫它 Noto Sans CJK(CJK:Chinese, Japanese, Korean)。

这款字体总大小有 19MB,包括 7 种粗细,支持简体中文、繁体中文、日语、韩语、希腊字母、拉丁字母以及西里尔字母。


这款字体的开发过程持续了 4 年,除了 Adobe 和 Google 之外,还有来自中国、日本、韩国的字体开发公司参与。设计的最初阶段由 Adobe 负责,后来 Google 也参与到字体的具体设计,并且承担了第二阶段的主要费用。

字体的主设计师是来自日本的 Adobe 设计师 Ryoko Nishizuka,参与项目的工作人员有 100 人。服务的人群可以达到 15 亿人,占到了世界总人口的近 1/4。由于字体是开源且免费的,用户还有权修改它,例如增加越南文字等。


(图:设计师手稿)

Adobe 做开源字体貌似有点不寻常,它希望利用这款字体优化自家的设计软件;而 Google 会把这款字体用于 Google 产品和开发者社区。

[本文参考以下来源: thenextweb.com]

本文链接

kafka集群安装

$
0
0

 


kafka是LinkedIn开发并开源的一个分布式MQ系统,现在是Apache的一个孵化项目。在它的主页描述kafka为一个高吞吐量的分布式(能将消息分散到不同的节点上)MQ。在这片博文中,作者简单提到了开发kafka而不选择已有MQ系统的原因。两个原因:性能和扩展性。Kafka仅仅由7000行Scala编写,据了解,Kafka每秒可以生产约25万消息(50 MB),每秒处理55万消息(110 MB)。


Kafka版本:0.8.0

约定:安装3台虚拟机

官网:http://kafka.apache.org/
官方文档:http://kafka.apache.org/documentation.html#quickstart


下载解压

# wget http://mirrors.hust.edu.cn/apache/kafka/0.8.0/kafka-0.8.0-src.tgz
# tar xzf kafka-0.8.0-src.tgz
# cd kafka-0.8.0-src

Kafka是用Scala写的,SBT是Simple Build Tool的简称,如果读者使用过Maven,那么可以简单将SBT看做是Scala世界的Maven,虽然二者各有优劣,但完成的工作基本是类似的。
## Building it ##
# ./sbt update
# ./sbt package
# ./sbt assembly-package-dependency

以上每一步完成就会提醒[Success]

例如:[success] Total time: 21 s, completed 2014-2-11 10:29:55



集群环境需要修改配置文件

# vim config/server.properties

brokerid:这个每个server(broker)必须唯一,写数字

hostname:这个也是唯一的,写服务器IP即可



    ############################# Server Basics ############################# 
     
    # The id of the broker. This must be set to a unique integer for each broker. 
    broker.id=3 
     
    ############################# Socket Server Settings ############################# 
     
    # The port the socket server listens on 
    port=9092 
     
    # Hostname the broker will bind to and advertise to producers and consumers. 
    # If not set, the server will bind to all interfaces and advertise the value returned from 
    # from java.net.InetAddress.getCanonicalHostName(). 
    #host.name=localhost 
    host.name=192.168.2.111 

还有就是zookeeper.connect也要配置


    zookeeper.connect=192.168.19.218:2181,192.168.19.217:2181,192.168.19.214:2181 

关于zookeeper的安装可以参考此文:ZooKeeper集群环境安装与配置

其他默认配置即可。


启动Kafka服务

# /usr/kafka-0.8.0-src/bin/kafka-server-start.sh /usr/kafka-0.8.0-src/config/server.properties

创建Topic
# /usr/kafka-0.8.0-src/bin/kafka-create-topic.sh --zookeeper localhost:2181 --partition 1 --topic test
查看Topic
# /usr/kafka-0.8.0-src/bin/kafka-list-topic.sh --zookeeper localhost:2181
输出:

topic: test     partition: 0    leader: 1       replicas: 1     isr: 1

说明:
partiton: partion id,由于此处只有一个partition,因此partition id 为0
leader:当前负责读写的lead broker id
relicas:当前partition的所有replication broker  list
isr:relicas的子集,只包含出于活动状态的broker


producer发送消息
# /usr/kafka-0.8.0-src/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test
This is a message
This is another message

consumer接收消息
# /usr/kafka-0.8.0-src/bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic test --from-beginning


注意,如果上述命令不能发送接收消息说明没有配置host,可以直接用ip

producer发送消息
# /usr/kafka-0.8.0-src/bin/kafka-console-producer.sh --broker-list 192.168.19.218:9092 --topic test

consumer接收消息
# /usr/kafka-0.8.0-src/bin/kafka-console-consumer.sh --zookeeper 192.168.19.218:2181 --topic test --from-beginning

如果要最新的数据,可以不带--from-beginning参数即可。

# /usr/kafka-0.8.0-src/bin/kafka-console-consumer.sh --zookeeper 192.168.19.218:2181 --topic test

 

 



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



花荣爆破点技术完整总结

$
0
0

爆破点分析及把握技术是最有效的短线技术,常见的股价爆破点有两类,1、时间爆破点:长假日前后、季度底、报表公布期和预告期、重要股东大会表决、重要承偌时间点、行政审批进程、制度价格触碰时间、除权前一日、制度到期前日、重要成份股更换品种日、事件联动题材(IPO影子等)、期货商品先导、突发题材;2、技术爆破点:连续放量、暴跌、生命线、均线纠集、筹码集中股异动、强势中冷门量比突出、因强势大盘短线突然调整的射击线、尾市单笔急挫、强势调整中筹码集中股、强势中的开盘价量合适股。谁有爆破点补充请写在评论区中,谁愿意开个每日爆破点展望微博专栏我愿意每日转发并与之交流讨论。


  青春就应该这样绽放   游戏测试:三国时期谁是你最好的兄弟!!   你不得不信的星座秘密

kafka开发实例

$
0
0

 

 

1.启动kafka。

//启动zookeeper server (用&是为了能退出命令行):
bin/zookeeper-server-start.sh config/zookeeper.properties  &
//启动kafka server: 
bin/kafka-server-start.sh config/server.properties  &

2.新建一个生产者例子

import java.util.Properties;
 
import kafka.javaapi.producer.Producer;
import kafka.producer.KeyedMessage;
import kafka.producer.ProducerConfig;
 
public class KafkaTest {
    public static void main(String[] args) { 
        Properties props = new Properties(); 
        props.put("zk.connect", "10.103.22.47:2181"); 
        props.put("serializer.class", "kafka.serializer.StringEncoder"); 
        props.put("metadata.broker.list", "10.103.22.47:9092");
        props.put("request.required.acks", "1");
        //props.put("partitioner.class", "com.xq.SimplePartitioner");
        ProducerConfig config = new ProducerConfig(props); 
        Producer<String, String> producer = new Producer<String, String>(config); 
        String ip = "192.168.2.3";
        String msg ="this is a messageuuu!";
        KeyedMessage<String, String> data = new KeyedMessage<String, String>("test", ip,msg); 
        producer.send(data);
        producer.close(); 
    } 
 
}

3.新建一个消费者例子

import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
import kafka.consumer.Consumer;
import kafka.consumer.ConsumerConfig;
import kafka.consumer.KafkaStream;
import kafka.javaapi.consumer.ConsumerConnector;
import kafka.message.Message;
import kafka.message.MessageAndMetadata;
 
 
public class ConsumerSample {
 
    public static void main(String[] args) { 
        // specify some consumer properties 
        Properties props = new Properties(); 
        props.put("zookeeper.connect", "10.103.22.47:2181"); 
        props.put("zookeeper.connectiontimeout.ms", "1000000"); 
        props.put("group.id", "test_group"); 
 
            // Create the connection to the cluster 
        ConsumerConfig consumerConfig = new ConsumerConfig(props); 
        ConsumerConnector connector = Consumer.createJavaConsumerConnector(consumerConfig); 
 
 
        Map<String,Integer> topics = new HashMap<String,Integer>(); 
        topics.put("test", 2); 
        Map<String, List<KafkaStream<byte[], byte[]>>> topicMessageStreams = connector.createMessageStreams(topics); 
        List<KafkaStream<byte[], byte[]>> streams = topicMessageStreams.get("test");
        ExecutorService threadPool = Executors.newFixedThreadPool(2); 
        for (final KafkaStream<byte[], byte[]> stream : streams) { 
            threadPool.submit(new Runnable() { 
                public void run() { 
                    for (MessageAndMetadata msgAndMetadata : stream) { 
                        // process message (msgAndMetadata.message()) 
                        System.out.println("topic: " + msgAndMetadata.topic()); 
                        Message message = (Message) msgAndMetadata.message(); 
                        ByteBuffer buffer = message.payload(); 
                        byte[] bytes = new byte[message.payloadSize()]; 
                        buffer.get(bytes); 
                        String tmp = new String(bytes); 
                        System.out.println("message content: " + tmp); 
                    } 
                } 
            }); 
        }   
    }
}



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



北京法院全面公开审判流程 防止以案谋私

$
0
0
中新网北京7月16日电为监督法官依法办案,防止以案谋私,北京市高级人民法院16日宣布,从即日起,法院立案、审理、执行、审限、结案等五大类93项审判流程信息进行全面公开。北京市高院副院长王明达在今天举行的司法公开新闻发布会上表示,除涉及国家秘密、未成年人犯罪、个人隐私,以及其他不适宜公开的案件外,所有符合条 ......

机器学习最佳入门学习资料汇总

$
0
0

这篇文章的确很难写,因为我希望它真正地对初学者有帮助。面前放着一张空白的纸,我坐下来问自己一个难题:面对一个对机器学习领域完全陌生的初学者,我该推荐哪些最适合的库,教程,论文及书籍帮助他们入门?

资源的取舍很让人纠结,我不得不努力从一个机器学习的程序员和初学者的角度去思考哪些资源才是最适合他们的。

我为每种类型的资源选出了其中最佳的学习资料。如果你是一个真正的初学者,并且有兴趣开始机器学习领域的学习,我希望你能在其中找到有用的东西。我的建议是,选取其中一项资源,一本书,或者一个库,从头到尾的读一边,或者完成所有的教程。选定一个后坚持学习,等到完全掌握以后,再选取另一个资源按同样的方法学习。现在开始吧。

程序库

我信奉这么一句话:学到一定程度后,你需要开始尝试做事。这就是我怎么学会编程的,并且我确信其他大部分的人也是这么学会的。要知道自己的极限,激发自己的能量。如果你知道怎么编程,你就能快速深入到机器学习的学习中。然后制定一个计划,在你实现一个工程系统前学习完这项技术相关的数学知识。

找一个库,先阅读其文档,然后就可以照着指南尝试做一些事情了。以下是最优秀的机器学习库开源代码。我并不认为这些库适用于你的工程项目,但是它们非常适合学习,开发及建模。

先选择一个你熟悉的语言对应的库,然后再尝试其他更功能强大的库。如果你是个很好的程序员,你应该知道你可以很容易的从一种语言切换到另一种语言。程序逻辑都是一样的,只是语法和API的区别而已。

R Project for Statistical Computing(用于统计计算的R工程):这是一个软件环境,采用类lisp脚本语言。提供了你想要的所有统计相关的东西,包括非常赞的绘图。CRAN(第三方机器学习包)的 机器学习分类下有该领域专家们编写的代码,最新的接口方法和其他你能想到的功能都可以在上面找到。如果你想快速建模并开发,R工程是必学的。不过你不一定从一开始就从这个工程学起。

WEKA:数据挖掘平台,提供了API,一些命令行及整个数据挖掘生命周期的图像化用户接口。你可以准备数据,进行可视化开发,创建分类、回归、集群模型和很多内嵌及第三方组件提供的算法。如果你需要基于Hadoop平台工作,那么Mahout就是一个很好的机器学习java框架,这个框架和和WEKA不相关。但如果你是大数据和机器学习的新手,那么还是坚持看WEKA,记得一次只学一样东西。

Scikit Learn:机器学习Python库,依赖Numpy和Scipy库。如果你是Python或者Ruby程序员,这个库比较合适。该库接口友好,功能强大,且有完善的文档支持。如果你想尝试其他东西,那么 Orange将是一个不错的选择。

Octave:如果你熟悉MatLab或者你是Numpy程序员且正尝试寻找一些不一样的东西,那么可以考虑Octave。它提供了跟Matlab相似的数据计算环境,并且可以很简单的通过编程解决线性及非线性的问题,这些问题是大部分机器学习算法的基础。如果你有工程师背景,你可以从这里开始学起。

BigML:可能你不想做任何的编程,那么你可以全部使用工具,比如WEKA。你还可以更深一步并使用像BigML一样的服务,BigML提供了web版的机器学习接口,开发及创建模型可以全部在浏览器上完成。

选取其中一个平台用于机器学习的实战练习。不要只是看,要做。

视频课程

现在很流行通过观看视频来学习机器学习。我在YouTube和VideoLectures.Net上看了很多机器学习的视频,看视频的风险在于你很容易只是看而不会去实践。我建议在看视频的时候一定要做好笔记,即便之后你很快就会把笔记扔掉。同时建议你不管在学什么,一定要去动手尝试。

坦白来说,我看过的视频中,没有哪个视频是特别适合初学者的,我指真正的初学者。他们都是基于读者有最基本的线性代数和概率理论知识的假设。斯坦福大学Andrew Ng 的教程可能是最适合用于入门的了,另外,我推荐了一些一次性视频。

Stanford Machine Learning(斯坦福机器学习):通过Coursera可以获取到,Andrew Ng主讲。除了招生,你可以在任何时间看到所有的课程,并且从 Stanford CS229 course(斯坦福CS229课程)上下载到所有的讲义和课堂笔记。课程包括家庭作业,测试。课程集中在线性代数上,使用Octave环境。

Caltech Learning from Data:可以在edX访问到,Yaser Abu-Mostafa主讲。所有的课程和材料在 CalTech网站上都可以获取到。和斯坦福课程一样,你可以按你自己的节奏来完成家庭作业和任务。它覆盖了和斯坦福类似的课程,然后在细节上有一些深入,并且用了更多的数学方面的知识。家庭作业对初学者来说可能太难了。

Machine Learning Category on VideoLectures.Net(VideoLectures.Net上的机器学习分类):初学者很容易沉溺于海量的内容中。你可以找寻一些看起来比较有趣的视频,然后尝试看看。如果不是你现阶段能看懂的,就先放放。如果你看着合适,就记笔记。我发现我自己总是不断的找寻自己感兴趣的标签,然后最终选择了完全不同的标签。当然,看看该领域专家真正是什么样的也挺好的。

“Getting In Shape For The Sport Of Data Science” – Talk by Jeremy Howard:和一个本土R用户团队关于机器学习实践应用的对话,这个团队在机器学习竞赛中获取了很好的成绩。这个视频很有用,因为很少有人去讲将机器学习应用到一个项目中真正是什么样的,及怎么去做这个项目。我幻想着能创建一个网络真人TV秀,这样可以能直接看到选手机器学习竞赛中的表现。我是多么的向往啊。

论文概述

如果你不习惯读研究性论文,你将会发现他们的语言非常枯燥。论文像是教科书的片段,但是论文描述了实验,或者是该领域其他前沿研究。不过,如果你正要开始学习机器学,这里有一些论文可能会引起你的兴趣。

The Discipline of Machine Learning(机器学习的原则):机器学习原则定义的白皮书,作者Tom Mitchell. 当时有一场辩论,Mitchell最终说服CMU主席成立单独的机器学习机构,以保证机器学习将在今后的100年里作为一个学科存在。(也可参考短片Tom Mitchell访谈)。

A Few Useful Things to Know about Machine Learning(一些你必须知道的关于机器学习的事):这是一篇好论文,因为它不拘泥于特定的算法,而是偏向于比如特征选取概述和模型简化这些重要的问题上。走对方向并且从一开始就想清楚,都是很好的事情。

上面我只罗列了两篇重要的论文,因为读论文会真的让你陷入困境。

机器学习初学者书籍

市面上有很多机器学习的书,但很少有针对初学者编写的。什么才是真正的初学者?可能是从其他领域转入机器学习的,也可能是从计算机科学,软件编程或者统计学转入的。即使这样,大部分的书籍都会认为你至少已经有了线性代数和概率论的知识背景。

然而,这里还是有一些书鼓励有兴趣的程序员从一个最小的算法开始学习,指定工具和库,这样编程人员就可以运行程序并得出结果。最著名的有Programming Collective Intelligence(中文版:《集体智慧编程》)、Machine Learning for Hackers(中文版《机器学习:实用案例解析》)和Data Mining: Practical Machine Learning Tools and Techniques(中文版《数据挖掘:实用机器学习技术》),以上三本分别基于Python,R和Java三种语言。如果有不懂的地方,可以参见这三本书。

[![Books for Machine Learning Beginners](http://machinelearningmastery.com/wp- content/uploads/2013/11/photo-300x225.jpg)](http://machinelearningmastery.com /wp-content/uploads/2013/11/photo.jpg)

Programming Collective Intelligence(中文版:《集体智慧编程》):创建精巧的web 2.0应用:这本书是专门为编程人员写的,轻理论,重实战,有大量的代码示例,实际上遇到的web问题及对应的解决方案。买这本书的读者,建议边读边做练习!

Machine Learning for Hackers(中文版:《机器学习:使用案例解析》):我建议在读完Programming Collective Intelligence以后再来读这本书。该书同样提供了大量的实用性很强的案例。但是它有更多数据分析的东西并且使用R语言。我真心喜欢这本书。

Machine Learning: An Algorithmic Perspective:这本书像是Programming Collective Intelligence的升级版。这两本书的目标相同(帮助程序员入门),但是这本书包含了数学和参考文献,同时也有用Python写的示例和代码片段。我建议读者先看Programming Collective Intelligence,如果看完以后还有兴趣,再来看这本书。

Data Mining: Practical Machine Learning Tools and Techniques, Third Edition(中文版:《数据挖掘:实用机器学习技术》):实际上我是从这本书开始学起的,2000年的第一版。当时我还是个java程序员,由于WEKA库提供了很好的开发环境,我利用这本书结合WEKA库进行尝试,用自己的算法做了插件并作了大量的机器学习应用,同时延伸到数据挖掘部分。因此我强力推荐这本书和这种学习方法。

Machine Learning(中文版:《机器学习》):这本书比较老,包含了公式和很多的参考文献。虽然是本教科书,但是每个算法的实用性依然非常强。

很多人能列举出很多优秀的机器学习教科书,我也可以。这些书的确很棒,只是个人觉得对初学者来说不太好入门而已。

扩展阅读

这篇文章经过我仔细推敲,为了确保自己没有漏掉任何一点重要的东西,我同时也看了其他人列出的资源。为了使内容更全面,这里再列出一些网上其他优秀的机器学习入门资源列表。

A List of Data Science and Machine Learning Resources:很详细的资源列表,花点时间读读作者的建议,再看看其中的链接。很值得一看。

What are some good resources for learning about machine learning? Why?:这个问答的第一个答案很不错,每次读我都会做笔记并打上标签。这个答案里面最有价值的部分是机器学习课程的笔记列表及Q&A页面的相关文章列表。

Overwhelmed by Machine Learning: is there an ML101 book?:一个StackOverflow上的帖子,上面确实列出了很多推荐的机器学习书籍列表,第一个回帖的是Jeff Moser,罗列了很多课程视频和谈话。

你是否已经看过或者用过这些资源呢?你觉得怎么样?

我不知道我是否为有兴趣学习机器学习的程序员提供了真正有用的资源,有任何问题和建议,请留下宝贵留言!

译者: teyla 原作者:Jasonb
本文转载自: 译言网


Oracle 如何释放数据库空间

$
0
0

        当需要释放数据库空间的时候,通常的方案会用有truncate、delete、drop/re-creating等处理。其中truncate 后会立即释放,并且不能回滚;但delete不能立即释放数据库空间,还会产生archive log。下面就简单介绍一下:

 

    如: Truncate table xxxx; 我们可以直接去查user_segments对应table的bytes就变小,数据库空间释放,并且不能回滚。用Truncate去删除记录比drop表再创建表效率更高。

 

Use the  TRUNCATE statement to remove all rows from a table or cluster. By default, Oracle Database also deallocates all space used by the removed rows except that specified by the  MINEXTENTS storage parameter and sets the  NEXT storage parameter to the size of the last extent removed from the segment by the truncation process.

Removing rows with the  TRUNCATE statement can be more efficient than dropping and re-creating a table. Dropping and re-creating a table invalidates dependent objects of the table, requires you to regrant object privileges on the table, and requires you to re-create the indexes, integrity constraints, and triggers on the table and respecify its storage parameters. Truncating has none of these effects.

 

      Delete操作后,不能立即释放数据库空间,并且还会产生archive log(查看user_segments大小没有变化),需要做其他操作。如Oracle 10g, 11可以用下面操作来释放数据库空间。

      alter table table_name shrink space cascade;

      如果报ora-10636 row movement is not enabled,先执行下面语句:

      alter table table_name enable row movement;

 

 

 

(由于是个人的一些理解,主要是总结一下,如有不对,欢迎指正)



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



(转)jrebel使用

$
0
0

From: http://truemylife.iteye.com/blog/1140921

 

背景与愿景:开发环境下,tomcat对热布署的支持还不够全面,致使开发人员浪费大量时间在重起服务上。为了提高开发效率,决定引入Jrebel,它对热布署的支持相对比较全面。虽然Jrebel官方号称使用它不存在内存泄漏问题,但是占用一定的资源是肯定的,因此不考虑在正式环境下使用热布署。Jrebel实际上支持非常多中间件,除了Tomcat还包括Jetty、Resin、Weblogic等等,从理论上来讲,他跟中间件也没什么关系,但实际配置的时候还是会根据中间件有所不同,具体可以上官网查看,本文要讲的是tomcat+ eclipse+ spring+ struts2+ maven的环境。在使用Jrebel后,我们期望看到开发人员早上开机启动一次tomcat后就够了。本文的前置文章m2eclipse+tomcat实现应用布署,点击进入 http://truemylife.iteye.com/blog/1669031

使用场景:Tomcat对热布署的使用场景是Servlet+JSP+JaveBean。如果项目含有其他框架时,其热布署效果就会大大降低,在与同事一同测试观察后发现:tomcat6在spring+struts框架下的项目,对java文件修改后的成功热布署概率偏低。由于概率太低,而且有无热布署成功不能确定,大部分开发人员修改类后不管什么情况直接选择重起,长此以往,浪费的时间积累起来不在少数。下面把tomcat和jrebel对热布署测试结果对比一下:

 

对比项

Jrebel

Tomcat

Class文件

绝大部分能热布署

小部分能热布署

Spring支持

改成用注释的方式后,可支持

不支持

Struts配置文件

支持

支持

页面相关文件

支持

支持

从对比可以看到,Jrebel最大的提升是对java类修改时,热布署大大提高;而对spring的支持实际上还是有限的,需要把IoC的实现改成使用注释的方式,而不能是配置的方式。如果你的工程的Spring已经是注释的方式,那就比较顺利,装好插件后,绝大部分情况下都能使用热布署了。如果你不是使用注释方式,那就麻烦了,要么全都改成注释方式,要么Jrebel对spring作用有限,看你自己的选择了。下面把已知Jrebel不能成功的热布署的情况作一列举:

1、替换了父类。

2、增加或删除了继承的接口。

3、Spring布署文件修改(如果改成注释方式,实际上spring只剩个别固定的第三方包的beans描述,比如数据库链接等)

4、web.xml,虽然jrebel和tomcat都支持web.xml修改的热布署,但是如果项目比较复杂,初始化工作较多的话,还是直接重起吧,直接热布署意义不大,而且重复初始化对于某些业务来说是会报错,所以建议有较复杂的初始化项目来说,还是直接重起得了。

 

Jrebel安装和使用

 

1、jrebel是商用软件,而且价格不扉,去下载个破解版吧,最新的破解版是4.0,如果网上找不到,请留下邮件。下载jrebel.jar到本地,比如放在d:\jrebel.jar

2、Eclipse window->preference->tomcat->JVM Settings,加入以下参数

-Drebel.spring_plugin=true 支持spring框架

-Drebel.aspectj_plugin=true 支持aspectj

-Drebel.struts2_plugin=true 支持strut2

-javaagent:D:\jrebel.jar 这里自行修改jrebel.jar正确的路径

-noverify

如果你要支持更多的框架,可以参考官网http://www.zeroturnaround.com/jrebel/features/frameworks/

如果你要了解更多的参数配置,可以参考官网

http://www.zeroturnaround.com/jrebel/configuration/

    jrebel支持监控多个目录下的classes、配置文件、jar包是否被修改,因此建议新建并配置rebel.xml文件,如果Eclipse安装了官网的jrebel plugin,那么可以从eclipse菜单里产生rebel.xml文件。以下是rebel.xml的简单手动配置:

<?xml version= "1.0" encoding= "UTF-8"?>

<application

  xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"

  xmlns= "http://www.zeroturnaround.com"

  xsi:schemaLocation= "http://www.zeroturnaround.com/alderaan/rebel-2_0.xsd">

  <classpath>

    <dir name= "E:\projects\cmac\target\classes"/>

    <dir name= "E:\projects\cmac\target\test-classes"/>

  </classpath>

  <web>

    <link target= "/">

      <dir name= "E:\projects\cmac\src\main\webapp"/>

    </link>

  </web>

</application>

rebel.xml更详细配置说明参考官网( http://www.zeroturnaround.com/jrebel/configuration/)

3、此时启动tomcat,会发现如下错误信息

严重: Exception starting filter Struts2

java.lang.NoClassDefFoundError: Lorg/apache/velocity/app/VelocityEngine;

         at java.lang.Class.getDeclaredFields0(Native Method)

         at java.lang.Class.privateGetDeclaredFields(Class.java:2291)

         at java.lang.Class.getDeclaredFields(Class.java:1743)

         at com.opensymphony.xwork2.inject.ContainerImpl.addInjectors(ContainerImpl.java:102)

         at com.opensymphony.xwork2.inject.ContainerImpl$1.create(ContainerImpl.java:84)

         at com.opensymphony.xwork2.inject.ContainerImpl$1.create(ContainerImpl.java:82)

         at com.opensymphony.xwork2.inject.util.ReferenceCache$CallableCreate.call(ReferenceCache.java:155)

         at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)

         at java.util.concurrent.FutureTask.run(FutureTask.java:138)

         at com.opensymphony.xwork2.inject.util.ReferenceCache.internalCreate(ReferenceCache.java:81)

         at com.opensymphony.xwork2.inject.util.ReferenceCache.get(ReferenceCache.java:121)

         at com.opensymphony.xwork2.inject.ContainerImpl$ConstructorInjector.<init>(ContainerImpl.java:333)

         at com.opensymphony.xwork2.inject.ContainerImpl$5.create(ContainerImpl.java:299)

         at com.opensymphony.xwork2.inject.ContainerImpl$5.create(ContainerImpl.java:298)

         at com.opensymphony.xwork2.inject.util.ReferenceCache$CallableCreate.call(ReferenceCache.java:155)

         at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)

         at java.util.concurrent.FutureTask.run(FutureTask.java:138)

         at com.opensymphony.xwork2.inject.util.ReferenceCache.internalCreate(ReferenceCache.java:81)

         at com.opensymphony.xwork2.inject.util.ReferenceCache.get(ReferenceCache.java:121)

         at com.opensymphony.xwork2.inject.ContainerImpl.getConstructor(ContainerImpl.java:578)

         at com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:476)

         at com.opensymphony.xwork2.inject.ContainerImpl$7.call(ContainerImpl.java:517)

         at com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:565)

         at com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:515)

         at com.opensymphony.xwork2.config.impl.LocatableFactory.create(LocatableFactory.java:32)

         at com.opensymphony.xwork2.inject.ContainerBuilder$4.create(ContainerBuilder.java:135)

         at com.opensymphony.xwork2.inject.Scope$2$1.create(Scope.java:49)

         at com.opensymphony.xwork2.inject.ContainerImpl$ParameterInjector.inject(ContainerImpl.java:447)

         at com.opensymphony.xwork2.inject.ContainerImpl.getParameters(ContainerImpl.java:462)

         at com.opensymphony.xwork2.inject.ContainerImpl.access$000(ContainerImpl.java:48)

         at com.opensymphony.xwork2.inject.ContainerImpl$MethodInjector.inject(ContainerImpl.java:288)

         at com.opensymphony.xwork2.inject.ContainerImpl$2.call(ContainerImpl.java:117)

         at com.opensymphony.xwork2.inject.ContainerImpl$2.call(ContainerImpl.java:115)

         at com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:558)

         at com.opensymphony.xwork2.inject.ContainerImpl.injectStatics(ContainerImpl.java:114)

         at com.opensymphony.xwork2.inject.ContainerBuilder.create(ContainerBuilder.java:495)

         at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:170)

         at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:55)

         at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:371)

         at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:424)

         at org.apache.struts2.dispatcher.FilterDispatcher.init(FilterDispatcher.java:213)

         at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:273)

         at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:254)

         at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:372)

         at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:98)

         at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4562)

         at org.apache.catalina.core.StandardContext$2.call(StandardContext.java:5240)

         at org.apache.catalina.core.StandardContext$2.call(StandardContext.java:5235)

         at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)

         at java.util.concurrent.FutureTask.run(FutureTask.java:138)

         at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)

         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)

         at java.lang.Thread.run(Thread.java:619)

Caused by: java.lang.ClassNotFoundException: org.apache.velocity.app.VelocityEngine

         at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1676)

         at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1521)

         at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:316)

         ... 53 more

竟然报出需要velocity相关包,那好吧,我的项目是用maven来做管理的,在pom.xml里加上相关依赖如下:

<dependency>

    <groupId>org.apache.velocity</groupId>

    <artifactId>velocity</artifactId>

    <version>1.7</version>

    </dependency>

    <dependency>

    <groupId>org.apache.velocity</groupId>

    <artifactId>velocity-tools</artifactId>

    <version>2.0</version>

</dependency>

再次重起tomcat后,一切正常,可以看到jrebel关键信息在console里输出:

JRebel: Directory 'E:\projects\cmac\target\classes' will be monitored for changes.

JRebel: Directory 'E:\projects\cmac\target\test-classes' will be monitored for changes.

JRebel: Directory 'E:\projects\cmac\src\main\webapp' will be monitored for changes.

4、如果你使用maven发布并启动tomcat,那么需要安装jrebel-maven-plugin。本文前面提到只是满足开发阶段而且启动tomcat方式不是使用mvn命令方式,因此不需要安装jrebel-maven-plugin。

 

Spring利用注释方式实现IoC

    现在大部分java项目有使用Spring框架,为了能使Jrebel更好的对Spring相关资源发生热布署作用,就得充分使用注释的方式实现依赖注入。这里对Spring实现注释方式作一下最简单的介绍,首先在applicationContext.xml里配置如下两行代码:

<context:annotation-config/> 

<context:component-scan base-package= "*"/>

简单的说,以上的配置让spring支持了我们将要实现的注释依赖注入。以下以登录为实例,按action层、业务层、数据库操作层、PO层分别新建四个类:

LoginAction.java//struts action

UserServiceImpl.java//business layer

UserDaoImpl.java//dao layer

User.java //pojo

那么怎样通过注释方式进行调用的呢,首先给要被调用的类加上@Component注释,Spring为了区分不同层次的类,分别定义了以下四种注释

@Reposity

@Service

@Controller

@Component

目前阶段这四个注释实际上效果是一样的,我们约定如下:PO类如有需要使用@Reposity注释;Dao和Service使用@Service注释;Action使用@Controller注释;剩余分不出层次的类使用@Component注释。

如本例,action、service、dao分别加上注释

@Scope("prototype")

@Controller("loginAction")

public class LoginAction extends BaseAction{

}

@Service("userService")

public class UserServiceImpl implements UserService{

}

@Service("userDao")

public class UserDaoImpl extends BaseDao implements UserDao{

}

Scope注释默认是singleton,可以缺省。使用这四个标签时,如果不使用参数值,那么spring会按自己规范取名,比如LoginAction,使用@Controller()注释,默认取名为loginAction。取好了名,相当于在配置文件里配置了一组bean,接下来看怎么注入依赖,比如LoginAction要调用UserService,代码片段如下:

@Scope("prototype")

@Controller("loginAction")

public class LoginAction extends BaseAction{

@Autowired

Private UserService userService

}

就这么简单,添加xwork.xml配置,新加跳转页面,这些操作统统不用重起服务。

 

弹出Continue or Terminate疑问

    装上jrebel后,可以进入你的tomcat/conf/context.xml或server.xml,其中有一个参数reload=true,把它改成false。表示关闭tomcat自身的热布署,在eclipse里启动tomcat,修改了类,有时还是会弹出Continue or Terminate框,难道是个Bug?不得而知。不过有jrebel在不用担心,继续continue,会发现你的修改是有效的。只有碰到前面提到的不适合jrebel热布署的场景时,即使没弹出Continue or Terminate提示框,你也要自己重起服务。

 

Jrebel官方对热布署支持的场景列表(查看官网说明http://www.zeroturnaround.com/jrebel/features/)

 

Java EE Support

Jrebel

JVM Hot Swap

Time to reload

< 1s

< 1s

No memory leak

YES

YES

 

Changes to method bodies

YES

YES

Adding/removing Methods

YES

NO

Adding/removing constructors

YES

NO

Adding/removing fields

YES

NO

Adding/removing classes

YES

NO

Adding/removing annotations

YES

NO

Changing static field value

YES JRebel 3.0+

NO

Adding/removing enum values

YES JRebel 3.0+

NO

Changing interfaces

YES

NO

Replacing superclass

NO

NO

Adding/removing implemented interfaces

NO

NO

 

Skip builds for WAR directories

YES

YES

Skip builds for .WAR/.EAR class updates

YES

YES

Skip builds for .WAR/.EAR resource updates

YES

NO

Map multiple source dirs to one .WAR/.EAR target dir

YES

NO

Map classes and resources with include/exclude patterns

YES

NO

Map multiple source dirs with Ant-style patterns

YES

NO

Use system properties to make mapping machine-independent

YES

NO

Maven plugin

YES

NO

JSP EL changes

YES

NO

JSP Scriptlet changes

YES Enterprise Add-on

NO

EJB 1.x session bean interface changes

YES Enterprise Add-on

NO

EJB 2.x session bean interface changes

YES Enterprise Add-on

NO

EJB 3.x session bean interface changes

YES JRebel 3.0+

NO

JSF changes (Mojarra)

YES JRebel 3.0+

NO

JPA changes (Hibernate, EclipseLink, TopLink, OpenJPA)

YES JRebel 3.0+

NO

CDI changes (Weld)

YES JRebel 3.0+

NO

ResourceBundle

YES

NO

Spring Framework 2.x or later

YES

NO

Hibernate

YES JRebel 3.0+

NO

JBoss Seam 2.x or later

YES JRebel 3.0+

NO

Google Guice

YES

NO

Stripes 1.x or later

YES

NO

Apache log4j 1.2.x or later

YES

NO

Apache Struts 1.x

YES

NO

Apache Struts 2.x or later

YES

NO

Apache Tapestry4

YES

NO

Apache Velocity

YES

NO

Apache Wicket

YES

NO

CgLib

YES JRebel 3.0+

NO

Javassist

YES JRebel 3.0+

NO

Atlassian Confluence plugins

YES

NO

ClassWorlds

YES Beta

NO

Apache Felix

YES Beta

NO

Eclipse Equinox

YES Beta

NO

IntelliJ IDEA 7.x, 8.x plugins

YES Beta

NO

NetBeans plugins

YES Beta

NO

 

 

Jrebel对第三方框架支持对应表

查看官网 http://www.zeroturnaround.com/jrebel/features/frameworks/



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



解密阿里巴巴的技术发展路径

$
0
0


2008年的一天, 阿里巴巴集团(下称“阿里”)开了一次内部会议。在这次当时看来很平常的会议上,明确了两个议题:一,阿里是一家数据公司;二,阿里要把“计算”变成一种像水和电一样的公共品。当时在中国还没有人谈“大数据”的概念;更没有人想到云计算会和一家互联网公司未来发展如此紧密。

1999年阿里成立之初,创始人“十八罗汉”中就不乏 技术基因。公开资料显示,创始人之一吴泳铭1996年毕业于浙江工业大学计算机系,后成为支付宝的技术总监。盛一飞有多年用户体验设计经验。周悦虹,java架构师,技术精湛,传言是一名极客。

随着淘宝网的成立,2003年阿里开始与IBM合作,解决用户、商品和消费信息分散的问题。当时的阿里已经从十几个人的小公司延展出很多新业务,技术系统也变得庞大复杂。到了2007年,阿里在IT上的投入之大,一度成为IBM、Oracle等国外IT厂商在中国的标杆用户。当年,阿里首席数据库管理员冯春培甚至受到了Oracle公司亚太区高级副总裁Brian Mitchell亲切接待,并被授予甲骨文全球第100个ACE(Oracle ACE 是指那些通过撰写书籍、文章或博客,分享Oracle经验的技术专家)。

但实际上,这种甜蜜的合作关系并没有持续太久。

2008年前后,阿里业务高速发展使已有的IT设备使用到达瓶颈。根据时任支付宝数据库架构师、现丁香园CTO冯大辉的描述:“在阿里的IT架构中,淘宝和支付宝等拥有大量IBM小型机和Oracle数据库,以及EMC、戴尔存储设备。用户激增与用户产生的数据越来越多,每年早上8:00~9:30之间CPU(中央处理器)要保持98%的使用率。”IBM小型机价格从几十万到高达百万级人民币,与Oracle签订的数据库软件费用达数千万,加之一大笔软硬件支付和一大笔维护费,阿里的技术发展进入一个压力很大的时期。

紧迫之中,阿里在寻找一名技术高管,要为庞大复杂的业务搭建起全新的技术架构,建立全球顶尖IT团队。在2008年的这次内部会议上,阿里确定了“数据”和“云计算”两个重要的新战略。

时任阿里巴巴首席架构师的王坚成为接受这个挑战的不二人选。

 

“去IOE”念头萌生

加入阿里巴巴之前,王坚任微软亚洲研究院常务副院长;再之前,他是浙江大学心理学系教授、系主任。加盟阿里后,王坚马上着手第一个重要工作——筹划集团全年的IT预算。他反复琢磨,发现一个重要问题:即便追加巨额IT投资,阿里购买的软硬件也未必能满足其业务的高速增长。

“双十一”大促对IT计算资源要求庞大,很难预测业务爆发点所需要的计算资源峰值。但过了高峰期,IT资源空下来,又会造成浪费。这些实实在在的难题是为阿里提供软硬件服务的厂商从没遇到过的,IBM、Oracle和他们的客户都不能为阿里IT提供任何可供借鉴的经验。其次,整个IT就像是一个黑箱子,一旦出现技术故障后,阿里的技术团队要打电话给厂商等待事故处理,而且高端存储设备的性能数据都是由厂商掌控,阿里自己的技术团队并没有太大的控制权。技术维护变成极其繁琐的工作,支撑业务的效率大大下降。

而在地球的另一端,Google和Amazon是和阿里业务相近,并值得学习的两个好榜样——Google是世界上少有的能拥有大规模分布式架构技术的互联网公司,Amazon是第一个将自己云计算技术对外提供服务,实现营收的公司。

在一次预算讨论中,阿里巴巴集团负责技术保障的副总裁刘振飞和阿里技术保障部DBA负责人周宝方偶然提到:“阿里应该尝试用PC技术替代小型机技术。”一听这句话,王坚一下子激动起来:“既然已经思考了这个问题,为什么我们不郑重写下来?明确阿里再也不购买小型机。”

“去IOE”(在IT设备中去除IBM小机、Oracle数据库及EMC存储)由此得名。

在2009年到2013年整个“去IOE”的过程中,阿里技术发展策略逐渐从“商业软件”、“开源软件”发展到自主技术和云计算构成的综合技术服务能力。便宜的Commodity PC替换掉过去昂贵的硬件设备,淘宝、支付宝等重要业务将旧的“IOE”集中式架构转变为分布化架构,这种架构是把IT后台迁移到云计算平台上的基础工作。

在“去IOE”过程中,阿里技术团队也完成了一次成熟的转型,这为阿里向外提供云服务打下了基础。王坚来阿里之前,阿里各业务技术后台是独立运营的,他将阿里运维团队、平台技术部、大淘宝运维团队、云计算运维团队等整合到一起,成立了集团统一的IT技术保障部。阿里旗下子业务模式差别巨大,IT工具和价值理念也完全不同,所以统一团队经历了很大的技术挑战和组织挑战。这项工作实际为后期阿里云向外提供服务打下了很好的基础,阿里后期推出的“聚石塔”、“聚宝盆”业务,与这支在“去IOE”过程中锻炼出的队伍密不可分。

除了团队,技术人员也面临着个人转型。王坚曾多次说:“‘去IOE’最难的就在于人。每一次的技术转换,我们都是在革自己的命。如果没有同事们当时敢于尝试的勇气,阿里的技术难题都可能扛不过去。”曾有一位技艺精湛、对业务非常熟悉的淘宝数据库管理员,在“去IOE”过程中,他从Oracle数据库技术,转到MySQL数据库,最后去研发阿里自有技术OceanBase数据库。

技术的重新选择让阿里最有价值的一批技术人才,随时要面对熟练的技术突然没有用的情况。曾参与IBM小机下线的技术人员楼方鑫曾说过这样一段话:“去掉一两个系统的IOE不是最难的,也不能代表成功;通过‘去IOE’提升和锻炼团队的能力,协调好运维和开发团队间的工作才是关键。”

 

小机,再见!

淘宝是首先推行“去IOE”战略的业务部门之一。“去IOE”之所以能从淘宝开始,是因为淘宝拥有阿里最大的Oracle数据库,成本和技术压力最大。

淘宝技术专家余锋曾说:尽管Oracle数据库性能稳定,但是对于淘宝来讲,Oracle数据库本身已经不能满足业务需求。淘宝的数据库专家从IT前端逐渐过渡到后端,弱化Oracle数据库,把“Oracle数据库+IBM小型机+EMC存储设备”切换到“MySQL数据库+PC Server的模式”。到2013年7月10日,淘宝重中之重的广告系统的Oracle数据库全部下线。

2013年5月17日,阿里集团最后一台IBM小机在支付宝下线时也使阿里“去IOE”运动越发受到关注。

在“去IOE”的进程中,支付宝首席架构师程立有自己的苦衷。支付宝有阿里最后一台IBM小机,这台小机管理着支付宝用户的所有资金。如果这台小机出现故障,用户将会无法支付,甚至连自己账户里有多少钱都看不到了,后果将不堪设想,因此对这台小机的任何改动都要确保万无一失。

去除支付宝IBM小机的第二个难点在于,去除小机的前提是实现技术架构分布化,为支付宝IT迁移到云平台打下基础。但将技术架构从集中变成分布后,很难保证强一致性,比如客户A给客户B转了一笔钱,不能出现A的钱扣了,但B的钱没增加的情况。如何在一个分布的系统中保证交易处理的一致性是一个要攻克的技术难题。

“在王坚博士梳理整个阿里技术架构的时候,支付宝曾经是他‘去IOE’最大的一个‘障碍’”程立向《商业价值》记者说道。“我们必须要保证每天处理的大量资金,一分钱都不能错,一笔都不能差。”出于谨慎,程立和团队在去掉支付宝系统中其它所有的IBM小型机后,还保留着这台小机管理最重要的账户资金。”

时间回溯到2012的“双十一”大促的凌晨,很多消费者不断点击支付按钮,却常常看到支付宝的排队页面。消费者以为支付宝系统崩溃了,实际上,当时是因为支付宝仅存的这台小机的承载能力有限,在高峰交易期,系统只能对来不及处理的请求进行排队,这种排队带来的延迟产生了巨大的用户体验障碍。

“双十一”的痛苦经历,让程立最后下定决心去掉这最后一台小机,最终,支付宝技术团队设计出了基于互联网技术的分布式交易处理方案,通过一次完美的项目执行去除了支付宝、同时也是阿里的最后一台IBM小机。

2013年的双十一是程立经历过的最轻松一次“大促”,再也不担心有任何技术节点会制约业务的发展了。

 

一台超级计算机

在阿里进行“去IOE”同时,另外一项重要的技术研发也在同时上演。2008年10月24日,飞天研发启动。“飞天”是什么?飞天是阿里的大规模分布式系统,几乎等同于整个阿里云的整个技术体系。

技术网站博客园对飞天——这种分布式技术有一段生动的描述:当你只有六七条鱼的时候, 一个小型鱼缸就够了;可是过一段时间新生了30多条小鱼,这个小缸显然不够大了。如果买一个大缸,把所有水草啊、布景、加热棒、温度计都从小缸里拿出来,重新布置到大缸。这个工程要花费很多时间,尤其水草,纠结在一起很难分开。分布式系统可以帮你在这个小缸旁边接了一个同样的小缸,两个缸联通。鱼可以自动分散到两个缸。帮你越过复杂的系统扩建过程,省掉了很多时间和设备成本。

阿里旧的“IOE”架构,本质上代表着基于传统高端设备、大型数据库等软硬件的集中式架构。陈旧集中的技术无法应对阿里爆炸式业务增长,如果在IT系统中有一点出现问题,整个架构都面临危险。飞天这种分布式系统集中大量的通用服务器在一个系统中,比单个的大型集中式系统运行速度更快。而且,把计算能力分散到众多机器上,单个节点的故障只会影响一台机器,其它机器可以照常工作。

2013年3月,阿里技术保障部给公司高层突然发信一封:“云梯1要撞墙了!”云梯1是阿里内部另一个基于Hadoop的分布式集群系统。保障部的员工发现按照现有数据增量和未来业务增长的情况,阿里的存储和计算能力将在3个月内达到瓶颈,数据业务面临停滞,必须将飞天系统快速扩建起来。

飞天的快速扩建要克服很多难题,国内有大规模分布式系统经验的人不多,阿里的技术团队里只有少数做过或用过分布式系统,所以整个研发的过程是一个探索学习的过程,只有遇到实际的问题,团队才会对工程上的难题有所领悟。

其次,在系统设计的时候,工程师会设定相应的工作场景、硬件环境的完备性。但在实际生产环境下,各种硬件环境、参数配置,往往会打破设计时的假设,因此总是会碰到各种问题。在解决这些问题过程中积累的经验,显然不是教科书上可以学到的理论。这个超大计算机也有自己的软肋,她要比单个服务器的可用性和可靠性要高很多,才能保证服务“永远”不中断,数据“永远”不丢失。

经过4个月的不懈努力,飞天资深技术总监唐洪和他的团队将5000台飞天集群部署成功。阿里成为国内首个单集群达到5000台规模的公司,在此之前,全球也只有Google、Facebook等顶级公司可以按照5000台机器来划分集群规模。

飞天能做什么?用唐洪的话来说:“它有100PB级别的硬盘,可以存放几百亿的网页;可以给几十万的用户,每人提供几百G的存储;再或者是拥有了一台万核以上的超级计算机,普通计算机一个月需要完成的渲染作业在这个计算机上只需要几分钟就可以完成。”

 

“双十一”云备战

“去IOE”与“飞天5K”技术成功后,阿里集团内部所有的重量级业务都已迁移到云计算平台上。

“聚石塔”、“聚宝盆”、“阿里金融”的大数据研发以及YunOS智能移动操作系统等,都运行在阿里云飞天平台上。淘宝、支付宝等各业务部门的底层技术也架设在飞天平台上。阿里金融基于云计算,几分钟之内就能让贷款发出,每天处理上百TB的交易数据,而且保证了每一笔贷款发放的计算成本相同。淘宝也基于阿里云推出电商云——聚石塔,为“双十一”服务。阿里云推出电商云—聚石塔,为“双十一”服务。2012年“双十一”,通过聚石塔,阿里云支撑了天猫20%的交易额, 2013年这一数字上升到75%。

2013年“双十一”大战前3个礼拜,天猫技术总监庄卓然接到集团通知:大促结束后,他将要被抽调到无线事业部。对他而言,3年的“双十一”备战完美收官,又将迎接新的挑战。2013年,阿里第5个“双十一”,天猫和淘宝单日成交额达到362亿元(根据招股书数据),网站PV过百亿,76%的商家处理工作在聚石塔云计算平台完成,且无一漏单,无一故障。支付宝成功支付1.88亿笔,最高每2分钟支付79万笔。用庄卓然的话:“疯狂业务数据的背后,是对阿里技术团队一次整体大阅兵。”这场阅兵检验了阿里“去IOE”和云计算的成果。

3年备战“双十一”,庄卓然每年都重复着高效的工作时间表。5月底,投入产品和技术准备。筹划新的突破点和创意同时启动,投入到一些较长周期的研发工作。8月底,真正的考验来临,冲刺时间段,他每晚习惯性要到两点多才能睡着。有时候,想一些技术难题觉得有突破时,一睁眼就到天亮。庄卓然自己形容自己的工作状态像“精神分裂”一样,左脑思考的是系统的稳定性建设,右脑不停地找寻当前系统的命门和瓶颈。每一次大促都是对团队技术能力的考验。

2011年和2012年的“双十一”前夜,庄卓然和技术团队都非常不踏实,即便该做的技术准备都做了,但面对“双十一”巨大的突发流量,只能尽力保证一个完善的技术机制,抓大放小。“双十一”的最大难点在于峰值流量一压过来,系统要扛得住千万人同时在线和每秒数亿笔交易。

淘宝和天猫的技术体系非常庞杂。每一笔交易都涉及到银行、商家、淘宝自身和网络等多个系统的处理能力。交易信息层层传递过程中,某一个技术细节执行不到位,交易就可能失败。比如,当用户量大到一定程度,系统让用户排队,如果这个功能失效,一连串的上下游系统都会受到影响。淘宝的几万台机器,上千个应用系统复杂交错,很难实景模拟所有的用户行为,比如1000万人同时在线,同时下单。2013年,庄卓然对“双十一”技术的确定和把握,一部分来源于技术团队已经能实现在短期内集结一大批虚拟用户去做压力测试;另一部分是淘宝天猫后台和大多数商家后台已经上云。

淘宝、天猫上大概近千万家商家,其中大部分的商家都有自己的ERP系统。消费者买一个东西需要点击购买,然后进行支付。这个动作会指向两条IT路径:一是连接支付宝,保证有钱可以完成支付;另一条则是进入卖家的ERP,卖家需要知道自己是否有库存,并减掉相应的货品数量。交易从淘宝或天猫链接到卖家后台系统的过程中,如果卖家IT系统薄弱,数据交换可能会因为网络等原因不通畅导致交易失败。

庄卓然详细讲解了这一过程:“聚石塔提供的云推送功能在第一时间将交易订单同步部署进商家的ERP、物流、CRM软件中,并提供动态弹性扩容和安全保护。消费者下单到发货、发票打印,所有信息流转都在云上完成。”

 

云上生态系统

聚石塔只是阿里云应用的一个侧面,阿里长在云上的商业生态体系已经初步形成。

王坚曾说过:“阿里云平台在内部的代码就是飞天。一个平台的力量有多大,可以造就的东西就有多大,这是过去阿里云为什么花费这么大力气做飞天的原因。”飞天以Web API的方式,向外提供计算、存储和大规模数据处理等云计算服务,建立起庞大的云计算生态体系。

未来的互联网将成为一个果园,各行各业像是一棵棵果树,如何为果树提供良好的养分服务,决定了果园生态的丰富程度。云计算就是牵引传统行业互联网化的引擎。数据将成为云生态里的生产资料,通过强大的计算能力进行实时分析和交互,可以催生出无数新的商业模式。

在阿里刚刚递交的招股说明书中写道:2013年1~9月,阿里云计算服务等收入达5.6亿人民币,占总收入的1.4%,同比增长15.7%,并且已经拥有98万用户。阿里云快速地将阿里和不同行业企业联系到一起,比如消费电子、公共卫生、能源管理、媒体、电子商务、电子政务、移动互联网等。阿里云客户中有传统的互联网公司,也有移动互联网公司,比如手游公司;还有一些传统企业,比如杭州九阳股份有限公司,这些传统企业的IT逐渐向云迁徙。例如,2013年,阿里与美的集团的深入合作,是基于天猫商城、大数据和阿里云计算平台的多维度合作,这种借助云和数据的能力,让传统企业能与互联网走向更深的耦合。

阿里云还在借助ISV合作伙伴,帮助更多的传统企业上云。2013年,东软将旗下SaCa、UniEAP等软件产品部署在阿里云上;普元推出基于阿里云的EOS-Cloud平台,直接在云上支撑企业软件开发。这些ISV厂商有大量传统企业用户积累,这种深入合作撬动了一批传统企业上云。2014年,5月8日,阿里云宣布香港数据中心正式投入使用,阿里云正与Amazon AWS、、微软Azure展开正面竞争,阿里的云生态体系部署已经蔓延到国外。阿里云业务总经理陈金培认为:“所有的产业竞争都是生态系统的竞争,你要么依存于一个生态,要么自己发展出来一个生态。”马云搭建的基于数据和云的生态,已初步形成。

2013年初开始,阿里将其战略调整为“平台、金融、数据”三大业务。云计算是金融、数据的基础。2014年春,马云的内部信件再次明确了阿里的未来战略:走向激活生产力为目的的DT(data technology)数据时代。马云的策略是让数据、云计算成为中国商业的基础设施。

 

阿里巴巴技术发展大事记

2007年—— 以互联网为平台的商务管理软件公司阿里软件成立。

2008年—— 王坚加盟阿里成为集团首席架构师;

阿里巴巴集团研发院成立;

飞天研发工作开始。

2009年—— 年阿里软件与阿里巴巴集团研发院合并;

阿里云计算成立,在杭州、北京、硅谷设研发中心和运营机构;

Oracle产品构建的RAC集群成为国内最大的数据仓库;

淘宝拥有第一个分布式计算系统Hadoop集群,规模300台。

2010年—— 阿里云第一个云计算机房启用;

阿里巴巴数据量大爆炸的一年,RAC集群不能满足业务发展速度,迁移到Hadoop。

2011年—— 阿里云官网上线,“飞天”开始对外提供云服务;

阿里巴巴云智能手机操作系统云OS正式发布。

2012年——“冰火鸟”启动建立支持集团数据化运营,自主研发的分布式计算平台对全集团

提供服务。

2013年—— 阿里云计算与万网合并为新的阿里云计算公司;

“飞天”集群达到5000台,100T数据TearSort算法30分钟完成,比当时的世界纪录快2倍以上。

2014年—— 阿里云发布移动云平台-聚无线;

香港数据中心正式启用。

(关注更多 钛媒体作者观点,参与钛媒体微信互动(微信搜索“钛媒体”或“taimeiti”))

hadoop记录

$
0
0
MapReduce的特征
1. 每个分片输入的文件可以比较大。默认64M



Map1结果与Map2结果重叠现象?(传统的分布式计算无法解决)
方案:Map2与Map2原封不动的把数据传到Reduce; 问题:结果Map啥事没干,Reduce最终累死, 分而治之成为了空谈。
最终方案:使用partition把相同key的结果分配到同一个reduce上执行

输入文件把切分成多个块, 每个块的默认大小是64M, 每一个块就是一个maptask任务
map任务工作过程:
Map从HDFS上获取数据块(Datanode上每个map任务都会有一个内存缓冲区(默认100M),用来存储它输出的结果「有它的原因:减少对磁盘的读写频率」)
如果map结果很大使缓冲区默认100M满了后将缓冲区中数据spill到磁盘上(spill过程), 默认是80%时就spill(可以设置), spill过程中map还产生结果; spill过程
对数据进行sort; spill出来的单独文件(又叫溢写文件);如果有大数据量的话,就生成多个溢写文件,又要将这些文件合并起来(merge过程「可以通过参数设置每次merge多少个文件」); 问题:如果merge只是只是合并过程,像WordCount例子,第一个溢写文件中key:name value:4, 第二个溢写文件key:name value:3 的话,merge后还会出现此key值的,所以如果之前设置了combiner,就会使用combiner将相同的key的value进行合并; 最终的这个输出文件也是存储在本地磁盘中。

reduce任务工作过程:
reduce是将map的输出作为reduce的输入,只要有一个map任务执行完就会有reduce任务开始执行。实际运行过程中,map与reduce运行过程很可能不是在同一个datanode上,那它们是通过什么来联系的呢?reduce是通过http向JobTracker发请求看那些map执行完了,然后从map所在的TaskTracker远程获取map的输出文件,注意:并不是获取整个map的输出文件, 而是获取reduce能处理的了的数据; 在这个下载过程中,也会做归并排序,因为不同的map很有可能含有相同的key值; 对于reduce来说它的文件来源可能来自多个map,这个下载过程可以是并行的,不过这个并行数据可以设置的,默认是5,即使reduce 所需要的数据是从很多个map上的(若是大于设置的并行度),也只能一次并行的从设置的这么多个Map上下载所需数据;copy获取到的数据也是放到内存当中,


问题:处理10亿条数据,只求最大值, 这样的话在网上传输占了很大的带宽/专利计算中最终会把数据聚集到reduce端,加重reduce负担

Combiner:就是把了减少map与reduce间数据传输而设置的; 
注意:combine的输入和reduce的完全一致,输出和map的完全一致;一个combiner只是处理一个结点的输出,不像reduce享受shuffle后的数据;“迷你reduce”

注意几点:
1.与map和reduce不同,combiner没有默认的实现
2.并不是所有的任务都适合使用combiner,比如 求最大值,求和可以, 求中值不行, 平均值也应该不行;
 词频统计map输出(hello, 1), (hello, 1)经过combiner后(hello, 2)压缩后再送到reduce

 



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



KeepAlive详解 - HavenShen

$
0
0

KeepAlive既熟悉又陌生,踩过坑的同学都知道痛。一线运维工程师踩坑之后对于KeepAlive的总结,你不应该错过!

 

最近工作中遇到一个问题,想把它记录下来,场景是这样的:

从上图可以看出,用户通过Client访问的是LVS的VIP, VIP后端挂载的RealServer是Nginx服务器。 Client可以是浏览器也可以是一个客户端程序。一般情况下,这种架构不会出现问题,但是如果Client端把请求发送给Nginx,Nginx的后端需要一段时间才能返回结果,超过1分30秒就会有问题,使用LVS作为负载均衡设备看到的现象就是1分30秒之后, Client和Nginx链接被断开,没有数据返回。

 

原因是LVS默认保持TCP的Session为90s,超过90s没有TCP报文在链接上传输,LVS就会给两端发送RESET报文断开链接。LVS这么做的原因相信大家都知道一二,我所知道的原因主要有两点:

 

1. 节省负载均衡设备资源,每一个TCP/UDP的链接都会在负载均衡设备上创建一个Session的结构, 链接如果一直不断开,这种Session结构信息最终会消耗掉所有的资源,所以必须释放掉。

 

2.另外释放掉能保护后端的资源,如果攻击者通过空链接,链接到Nginx上,如果Nginx没有做合适 的保护,Nginx会因为链接数过多而无法提供服务。

 

这种问题不只是在LVS上有,之前在商用负载均衡设备F5上遇到过同样的问题,F5的session断开方式和LVS有点区别,F5不会主动发送RESET给链接的两端,session消失之后,当链接中一方再次发送报文时会接收到F5的RESET, 之后的现象是再次发送报文的一端TCP链接状态已经断开,而另外一端却还是ESTABLISH状态。

 

知道是负载均衡设备原因之后,第一反应就是通过开启KeepAlive来解决。到此这个问题应该是结束了,但是我发现过一段时间总又有人提起KeepAlive的问题,甚至发现由于KeepAlive的理解不正确浪费了很多资源,原本能使用LVS的应用放在了公网下沉区,或者换成了商用F5设备(F5设备的Session断开时间要长一点,默认应该是5分钟)。

 

所以我决定把我知道的KeepAlive知识点写篇博客分享出来。

 

为什么要有KeepAlive?

 

在谈KeepAlive之前,我们先来了解下简单TCP知识(知识很简单,高手直接忽略)。首先要明确的是在TCP层是没有“请求”一说的,经常听到在TCP层发送一个请求,这种说法是错误的。

 

TCP是一种通信的方式,“请求”一词是事务上的概念,HTTP协议是一种事务协议,如果说发送一个HTTP请求,这种说法就没有问题。也经常听到面试官反馈有些面试运维的同学,基本的TCP三次握手的概念不清楚,面试官问TCP是如何建立链接,面试者上来就说,假如我是客户端我发送一个请求给服务端,服务端发送一个请求给我。。。

 

这种一听就知道对TCP基本概念不清楚。下面是我通过wireshark抓取的一个TCP建立握手的过程。(命令行基本上用TCPdump,后面我们还会用这张图说明问题):

现在我看只要看前3行,这就是TCP三次握手的完整建立过程,第一个报文SYN从发起方发出,第二个报文SYN,ACK是从被连接方发出,第三个报文ACK确认对方的SYN,ACK已经收到,如下图:

但是数据实际上并没有传输,请求是有数据的,第四个报文才是数据传输开始的过程,细心的读者应该能够发现wireshark把第四个报文解析成HTTP协议,HTTP协议的GET方法和URI也解析出来,所以说TCP层是没有请求的概念,HTTP协议是事务性协议才有请求的概念,TCP报文承载HTTP协议的请求(Request)和响应(Response)。

 

 

现在才是开始说明为什么要有KeepAlive。链接建立之后,如果应用程序或者上层协议一直不发送数据,或者隔很长时间才发送一次数据,当链接很久没有数据报文传输时如何去确定对方还在线,到底是掉线了还是确实没有数据传输,链接还需不需要保持,这种情况在TCP协议设计中是需要考虑到的。

 

TCP协议通过一种巧妙的方式去解决这个问题,当超过一段时间之后,TCP自动发送一个数据为空的报文给对方,如果对方回应了这个报文,说明对方还在线,链接可以继续保持,如果对方没有报文返回,并且重试了多次之后则认为链接丢失,没有必要保持链接。

 

如何开启KeepAlive?

 

KeepAlive并不是默认开启的,在Linux系统上没有一个全局的选项去开启TCP的KeepAlive。需要开启KeepAlive的应用必须在TCP的socket中单独开启。Linux Kernel有三个选项影响到KeepAlive的行为:


1.net.ipv4.tcpkeepaliveintvl = 75
2.net.ipv4.tcpkeepaliveprobes = 9
3.net.ipv4.tcpkeepalivetime = 7200


tcpkeepalivetime的单位是秒,表示TCP链接在多少秒之后没有数据报文传输启动探测报文; tcpkeepaliveintvl单位是也秒,表示前一个探测报文和后一个探测报文之间的时间间隔,tcpkeepaliveprobes表示探测的次数。

 

 

TCP socket也有三个选项和内核对应,通过setsockopt系统调用针对单独的socket进行设置:


TCPKEEPCNT: 覆盖 tcpkeepaliveprobes
TCPKEEPIDLE: 覆盖 tcpkeepalivetime
TCPKEEPINTVL: 覆盖 tcpkeepalive_intvl

 

 

举个例子,以我的系统默认设置为例,kernel默认设置的tcpkeepalivetime是7200s, 如果我在应用程序中针对socket开启了KeepAlive,然后设置的TCP_KEEPIDLE为60,那么TCP协议栈在发现TCP链接空闲了60s没有数据传输的时候就会发送第一个探测报文。

 

TCP KeepAlive和HTTP的Keep-Alive是一样的吗?

 

估计很多人乍看下这个问题才发现其实经常说的KeepAlive不是这么回事,实际上在没有特指是TCP还是HTTP层的KeepAlive,不能混为一谈。TCP的KeepAlive和HTTP的Keep-Alive是完全不同的概念。

 

TCP层的KeepAlive上面已经解释过了。 HTTP层的Keep-Alive是什么概念呢? 在讲述TCP链接建立的时候,我画了一张三次握手的示意图,TCP在建立链接之后, HTTP协议使用TCP传输HTTP协议的请求(Request)和响应(Response)数据,一次完整的HTTP事务如下图:

各位看官请注意,这张图我简化了HTTP(Req)和HTTP(Resp),实际上的请求和响应需要多个TCP报文。

 

从图中可以发现一个完整的HTTP事务,有链接的建立,请求的发送,响应接收,断开链接这四个过程,早期通过HTTP协议传输的数据以文本为主,一个请求可能就把所有要返回的数据取到,但是,现在要展现一张完整的页面需要很多个请求才能完成,如图片,JS,CSS等,如果每一个HTTP请求都需要新建并断开一个TCP,这个开销是完全没有必要的。

 

开启HTTP Keep-Alive之后,能复用已有的TCP链接,当前一个请求已经响应完毕,服务器端没有立即关闭TCP链接,而是等待一段时间接收浏览器端可能发送过来的第二个请求,通常浏览器在第一个请求返回之后会立即发送第二个请求,如果某一时刻只能有一个链接,同一个TCP链接处理的请求越多,开启KeepAlive能节省的TCP建立和关闭的消耗就越多。

 

当然通常会启用多个链接去从服务器器上请求资源,但是开启了Keep-Alive之后,仍然能加快资源的加载速度。HTTP/1.1之后默认开启Keep-Alive, 在HTTP的头域中增加Connection选项。当设置为Connection:keep-alive表示开启,设置为Connection:close表示关闭。实际上HTTP的KeepAlive写法是Keep-Alive,跟TCP的KeepAlive写法上也有不同。所以TCP KeepAlive和HTTP的Keep-Alive不是同一回事情。

 

Nginx的TCP KeepAlive如何设置?

 

开篇提到我最近遇到的问题,Client发送一个请求到Nginx服务端,服务端需要经过一段时间的计算才会返回, 时间超过了LVS Session保持的90s,在服务端使用Tcpdump抓包,本地通过wireshark分析显示的结果如第二副图所示,第5条报文和最后一条报文之间的时间戳大概差了90s。

 

在确定是LVS的Session保持时间到期的问题之后,我开始在寻找Nginx的TCP KeepAlive如何设置,最先找到的选项是keepalivetimeout,从同事那里得知keepalivetimeout的用法是当keepalivetimeout的值为0时表示关闭keepalive,当keepalivetimeout的值为一个正整数值时表示链接保持多少秒,于是把keepalivetimeout设置成75s,但是实际的测试结果表明并不生效。

 

显然keepalivetimeout不能解决TCP层面的KeepAlive问题,实际上Nginx涉及到keepalive的选项还不少,Nginx通常的使用方式如下:

从TCP层面Nginx不仅要和Client关心KeepAlive,而且还要和Upstream关心KeepAlive, 同时从HTTP协议层面,Nginx需要和Client关心Keep-Alive,如果Upstream使用的HTTP协议,还要关心和Upstream的Keep-Alive,总而言之,还比较复杂。

 

所以搞清楚TCP层的KeepAlive和HTTP的Keep-Alive之后,就不会对于Nginx的KeepAlive设置错。我当时解决这个问题时候不确定Nginx有配置TCP keepAlive的选项,于是我打开Ngnix的源代码,在源代码里面搜索TCP_KEEPIDLE,相关的代码如下:

从代码的上下文我发现TCP KeepAlive可以配置,所以我接着查找通过哪个选项配置,最后发现listen指令的so_keepalive选项能对TCP socket进行KeepAlive的配置。

以上三个参数只能使用一个,不能同时使用, 比如sokeepalive=on, sokeepalive=off或者sokeepalive=30s::(表示等待30s没有数据报文发送探测报文)。通过设置listen 80,sokeepalive=60s::之后成功解决Nginx在LVS保持长链接的问题,避免了使用其他高成本的方案。在商用负载设备上如果遇到类似的问题同样也可以通过这种方式解决。


本文链接: KeepAlive详解,转载请注明。

Viewing all 15843 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>