给.Net程序加个cache

作者 : admin 于 2009年09月06日, 22:47:07
2009
09-6

朋友说一个.net的网站总被dos攻击,让给个方案,还不能贵了。听对方描述一番,感觉是iis的垃圾造成连接数的问题。

很少研究iis,但我知道linux下很多软件可以很好的提升并发连接数,于是出一简单方案去尝试。

未命名-1

mysql5.1触发器小试

作者 : admin 于 2009年08月25日, 22:51:18
2009
08-25

我一直以为mysql5.0的触发器好似没那么强大,被一个搞mssql的老大给忽悠了,其实mysql触发器从5.0就变得很强大,当然包括5.1。

这里拿一个demo说事:

  1. DROP TRIGGER IF EXISTS `ucenterhome`.`uchome_doing_test`;
  2. DELIMITER //
  3. CREATE TRIGGER `ucenterhome`.`uchome_doing_test` AFTER INSERT ON `ucenterhome`.`uchome_doing`
  4.  FOR EACH ROW BEGIN
  5.     INSERT INTO uchome_doing_1 SET doid= NEW.doid+3, uid= NEW.uid , username= NEW.username,`from`=NEW.`from`,dateline=NEW.dateline,message=NEW.message,ip=NEW.ip,replynum = NEW.replynum,mood=NEW.mood;   
  6. END
  7. //
  8. DELIMITER ;

每向uchome_doing表中插一条数据,就复制到uchome_dong_1表中一条。

有两个关键字:

  1. OLD  NEW

官方的解释:

The OLD and NEW keywords enable you to access columns in the rows affected by a trigger. (OLD and NEW are not case sensitive.) In an INSERT trigger, only NEW.col_name can be used; there is no old row. In a DELETE trigger, only OLD.col_name can be used; there is no new row. In an UPDATE trigger, you can use OLD.col_name to refer to the columns of a row before it is updated and NEW.col_name to refer to the columns of the row after it is updated.

还有两个关键字

  1. BEFORE AFTER

官方解释

The keyword BEFORE indicates the trigger action time. In this case, the trigger should activate before each row inserted into the table. The other allowable keyword here is AFTER.

mysql数据抽象层-PDO

作者 : admin 于 2009年08月20日, 16:02:02
2009
08-20

好久不用PDO了,公司这边有的项目使用PDO,再熟悉一下,继续沿用之前的方法:

没用数据绑定和一些高级的功能,只是实现基础功能。

  1. < ?php
  2. interface DateBaseConnect
  3. {
  4. #数据库连接
  5. public function Connect( $host , $user , $pass , $datebase );
  6. #使用数据库
  7. public function selectDateBase( $datebase );
  8. #执行一个查询
  9. public function query( $sql );
  10. #取得一行
  11. public function fetch( $sql );
  12. #取得所有
  13. public function fetchAll( $sql );
  14. #取得影响行数
  15. public function affectedRow();
  16. #取得结果行数
  17. public function recordCount();
  18. #取得上次插入ID
  19. public function insertID();
  20. #释放资源
  21. public function close();
  22. }
  23. class sPDO implements DateBaseConnect
  24. {
  25. #连接标识
  26. public $handle = false;
  27. #结果标识
  28. public $query;
  29. #查询次数
  30. public $exetime;
  31. #影响行数
  32. public $affectedRows;
  33. #statement
  34. public $statement;
  35. #数据库连接
  36. public function Connect( $host , $user , $pass , $datebase )
  37. {
  38. try
  39. {
  40. $this->handle = new PDO("mysql:dbname=".$datebase.";host=".$host, $user, $pass);
  41. }
  42. catch (PDOException $e)
  43. {
  44.             echo 'Connection failed: ' . $e->getMessage();
  45. }
  46. $this->exetime = 0;
  47. }
  48. #选择数据库
  49. public function selectDateBase( $database )
  50. {
  51.     return true;
  52. }
  53. #执行一个查询
  54. public function query( $sql )
  55. {
  56.     $this->affectedRows = $this->handle->exec( $sql );
  57. $this->exetime++;
  58. return true;
  59. }
  60. #取得一行
  61. public function fetch( $sql )
  62. {
  63. $this->statement = $this->handle->query( $sql );
  64. return $this->statement->fetch(PDO::FETCH_ASSOC);
  65. }
  66. #取得所有
  67. public function fetchAll( $sql )
  68. {
  69. $this->statement = $this->handle->query( $sql );
  70. return $this->statement->fetchAll(PDO::FETCH_ASSOC);
  71. }
  72. #取得影响行数
  73. public function affectedRow()
  74. {
  75. return $this->affectedRows;
  76. }
  77. #取得结果行数
  78. public function recordCount()
  79. {
  80. return $this->statement->rowCount();
  81. }
  82. #取得上次插入ID
  83. public function insertID()
  84. {
  85. $sql = sprintf("SELECT LAST_INSERT_ID() AS id");
  86. $pdostatement = $this->handle->query( $sql );
  87. $rs = $pdostatement->fetch();
  88. return $rs['id'];
  89. }
  90. #释放资源
  91. public function close()
  92. {
  93. unset($this->handle);
  94. }
  95. #析构函数
  96. function __destruct()
  97. {
  98. $this->close();
  99. }
  100. }
  101. #Demo
  102. $db = new sPDO;
  103. $db->Connect( 'localhost' , 'root' , '123456' , 'ucenterhome' );
  104. $rs = $db->fetchAll( "SELECT * FROM uchome_blogfield" );
  105. print_r( $rs );
  106. ?>

