J2EE框架 Spring

J2EE框架 Spring 推荐

J2EE框架 面向方面AOP/IoC Web框架
Apache
Java
跨平台

Spring Framework 是一个开源的Java/Java EE全功能栈(full-stack)的应用程序框架,以Apache许可证形式发布,也有.NET平台上的移植版本。该框架基于 Expert One-on-One Java EE Design and Development(ISBN 0-7645-4385-7)一书中的代码,最初由 Rod Johnson 和 Juergen Hoeller等开发。Spring Framework 提供了一个简易的开发方式,这种开发方式,将避免那些可能致使底层代码变得繁杂混乱的大量的属性文件和帮助类。

Spring 中包含的关键特性:

  • 强大的基于 JavaBeans 的采用控制翻转(Inversion of Control,IoC)原则的配置管理,使得应用程序的组建更加快捷简易。
  • 一个可用于从 applet 到 Java EE 等不同运行环境的核心 Bean 工厂。
  • 数据库事务的一般化抽象层,允许宣告式(Declarative)事务管理器,简化事务的划分使之与底层无关。
  • 内建的针对 JTA 和 单个 JDBC 数据源的一般化策略,使 Spring 的事务支持不要求 Java EE 环境,这与一般的 JTA 或者 EJB CMT 相反。
  • JDBC 抽象层提供了有针对性的异常等级(不再从SQL异常中提取原始代码), 简化了错误处理, 大大减少了程序员的编码量. 再次利用JDBC时,你无需再写出另一个 ‘终止’ (finally) 模块. 并且面向JDBC的异常与Spring 通用数据访问对象 (Data Access Object) 异常等级相一致.
  • 以资源容器,DAO 实现和事务策略等形式与 Hibernate,JDO 和 iBATIS SQL Maps 集成。利用众多的翻转控制方便特性来全面支持, 解决了许多典型的Hibernate集成问题. 所有这些全部遵从Spring通用事务处理和通用数据访问对象异常等级规范.
  • 灵活的基于核心 Spring 功能的 MVC 网页应用程序框架。开发者通过策略接口将拥有对该框架的高度控制,因而该框架将适应于多种呈现(View)技术,例如 JSP,FreeMarker,Velocity,Tiles,iText 以及 POI。值得注意的是,Spring 中间层可以轻易地结合于任何基于 MVC 框架的网页层,例如 Struts,WebWork,或 Tapestry。
  • 提供诸如事务管理等服务的面向方面编程框架。

在设计应用程序Model时,MVC 模式(例如Struts)通常难于给出一个简洁明了的框架结构。Spring却具有能够让这部分工作变得简单的能力。程序开发员们可以使用Spring的 JDBC 抽象层重新设计那些复杂的框架结构。

高性能PHP框架 Phalcon

BSD
PHP,C
跨平台

PhalconPHP 是一个使用 C 扩展开发的 PHP Web 框架,提供高性能和低资源占用。

Phalcon 是一个开源的、全堆栈的 PHP 5 框架,使用 C 扩展编写,专门为高性能优化。无需学习和使用 C 语言,所有函数都以 PHP 类的方式曾现。Phalcon 是一个松耦合的框架。

使用时需在 php.ini 中添加:extension=phalcon.so

参考:https://www.oschina.net/p/phalcon

雨中的旋律

《雨中的旋律》(Rhythm of the Rain)是欧美经典歌曲,由瀑布合唱团演唱。

英文歌词

Rhythm of the Rain
Listen to the rhythm of the falling rain,
Telling me just what a fool I’ve been.
I wish that it would go and let me cry in vain,
And let me be alone again.
The only girl I care about has gone away.
Looking for a brand new start!
But little does she know that when she left that day.
Along with her she took my heart.
Rain, please tell me now. Does that seem fair for her
To steal my heart away when she don’t care
I can’t love another, when my heart’s somewhere far away.
The only girl I care about has gone away.
Looking for a brand new start!
But little does she know that when she left that day.
Along with her she took my heart.
Rain, won’t you tell her that I love her so
Please ask the sun to set her heart aglow
Rain in her heart and let the love we knew start to grow.
Listen to the rhythm of the falling rain,
Telling me just what a fool I’ve been.
I wish that it would go and let me cry in vain,
And let me be alone again.
Oh, listen to the falling rain–pitter-patter…

歌词大意

听那淅淅沥沥的雨声,它好像在说,我是个傻瓜。 我真希望雨停下来。 让我无望地哭泣, 让我再次孤身单影。
我唯一在乎的姑娘已经离去, 去寻找她的新生活。 然而,她不知道, 当她离去的那天, 也将我的心带走。
雨呀,请告诉我,那样公平吗?她偷走了我的心, 居然毫不在乎。 我无法再爱别人, 我的心已远远漂向异地。
雨呀,你就不能告诉她 我多么地爱她, 请让太阳燃起她心中的爱苗, 让雨滋润她的心田。 让我们爱情之花重新盛开。
哦,听那雨声, 噼哩啪啦。
歌词、句型分析
1、Listen to the rhythm Of the falling rain,telling me just what a fool I have been.
= As I listen to the rhythm of the falling rain, it seems that it is telling me that I’ve been a stupid guy.
听那淅淅沥沥的雨声,它好像在说,我是个傻瓜。
2、I wish that it would go and let me cry in vain….
=I wish that the rain would stop and let me cry in vain…
我真希望雨停下来,让我无望地哭泣,
in vain 徒然,白费,无效,徒劳的
eg: All our efforts were in vain, which made us very angry.
我们所有的努力都白费了,真令人生气。
3、The only girl I care about has gone away, looking for a brand-new start!
=The only girl that I love has left me and is looking for a new life!
我唯一在乎的姑娘已经离去,去寻找她的新生活。
Care about 喜欢,在乎
eg: She doesn’t care about being ladylike
她不在乎淑女仪态
brand-new a. 全新的
eg: Peter is showing off his brand-new motorcycle to his friends
彼得正在对他的朋友们炫耀他的新摩托车。
4、But little does she know that when she left that day,along with her she took my heart.
=But she doesn’t know that when she left that day,she also took my heart with her.
然而,她不知道,当她离去的那天,也将我的心带走。
But little does she know…此为否定倒装句型。
eg: He was hardly able to tell right from wrong
=Hardly was he able to tell right from wrong

中文版

(红苹果演唱)
歌词:
大雨哗啦啦淋湿我的梦
你我曾经相遇在雨中
那青春年少无知可爱的笑容
像雨后美丽的彩虹
等大雨再次击醒你我的美梦
你却消失无影踪
等心中攒成点点滴滴的感动
有星光闪烁在夜空
也许你我生来太轻松
初恋故事短暂而冲动
我也幻想成为你的大英雄 谁能够
等大雨再次击醒你我的美梦
你却消失无影踪
等心中攒成点点滴滴的感动
有星光闪烁在夜空
等大雨再次击醒你我的美梦
你却消失无影踪
等心中攒成点点滴滴的感动
有星光闪烁在夜空
也许你我生来太轻松
初恋故事短暂而冲动
我也幻想成为你的大英雄 谁能够
噢 听那大雨还在下
哗啦啦啦哗啦啦啦噢
啦啦啦啦啦啦还在下
啦啦啦啦啦啦啦.
啦啦啦啦还在下.
啦啦啦啦啦啦啦
噢 听那大雨还在下
啦啦啦啦啦啦啦啦噢
啦啦啦啦啦啦还在下

婚姻周年纪念日

第1年:纸婚
第2年:棉婚 第3年:皮革婚 第4年:水果婚 第5年:木婚 第6年:铁婚
第7年:铜婚
第8年:陶婚 第9年:柳婚
第10年:铝婚
第11年:钢婚 第12年:丝婚 第13年:丝带婚 第14年:象牙婚
第15年:水晶婚 第20年:瓷婚
第25年:银婚
第30年:珍珠婚 第35年:珊瑚婚 第40年:红宝石婚 第45年:蓝宝石婚
第50年:金婚
第55年:绿宝石婚
第60年:钻石婚
第70年:白金婚
第75年:白石婚
第80年:   橡树婚


结婚后的每一个纪念日都有不同的名称,不同的象征意义:
第一年是 纸婚(意思是一张纸印的婚姻关系,比喻最初结合薄如纸,要小心保护!)Paper wedding
第二年 棉婚(加厚一点,尚须磨炼!)Cotton wedding
第三年 皮革婚(开始有点韧性)Leather wedding
第四年 丝婚(缠紧,如丝般柔韧,你浓我浓。)Silk wedding
第五年 木婚(硬了心,已经坚韧起来)Wood wedding
第六年 铁婚(夫妇感情如铁般坚硬永固) Iron or Sugar Candy wedding
第七年 铜婚(比铁更不会生锈,坚不可摧) Copper wedding
第八年 陶婚 (如陶瓷般美丽,并须呵护)Pottery wedding
第九年 柳婚 (像垂柳一样,风吹雨打都不怕。)Willow wedding
第十年 锡婚 (锡器般坚固,不易跌破。)Tin wedding
第十一年 钢婚 (如钢铁般坚硬,今生不变。)Steel wedding
第十二年 链婚 (像铁链一样,心心相扣)Linen wedding
第十三年 花边婚 (多姿多彩,多样化的生活)Lace wedding
第十四年 象牙婚 (时间愈久,色泽愈光亮美丽)Ivory wedding
第十五年 水晶婚 (透明清澈而光彩夺目)Crystal wedding


以后每5年一个名称:
第二十年 瓷婚 (光滑无暇,需呵护,不让跌破)China wedding
第二十五年 银婚 (已有恒久价值,是婚后第一个大庆典)Silver wedding
第三十年 珍珠婚 (像珍珠般浑圆,美丽和珍贵)Pearls wedding
第三十五年 珊瑚婚 (嫣红而宝贵,生色出众)Coral wedding
第四十年 红宝石婚 (名贵难得,色泽永恒)Ruby wedding
第四十五年 蓝宝石婚 (珍贵灿烂,值得珍惜)Sapphire wedding
第五十年 金婚 (至高无上,婚后第二大庆典,情如金坚,爱情历久弥新)Golden wedding
第五十五年 翡翠婚 (如翡翠玉石,人生难求)Emerald wedding
第六十年 钻石婚(夫妻一生中最大的一次结婚典庆,珍奇罕有,今生无悔,是最隆重庆典) Diamond wedding (Diamond Jubilee)
凡六十一七十结婚周年纪念,中国人统称为“福禄寿婚”。

linux信号Signal信号

信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念、Linux对信号机制的大致实现方法、如何使用信号,以及有关信号的几个系统调用。

信号机制是进程之间相互传递消息的一种方法,信号全称为软中断信号,也有人称作软中断。从它的命名可以看出,它的实质和使用很象中断。所以,信号可以说是进程控制的一部分。

软中断信号(signal,又简称为信号)用来通知进程发生了异步事件。进程之间可以互相通过系统调用kill发送软中断信号。内核也可以因为内部事件而给进程发送信号,通知进程发生了某个事件。注意,信号只是用来通知某进程发生了什么事件,并不给该进程传递任何数据。

收 到信号的进程对各种信号有不同的处理方法。

处理方法可以分为三类:

  1. 第一种是类似中断的处理程序,对于需要处理的信号,进程可以指定处理函数,由该函数来处 理。
  2. 第二种方法是,忽略某个信号,对该信号不做任何处理,就象未发生过一样。
  3. 第三种方法是,对该信号的处理保留系统的默认值,这种缺省操作,对大部分的信 号的缺省操作是使得进程终止。进程通过系统调用signal来指定进程对某个信号的处理行为。

在进程表的表项中有一个软中断信号域,该域中每一位对应一个信号,当有信号发送给进程时,对应位置位。由此可以看出,进程对不同的信号可以同时保留,但对于同一个信号,进程并不知道在处理之前来过多少个。

发出信号的原因很多,这里按发出信号的原因简单分类,以了解各种信号:

  1. 与进程终止相关的信号。当进程退出,或者子进程终止时,发出这类信号。
  2. 与进程例外事件相关的信号。如进程越界,或企图写一个只读的内存区域(如程序正文区),或执行一个特权指令及其他各种硬件错误。
  3. 与在系统调用期间遇到不可恢复条件相关的信号。如执行系统调用exec时,原有资源已经释放,而目前系统资源又已经耗尽。
  4. 与执行系统调用时遇到非预测错误条件相关的信号。如执行一个并不存在的系统调用。
  5. 在用户态下的进程发出的信号。如进程调用系统调用kill向其他进程发送信号。
  6. 与终端交互相关的信号。如用户关闭一个终端,或按下break键等情况。
  7. 跟踪进程执行的信号。

Linux支持的信号列表如下。很多信号是与机器的体系结构相关的

POSIX.1中列出的信号:
信号 值 处理动作 发出信号的原因
———————————————————————-
SIGHUP 1 A 终端挂起或者控制进程终止
SIGINT 2 A 键盘中断(如break键被按下)
SIGQUIT 3 C 键盘的退出键被按下
SIGILL 4 C 非法指令
SIGABRT 6 C 由abort(3)发出的退出指令
SIGFPE 8 C 浮点异常
SIGKILL 9 AEF Kill信号
SIGSEGV 11 C 无效的内存引用
SIGPIPE 13 A 管道破裂: 写一个没有读端口的管道
SIGALRM 14 A 由alarm(2)发出的信号
SIGTERM 15 A 终止信号
SIGUSR1 30,10,16 A 用户自定义信号1
SIGUSR2 31,12,17 A 用户自定义信号2
SIGCHLD 20,17,18 B 子进程结束信号
SIGCONT 19,18,25 进程继续(曾被停止的进程)
SIGSTOP 17,19,23 DEF 终止进程
SIGTSTP 18,20,24 D 控制终端(tty)上按下停止键
SIGTTIN 21,21,26 D 后台进程企图从控制终端读
SIGTTOU 22,22,27 D 后台进程企图从控制终端写

下面的信号没在POSIX.1中列出,而在SUSv2列出

信号 值 处理动作 发出信号的原因
——————————————————————–
SIGBUS 10,7,10 C 总线错误(错误的内存访问)
SIGPOLL A Sys V定义的Pollable事件,与SIGIO同义
SIGPROF 27,27,29 A Profiling定时器到
SIGSYS 12,-,12 C 无效的系统调用 (SVID)
SIGTRAP 5 C 跟踪/断点捕获
SIGURG 16,23,21 B Socket出现紧急条件(4.2 BSD)
SIGVTALRM 26,26,28 A 实际时间报警时钟信号(4.2 BSD)
SIGXCPU 24,24,30 C 超出设定的CPU时间限制(4.2 BSD)
SIGXFSZ 25,25,31 C 超出设定的文件大小限制(4.2 BSD)

(对于SIGSYS,SIGXCPU,SIGXFSZ,以及某些机器体系结构下的SIGBUS,Linux缺省的动作是A (terminate),SUSv2 是C (terminate and dump core))。

下面是其它的一些信号

信号 值 处理动作 发出信号的原因
———————————————————————-
SIGIOT 6 C IO捕获指令,与SIGABRT同义
SIGEMT 7,-,7
SIGSTKFLT -,16,- A 协处理器堆栈错误
SIGIO 23,29,22 A 某I/O操作现在可以进行了(4.2 BSD)
SIGCLD -,-,18 A 与SIGCHLD同义
SIGPWR 29,30,19 A 电源故障(System V)
SIGINFO 29,-,- A 与SIGPWR同义
SIGLOST -,-,- A 文件锁丢失
SIGWINCH 28,28,20 B 窗口大小改变(4.3 BSD, Sun)
SIGUNUSED -,31,- A 未使用的信号(will be SIGSYS)

(在这里,- 表示信号没有实现;有三个值给出的含义为,第一个值通常在Alpha和Sparc上有效,中间的值对应i386和ppc以及sh,最后一个值对应mips。信号29在Alpha上为SIGINFO / SIGPWR ,在Sparc上为SIGLOST。)

处理动作一项中的字母含义如下
A 缺省的动作是终止进程
B 缺省的动作是忽略此信号
C 缺省的动作是终止进程并进行内核映像转储(dump core)
D 缺省的动作是停止进程
E 信号不能被捕获
F 信号不能被忽略

上 面介绍的信号是常见系统所支持的。以表格的形式介绍了各种信号的名称、作用及其在默认情况下的处理动作。各种默认处理动作的含义是:终止程序是指进程退 出;忽略该信号是将该信号丢弃,不做处理;停止程序是指程序挂起,进入停止状况以后还能重新进行下去,一般是在调试的过程中(例如ptrace系统调 用);内核映像转储是指将进程数据在内存的映像和进程在内核结构中存储的部分内容以一定格式转储到文件系统,并且进程退出执行,这样做的好处是为程序员提 供了方便,使得他们可以得到进程当时执行时的数据值,允许他们确定转储的原因,并且可以调试他们的程序。

注意 信号SIGKILL和SIGSTOP既不能被捕捉,也不能被忽略。信号SIGIOT与SIGABRT是一个信号。可以看出,同一个信号在不同的系统中值可能不一样,所以建议最好使用为信号定义的名字,而不要直接使用信号的值。

只有第9种信号(SIGKILL)才可以无条件终止进程,其他信号进程都有权利忽略,

下面是常用的信号:
HUP 1 终端断线
INT 2 中断(同 Ctrl + C)
QUIT 3 退出(同 Ctrl + \)
TERM 15 终止
KILL 9 强制终止
CONT 18 继续(与STOP相反, fg/bg命令)
STOP 19 暂停(同 Ctrl + Z)

linux 常见终端热键以及Ctrl+C、Ctrl+Z比较 [转]

linux中存在一些按键,那么如何查阅目前的一些按键内容了?可以利用stty(setting tty 终端机的意思)。stty也可以帮助设置终端机的输入按键代表意义。

 >$ stty -a
speed 38400 baud; rows 24; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = ;
eol2 = ; swtch = ; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke

需要注意的是特殊字体那几个,此外^表示[Ctrl]那个按键的意思,如:intr = ^C表示利用【Ctrl】+c来完成的。几个重要的代表意义是:

eof:End of file的意思,代表结束输入;

erase:向前删除一个字符;

intr:送出一个interrupt(中断)的信号给目前正在运行的程序;
kill:删除在目前命令行上的所有字符;

quit:送出一个quit的信号给目前正在运行的进程;

start:在某个进程停止后,重新启动它的输出;

stop:停止目前屏幕的输出;

susp:送出一个terminal stop的信号给正在运行的进程;

如果你想要执行[ctrl]+h来进行字符的删除,那么可以执行:

root@mycomputer:~# stty erase ^h
Ctrl+C终止目前的命令

Ctrl+D输入结束(eof),例如邮件结束的时候

eof代表End of file的意思,代表结束输入

Ctrl+M就是Enter

Ctrl+S暂停屏幕的输出

Ctrl+Q恢复屏幕的输出

Ctrl+U在提示符下,将整行命令删除

Ctrl+Z暂停目前的命令

Ctrl+Z和Ctrl+C都是中断命令,但是它们的作用却不一样。

Ctrl+C是强制中断程序的执行,而Ctrl+Z是将任务中断,但是此任务并没有结束,还是在进程中只是保持挂起的状态,用户可以使用fg/bg操作继续前台或后台飞任务,fg命令重新启动前台被中断的任务。bg命令把被中断的任务放在后台执行。

来源:http://blog.sina.com.cn/s/blog_14ecbe4520102wrmv.html

 

信号具有平台相关性,不同平台下能使用的信号种类是有差异的。

Linux下支持的信号:

SEGV, ILL, FPE, BUS, SYS, CPU, FSZ, ABRT, INT, TERM, HUP, USR1, USR2, QUIT, BREAK, TRAP, PIPE

Windows下支持的信号:

SEGV, ILL, FPE, ABRT, INT, TERM, BREAK

孙悟空是哪一年出生

以地上时间计算,孙悟空入地狱时生死簿记载其342岁,其后孙悟空在天上呆了三次,计15天(弼马温)+180天左右(齐天大圣)+49天(炼丹炉)=244天左右,即244年,偷了蟠桃后在花果山上呆了一年,则孙悟空被压到五行山时已经587岁左右,而此年书中写明是王莽篡汉之时(第十四回),即公元8年,则猴王出世发生在公元前579年左右——而后贞观十三年(639年)取经,过了十四年取经结束,即653年(当然历史上这年唐太宗已经死了)。

若考虑王莽篡汉一说为误传,即孙悟空确实只是压了五百年,则孙悟空被压五行山为公元139年,东汉汉顺帝永和四年左右,那么再次以贞观十三年(639年)计算, 猴王出世是在公元前448年左右。

以上,孙悟空的出生年份:
1.采取第十四回王莽篡汉之说,孙悟空出生于公元前579年左右,时为春秋时代,周简王在位。
2.采取书中出现的大多数【被压了五百年】之说,孙悟空出生于公元前448年左右,时为战国时代,周贞定王在位。

一想到孙悟空当美猴王之时,那头正春秋五霸纷争,战国七雄裂土——花果山果然是人间福地,世外桃源啊!

作者:黄粱
链接:https://www.zhihu.com/question/35327628/answer/62342484
来源:知乎

卡巴斯基悲催:美国全力封杀全球第一杀软

虽然在AV-TEST最新杀软评测中,卡巴斯基得到了满分成为第一,但美国依然不允许它出现在政府采购名录中,而这个封杀的事态还在加剧。

据外媒CNET报道称,除了美国的政府机构外,FBI也在悄悄暗示那些私营机构停止使用卡巴斯基,情况十分严重。

报道中提到,能源行业以及使用工业控制系统等企业,都在被警告的名单中,而按照美国的意思,就是先让该国企业尽可能快的从其系统中移除卡巴斯基。

虽然卡巴严正否认自己进行涉嫌收集不法信息的“间谍”活动,甚至可以交出软件源代码,但目前的情况是,这丝毫没有打动当局控制者,而消息中还透露,俄罗斯也正努力移除美国科技公司如微软的操作系统。

对于微软来说,这件事他们暗地里非常开心,因为这样可以让更多的用户来换用Windows Defender,尤其是随着创意者更新全面升级的“新安全中心”。

来自:驱动之家

转自:https://www.oschina.net/news/87919/kaspersky-banned-by-american-government

React 定义组件的参数-生命周期

定义组件的参数-生命周期
创建期:getDefaultProps
创建期:getInitialState
创建期:componentWillMount
创建期:componentDidMount
存在期:componentWillReceiveProps
存在期:shouldComponentUpdate
存在期:componentWillUpdate
存在期:componentDidUpdate
销毁&清理期:componentWillUnmount

定义组件的参数-生命周期
生命周期相关参数,是React定义组件时提供的一系列处理函数(钓子函数),这些函数会在组件生命周期的某个阶段调用。

创建期:getDefaultProps

object getDefaultProps()

创建期:getInitialState

object getInitialState()
在组件挂载前(即:创建期)调用一次,其返回值将做为this.state的初始值。

getInitialState()方法会组件类创建的时候调用一次,其返回值会被缓存下来。该方法用于设置props属性的默认值,但仅对于非必须属性。如果父组件没有指定props中的某个值,此返回对象中的相应属性将会合并到this.props。

getInitialState()方法会在组件实例创建前调用,这时还不能使用this.props属性,且其返回对象是在所有实例间共享的。

创建期:componentWillMount

componentWillMount()
componentWillMount()服务器端和客户端都只调用一次,在初始化渲染执行之前被调用。如果在这个方法内调用setState()方法,render()方法将会收到更新后的state,也就是说这是我做在组件渲染前最后一个修改state的机会。

创建期:componentDidMount

componentDidMount()
componentDidMount()会在组件初始化(渲染完成)后立即调用一次,我们一般在这个方法中使用this.getDOMNode()方法访问原始DOM。

存在期:componentWillReceiveProps

componentWillReceiveProps(object nextProps)

componentWillReceiveProps在将要接受新的props时被调用
componentWillReceiveProps()方法会在组件生命周期的存在期调用,当组件感知到props属性改变,会调用此方法。render()方法将会在其后调用,这时我们可以通过this.setState()来阻止组件的再次渲染。

存在期:shouldComponentUpdate

boolean shouldComponentUpdate(object nextProps, object nextState)
shouldComponentUpdate()方法发生在组件生命周期的存在器,在组件收到新的props或state。在这个方法中,我们可以访问组件的props和state属性,通过这两个属性可以确认组件是否需要更新,如果不需要更新,则返回false,则其后的方法将不会在执行。如:

shouldComponentUpdate: function(nextProps, nextState) {
return nextProps.id !== this.props.id;
}

存在期:componentWillUpdate

componentWillUpdate(object nextProps, object nextState)
componentWillUpdate()会在收到新的props或state后调用,类似componentWillMount()。

存在期:componentDidUpdate

componentDidUpdate(object prevProps, object prevState)
componentDidUpdate()会在组件重新渲染后立即被调用,当我们需要在组件重新渲染后操作DOM则需要使用这个方法。

销毁&清理期:componentWillUnmount

componentWillUnmount()
componentWillUnmount()是组件销毁&清理期唯一调用的方法,它会在组件从DOM中移除时被调用,这时我们可以清理一些状态或清理在componentDidMount中创建的DOM元素。

据说只有程序员才能看懂的时钟 [转]

据说只有程序员才能看懂的时钟,你看明白了吗?

最近发现一个关于程序员的“数学钟”,也就是非常流行的下面这幅图:

以前,只知道其中十一个点钟的分析;对于3点钟,一直没有思路。于是发了一条朋友圈,求助大神解释其中的3点钟。在刘梓溪、贾顾森、黎鸣等大神的指导下,明白了其中是怎么回事。所以这里介绍下这十二个点,应该如何解释。个人观点,仅供参考。

12点

不用说了,1728的立方根。

1点

可能很多人不大知道,这是勒让德常数:
勒让德常数

其中的π(x)表示不大于x的素数的个数,可以用近似。

这个值经过勒让德、高斯等一批数学大佬的努力,最后被数学家Charles Jean证明为1。

2点

无穷递缩等比级数的求和,首项为1,公比为1/2,所以它的和为