对UCenter Home的一点看法

作者 : admin 于 2009年08月17日, 22:27:19
2009
08-17

最近改了改UCenter Home,发现,这的确是个不错的产品,但不能算一个成熟的程序。

产品看法:

这个产品主要是服务一些个人站长和小型站点,功能模仿一些成熟的sns系统,模仿比较到位,而且功能上尽可能大的去完善,让管理员可以方便进行比较系统全面的管理。而从产品的设计体验上,也能适应中国大多数的用户。

所以,这个产品在国内算一套非常不错的sns建站系统。

编码方面:

要说代码,我相信阅读过代码的人一定很头疼,从discuz的bbs就这样。

代码只是面向过程,这个,在discuz方面,我估计是累积开发造成的,一个个版本升级,变化不能太大,如果变化真的太大,会失去一些开发者。另外,他自己升级也是个问题。

不过uch这个产品也开发成了这样。代码结构我倒挺喜欢,之前我写那个架子也是这样。优点:结构规范,适合多人协作。缺点,面向对象性,代码复用差。这个结构,我估计是公司某元老折腾的,然后有几个小弟进行模块开发。

为什么这么说,是有原因的,因为遍历整个代码,起码有两种以上的代码风格,而且人员之间沟通配合也造成了一些错误,虽然不是bug,但看得出来项目进行的仓促。不过这也是公司的一个战略措施,小戴同学总是及时放出产品来打压竞争对手。

再说负载,其实这个问题就不用说,从大量的垃圾sql语句就能看出,这个产品不能支持较大的负载。

再说最后一点,如果你想去优化改善,彻底改善,放弃吧。重写。

我看的只是uch2.0的预览版,估计正式版放出的时候,这些问题会有所改善。

最近的总结

作者 : admin 于 2009年08月13日, 22:04:35
2009
08-13

1、相信团队的力量是无穷的,就好像组队打怪升级快。

2、不提倡个人英雄主义,一个人打boss一般的结果是over

3、分工合作,发挥长处。

4、集中精力做事情,稳下心来,事半功倍。

5、相信自己的实力,勇敢向前。

6、人都是善良的,世界多么美好。

7、同一个事情,同一个梦想。

8、大鱼大肉会长小肚子。

9、运动得坚持,人的耐性其实是表现在各个方面,坚持运动,还得坚持学习。

10、还有很多,因为数据库很贵,不多浪费。

11、做事想周全。

Discuz一些乱码错误的总结

作者 : admin 于 2009年08月03日, 22:19:12
2009
08-3

最近用Discuz6.0,在用到分类信息功能的时候,自建模板总是出现错误,仔细跟踪,发现是个别模板编码错误。我用的UTF-8版本,有不少文件里用了中文字符,而且是gbk编码,造成了这种错误。

我google此类信息,有不少问题都出现在了编码上,建议网友在使用的时候,发现编码错误,仔细跟踪一下,找出模板。大部分的问题基本能以此方式解决。

一个备份mysql的脚本,很简单

作者 : admin 于 2009年07月29日, 21:43:46
2009
07-29

帮朋友维护服务器的时候,习惯性得检查各项服务和维护,偶然间发现了这个脚本,冒着被BS的风险分享给大家,希望大家捧个钱场,施舍给老衲几万块钱买套房。

  1. @echo off
  2. C:
  3. CD "C:\Program Files\WinRAR"
  4.  
  5. net stop Mysql
  6. winrar.exe a -ag"-[YYYY-MM-DD-HH-MM-SS]" -k -r -s -ibck -inul "D:\MYSQL备份生成的文件.rar" "E:\bak\data\*.*"
  7. net start Mysql