3点

在刘梓溪、贾顾森、黎鸣等大神的帮助下,终于知道了。

广泛用于XML、HTML中。&#后面接十进制字符,&#x后面接十六进制字符。相当于转义序列吧。

其中十六进制33,等于十进制51,即’3’。

4点

同余问题(Modular Multiplicative Inverse)


5点

ϕ表示黄金分割比,

黄金分割比在斐波那契数列的通项公式中出现。

不过这个地方,我没搞懂,不知道这是不是这幅图作者的笔误?个人认为应该是 而不是

6点

不用说了,阶乘。

7点

表示6.999999999…其中9的头上一横,表示循环节是9。

那么,6.9999….为什么等于7呢?恩,还是无穷递缩等比级数的视角来考虑,就老少皆宜了。

6.9999…= 6 + 0.9 + 0.09 + 0.009 + 0.0009 + …

后面的那个,

0.9 + 0.09 + 0.009 + 0.0009 + …

首项为0.9,公比为0.1,收敛于1。

因此6.9999… = 7

8点

代表1000(二进制),因为只有第一个是亮的,其他是暗的。(亮为1,暗为0,bitmap的感觉。可能是盲文),因此为8。

9点

四进制。21(四进制) = 2 * 4 + 1 = 9。

10点

组合数,5! /(2! * 3!) = 10

11点

十六进制,A是10,B是11,C是12。注意,注意,这里是0x0B,不是0x08。哈哈。

点评:知识点有点重复,比如进制就有好几个。

来源:程序师

原标题:程序员的时钟

原文:https://www.oschina.net/news/87686/programmer-clock

巴科斯-诺尔范式 (BNF) 基本语法[转]

语法规范:BNF与ABNF

BNF 

巴科斯范式(BNF: Backus-Naur Form 的缩写)是由 John Backus 和 Peter Naur 首先引入的用来描述计算机语言语法的符号集。现在,几乎每一位新编程语言书籍的作者都使用巴科斯范式来定义编程语言的语法规则。

在BNF中,双引号中的字(“word”)代表着这些字符本身。而double_quote用来代表双引号。

在双引号外的字(有可能有下划线)代表着语法部分。

< > : 内包含的为必选项。
[ ] : 内包含的为可选项。
{ } : 内包含的为可重复0至无数次的项。
|  : 表示在其左右两边任选一项,相当于”OR”的意思。
::= : 是“被定义为”的意思
“…” : 术语符号
[…] : 选项,最多出现一次
{…} : 重复项,任意次数,包括 0 次
(…) : 分组
|   : 并列选项,只能选一个
斜体字: 参数,在其它地方有解释

下面是是用BNF来定义的Java语言中的For语句的实例:

FOR_STATEMENT ::= 
      "for" "(" ( variable_declaration | 
  ( expression ";" ) | ";" ) 
      [ expression ] ";" 
      [ expression ] ";" 
      ")" statement

 

理解巴科斯-诺尔范式 (BNF) 语法

语法结构使用BNF范式形式给出,先做一个简单了解。

在双引号中的字(“word”)代表着这些字符本身。而double_quote用来代表双引号。
在双引号外的字(有可能有下划线)代表着语法部分。
尖括号( < > )内包含的为必选项。
方括号( [ ] )内包含的为可选项。
大括号( { } )内包含的为可重复0至无数次的项。
竖线( | )表示在其左右两边任选一项,相当于”OR”的意思。
::= 是“被定义为”的意思。

BNF 语法使用下表中显示的表示法。

约定/符号 含义
::= 等效
| OR
X+ 一个或多个 X。
[X] X 可选。可选的分隔符由 [] 表示。
任何粗体文本 字符串。
任何斜体 文本 如何构造字符串。

正如前表中所指出的,注册器脚本使用字符串。这些值是必须出现在脚本中的实际的文本。下表描述 ATL 注册器脚本中使用的字符串。

字符串 操作
ForceRemove 完全移除下一项(如果存在),然后重新创建它。
NoRemove 在“注销”期间不移除下一项。
val 指定 <Key Name> 实际上是一个命名值。
Delete 在“注册”期间删除下一项。
s 指定下一个值为字符串 (REG_SZ)。
d 指定下一个值为 DWORD (REG_DWORD)。
m 指定下一个值为多字符串 (REG_MULTI_SZ)。
b 指定下一个值为二进制值 (REG_BINARY)。

  ABNF

RFC2234 定义了扩展的巴科斯范式(ABNF)。近年来在Internet的定义中 ABNF 被广泛使用。ABNF 做了更多的改进。扩充巴科斯-瑙尔范式(ABNF)基于了巴科斯-瑙尔范式(BNF),但由它自己的语法和推导规则构成。这种元语言的发起原则是描述作为通信协议(双向规范)的语言的形式系统。它建档于 RFC 4234 中通常充当 IETF 通信协议的定义语言。

ABNF 规定是一组推导规则,写为:

规则 = 定义 ; 注释 CR LF

这里的规则是大小写敏感的非终止符,定义由定义这个规则的符号序列,一个文档注释组成,并结束于回车换行。

规则名字是大小写不敏感的: <rulename><Rulename><RULENAME> 和 <rUlENamE> 都提及同一个规则。规则名字由开始于一个字母的字母、数字和连字符组成。不要求用尖括号(“<”, “>”) (如 BNF 那样)包围规则名字。但是它们可以用来界定规则名字,比如在冗文中识别出规则名字的时候。ABNF 使用 7-位 ASCII 编码,在 8-位域中把高位置零。

终结符由一个或多个数值字符指定。数值字符可以指定为跟随着基数(b = 二进制, d = 十进制, x = 十六进制)的一个百分号“%”,随后是这个数值,或数值的串联(用“.” 来指示)。例如回车可以指定为十进制的 %d13 或十六进制的 %x0D。回车换行可以指定为 %d13.10

文字正文通过使用包围在引号(")中字符串来指定。这些字符串是大小写不敏感的,使用的字符集是 US-ASCII。所以字符串“abc”将匹配“abc”, “Abc”, “aBc”, “abC”, “ABc”, “AbC”, “aBC” 和 “ABC”。对于大小写敏感匹配,必须定义明确的字符: 要匹配 “aBc” 定义将是 %d97 %d66 %d99

操作符

空白被用来分隔定义的各个元素: 要使空格被识别为分割符则必须明确的包含它。

串联

规则1 规则2

规则可以通过列出一序列的规则名字来定义。

要匹配字符串“aba”可以使用下列规则:

fu = %x61; a
bar = %x62; b
mumble = fu bar fu

选择

规则1 / 规则2

规则可以通过用反斜杠(“/”)分隔的多选一规则来定义。

要接受规则 <fu> 或规则 <bar> 可构造如下规则:

fubar = fu / bar

递增选择

规则1 =/ 规则2

可以通过使用在规则名字和定义之间的“=/”来向一个规则增加补充选择。

规则

ruleset = alt1 / alt2 / alt3 / alt4 / alt5

等价于

ruleset = alt1 / alt2
ruleset =/ alt3
ruleset =/ alt4 / alt5

值范围

%c##-##

数值范围可以通过使用连字符(“-”)来指定。

规则

OCTAL = "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7"

等价于

OCTAL = %x30-37

序列分组

(规则1 规则2)

元素可以放置在圆括号中来组合定义中的规则。

要匹配“elem fubar snafu”或“elem tarfu snafu”可以构造下列规则:

group = elem (fubar / tarfu) snafu

要匹配“elem fubar”或“tarfu snafu”可以构造下列规则:

group = elem fubar / tarfu snafu
group = (elem fubar) / (tarfu snafu)

可变重复

n*n规则

要指示一个元素的重复可以使用形式 <a>*<b> 元素。可选的 <a> 给出要包括的元素的最小数目,缺省为 0。可选的 <b> 给出要包括的元素的最大数目,缺省为无穷。

对零或多个元素使用 *元素,对一或多个元素使用 1*元素,对二或三个元素使用 2*3元素

特定重复  

n规则

要指示明确数目的元素可使用形式 <a> 元素,它等价于 <a>*<a>元素

使用 2DIGIT 得到两个数字,使用 3DIGIT 得到三个数字。(DIGIT 在下面的核心规则中定义)。

可选序列

[规则]

要指示可选元素下列构造是等价的:

[fubar snafu]
*1(fubar snafu)
0*1(fubar snafu)

注释

; 注释

分号(“;”)开始一个注释并持续到此行的结束。

操作符优先级

上述操作符有从最紧绑定(binding)到最松绑定的给定优先级:

  1. 字符串,名字形成(formation)
  2. 注释
  3. 值范围
  4. 重复
  5. 分组,可选
  6. 串联
  7. 选择

与串联一起使用选择操作符可以造成混淆,建议使用分组来做明确串联分组。

核心规则

核心规则定义于 ABNF 标准中。

规则 形式定义 意义
ALPHA %x41-5A / %x61-7A 大写和小写 ASCII 字母 (A-Z a-z)
DIGIT %x30-39 数字 (0-9)
HEXDIG DIGIT / “A” / “B” / “C” / “D” / “E” / “F” 十六进制数字 (0-9 A-F a-f)
DQUOTE %x22 双引号
SP %x20 空格
HTAB %x09 水平tab
WSP SP / HTAB 空格和水平tab
LWSP *(WSP / CRLF WSP) 线性空白(晚于换行)
VCHAR %x21-7E 可见(打印)字符
CHAR %x01-7F 任何 7-位 US-ASCII 字符,不包括 NUL
OCTET %x00-FF 8 位数据
CTL %x00-1F / %x7F 控制字符
CR %x0D 回车
LF %x0A 换行
CRLF CR LF 互联网标准换行
BIT “0” / “1”

例子

在巴科斯范式(BNF)条目中的邮政地址的例子可以被指定为:

postal-address = name-part street zip-part

name-part = *(personal-part SP) last-name [SP suffix] CRLF
name-part = / personal-part CRLF

personal-part = first-name / (initial ".")
first-name = *ALPHA
initial = ALPHA
last-name = *ALPHA
suffix = ("Jr." / "Sr." / 1*("I" / "V" / "X"))

street = [apt SP] house-num SP street-name CRLF
apt = 1*4DIGIT
house-num = 1*8(DIGIT / ALPHA)
street-name = 1*VCHAR

zip-part = town-name "," SP state 1*2SP zip-code CRLF
town-name = 1*(ALPHA / SP)
state = 2ALPHA
zip-code = 5DIGIT ["-" 4DIGIT]

引用

参考

来源:http://kb.cnblogs.com/page/189566/

来源:http://tianya23.blog.51cto.com/1081650/633141

IceGrid应用配置[转]

1. 概述

1.1 配置目标

本文档是描述Ice中间件中的IceGrid服务的应用配置,通过使用IceGrid服务来实现:
1. 服务器端服务分布式部署。
2. 服务器端服务按需激活。
3. 服务器端服务多节点负载均衡。
4. 注册服务主/从热备(Master/Slaves)
5. 集成IceBox服务

1.2 实验环境

1. 硬件:hp服务器,3台
2. 操作环境:Red Hat 5
3. 服务器程序:ServerApp.jar
4. 说明:实际应用中,服务器节点可任意扩充、操作系统可被更换、服务器程序可用实际项目的服务程序替换,本文档所描述的配置方式具有通用性,适用但不局限于当前实验环境。

1.3 局限

本文档不详细描述IceGrid服务的运行机制和实现原理,不详细介绍服务器端和客户端程序的实现,主要描述IceGrid服务应用的配置步骤、主要配置项及验证配置结果等。

2. 配置过程

2.1 服务器端配置

配置步骤:
1. 创建主注册服务(Master)的配置文件config_master.grid,文件名称可以任意
2. 创建从注册服务(Slave)的配置文件 config_slave.grid, 文件名称可以任意
3. 创建各节点服务的配置文件config.node,文件名称可以任意
4. 创建分布式应用配置文件app.xml,文件名称可以任意,但格式最好定义成xml
5. 运行Ice提供的工具,启动我们的分布式应用,主要有如下两个工具:icegridnode和icegridadmin。详细启动过程如下:
1) icegridnode–Ice.Config=config_master.grid 启动主注册服务
2) icegridnode–Ice.Config=config_slave.grid 启动从注册服务
3) icegridadmin–Ice.Config= config_master.grid -e “application add app.xml” 部署分布式服务
icegridadmin –Ice.Config= config_master.grid-e “application update app.xml” 重新部署分布式服务
4) icegridnode–Ice.Config=config.node 将各节点注册到注册服务的注册表中
配置文件清单:
假设有n个节点(n > 0), 其中从注册服务有x个,(x > 0)
config_master.grid ———- 主注册服务配置文件 ——— 1份
config_slave.grid ———– 从注册服务配置文件 ——— x份
config.node —————– 节点配置文件 ————– n份
app.xml ———————- 部署配置文件 ————– 1份
通常情况下,由于注册服务占用资源很少,所以一般都会和一个节点集成在一起,并且可以和节点服务在一个进程中运行。因此,如果假设服务部署到n个服务器,通常情况下配置文件清单如下:
config_master.grid– 主注册服务配置文件 — 1份 — 主注册服务信息+节点信息
config_slave.grid— 从注册服务配置文件 — x份 — 从注册服务信息+节点信息
config.node——— 节点配置文件 —- n-1-x份 — 节点信息
app.xml————- 部署配置文件 ——– 1份 — 部署信息
其中app.xml要和config_master.grid放在一台服务器上,下面的各章节将详细介绍各配置文件。

2.1.1 主注册服务配置

config_master.grid的内容:

#
# The IceGrid InstanceName
#
IceGrid.InstanceName=YunIceGrid # 1
#
# The IceGridlocator proxy.
#
Ice.Default.Locator=YunIceGrid/Locator:default-h liyunde.com -p 4061:default -h ice.liyunde.com -p 4061 #2
#
# IceGridregistry configuration.
#
IceGrid.Registry.Client.Endpoints=default-p 4061 #3
IceGrid.Registry.Server.Endpoints=default #4
IceGrid.Registry.Internal.Endpoints=default #5
IceGrid.Registry.Data=master #6
IceGrid.Registry.PermissionsVerifier=YunIceGrid/NullPermissionsVerifier #7
IceGrid.Registry.AdminPermissionsVerifier=YunIceGrid/NullPermissionsVerifier#8
IceGrid.Registry.SSLPermissionsVerifier=YunIceGrid/NullSSLPermissionsVerifier#9
IceGrid.Registry.AdminSSLPermissionsVerifier=YunIceGrid/NullSSLPermissionsVerifier #10
#
# IceGrid SQLconfiguration if using SQL database.
#
#Ice.Plugin.DB=IceGridSqlDB:createSqlDB #11
#IceGrid.SQL.DatabaseType=QSQLITE #12
#IceGrid.SQL.DatabaseName=register/Registry.db #13
#
#
#Ice Error andStandard output Set
#
#Ice.StdErr=master/stderr.txt #14
#Ice.StdOut= master/stdout.txt #15
#
#Trace Registryproperties
#
Ice.ProgramName=Master #16
IceGrid.Registry.Trace.Node=3 #17
IceGrid.Registry.Trace.Replica=3 #18
#
# IceGrid nodeconfiguration.
#
IceGrid.Node.Name=node_1 #19
IceGrid.Node.Endpoints=default #20
IceGrid.Node.Data=node_1 #21
IceGrid.Node.CollocateRegistry=1 #22
#IceGrid.Node.Output=node_1 #23
#IceGrid.Node.RedirectErrToOut=1 #24
# Traceproperties.
#
IceGrid.Node.Trace.Activator=1 #25
#IceGrid.Node.Trace.Adapter=2 #26
#IceGrid.Node.Trace.Server=3 #27
#
# Dummy usernameand password for icegridadmin.
#
IceGridAdmin.Username=mygrid #28
IceGridAdmin.Password=mygrid #29

配置项说明:
#1 为这个应用实例指定一个唯一的标识
# 2 注册服务的端点信息(主注册服务和所有的从注册服务),节点注册时要用到
# 3 客户端访问注册服务器的端点信息
# 4 服务访问注册服务器的端点信息,通常是default
# 5 内部访问端点信息,通常是default,节点用这个端口和注册服务通信
# 6 注册服务的数据目录的路径
# 7 设定防火墙安全代理,从而控制客户端访问注册表时可用的权限
# 8 设定防火墙安全代理,从而控制注册表管理者可用的权限
# 9 设定SSL安全代理,从而设定客户端访问注册表时的SSL安全访问机制
# 10 设定SSL安全代理,从而设定注册表管理者的SSL安全访问机制
# 11 指定Ice对象序列化的机制,如果不设置,默认用Freeze机制
# 12 指定使用数据库的类型
#13 指定使用数据库的名称
#14 指定标准错误输出文件
#15 指定标准输出文件
#16 指定主注册服务的名称
#17 指定主注册服务跟踪节点信息的级别(0~3),默认为0
#18 指定主/从热备注册服务的跟踪级别(0~3),默认为0
# 19 定义节点的名称,必须唯一
# 20 节点被访问的端口信息,注册服务使用这个端点和节点通信,通常设为default
# 21 节点的数据目录的路径
# 22 定义节点是否和注册服务并置在一起,设为1时并置,设为0时不并置
# 23 节点标准输出信息重定向蹈的目录路径,会自动生成输出文件
# 24 节点上的服务程序的标准错误重定向到标准输出
# 25 激活器跟踪级别,通常有0,1,2,3级,默认是0
# 26 对象适配器跟踪级别,通常有0,1,2,3级,默认是0
# 27 服务跟踪级别,通常有0,1,2,3级,默认是0
# 28 IceGrid管理器登录该应用的用户名
# 29 IceGrid管理器登录该应用的密码
未涉及的属性还有一些,如果需要请参考官方文档。

2.1.2 从注册服务配置

config_slave.grid的内容:
#
# The IceGridlocator proxy.
#
Ice.Default.Locator=YunIceGrid/Locator:default-h 10.0.2.241 -p 4061:default -h 10.0.2.242-p 4061 #1
#
# IceGridregistry configuration.
#
IceGrid.Registry.Client.Endpoints=default-p 4061 #2
IceGrid.Registry.Server.Endpoints=default #3
IceGrid.Registry.Internal.Endpoints=default #4
IceGrid.Registry.Data=slave_1 #5
IceGrid.Registry.ReplicaName=slave_1 #6
IceGrid.Registry.PermissionsVerifier=YunIceGrid/NullPermissionsVerifier #7
IceGrid.Registry.AdminPermissionsVerifier=YunIceGrid/NullPermissionsVerifier#8
IceGrid.Registry.SSLPermissionsVerifier=YunIceGrid/NullSSLPermissionsVerifier#9
IceGrid.Registry.AdminSSLPermissionsVerifier=YunIceGrid/NullSSLPermissionsVerifier #10
#
# IceGrid SQLconfiguration if using SQL database.
#
#Ice.Plugin.DB=IceGridSqlDB:createSqlDB #11
#IceGrid.SQL.DatabaseType=QSQLITE #12
#IceGrid.SQL.DatabaseName=register/Registry.db #13
#
#Ice Error andStandard output Set
#
#Ice.StdErr=slave_1/stderr.txt #14
#Ice.StdOut=slave_1/stdout.txt #15
#
#Trace Registryproperties
#
Ice.ProgramName=Slave_1 #16
IceGrid.Registry.Trace.Node=3 #17
IceGrid.Registry.Trace.Replica=3 #18
#
# IceGrid nodeconfiguration.
#
IceGrid.Node.Name=node_2 #19
IceGrid.Node.Endpoints=default #20
IceGrid.Node.Data=node_2 #21
IceGrid.Node.CollocateRegistry=1 #22
#IceGrid.Node.Output=node_2 #23
#IceGrid.Node.RedirectErrToOut=1 #24
# Traceproperties.
#
IceGrid.Node.Trace.Activator=1 #25
#IceGrid.Node.Trace.Adapter=2 #26
#IceGrid.Node.Trace.Server=3 #27
#
# Dummy usernameand password for icegridadmin.
#
IceGridAdmin.Username=mygrid #28
IceGridAdmin.Password=mygrid #29
配置项说明:
其实这个文件和主注册配置文件基本一样,差别只有一点:
1. 没有指定应用实例名,因为在主注册服务中已经有了定义
2. 多了第6行,IceGrid.Registry.ReplicaName=slave_1,指定从注册服务的名称
其它的基本就没有差别了,大部分属性项在config_master.grid里面都有定义,为了方便阅读,下面也将用到的各项给出说明:
# 1 注册服务的端点信息(主注册服务和所有的从注册服务),节点注册时要用到
# 2 客户端访问注册服务器的端点信息
# 3 服务访问注册服务器的端点信息,通常是default
#4 内部访问端点信息,通常是default,节点用这个端口和注册服务通信
# 5 注册服务的数据目录的路径
# 6 指定从注册服务的名称
# 7 设定防火墙安全代理,从而控制客户端访问注册表时可用的权限
#8 设定防火墙安全代理,从而控制注册表管理者可用的权限
# 9 设定SSL安全代理,从而设定客户端访问注册表时的SSL安全访问机制
#10 设定SSL安全代理,从而设定注册表管理者的SSL安全访问机制
# 11 指定Ice对象序列化的机制,如果不设置,默认用Freeze机制
# 12 指定使用数据库的类型
#13 指定使用数据库的名称
#14 指定标准错误输出文件
#15 指定标准输出文件
#16 指定从注册服务运行时程序名称
#17 指定从注册服务跟踪节点信息的级别(0~3),默认为0
#18 指定主/从热备注册服务的跟踪级别(0~3),默认为0
# 19 定义节点的名称,必须唯一
# 20 节点被访问的端口信息,注册服务使用这个端点和节点通信,通常设为default
# 21 节点的数据目录的路径
# 22 定义节点是否和注册服务并置在一起,设为1时并置,设为0时不并置
# 23 节点标准输出信息重定向蹈的目录路径,会自动生成输出文件
# 24 节点上的服务程序的标准错误重定向到标准输出
# 25 激活器跟踪级别,通常有0,1,2,3级,默认是0
# 26 对象适配器跟踪级别,通常有0,1,2,3级,默认是0
# 27 服务跟踪级别,通常有0,1,2,3级,默认是0
# 28 IceGrid管理器登录该应用的用户名
# 29 IceGrid管理器登录该应用的密码

2.1.3 应用部署配置

app.xml配置文件内容:

1<icegrid>

2 <application name=“RTDSSystem”>

3 <server-template id=“RTDSSystemServer”>

4 <parameter name=“index”/>

5 <server id=“RTDSSystemServer-${index}”exe=Java activation=“on-demand”>

6 <adapter name=“RTDataSysytem” endpoints=“tcp” replica-group=“ReplicatedRTDataSysytemAdp”/>

7 <option>-jar</option>

8 <option>ServerApp.jar</option>

9 </server>

10 </server-template>

11

12 <replica-group id=“ReplicatedRTDataSysytemAdp”>

13 <load-balancing type=“round-robin”/>

14 <object identity=“RTDataSource” type=“::RTDataSystem::RTDataSource”/>

15 </replica-group>

16

17 <node name=“node_1”>

18 <server-instance template=“RTDSSystemServer” index=“1”/>

19 <server-instance template=“RTDSSystemServer” index=“11”/>

20 <server-instance template=“RTDSSystemServer” index=“111”/>

21 </node>

22 <node name=“node_2”>

23 <server-instance template=“RTDSSystemServer” index=“2”/>

24 <!–server-instancetemplate=”RTDSSystemServer” index=”22″/–>

25 <!–server-instancetemplate=”RTDSSystemServer” index=”222″/–>

26 </node>

27 <node name=“node_3”>

28 <server-instance template=“RTDSSystemServer” index=“3”/>

29 <!–server-instancetemplate=”RTDSSystemServer” index=”33″/–>

30 <!–server-instancetemplate=”RTDSSystemServer” index=”333″/–>

31 </node>

32 </application>

33</icegrid>

配置文件结构分析:

IceGrid里,部署是一个在注册服务中表述一个应用(Application)的过程,而部署配置文件就是来描述这些配置信息的文件,这个配置文件是用xml标记性语言来描述的。通常一个部署应该包含如下信息:

1. 应用标签(application),name属性定义这个应用的名字

2. 服务(server), 一个逻辑上的服务器,能够通过exe命令而启动的一个服务程序。activation属性,是设置服务的启动方式,on-demand是最常用的方式,另外还有always等启动方式;option标签是exe执行命令命令行的参数;

3. 适配器(adpter),定义服务器端的适配器。

name属性唯一标志这个适配器;

endpoints属性指定端点信息;

replica-group属性标示该适配器是个可复制组集群,并指定这个可复制组的名称;

register-process属性定义了是否这个节点是否可以被icegrid关闭;

4. 节点(node),它应该代表了一个物理上的节点。

name属性指定节点的名字,并且是唯一的。

5. 可复制组(replica-group),一组对象适配器的集合。

id属性唯一标识一个可复制组;

load-balancing子项中type属性指定负载均衡策略,icegrid提供了四种负载均衡策略: Random (随机方式)

Adaptive(适配方式)

Round Robin(最近最少使用)

Ordered(顺序方式)

object子项定义适配器绑定的服务对象信息。其中identity属性指定对象的标识,type属性指定了对象的层次结构类型。这两个属性都可以唯一的标识一个服务对象。

6. 服务模板(server-temple),服务模板是对服务的一个抽象,避免了重复定义。这样,在节点中描述服务时只需要实例化它的服务模板就可以了。

id属性唯一标识一个服务模板;

parameter子项定义服务模板的参数,可包含多个,主要实例化服务时用;

server子项就是上面2中的服务定义;

另外还有一些特殊的服务模板,比如:icebox服务模板,它的定义和通用的服务模板的定义不太一样。

解析app.xml文件:

通过对配置文件结构的分析,来解析一下app.xml。

第1行,标识这是一个icegrid的配置文件;

第2行,标识应用的名称为RTDSSystem,这个名称是唯一的;

第3~10行,定义了一个服务模板RTDSSystemServer,并有一个参数index;