如何选择一个称心的IDC

作者 : admin 于 2009年07月28日, 11:07:09
2009
07-28

最近跟我那个成都的某个IDC机房扯皮,扯得我是下三滥的手段都想用了,不过看在还混在这个圈子的面子上,没跟他们使损招。我最看不惯的就是那些销售,以为技术人员都是木头,都是榆木疙瘩。凭借一张三寸不烂之舌就想敷衍了事。套用一句流行语:咱民工玩的是风度,不是阴沟。

其实自打毕业干IT这行,从买51.net的虚拟主机到现在,接触的IDC是不下几十家,出入过的机房也有十几个之多,当然碰到的一些扯皮的事情当然就更多了。写这篇文章,就是把一些细节纰漏出来。不针对某个无良IDC,当然也不是给哪个IDC做广告,都是自己经验之谈。也许有理解和认识的错误,欢迎朋友和同行们指正。

因为虚拟主机已经不常用,我说的主要是服务器托管租用方面,我的经历主要是北京范围内。

首先是如何找一个优秀的IDC。IDC分一线二线三线,就好像买车分几个系列一样。如果你想拥有军用悍马的性能,那十个奥拓的价格也不行。如果你真买了10万以下的车,那半路抛锚或者高速上被车皮挤死也别太抱怨。一线IDC主要集中了国内顶尖的网络公司:腾讯,搜狐,新浪,盛大,完美之类的大客户。他们的价格绝对让你乍舌,但质量也能有你想象那么高。你上这几家的网站,有几次断网,有几次感觉速度慢了。而二线的IDC就有大多数也许是发展中的网站,比较拮据的,或者一些知名客户但需要价格比比较高的流量的。三线的IDC,就难说了,小的不能再小的公司,一些个人网站,垃圾站,或者,就是皮包公司。

所以,寻找IDC,先问问销售,贵机房有什么知名的大客户,给个ip或者地址看看(当然,要说是搜狐的某个分站,不用他说,你自己就找到了)。这时,你可以根据销售提供的客户的质量来评价这个机房的档次。

当你选定一个机房后,测试是必须的——三天最少。当你的机器上架后,首先要做的,就是测试带宽,探测网络结构,测试稳定性,甚至网管反应(有点破坏性测试)。测试带宽,要测试上行和下行的带宽,是否能跑足。如果没有从三层以下限速,你尝试持续高带宽,网管有没有反应。(不要期望你能跑那么大的带宽,你跑的大,别的客户也能跑那么大,抢来抢去,自己正常业务也就受损了)。探测下你ip段的网络拓扑,是否划分vlan,你的vlan里有没有windows机器(防止arp,我一般用linux)。最后关机,你看网管是否有反应。我曾经用过一线IDC的带宽,但是网关配置出错,造成流量为0,结果我们刚出机房,网管就打来了电话。这样的服务,你能不感动么。

合同:不管什么业务,合同是要签的。这方面我很无奈,我可以直言不讳得说,做这行的都是流氓,因为合同上基本都是霸王条款。非可控的意外,他们基本都不赔偿。可以说,基本出现的故障,都是他们不可控的:大网出现意外,比如光纤让铲车铲了,或者市电被掐了。当然他们不可控。不过一定要记住,机房设计是必须把意外情况设计进去的,UPS、柴油发电机组是机房必须的设备,这也是你服务的一部分,如果这些都没有,那机房的价值就很低(带宽,电力只是成本的一部分,一部分成本用在了对于意外情况的冗余上)。所以,最好能让他们补充:何种电力冗余,何种网络冗余,意外故障如何赔偿。

实地勘察:光有合同不行,最近我碰到的事情很生气。机房电力出了问题(他们居然走普通市电而没有备用电力),UPS是有,没接到你机器上。结果断电,造成我mysql故障而无法恢复,我正在跟他们交涉。记得问问现场网管的情况,说两个比较常见的问题咨询一下。另外问问他们的收入情况。别小看这些细节:我的linux系统,让网管给关系,网管居然说不会linux。汗得我差点从自行车上载下来。去机房,多看看设备:电力,空调,防火,还有就是机房是否整齐,管理是否到位。看看机房后边的线是否都清晰(曾经在丰台一个机房,一下子就把邻居的电源拔了……)。