其中5~9定义了这个模板包含的服务定义,第6行是这个服务包含的对象适配器

的定义;

第12~15行,是对可复制组的定义,包括服务对象的定义和负载均衡策略;

第17~21行,是对节点node_1的定义,指定了节点的名称,包含的服务(3个服务);

第22~26行,是对节点node_2的定义

第27~31行,是对节点node_3的定义

最后两行是闭合标签,至此一个icegrid的分布式部署配置文件就完成了。

部署配置文件的扩展:

app.xml中对服务模板、适配器、服务对象等的配置都是一个,事实上这些可以在文件中定义多个,比如可以有多个服务模板,一个服务里可以有多个适配器,可以有多个可复制组,一个节点里可以有多个不同类型的服务等。

另外,app.xml可以包含其它的xml。

2.1.4 节点配置

config.grid文件的内容:

# The IceGridlocator proxy.
#
Ice.Default.Locator=YunIceGrid/Locator:default-h 10.0.2.241 -p 4061:default -h 10.0.2.242-p 4061 #1
#
# IceGrid nodeconfiguration.
#
IceGrid.Node.Name=node_2 #2
IceGrid.Node.Endpoints=default #3
IceGrid.Node.Data=node_2 #4
IceGrid.Node.Output=node_2 #5
IceGrid.Node.RedirectErrToOut=1 #6
# Trace properties.
#
IceGrid.Node.Trace.Activator=1 #7
#IceGrid.Node.Trace.Adapter=2 #8
#IceGrid.Node.Trace.Server=3 #9

配置项说明:
事实上,这个文件里面的配置项,在config_slave.grid中都有描述,但这里也列出来,方便阅读。
#1 注册服务的端点信息(主注册服务和所有的从注册服务),节点注册时要用到
#2 定义节点的名称,必须唯一
#3 节点被访问的端口信息,注册服务使用这个端点和节点通信,通常设为default
#4 节点的数据目录的路径
#5 节点标准输出信息重定向的目录路径,会自动生成输出文件
#6 节点上的服务程序的标准错误重定向到标准输出
#7 激活器跟踪级别,通常有0,1,2,3级,默认是0
#8 对象适配器跟踪级别,通常有0,1,2,3级,默认是0
#9 服务跟踪级别,通常有0,1,2,3级,默认是0

2.2 客户端配置

客户端的配置很简单,和分布式相关的配置就一项,添加如下:
#
# The IceGridlocator proxy.
#注册服务的端点信息(主注册服务和所有的从注册服务),用于定位
Ice.Default.Locator=YunIceGrid/Locator:default-h 10.0.2.241 -p 4061:default -h 10.0.2.242-p 4061

3. 结果验证

3.1 程序方式

1. 启动服务器
1) icegridnode–Ice.Config=config_master.grid 启动主注册服务和节点1
2) icegridnode–Ice.Config=config_slave.grid 启动从注册服务和节点2
3) icegridadmin–Ice.Config=config_master.grid -e “application add app.xml” 部署分布式服务
4) icegridnode–Ice.Config=config.node 启动节点3
2. 启动客户端,进行多次远程调用,根据执行情况就可以判断服务器端是否配置成功。

3.2 工具方式

用Ice官方提供的可视化管理工具IceGridGUI.jar来验证和管理icegrid的部署。
打开dos窗口,在命令行下进入C:\Program Files\ZeroC\Ice-3.4.1\bin目录下,然后运行“java –jar IceGridGUI.jar”,弹出IceGrid Admin的主界面

1. 高级应用配置

4.1 集成IceBox

在文档《IceBox开发和配置》(当前是1.0版)中,介绍了一个IceBox服务程序的开发方法和单独应用中配置和管理的过程。在实际的应用中,IceBox服务通常集成到IceGrid中,并通过IceGrid进行激活和部署。
本章节中IceBox服务是集成在IceGrid中,并通过IceGrid进行部署,所以IceBox服务的配置信息不再同《IceBox开发和配置》中一样在config.icebox中描述,而是直接配置在部署文件app.xml中。那也就是说,IceGrid集成IceBox服务,只需要在app.xml文件中添加Icebox服务相关的配置信息就可以了。事实上,有关Ice所有的配置信息(除IceGrid自身的配置信息),都可以添加到app.xml中,并通过icegrid部署后生效。
下面各节详细描述IceBox服务的集成过程。

4.1.1 IceBox服务程序编写

请参考文档《IceBox开发和配置》,这里不再详述。由于IceBox服务相关的配置信息都放在了app.xml中,并且服务是通过IceGrid按需激活的,因此这里程序代码略有调整。下面列出IceBox服务的实现代码:
文件名:ServerService.java

import main.java.DataSource;

import IceBox.Service;

public class ServerService implements IceBox.Service {

/**

* @param name 配置文件中的service名称

* @param communicator对象,由IceBox.ServiceManager负责创建和销毁。

* 可能同时被其他服务共享使用(由配置文件决定),object Adapter的名

* 称必须是唯一的;

* @param args 配置文件中的参数列表

* @Override

**/

public void start(String name,Ice.Communicator communicator,

String[] args){

//创建objectAdapter,名称有配置文件决定

Adapter =communicator.createObjectAdapter(

“RTDataSystem-“+name);

//创建servant

StringRTDataSourceIdentity = communicator.getProperties().

getProperty(“RTDataSource.Identity”);

DataSourceobjDataSrc = new DataSource(“dataSource”);

Adapter.add(objDataSrc,

communicator.stringToIdentity(RTDataSourceIdentity));

Adapter.activate();

}

/**

*

* @param args

* @Override

*

**/

public void stop()

{

Adapter.destroy();

}

private Ice.ObjectAdapter Adapter;

}

4.1.2 IceGrid集成IceBox服务

IceGrid集成IceBox只和部署文件(app.xml)有关,IceBox服务(service)的粒度和普通的server是一样的,因此IceBoxservice的部署和普通的server非常类似,它同样有模板、服务(service)和实例化的概念,可以将IceBox service理解为一个特殊的server。
为了能更清楚的描述这个集成配置的过程,在IceGrid配置的基础上,添加IceBox服务。具体目标如下:
1. 集成ServerService服务(service),并且ServerService服务(service)使用的服务对象和之前server的服务对象使用同一个(type–::RTDataSystem::RTDataSource)
2. 在节点1(node_1)上添加IceBox服务功能(IceBox-Node1),这个IceBox服务包含了5个ServerService服务;同样的在节点2(node_2)上也添加一个IceBox服务功能(IceBox-Node2),也包含了5个ServerService服务
3. 这些IceBox服务中分布的多个服务(service)和之前已经存在的服务(server)一起通过IceGrid实现负载均衡
为了实现上述的功能,需要添加IceBox服务的相关配置,首先看一下此时app.xml的变化,变化和添加部分用浅灰阴影标出。
app.xml
<?xml version=”1.0″encoding=”UTF-8″ ?>
<icegrid>
<applicationname=”RTDSSystem“>
<server-templateid=”RTDSSystemServer“>
<parameter name=”index“/>
<server id=”RTDSSystemServer-${index}” exe=”java“activation=”on-demand“>
<adapter name=”RTDataSysytem“endpoints=”tcp
replica-group=”RTDataSystemGroup“/>
<option>jar</option>
<option>ServerApp.jar</option>
</server>
</server-template>
<!— begin服务模板定义–>
1 <service-templateid=”RTDSystemService“>
2 <parameter name=”name“/>
3 <service name=”${name}” entry=”ServerService“>
4 <description>A simple service named after ${name}</description>
5 <properties>
6 <property name=”RTDataSource.Identity” value=”RTDataSource“/>
7 </properties>
8 <adapter name=”RTDataSystem-${name}” endpoints=”tcp
id=”RTDataSystem-${name}” replica-group=”RTDataSystemGroup
server-lifetime=”false“/>
11 </service>
12 </service-template>
<!– end服务模板定义–>
<replica-groupid=”RTDataSystemGroup“>
<load-balancingtype=”round-robin“/>
<!–load-balancingtype=”ordered” /–>
<!–load-balancingtype=”adaptive” /–>
<!–load-balancingtype=”random” n-replicas=”0″/–>
<object identity=”RTDataSource” type=”::RTDataSystem::RTDataSource“/>
</replica-group>
<node name=”node_1“>
<server-instancetemplate=”RTDSSystemServer” index=”1“/>
<server-instancetemplate=”RTDSSystemServer” index=”11“/>
<server-instancetemplate=”RTDSSystemServer” index=”111“/>
<!— begin IceBox服务配置 IceBox-Node1–>
1 <icebox id=”IceBox-Node1” activation=”on-demand“exe=”java”>
2 <description>Asample IceBox server IceBox-Node1</description>
3 <option>IceBox.Server</option>
4 <properties>
5 <property name=”IceBox.InstanceName” value=”${server}“/>
6 <property name=”Ice.Admin.Endpoints” value=”tcp -h 10.0.2.241“/>
7 <property name=”IceBox.Trace.ServiceObserver” value=”1“/>
8 </properties>
9 <service-instance template=”RTDSystemService” name=”one“/>
10 <service-instancetemplate=”RTDSystemService” name=”two“/>
11 <service-instancetemplate=”RTDSystemService” name=”three“/>
12 <service-instancetemplate=”RTDSystemService” name=”four“/>
13 <service-instancetemplate=”RTDSystemService” name=”five“/>
14 </icebox>
<!— end IceBox服务配置 IceBox-Node1–>
</node>
<node name=”node_2“>
<server-instancetemplate=”RTDSSystemServer” index=”2“/>
<server-instancetemplate=”RTDSSystemServer” index=”22“/>
<server-instancetemplate=”RTDSSystemServer” index=”222“/>
<!— begin IceBox服务配置 IceBox-Node2–>
1 <icebox id=”IceBox-Node2” activation=”on-demand“exe=”java“>
2 <description>Asample IceBox server IceBox-Node2</description>
3 <option>IceBox.Server</option>
4 <properties>
5 <property name=”IceBox.InstanceName” value=”${server}“/>
6 <property name=”Ice.Admin.Endpoints” value=”tcp -h 10.0.2.242“/>
7 <property name=”IceBox.Trace.ServiceObserver” value=”1“/>
8 </properties>
9 <service-instancetemplate=”RTDSystemService” name=”2-one”/>
10 <service-instancetemplate=”RTDSystemService” name=”2-two“/>
11 <service-instancetemplate=”RTDSystemService” name=”2-three“/>
12 <service-instancetemplate=”RTDSystemService” name=”2-four“/>
13 <service-instancetemplate=”RTDSystemService” name=”2-five“/>
14 </icebox>
<!— begin IceBox服务配置 IceBox-Node2–>
</node>
<node name=”node_3“>
<server-instancetemplate=”RTDSSystemServer” index=”3“/>
</node>
</application>
</icegrid>
app.xml中增加的IceBox服务相关的配置部分如下:
n 服务摸板(Service Template):
可以对比一下servertemplate的定义,两者基本上没有什么区别,最大的不同是
Server template中server是指定一个可执行的程序,而service中指定的是动态加载
的组件入口。以下解释上述配置中的服务模板的定义:
第1行指定定义模板的id,唯一标志一个服务模板,第12是闭合标签;
第2行定义了一个参数name,默认值是“name”;
第3~11行定义了模板中使用的服务(service),并在该service中指定了名称、
入口、描述信息、配置属性,定义了一个对象适配器;
第4行,是该服务的描述信息;
第5~7行,是属性定义列表,这里定义了一个属性RTDataSource.Identity,并
指定其值为RTDataSource;
第8行,定义了一个对象适配器,指定了其name、endpoints、id、replica-group
等属性信息,这个基本上和server中adapter的定义没有什么区别
以上内容就是service模板的定义。
n IceBox服务(IceBox-Node1):
icebox服务的定义被包含在分布的服务器节点中,主要包括三部分的信息:
1. IceBox服务的启动配置信息
2. IceBox的属性配置信息
3. Service服务实例化列表
下面解释这块内容:
第1~3行,指定了IceBox服务的名称,启动方式,启动执行程序等
第4~8行,指定了IceBox服务的属性配置列表,这里定义了IceBox服务的实
例名称、管理器访问端点以及service被跟踪的级别
第9~13行,实例化了5个service服务
至此,一个包含了5个serverservice服务的IceBox服务被集成在node1中。
n IceBox服务(IceBox-Node2)
同IceBox服务(IceBox-Node1)中描述,只是具体value有所不同,这里不再解释。

4.1.3 测试验证

验证方式同第3章,这里不再赘述。部署完成后,就可以通过IceGridGUI.jar程序来进行管理
参考来源:http://blog.csdn.net/educast/article/details/9414789

优秀程序员眼中的整洁代码[转]

有多少程序员,就有多少定义。所以我只询问了一些非常知名且经验丰富的程序员。

image.php_-57.gif

Bjarne Stroustrup,C++语言发明者,C++ Programming Language(中译版《C++程序设计语言》)一书作者。

我喜欢优雅和高效的代码。代码逻辑应当直截了当,叫缺陷难以隐藏;尽量减少依赖关系,使之便于维护;依据某种分层战略完善错误处理代码;性能调至最优,省得引诱别人做没规矩的优化,搞出一堆混乱来。整洁的代码只做好一件事。

Bjarne用了“优雅”一词。说得好!我MacBook上的词典提供了如下定义:外表或举止上令人愉悦的优美和雅观;令人愉悦的精致和简单。注意对“愉悦”一词的强调。Bjarne显然认为整洁的代码读起来令人愉悦。读这种代码,就像见到手工精美的音乐盒或者设计精良的汽车一般,让你会心一笑。

Bjarne也提到效率——而且两次提及。这话出自C++发明者之口,或许并不出奇;不过我认为并非是在单纯追求速度。被浪费掉的运算周期并不雅观,并不令人愉悦。留意Bjarne怎么描述那种不雅观的结果。他用了“引诱”这个词。诚哉斯言。糟糕的代码引发混乱!别人修改糟糕的代码时,往往会越改越烂。

务实的Dave Thomas和Andy Hunt从另一角度阐述了这种情况。他们提到破窗理论4。窗户破损了的建筑让人觉得似乎无人照管。于是别人也再不关心。他们放任窗户继续破损。最终自己也参加破坏活动,在外墙上涂鸦,任垃圾堆积。一扇破损的窗户开辟了大厦走向倾颓的道路。

Bjarne也提到完善错误处理代码。往深处说就是在细节上花心思。敷衍了事的错误处理代码只是程序员忽视细节的一种表现。此外还有内存泄漏,还有竞态条件代码。还有前后不一致的命名方式。结果就是凸现出整洁代码对细节的重视。

Bjarne以“整洁的代码只做好一件事”结束论断。毋庸置疑,软件设计的许多原则最终都会归结为这句警语。有那么多人发表过类似的言论。糟糕的代码想做太多事,它意图混乱、目的含混。整洁的代码力求集中。每个函数、每个类和每个模块都全神贯注于一事,完全不受四周细节的干扰和污染。

image.php_-58.gif

Grady Booch,Object Oriented Analysis and Design with Applications(中译版《面向对象分析与设计》)一书作者。

整洁的代码简单直接。整洁的代码如同优美的散文。整洁的代码从不隐藏设计者的意图,充满了干净利落的抽象和直截了当的控制语句。

Grady的观点与Bjarne的观点有类似之处,但他从可读性的角度来定义。我特别喜欢“整洁的代码如同优美的散文”这种看法。想想你读过的某本好书。回忆一下,那些文字是如何在脑中形成影像!就像是看了场电影,对吧?还不止!你还看到那些人物,听到那些声音,体验到那些喜怒哀乐。

阅读整洁的代码和阅读Lord of the Rings(中译版《指环王》)自然不同。不过,仍有可类比之处。如同一本好的小说般,整洁的代码应当明确地展现出要解决问题的张力。它应当将这种张力推至高潮,以某种显而易见的方案解决问题和张力,使读者发出“啊哈!本当如此!”的感叹。

窃以为Grady所谓“干净利落的抽象”(crisp abstraction),乃是绝妙的矛盾修辞法。毕竟crisp几乎就是“具体”(concrete)的同义词。我MacBook上的词典这样定义crisp一词:果断决绝,就事论事,没有犹豫或不必要的细节。尽管有两种不同的定义,该词还是承载了有力的信息。代码应当讲述事实,不引人猜测。它只该包含必需之物。读者应当感受到我们的果断决绝。

image.php_-59.gif

“老大”Dave Thomas,OTI公司创始人,Eclipse战略教父

整洁的代码应可由作者之外的开发者阅读和增补。它应当有单元测试和验收测试。它使用有意义的命名。它只提供一种而非多种做一件事的途径。它只有尽量少的依赖关系,而且要明确地定义和提供清晰、尽量少的API。代码应通过其字面表达含义,因为不同的语言导致并非所有必需信息均可通过代码自身清晰表达。

Dave老大在可读性上和Grady持相同观点,但有一个重要的不同之处。Dave断言,整洁的代码便于其他人加以增补。这看似显而易见,但亦不可过分强调。毕竟易读的代码和易修改的代码之间还是有区别的。

Dave将整洁系于测试之上!要在十年之前,这会让人大跌眼镜。但测试驱动开发(Test Driven Development)已在行业中造成了深远影响,成为基础规程之一。Dave说得对。没有测试的代码不干净。不管它有多优雅,不管有多可读、多易理解,微乎测试,其不洁亦可知也。

Dave两次提及“尽量少”。显然,他推崇小块的代码。实际上,从有软件起人们就在反复强调这一点。越小越好。

Dave也提到,代码应在字面上表达其含义。这一观点源自Knuth的“字面编程”(literate programming)5。结论就是应当用人类可读的方式来写代码。

image.php_-60.gif

Michael Feathers,Working Effectively with Legacy Code(中译版《修改代码的艺术》)一书作者。

我可以列出我留意到的整洁代码的所有特点,但其中有一条是根本性的。整洁的代码总是看起来像是某位特别在意它的人写的。几乎没有改进的余地。代码作者什么都想到了,如果你企图改进它,总会回到原点,赞叹某人留给你的代码——全心投入的某人留下的代码。

一言以蔽之:在意。这就是本书的题旨所在。或许该加个副标题,如何在意代码。

Michael一针见血。整洁代码就是作者着力照料的代码。有人曾花时间让它保持简单有序。他们适当地关注到了细节。他们在意过。

image.php_-61.gif

Ron Jeffries,Extreme Programming Installed(中译版《极限编程实施》)以及Extreme Programming Adventures in C#(中译版《C#极限编程探险》)作者。

Ron初入行就在战略空军司令部(Strategic Air Command)编写Fortran程序,此后几乎在每种机器上编写过每种语言的代码。他的言论值得咀嚼。

近年来,我开始研究贝克的简单代码规则,差不多也都琢磨透了。简单代码,依其重要顺序:

能通过所有测试;

没有重复代码;

体现系统中的全部设计理念;

包括尽量少的实体,比如类、方法、函数等。

在以上诸项中,我最在意代码重复。如果同一段代码反复出现,就表示某种想法未在代码中得到良好的体现。我尽力去找出到底那是什么,然后再尽力更清晰地表达出来。

在我看来,有意义的命名是体现表达力的一种方式,我往往会修改好几次才会定下名字来。借助Eclipse这样的现代编码工具,重命名代价极低,所以我无所顾忌。然而,表达力还不只体现在命名上。我也会检查对象或方法是否想做的事太多。如果对象功能太多,最好是切分为两个或多个对象。如果方法功能太多,我总是使用抽取手段(Extract Method)重构之,从而得到一个能较为清晰地说明自身功能的方法,以及另外数个说明如何实现这些功能的方法。

消除重复和提高表达力让我在整洁代码方面获益良多,只要铭记这两点,改进脏代码时就会大有不同。不过,我时常关注的另一规则就不太好解释了。

这么多年下来,我发现所有程序都由极为相似的元素构成。例如“在集合中查找某物”。不管是雇员记录数据库还是名-值对哈希表,或者某类条目的数组,我们都会发现自己想要从集合中找到某一特定条目。一旦出现这种情况,我通常会把实现手段封装到更抽象的方法或类中。这样做好处多多。

可以先用某种简单的手段,比如哈希表来实现这一功能,由于对搜索功能的引用指向了我那个小小的抽象,就能随需应变,修改实现手段。这样就既能快速前进,又能为未来的修改预留余地。

另外,该集合抽象常常提醒我留意“真正”在发生的事,避免随意实现集合行为,因为我真正需要的不过是某种简单的查找手段。

减少重复代码,提高表达力,提早构建简单抽象。这就是我写整洁代码的方法。

Ron以寥寥数段文字概括了本书的全部内容。不要重复代码,只做一件事,表达力,小规模抽象。该有的都有了。

image.php_-62.gif

Ward Cunningham,Wiki发明者,eXtreme Programming(极限编程)的创始人之一,Smalltalk语言和面向对象的思想领袖。所有在意代码者的教父。

如果每个例程都让你感到深合己意,那就是整洁代码。如果代码让编程语言看起来像是专为解决那个问题而存在,就可以称之为漂亮的代码。

这种说法很Ward。它教你听了之后就点头,然后继续听下去。如此在理,如此浅显,绝不故作高深。你大概以为此言深合己意吧。再走近点看看。

“……深合己意”。你最近一次看到深合己意的模块是什么时候?模块多半都繁复难解吧?难道没有触犯规则吗?你不是也曾挣扎着想抓住些从整个系统中散落而出的线索,编织进你在读的那个模块吗?你最近一次读到某段代码、并且如同对Ward的说法点头一般对这段代码点头,是什么时候的事了?

Ward期望你不会为整洁代码所震惊。你无需花太多力气。那代码就是深合你意。它明确、简单、有力。每个模块都为下一个模块做好准备。每个模块都告诉你下一个模块会是怎样的。整洁的程序好到你根本不会注意到它。设计者把它做得像一切其他设计般简单。

那Ward有关“美”的说法又如何呢?我们都曾面临语言不是为要解决的问题所设计的困境。但Ward的说法又把球踢回我们这边。他说,漂亮的代码让编程语言像是专为解决那个问题而存在!所以,让语言变得简单的责任就在我们身上了!当心,语言是冥顽不化的!是程序员让语言显得简单。

稿源:代码湾

转自:https://www.oschina.net/news/87473/good-programmers-clean-code

苹果下架中国区主流VPN应用

苹果下架中国区主流VPN应用

雷锋网(公众号:雷锋网)消息,根据纽约时报的报道,苹果下架了中国区App Store的一些主流VPN应用。

据报道,一些公司收到了来自苹果的通知,称他们的APP已从中国区应用市场下架。

一个名为ExpressVPN的应用在其博客上称,苹果给出的解释是产品违反了中国法律,应用中包含一些非法的内容。这家公司还称,他们发现所有的主流iOS端VPN应用都被下架了。

苹果下架中国区主流VPN应用

ExpressVPN收到的通知

另一家名为Star VPN的应用也称收到了同样的通知。

雷锋网以VPN为关键词搜索中国区苹果商店,发现还是有很多应用可以下载。不过上述两家的应用确实搜不到。

之前有消息称,明年2月国内会停止所有VPN服务,不过后来工信部称,规范对象主要是未经电信主管部门批准,无国际通信业务经营资质企业和个人。

苹果越来越重视中国市场。不久前雷锋网报道,苹果将在贵州建其在中国的首个数据中心。另外,一个多星期前,苹果还宣布任命原苹果无线技术副总裁葛越女士担任大中华区董事总经理,全面负责中国的业务和团队,而且这一职位为新设立的。

雷锋网原创文章,未经授权禁止转载。详情见转载须知

来源:https://www.leiphone.com/news/201707/nB4mZxwvxz3iYaPy.html

Linux TCP/IP 协议栈调优

参考:http://colobu.com/2014/09/18/linux-tcpip-tuning/

有些性能瓶颈和Linux的TCP/IP的协议栈的设置有关,所以特别google了一下Linux TCP/IP的协议栈的参数意义和配置,记录一下。

如果想永久的保存参数的设置, 可以将参数加入到/etc/sysctl.conf中。如果想临时的更改参数的配置, 可以修改/proc/sys/net/ipv4/下的参数, 机器重启后更改失效。

linux内核参数优化
http://blog.chinaunix.net/uid-29081804-id-3830203.html
Sysctl命令及linux内核参数调整,系统工具的使用不熟悉地请先阅读上面的文章

linux内核参数注释

根据参数文件所处目录不同而进行分表整理
下列文件所在目录:/proc/sys/net/ipv4/

名称 默认值 建议值 描述
tcp_syn_retries 5 1 对于一个新建连接,内核要发送多少个 SYN 连接请求才决定放弃。不应该大于255,默认值是5,对应于180秒左右时间。。(对于大负载而物理通信良好的网络而言,这个值偏高,可修改为2.这个值仅仅是针对对外的连接,对进来的连接,是由tcp_retries1决定的)
tcp_synack_retries 5 1 对于远端的连接请求SYN,内核会发送SYN + ACK数据报,以确认收到上一个 SYN连接请求包。这是所谓的三次握手( threeway handshake)机制的第二个步骤。这里决定内核在放弃连接之前所送出的 SYN+ACK 数目。不应该大于255,默认值是5,对应于180秒左右时间。
tcp_keepalive_time 7200 600 TCP发送keepalive探测消息的间隔时间(秒),用于确认TCP连接是否有效。

防止两边建立连接但不发送数据的攻击。