好的机房,不仅是硬件资源好,软件也不可缺的。当然软件不是指安装的软件,而是机房的配套设施。去的时候,网管都会自带工具软件。测试的时候建议让机房去做,比如,借一个移动光驱,借一张光盘,下载一个iso去刻盘,打一颗网线,让现场的技术给帮忙之类的事情。别怕机房的人BS你,这只是去感觉一下你应该有的服务。

补充1:上文所说测试上下行带宽问题,事出有因:大部分的专业idc,上下行给的都是一致的,但个别的idc,把下行带宽克扣出来,去给一些小区或者单位做接入,这样达到了更高的利润,但这样给一些下行需求高的客户带来了问题。所以我提到了这点。(学过通讯技术的应该都知道带宽复用这么一个技术,大家可以google一下。)

说了半天,这些经验的确都是自己交学费的成果,希望把这些细节分享给大家,欢迎大家交流,可以加我的qq 176300676 或者msn sunboyu@gmail.com

当然也可以加入lamp大家庭 msn用户加 lamper@live.cn 为好友

本文为作者原创,转载须注明出处。 http://www.sunboyu.cn/2009/07/28/%E5%A6%82%E4%BD%95%E9%80%89%E6%8B%A9%E4%B8%80%E4%B8%AA%E7%A7%B0%E5%BF%83%E7%9A%84idc.shtml

smarty分页程序,模板小改进

作者 : admin 于 2009年07月27日, 15:11:04
2009
07-27

增加了:跳转到第几页的功能

模板部分

  1. <div id="page">
  2. <table>
  3.     <tr>
  4.     <td>
  5. 共{{$page.count}}条数据 每页{{$page.pagesize}}条  共{{$page.pagecount}}页 当前第{{$page.page}}页
  6.                 <!-- 新加的跳转功能  start -->
  7.                 跳转到第
  8.                 <select onchange="window.location.href='{{$page.baseurl}}&page='+this.options[this.selectedIndex].value">
  9.                 {{section name=pagejump loop=4 start=0 step=1 max=4}}
  10.                 <option value="{{$smarty.section.pagejump.index+1}}">{{$smarty.section.pagejump.index+1}}</option>
  11.                 {{/section}}
  12.                 </select> 页
  13.                 <!-- 新加的跳转功能  start -->
  14. </td>
  15. <td>
  16. {{if $page.pagecount>1}}
  17. {{if $page.first eq 1}}
  18. <a href="{{$page.baseurl}}">首页</a>
  19. {{else}}
  20. 首页
  21. {{/if}}
  22. {{if $page.pre eq 1}}
  23. <a href="{{$page.baseurl}}&page={{$page.page-1}}">上一页</a>
  24. {{else}}
  25. 上一页
  26. {{/if}}
  27. {{foreach from=$page.pagelist item=vols}}
  28.     {{if ($vols.page > 0 ) && ($vols.page < = $page.pagecount) }}
  29. {{if $vols.link eq 1}}
  30. <a href="{{$page.baseurl}}&page={{$vols.page}}">[{{$vols.page}}]
  31. {{else}}
  32. [{{$vols.page}}]
  33. {{/if}}
  34. {{/if}}
  35. {{/foreach}}
  36. {{if $page.next eq 1}}
  37. <a href="{{$page.baseurl|default:"?"}}&page={{$page.page+1}}">下一页</a>
  38. {{else}}
  39. 下一页
  40. {{/if}}
  41. {{if $page.last eq 1}}
  42. <a href="{{$page.baseurl|default:"?"}}&page={{$page.pagecount}}">尾页</a>
  43. {{else}}
  44. 尾页
  45. {{/if}}
  46. {{/if}}
  47. </td>
  48. </tr>
  49. </table>
  50. </div>

其实我在做的时候又出现个问题,如果是url重写了,如何来做这个baseurl变量。问题解决方法是,把url当做模板,比如/blog/index/%d

使用成语的文字验证码

作者 : admin 于 2009年07月24日, 21:48:44
2009
07-24

上次写的nb验证码程序,遭到了大部分人的唾弃,因为我使用了中国汉字全集,而大部分中国人对汉字了解还只能占其一半,也就是四个汉字中经常出现生僻字,造成无法使用。

这次使用成语作为汉字验证码(其实已经发现其他网站再用),则中文用户识别的几率就大得多。

demo:

程序下载:点击下载

 Page 8 of 30  « First  ... « 6  7  8  9  10 » ...  Last »