tcp_keepalive_probes 9 3 TCP发送keepalive探测消息的间隔时间(秒),用于确认TCP连接是否有效。
tcp_keepalive_intvl 75 15 探测消息未获得响应时,重发该消息的间隔时间(秒)。默认值为75秒。 (对于普通应用来说,这个值有一些偏大,可以根据需要改小.特别是web类服务器需要改小该值,15是个比较合适的值)
tcp_retries1 3 3 放弃回应一个TCP连接请求前﹐需要进行多少次重试。RFC 规定最低的数值是3
tcp_retries2 15 5 在丢弃激活(已建立通讯状况)的TCP连接之前﹐需要进行多少次重试。默认值为15,根据RTO的值来决定,相当于13-30分钟(RFC1122规定,必须大于100秒).(这个值根据目前的网络设置,可以适当地改小,我的网络内修改为了5)
tcp_orphan_retries 7 3 在近端丢弃TCP连接之前﹐要进行多少次重试。默认值是7个﹐相当于 50秒 – 16分钟﹐视 RTO 而定。如果您的系统是负载很大的web服务器﹐那么也许需要降低该值﹐这类 sockets 可能会耗费大量的资源。另外参的考tcp_max_orphans。(事实上做NAT的时候,降低该值也是好处显著的,我本人的网络环境中降低该值为3)
tcp_fin_timeout 60 2 对于本端断开的socket连接,TCP保持在FIN-WAIT-2状态的时间。对方可能会断开连接或一直不结束连接或不可预料的进程死亡。默认值为 60 秒。
tcp_max_tw_buckets 180000 36000 系统在同时所处理的最大 timewait sockets 数目。如果超过此数的话﹐time-wait socket 会被立即砍除并且显示警告信息。之所以要设定这个限制﹐纯粹为了抵御那些简单的 DoS 攻击﹐不过﹐如果网络条件需要比默认值更多﹐则可以提高它(或许还要增加内存)。(事实上做NAT的时候最好可以适当地增加该值)
tcp_tw_recycle 0 1 打开快速 TIME-WAIT sockets 回收。除非得到技术专家的建议或要求﹐请不要随意修改这个值。(做NAT的时候,建议打开它)
tcp_tw_reuse 0 1 表示是否允许重新应用处于TIME-WAIT状态的socket用于新的TCP连接(这个对快速重启动某些服务,而启动后提示端口已经被使用的情形非常有帮助)
tcp_max_orphans 8192 32768 系统所能处理不属于任何进程的TCP sockets最大数量。假如超过这个数量﹐那么不属于任何进程的连接会被立即reset,并同时显示警告信息。之所以要设定这个限制﹐纯粹为了抵御那些简单的 DoS 攻击﹐千万不要依赖这个或是人为的降低这个限制。如果内存大更应该增加这个值。(这个值Redhat AS版本中设置为32768,但是很多防火墙修改的时候,建议该值修改为2000)
tcp_abort_on_overflow 0 0 当守护进程太忙而不能接受新的连接,就象对方发送reset消息,默认值是false。这意味着当溢出的原因是因为一个偶然的猝发,那么连接将恢复状态。只有在你确信守护进程真的不能完成连接请求时才打开该选项,该选项会影响客户的使用。(对待已经满载的sendmail,apache这类服务的时候,这个可以很快让客户端终止连接,可以给予服务程序处理已有连接的缓冲机会,所以很多防火墙上推荐打开它)
tcp_syncookies 0 1 只有在内核编译时选择了CONFIG_SYNCOOKIES时才会发生作用。当出现syn等候队列出现溢出时象对方发送syncookies。目的是为了防止syn flood攻击。
tcp_stdurg 0 0 使用 TCP urg pointer 字段中的主机请求解释功能。大部份的主机都使用老旧的 BSD解释,因此如果您在 Linux 打开它﹐或会导致不能和它们正确沟通。
tcp_max_syn_backlog 1024 16384 对于那些依然还未获得客户端确认的连接请求﹐需要保存在队列中最大数目。对于超过 128Mb 内存的系统﹐默认值是 1024 ﹐低于 128Mb 的则为 128。如果服务器经常出现过载﹐可以尝试增加这个数字。警告﹗假如您将此值设为大于 1024﹐最好修改include/net/tcp.h里面的TCP_SYNQ_HSIZE﹐以保持TCP_SYNQ_HSIZE16(SYN Flood攻击利用TCP协议散布握手的缺陷,伪造虚假源IP地址发送大量TCP-SYN半打开连接到目标系统,最终导致目标系统Socket队列资源耗尽而无法接受新的连接。为了应付这种攻击,现代Unix系统中普遍采用多连接队列处理的方式来缓冲(而不是解决)这种攻击,是用一个基本队列处理正常的完全连接应用(Connect()和Accept() ),是用另一个队列单独存放半打开连接。这种双队列处理方式和其他一些系统内核措施(例如Syn-Cookies/Caches)联合应用时,能够比较有效的缓解小规模的SYN Flood攻击(事实证明)
tcp_window_scaling 1 1 该文件表示设置tcp/ip会话的滑动窗口大小是否可变。参数值为布尔值,为1时表示可变,为0时表示不可变。tcp/ip通常使用的窗口最大可达到 65535 字节,对于高速网络,该值可能太小,这时候如果启用了该功能,可以使tcp/ip滑动窗口大小增大数个数量级,从而提高数据传输的能力(RFC 1323)。(对普通地百M网络而言,关闭会降低开销,所以如果不是高速网络,可以考虑设置为0)
tcp_timestamps 1 1 Timestamps 用在其它一些东西中﹐可以防范那些伪造的 sequence 号码。一条1G的宽带线路或许会重遇到带 out-of-line数值的旧sequence 号码(假如它是由于上次产生的)。Timestamp 会让它知道这是个 ‘旧封包’。(该文件表示是否启用以一种比超时重发更精确的方法(RFC 1323)来启用对 RTT 的计算;为了实现更好的性能应该启用这个选项。)
tcp_sack 1 1 使用 Selective ACK﹐它可以用来查找特定的遗失的数据报— 因此有助于快速恢复状态。该文件表示是否启用有选择的应答(Selective Acknowledgment),这可以通过有选择地应答乱序接收到的报文来提高性能(这样可以让发送者只发送丢失的报文段)。(对于广域网通信来说这个选项应该启用,但是这会增加对 CPU 的占用。)
tcp_fack 1 1 打开FACK拥塞避免和快速重传功能。(注意,当tcp_sack设置为0的时候,这个值即使设置为1也无效)[这个是TCP连接靠谱的核心功能]
tcp_dsack 1 1 允许TCP发送”两个完全相同”的SACK。
tcp_ecn 0 0 TCP的直接拥塞通告功能。
tcp_reordering 3 6 TCP流中重排序的数据报最大数量。 (一般有看到推荐把这个数值略微调整大一些,比如5)
tcp_retrans_collapse 1 0 对于某些有bug的打印机提供针对其bug的兼容性。(一般不需要这个支持,可以关闭它)
tcp_wmem:mindefaultmax 4096

16384

131072

8192

131072

16777216

发送缓存设置

min:为TCP socket预留用于发送缓冲的内存最小值。每个tcp socket都可以在建议以后都可以使用它。默认值为4096(4K)。

default:为TCP socket预留用于发送缓冲的内存数量,默认情况下该值会影响其它协议使用的net.core.wmem_default 值,一般要低于net.core.wmem_default的值。默认值为16384(16K)。

max: 用于TCP socket发送缓冲的内存最大值。该值不会影响net.core.wmem_max,”静态”选择参数SOSNDBUF则不受该值影响。默认值为131072(128K)。(对于服务器而言,增加这个参数的值对于发送数据很有帮助,在我的网络环境中,修改为了51200 131072 204800)

tcprmem:mindefaultmax 4096

87380

174760

32768

131072

16777216

接收缓存设置

同tcp_wmem

tcp_mem:mindefaultmax 根据内存计算 786432

1048576 1572864

low:当TCP使用了低于该值的内存页面数时,TCP不会考虑释放内存。即低于此值没有内存压力。(理想情况下,这个值应与指定给 tcp_wmem 的第 2 个值相匹配 – 这第 2 个值表明,最大页面大小乘以最大并发请求数除以页大小 (131072 300 / 4096)。 )

pressure:当TCP使用了超过该值的内存页面数量时,TCP试图稳定其内存使用,进入pressure模式,当内存消耗低于low值时则退出pressure状态。(理想情况下这个值应该是 TCP 可以使用的总缓冲区大小的最大值 (204800 300 / 4096)。 )

high:允许所有tcp sockets用于排队缓冲数据报的页面量。(如果超过这个值,TCP 连接将被拒绝,这就是为什么不要令其过于保守 (512000 300 / 4096) 的原因了。 在这种情况下,提供的价值很大,它能处理很多连接,是所预期的 2.5 倍;或者使现有连接能够传输 2.5 倍的数据。 我的网络里为192000 300000 732000)

一般情况下这些值是在系统启动时根据系统内存数量计算得到的。

tcp_app_win 31 31 保留max(window/2^tcp_app_win, mss)数量的窗口由于应用缓冲。当为0时表示不需要缓冲。
tcp_adv_win_scale 2 2 计算缓冲开销bytes/2^tcp_adv_win_scale(如果tcp_adv_win_scale > 0)或者bytes-bytes/2^(-tcp_adv_win_scale)(如果tcp_adv_win_scale BOOLEAN>0)
tcp_low_latency 0 0 允许 TCP/IP 栈适应在高吞吐量情况下低延时的情况;这个选项一般情形是的禁用。(但在构建Beowulf 集群的时候,打开它很有帮助)
tcp_westwood 0 0 启用发送者端的拥塞控制算法,它可以维护对吞吐量的评估,并试图对带宽的整体利用情况进行优化;对于 WAN 通信来说应该启用这个选项。
tcp_bic 0 0 为快速长距离网络启用 Binary Increase Congestion;这样可以更好地利用以 GB 速度进行操作的链接;对于 WAN 通信应该启用这个选项。
ip_forward 0 NAT必须开启IP转发支持,把该值写1
ip_local_port_range:minmax 32768

61000

1024

65000

表示用于向外连接的端口范围,默认比较小,这个范围同样会间接用于NAT表规模。
ip_conntrack_max 65535 65535 系统支持的最大ipv4连接数,默认65536(事实上这也是理论最大值),同时这个值和你的内存大小有关,如果内存128M,这个值最大8192,1G以上内存这个值都是默认65536

所处目录/proc/sys/net/ipv4/netfilter/
文件需要打开防火墙才会存在

名称 默认值 建议值 描述
ip_conntrack_max 65536 65536 系统支持的最大ipv4连接数,默认65536(事实上这也是理论最大值),同时这个值和你的内存大小有关,如果内存128M,这个值最大8192,1G以上内存这个值都是默认65536,这个值受/proc/sys/net/ipv4/ip_conntrack_max限制
ip_conntrack_tcp_timeout_established 432000 180 已建立的tcp连接的超时时间,默认432000,也就是5天。影响:这个值过大将导致一些可能已经不用的连接常驻于内存中,占用大量链接资源,从而可能导致NAT ip_conntrack: table full的问题。建议:对于NAT负载相对本机的 NAT表大小很紧张的时候,可能需要考虑缩小这个值,以尽早清除连接,保证有可用的连接资源;如果不紧张,不必修改
ip_conntrack_tcp_timeout_time_wait 120 120 time_wait状态超时时间,超过该时间就清除该连接
ip_conntrack_tcp_timeout_close_wait 60 60 close_wait状态超时时间,超过该时间就清除该连接
ip_conntrack_tcp_timeout_fin_wait 120 120 fin_wait状态超时时间,超过该时间就清除该连接

文件所处目录/proc/sys/net/core/

名称 默认值 建议值 描述
netdev_max_backlog 1024 16384 每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目,对重负载服务器而言,该值需要调高一点。
somaxconn 128 16384 用来限制监听(LISTEN)队列最大数据包的数量,超过这个数量就会导致链接超时或者触发重传机制。

web应用中listen函数的backlog默认会给我们内核参数的net.core.somaxconn限制到128,而nginx定义的NGX_LISTEN_BACKLOG默认为511,所以有必要调整这个值。对繁忙的服务器,增加该值有助于网络性能

wmem_default 129024 129024 默认的发送窗口大小(以字节为单位)
rmem_default 129024 129024 默认的接收窗口大小(以字节为单位)
rmem_max 129024 873200 最大的TCP数据接收缓冲
wmem_max 129024 873200 最大的TCP数据发送缓冲

两种修改内核参数方法

  1. 使用echo value方式直接追加到文件里如echo “1” >/proc/sys/net/ipv4/tcp_syn_retries,但这种方法设备重启后又会恢复为默认值
  2. 把参数添加到/etc/sysctl.conf中,然后执行sysctl -p使参数生效,永久生效

内核生产环境优化参数

生产中常用的参数:
[code lang=”bash”]
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl =15
net.ipv4.tcp_retries2 = 5
net.ipv4.tcp_fin_timeout = 2
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_orphans = 32768
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_wmem = 8192 131072 16777216
net.ipv4.tcp_rmem = 32768 131072 16777216
net.ipv4.tcp_mem = 786432 1048576 1572864
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.ip_conntrack_max = 65536
net.ipv4.netfilter.ip_conntrack_max=65536
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established=180
net.core.somaxconn = 16384
net.core.netdev_max_backlog = 16384
[/code]

不同的生产环境需要优化的参数基本差不多,只是值有相应的变化。具体优化值要参考应用场景,这儿所列只是常用优化参数,是否适合,可在上面查看该参数描述,理解后,再根据自己生产环境而设。

其它相关linux内核参数调整文章:
Linux内核参数优化
http://flandycheng.blog.51cto.com/855176/476769

优化linux的内核参数来提高服务器并发处理能力
http://www.ha97.com/4396.html

nginx做web服务器linux内核参数优化
http://blog.csdn.net/force_eagle/article/details/6725243


sudops网站提供的优化例子:
Linux下TCP/IP及内核参数优化有多种方式,参数配置得当可以大大提高系统的性能,也可以根据特定场景进行专门的优化,如TIME_WAIT过高,DDOS攻击等等。
如下配置是写在sysctl.conf中,可使用sysctl -p生效,文中附带了一些默认值和中文解释(从网上收集和翻译而来),确有些辛苦,转载请保留链接,谢谢~。
相关参数仅供参考,具体数值还需要根据机器性能,应用场景等实际情况来做更细微调整。
[code lang=”bash”]
net.core.netdev_max_backlog = 400000
#该参数决定了,网络设备接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。
net.core.optmem_max = 10000000
#该参数指定了每个套接字所允许的最大缓冲区的大小
net.core.rmem_default = 10000000
#指定了接收套接字缓冲区大小的缺省值(以字节为单位)。
net.core.rmem_max = 10000000
#指定了接收套接字缓冲区大小的最大值(以字节为单位)。
net.core.somaxconn = 100000
#Linux kernel参数,表示socket监听的backlog(监听队列)上限
net.core.wmem_default = 11059200
#定义默认的发送窗口大小;对于更大的 BDP 来说,这个大小也应该更大。
net.core.wmem_max = 11059200
#定义发送窗口的最大大小;对于更大的 BDP 来说,这个大小也应该更大。
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
#严谨模式 1 (推荐)
#松散模式 0
net.ipv4.tcp_congestion_control = bic
#默认推荐设置是 htcp
net.ipv4.tcp_window_scaling = 0
#关闭tcp_window_scaling
#启用 RFC 1323 定义的 window scaling;要支持超过 64KB 的窗口,必须启用该值。
net.ipv4.tcp_ecn = 0
#把TCP的直接拥塞通告(tcp_ecn)关掉
net.ipv4.tcp_sack = 1
#关闭tcp_sack
#启用有选择的应答(Selective Acknowledgment),
#这可以通过有选择地应答乱序接收到的报文来提高性能(这样可以让发送者只发送丢失的报文段);
#(对于广域网通信来说)这个选项应该启用,但是这会增加对 CPU 的占用。
net.ipv4.tcp_max_tw_buckets = 10000
#表示系统同时保持TIME_WAIT套接字的最大数量
net.ipv4.tcp_max_syn_backlog = 8192
#表示SYN队列长度,默认1024,改成8192,可以容纳更多等待连接的网络连接数。
net.ipv4.tcp_syncookies = 1
#表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
net.ipv4.tcp_timestamps = 1
#开启TCP时间戳
#以一种比重发超时更精确的方法(请参阅 RFC 1323)来启用对 RTT 的计算;为了实现更好的性能应该启用这个选项。
net.ipv4.tcp_tw_reuse = 1
#表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1
#表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_fin_timeout = 10
#表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。
net.ipv4.tcp_keepalive_time = 1800
#表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为30分钟。
net.ipv4.tcp_keepalive_probes = 3
#如果对方不予应答,探测包的发送次数
net.ipv4.tcp_keepalive_intvl = 15
#keepalive探测包的发送间隔
net.ipv4.tcp_mem
#确定 TCP 栈应该如何反映内存使用;每个值的单位都是内存页(通常是 4KB)。
#第一个值是内存使用的下限。
#第二个值是内存压力模式开始对缓冲区使用应用压力的上限。
#第三个值是内存上限。在这个层次上可以将报文丢弃,从而减少对内存的使用。对于较大的 BDP 可以增大这些值(但是要记住,其单位是内存页,而不是字节)。
net.ipv4.tcp_rmem
#与 tcp_wmem 类似,不过它表示的是为自动调优所使用的接收缓冲区的值。
net.ipv4.tcp_wmem = 30000000 30000000 30000000
#为自动调优定义每个 socket 使用的内存。
#第一个值是为 socket 的发送缓冲区分配的最少字节数。
#第二个值是默认值(该值会被 wmem_default 覆盖),缓冲区在系统负载不重的情况下可以增长到这个值。
#第三个值是发送缓冲区空间的最大字节数(该值会被 wmem_max 覆盖)。
net.ipv4.ip_local_port_range = 1024 65000
#表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为1024到65000。
net.ipv4.netfilter.ip_conntrack_max=204800
#设置系统对最大跟踪的TCP连接数的限制
net.ipv4.tcp_slow_start_after_idle = 0
#关闭tcp的连接传输的慢启动,即先休止一段时间,再初始化拥塞窗口。
net.ipv4.route.gc_timeout = 100
#路由缓存刷新频率,当一个路由失败后多长时间跳到另一个路由,默认是300。
net.ipv4.tcp_syn_retries = 1
#在内核放弃建立连接之前发送SYN包的数量。
net.ipv4.icmp_echo_ignore_broadcasts = 1
# 避免放大攻击
net.ipv4.icmp_ignore_bogus_error_responses = 1
# 开启恶意icmp错误消息保护
net.inet.udp.checksum=1
#防止不正确的udp包的攻击
net.ipv4.conf.default.accept_source_route = 0
#是否接受含有源路由信息的ip包。参数值为布尔值,1表示接受,0表示不接受。
#在充当网关的linux主机上缺省值为1,在一般的linux主机上缺省值为0。
#从安全性角度出发,建议你关闭该功能。
[/code]
最初的幸福ever也提供了一些参数的说明。

/proc/sys/net目录
所有的TCP/IP参数都位于/proc/sys/net目录下(请注意,对/proc/sys/net目录下内容的修改都是临时的,任何修改在系统重启后都会丢失),例如下面这些重要的参数:

Thrift 数据类型

要编写Thrift定义文件,肯定要熟悉Thrift常见的数据类型:

1.基本类型(括号内为对应的Java类型):
bool(boolean): 布尔类型(TRUE or FALSE)
byte(byte): 8位带符号整数
i16(short): 16位带符号整数
i32(int): 32位带符号整数
i64(long): 64位带符号整数
double(double): 64位浮点数
string(String): 采用UTF-8编码的字符串

2.特殊类型(括号内为对应的Java类型):
binary(ByteBuffer):未经过编码的字节流

3.Structs(结构):
struct定义了一个很普通的OOP对象,但是没有继承特性。

struct UserProfile {
1: i32 uid,
2: string name,
3: string blurb
}

如果变量有默认值,可以直接写在定义文件里:

struct UserProfile {
1: i32 uid = 1,
2: string name = “User1”,
3: string blurb
}

4.容器,除了上面提到的基本数据类型,Thrift还支持以下容器类型:
list(java.util.ArrayList):
set(java.util.HashSet):
map(java.util.HashMap):

Thrift容器与类型密切相关,它与当前流行编程语言提供的容器类型相对应,采用java泛型风格表示的。Thrift提供了3种容器类型:
List<t1>:一系列t1类型的元素组成的有序表,元素可以重复
Set<t1>:一系列t1类型的元素组成的无序表,元素唯一
Map<t1,t2>:key/value对(key的类型是t1且key唯一,value类型是t2)。
容器中的元素类型可以是除了service意外的任何合法thrift类型(包括结构体和异常)。
用法如下:

struct Node {
1: i32 id,
2: string name,
3: list<i32> subNodeList,
4: map<i32,string> subNodeMap,
5: set<i32> subNodeSet
}

包含定义的其他Object:

struct SubNode {
1: i32 uid,
2: string name,
3: i32 pid
}

struct Node {
1: i32 uid,
2: string name,
3: list<subNode> subNodes
}

5.Services服务,也就是对外展现的接口:

service UserStorage {
void store(1: UserProfile user),
UserProfile retrieve(1: i32 uid)
}

mac os x10.12 安装thrift0.8 源码

参考:http://www.cnblogs.com/peterpanzsy/p/4210127.html

http://thrift.apache.org/docs/install/

一:安装最新版(自动安装)

最简单的是用homebrew进行安装

  • 安装homebrew 在终端输入ruby -e “$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)”
  • 安装thrift   brew install thrift

用brew安装的thrift版本是0.9的,but,我们项目中得thrift版本是0.8的,所以果断卸载掉。

brew uninstall thrift。转到下面第二种方法安装thrift

二:手动安装0.8.0

先安装依赖。

http://www.jattcode.com/installing-autoconf-automake-libtool-on-mac-osx-mountain-lion/

  • 安装BOOST

下载:http://www.boost.org/

命令:./bootstrap.sh,该命令用于生成bjam可执行文件,这个东西就是用来编译boost库

命令:sudo ./b2 threading=multi address-model=64 variant=release stage install

  • 安装 libevent

下载:http://libevent.org/

命令:./configure –prefix=/usr/local

命令:make

命令:sudo make install

  • 安装 Apache Thrift

下载:http://thrift.apache.org/

编译命令:./configure –prefix=/usr/local/ –with-boost=/usr/local/lib –with-libevent=/usr/local/lib –without-ruby –without-python –without-perl –without-php

有一些不相关的code genorater可以不要了,不然又得会报错。。。

安装命令:sudo make install

thrift -version 可以查看安装是否成功和版本

thrift-0.8.0.tar.gz

安装8的时候会遇到如下问题,并按如下解决:

以下摘自美团 Created by 曹继光, last modified by 严鑫 on 十月 10, 2014

Osx 10.9 是比较新的系统, 从这个版本开始, 系统默认编译器从GCC 改为 Clang(GCC -v 一下, 给的是clang 的提示).

Thrift 0.8  代码相对又比较老, 在新的编译器上遇到了下列一些问题.

问题1 :

多个源码文件报错 # include <tr1/functional>, file not found, 改为 # include <boost/tr1/functional.hpp> 解决.

需要修改以下文件:

  • lib/cpp/src/concurrency/ThreadManager.h  line:24
  • lib/cpp/src/async/TAsyncChannel.h line:23
  • lib/cpp/src/async/TAsyncChannel.cpp line:21
  • lib/cpp/src/async/TAsyncProcessor.h line:23
  • lib/cpp/src/async/TAsyncBufferProcessor.h line:23

原因:  在我试验的环境下, 此头文件有后缀名/usr/local/include/boost/ tr1/functional.hpp

问题2:

cpp 测试代码 lib/cpp/test/Benchmark.cpp 编译失败,  shared_ptr  ambigous , 用 boost::shared_ptr 替换 shared_ptr,

错误消失.

原因: Clang 支持 C++ 11, 其 标准库自带 shared_ptr(std::shared_ptr, 参考 http://zh.cppreference.com/w/cpp/memory/shared_ptr)

故需显式指定名字空间.

三:测试

下面编写一个HelloWorld.thrift 来测试一下,内容如下:

namespace java com.xx.mobile.hotel.sc.demo

service HelloWorldService {
string sayHello(1:string username)
}

执行:thrift -gen java HelloWorld.thrift 将在同级目录下生成gen-java/com/xx/mobile/hotel/sc/demo/HelloWorldService.java文件。

Hibernate5 注解 命名策略

对于hibernate注解实体中属性对应数据库表的列名,怎么命名的问题,我们肯定不愿一个个属性去配置

Hibernaet5.1 之前  在applicationContext.xml中的sessionFactory中配置

<property name=”namingStrategy”>
<bean class=”org.hibernate.cfg.ImprovedNamingStrategy”></bean>
</property>

5.1开始

hibernate.ejb.naming_strategy将不再被支持,而是被替换成了两个属性:
hibernate.physical_naming_strategy
hibernate.implicit_naming_strategy

对于physical_naming_strategy有两个常用的配置:

org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

对于PhysicalNamingStrategyStandardImplDefaultNamingStrategy的效果,

对于SpringPhysicalNamingStrategyImprovedNamingStrategy的效果。

法1:在sessionFactory的bean里配置

<property name=”PhysicalNamingStrategy”>
<bean class=”org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl”></bean>
</property>

法2:在sessionFactory bean的hibernateProperties property中配置

<prop key=”hibernate.physical_naming_strategy”>org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl</prop>

org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy 是 spring boot 包提供地

<property name=”ImplicitNamingStrategy”>
<bean class=”org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl” />
</property>

或是

<prop key=”hibernate.implicit_naming_strategy”>org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl</prop>

centos7 安装 sqlserver

安装可参考:https://docs.microsoft.com/zh-cn/sql/linux/sql-server-linux-setup-red-hat

1.下载sql server的源,便于通过yum命令来安装

curl https://packages.microsoft.com/config/rhel/7/mssql-server.repo > /etc/yum.repos.d/mssql-server.repo

2.安装

yum install -y mssql-server

3.配置

sqlservr-setup 或 mssql-conf setup

安装客户端工具

可以参考:https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-setup-tools

1.设置防火墙

要连接数据库,首先要打开防火墙上1433端口,也就是,增加tcp端口1433到公共区域,并且永久生效

2.下载客户端工具的源

curl https://packages.microsoft.com/config/rhel/7/prod.repo > /etc/yum.repos.d/msprod.repo

3.安装客户端工具

yum install mssql-tools unixODBC-devel

4.连接sql sever

sqlcmd -S localhost -U sa