Skip to content

{ Monthly Archives } 十一月 2007

编码的陷阱之 mysql

MySQL 从 4.1 开始对多语言的支持有了很大变化 ,这导致了问题的出现。 许多 PHP 程序以 MySQL 作为默认的数据库管理软件,但它们一般不区分 MySQL 4.1 与 4.1 以下版本的区别,笼统地称“MySQL 3.xx.xx 以上版本”就满足安装需求了。因为 latin1 在许多地方 (下边会详细描述具体是哪些地方) 作为默认的字符集,成功的蒙蔽了许多 PHP 程序的开发者和用户,掩盖了在中文等语言环境下会出现的问题。 简单的说,MySQL 自身的变化和使用 MySQL 的 PHP 程序对此忽略,导致了问题的出现和复杂化,而由于大部分用户使用的是英文,使这种问题不被重视。这里提到的 PHP 程序,以 WordPress 为例。 MySQL 4.1 字符集支持的粒度:MySQL 4.1 对于字符集的指定可以细化到一台机器上安装的 MySQL,其中的一个数据库,其中的一张表,其中的一栏,应该用什么字符集。但是,传统的 Web 程序在创建数据库和数据表时并没有使用那么复杂的配置,它们用的是默认的配置,那么,默认的配置从何而来呢? 编译 MySQL 时,指定了一个默认的字符集,这个字符集是 latin1; 安装 MySQL 时,可以在配置文件 (my.ini,my.cnf) 中指定一个默认的的字符集,如果没指定,这个值继承自编译时指定的; 启动 mysqld 时,可以在命令行参数中指定一个默认的的字符集,如果没指定,这个值继承自配置文件中的; 此时 character_set_server [...]

HTTP Chunked 编码

原始链接:http://www.zeali.net/blog/entry.php?id=129 关键字: HTTP,Transfer-Encoding,Chunked,decode,解码 有时候,Web服务器生成HTTP Response是无法在Header就确定消息大小的,这时一般来说服务器将不会提供Content-Length的头信息,而采用Chunked编码动态的提供body内容的长度。 进行Chunked编码传输的HTTP Response会在消息头部设置: Transfer-Encoding: chunked 表示Content Body将用Chunked编码传输内容。 Chunked编码使用若干个Chunk串连而成,由一个标明长度为0的chunk标示结束。每个Chunk分为头部和正文两部分,头部内容指定下一段正文的字符总数(十六进制的数字)和数量单位(一般不写),正文部分就是指定长度的实际内容,两部分之间用回车换行(CRLF)隔开。在最后一个长度为0的Chunk中的内容是称为footer的内容,是一些附加的Header信息(通常可以直接忽略)。具体的Chunk编码格式如下: Chunked-Body = *chunk “0″ CRLF footer CRLF chunk = chunk-size [ chunk-ext ] CRLF chunk-data CRLF hex-no-zero = chunk-size = hex-no-zero *HEX chunk-ext = *( “;” chunk-ext-name [ "=" chunk-ext-value ] ) chunk-ext-name = token chunk-ext-val = token | quoted-string chunk-data = chunk-size(OCTET) [...]

YouTube 架构学习

YouTube发展迅速,每天超过1亿的视频点击量,但只有很少人在维护站点和确保伸缩性。 平台 Apache Python Linux(SuSe) MySQL psyco,一个动态的Python到C的编译器 lighttpd代替Apache做视频查看 状态 支持每天超过1亿的视频点击量 成立于2005年2月 于2006年3月达到每天3千万的视频点击量 于2006年7月达到每天1亿的视频点击量 2个系统管理员,2个伸缩性软件架构师 2个软件开发工程师,2个网络工程师,1个DBA 处理飞速增长的流量 代码   while (true) { identify_and_fix_bottlenecks(); drink(); sleep(); notice_new_bottleneck(); } 每天运行该循环多次 Web服务器 1,NetScaler用于负载均衡和静态内容缓存 2,使用mod_fast_cgi运行Apache 3,使用一个Python应用服务器来处理请求的路由 4,应用服务器与多个数据库和其他信息源交互来获取数据和格式化html页面 5,一般可以通过添加更多的机器来在Web层提高伸缩性 6,Python的Web层代码通常不是性能瓶颈,大部分时间阻塞在RPC 7,Python允许快速而灵活的开发和部署 8,通常每个页面服务少于100毫秒的时间 9,使用psyco(一个类似于JIT编译器的动态的Python到C的编译器)来优化内部循环 10,对于像加密等密集型CPU活动,使用C扩展 11,对于一些开销昂贵的块使用预先生成并缓存的html 12,数据库里使用行级缓存 13,缓存完整的Python对象 14,有些数据被计算出来并发送给各个程序,所以这些值缓存在本地内存中。这是个使用不当的策略。应用服务器里最快的缓存将预先计算的值发送给所有服务器也花不了多少时间。只需弄一个代理来监听更改,预计算,然后发送。

日志检查工具——Logcheck

  Logcheck (主页)是用来自动检查系统安全入侵事件和非正常活动记录的工具,它分析各种Linux下的日志文件,比如 /var/log/messages、/var/log/secure、/var/log/maillog 等等,生成一个可能有安全问题的问题报告,并自 动发送电子邮件给管理员。能设置它基于每小时或者每天用crond来自动运行。 Logcheck是一个软件包,用来实现自动检查日志文件,以发现安全入侵和不正常的活动。Logcheck用logtail程序来记录读到的日志文件的位置,下一次运行的时候从记录下的位置开始处理新的信息。所有的源代码都是公开的,实现方法也非常简单。 Logcheck SHELL脚本和logtail.c程序用关键字查找的方法进行日志检测。在这儿提到的关键字就是指在日志文件中出现的关键字,会触发向系统管理员发的报 警信息。Logcheck的配置文件自带了缺省的关键字,适用于大多数的Unix系统。但是最好还是自己检查一下配置文件,看看自带的关键字是否符合自己 的需要。 Logcheck脚本是简单的SHELL程序,logtail.c程序只调用了标准的ANSI C函数。Logcheck要在cron守护进程中配置,至少要每小时运行一次。脚本用简单的grep命令来从日志文件检查不正常的活动,如果发现了就发送 电子邮件给管理员。如果没有发现异常活动,就不会收到电子邮件。 logcheck工具的主页在 http://logcheck.org/,用户可以在上面下载其最新版本: logcheck-1.1.1.tar.gz。下载后用tar xvfz logcheck-1.1.1.tar.gz命令解开到一临时目录下,然后用make linux自动生成相应的文件到/usr/local/etc、/usr/local/bin/等目录下。用户可能需要更改设置,如发送通知到谁的邮件账 号等,默认发送到root。 利用logcheck工具分析所有logfile,避免每天经常手动地检查它们,节省了时间,提高了效率。

被保护: 我的WebService

盛大灵游记:http://shop.ourgame.com/GLGGBilling/Service4Partner.asmx 新浪机战:http://222.77.177.169/sinapay/ChargeMoneyInterface1.asmx 腾龙功夫世界:http://secure.tengwu.com.cn/MainService.asmx 星级家园:(非webservice提供接口) PHP5 Soap 接口代码框架: try { $response = $soap_client->__soapCall(“m_GetRolesList”,$params); if ($response['m_GetRolesListResult'] != 1) { $err = m_GFSJ_GetErrText($response['m_GetRolesListResult']); $loge->uniLog(“$err”); return false; }else { $logv->uniLog(“{$response['lsRoleIDName']}”); $rolestr = trim($response['lsRoleIDName']); return $rolestr; } } catch (SoapFault $fault) { $loge->uniLog(“faultcode:{$fault->faultcode}\tfaultstring:{$fault->faultstring}”); return false; }

关于sizeof()的简单解析

在所有说明之前,先给出一道题目: int a=256; printf(“%d\n”, sizeof(++a)); printf(“%d\n”, a); 那么到底打印的是多少呢? 应该是4和256,第一个答案大家应该已经没有问题了,但是为什么在++a以后,a的数值还是没有发生变化呢?因为sizeof()是一个运算符,在其中的所有的运算都是无效的,所以++a根本就没有运行。 上面的一个例子提醒我们,虽然sizeof看这简单,但是其中还是有很多的问题值得讨论的: 一、sizeof的概念 sizeof是C语言的一种单目操作符,如C语言的其他操作符++、–等。它并不是函数。sizeof操作符以字节形式给出了其操作数的存储大小。操作数可以是一个表达式或括在括号内的类型名。操作数的存储大小由操作数的类型决定。 二、sizeof的使用方法  1、用于数据类型  sizeof使用形式:sizeof(type) 数据类型必须用括号括住。如sizeof(int)。 2、用于变量  sizeof使用形式:sizeof(var_name)或sizeof var_name 变量名可以不用括号括住。如sizeof (var_name),sizeof var_name等都是正确形式。带括号的用法更普遍,大多数程序员采用这种形式。 注意:sizeof操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。 如sizeof(max)若此时变量max定义为int max(),sizeof(char_v) 若此时char_v定义为char char_v [MAX]且MAX未知,sizeof(void)都不是正确形式。 三、sizeof的结果  sizeof操作符的结果类型是size_t,它在头文件 <stddef.h> 中typedef为unsigned int类型。该类型保证能容纳实现所建立的最大对象的字节大小。 1、若操作数具有类型char、unsigned char或signed char,其结果等于1。 ANSI C正式规定字符类型为1字节。 2、int、unsigned int 、short int、unsigned short 、long int 、unsigned long 、 float、double、long double类型的sizeof 在ANSI C中没有具体规定,大小依赖于实现,一般可能分别为2、2、2、 2、 4、4、4、8、10。 3、当操作数是指针时,sizeof依赖于编译器。例如Microsoft C/C++7.0中,near类指针字节数为2,far、huge类指针字节数为4。一般Unix的指针字节数为4。 4、当操作数具有数组类型时,其结果是数组的总字节数。 5、联合类型操作数的sizeof是其最大字节成员的字节数。结构类型操作数的sizeof是这种类型对象的总字节数,包括任何垫补在内。 让我们看如下结构: struct {char b; double x;} a; 在某些机器上sizeof(a)=12,而一般sizeof(char)+ sizeof(double)=9。 这是因为编译器在考虑对齐问题时,在结构中插入空位以控制各成员对象的地址对齐。如double类型的结构成员x要放在被4整除的地址。 6、如果操作数是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小。 四、sizeof与其他操作符的关系  sizeof的优先级为2级,比/、%等3级运算符优先级高。它可以与其他操作符一起组成表达式。如i*sizeof(int);其中i为int类型变量。 五、sizeof的主要用途  1、sizeof操作符的一个主要用途是与存储分配和I/O系统那样的例程进行通信。例如: void *malloc(size_t size), size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream)。 2、sizeof的另一个的主要用途是计算数组中元素的个数。例如: void * memset(void * s,int c,sizeof(s))。 六、建议  由于操作数的字节数在实现时可能出现变化,建议在涉及到操作数字节大小时用sizeof来代替常量计算。

PHP忽略用户中断

        做  Web 开发的人都知道,浏览器和服务器之间是通过 HTTP 协议进行连接通讯的。这是一种基于请求和响应模型的协议。浏览器通过 URL 向某台服务器发起请求(Request),Web 服务器接收到请求,执行一段程序,然后做出响应(Response),也就是一段字符串,这个字符串符合 HTTP 协议的格式,有 HEAD 和 BODY 两部分。 这其中有一个问题,Web  服务器执行一段程序,可能几毫秒就完成,也可能几分钟都完不成。如果程序执行缓慢,用户可能没有耐心等下去,就关闭浏览器了。这个时候,服务器会接收到连 接状态改变的通知,因为 HTTP  是最上层的协议,下面还有一层 TCP 协议,TCP  会知道连接中断。连接一断,服务端的程序会立即停止执行。 现在说到问题的关键了,服务端的程序立即停止执行,如果这个程序只是读取信息的还好说,停了不读了就是了。万一是一个写入的程序呢?比如,用户提交一 段文本,也许服务端的设计比较复杂,需要同时更新好几个表,但由于某些原因,例如其中一个表被其他进程锁定,那么这个程序就会一直等待,这个时候用户要是 关闭浏览器,那程序就不等了,直接退出了。结果就是这条信息保存不完整。 举个具体的例子,用户提交的文本需要写到 A、B、C、D 四个表里,写入 A、B 两个表可能 0.1 毫秒就完成了,但 C 表被另一个进程锁定,那当前进程就得一直等,这时用户关闭浏览器,当前进程退出,那么,就会造成一种状况,A、B 表里有新的内容,而 C、D 表里没有这条内容,产生了严重的数据一致性的问题! 虽然,利用数据库的事务,可以使状态回滚,但结果就是用户的本次提交无效。 现在希望的是,只要用户提交了,就要成功保存,也许遇到意外情况导致执行时间过长,但用户关闭浏览器也没关系。 于是,就需要 ignore_user_abort 这个函数。 当调用 ignore_user_abort(1) 时, 就设定了忽略用户退出这个标志位,也就是不管怎样,也要把程序执行到底,除非在程序中调用了 exit。 其实,还有另一个函数,register_shutdown_function,它可以注册一个函数或方法,在程序退出的时候调用,有些类似于 javascript 里面的 onunload 和 onbeforeunload 事件。 [...]

不常用的Linux进程信息

        ps能够提供不少进程信息,比如进程号、进程运行状态、进程名称、所占CPU时间、所占内存等。除此以外,还有一些不很常用的进程信息,可以用来解决一些 可能很常见的问题 (比如内存泄漏,进程运行异常等)。 所打开的文件 获取方法1: # ls -l /proc/$PID/fd/ 获取方法2: # lsof -p $PID 内存分配表 获取方法: # lcat /proc/$PID/maps 堆栈 获取方法: # pstack $PID 所发出的系统调用 获取方法: # strace -p $PID 所发出的库函数调用 获取方法: # ltrace -p $PID 进程继承关系 获取方法: ps -eo user,pid,ppid,%cpu,%mem,vsz,rss,tty,stat,start,time,wchan,command –forest 运行时dumpcore 获取方法: # gcore $PID

搞笑对联

★上联:风在刮,雨在下,我在等你回电话;下联:为你生,为你死,为你守候一辈子;横批:发错人了。  ★上联:看背影急煞千军万马;下联:转过头吓退百万雄师;横批:我的妈呀 ★上联:考试不作弊来年当学弟;下联:宁可没人格不可不及格;横批:就是要过! ★上联:麻将扑克金花,输完之后回家;下联:古道西风瘦马,断肠人在天涯;横批:惨啊! ★上联:去除数字一和二;下联:还有四五六七九;横批:只剩三八! ★上联:说你行你就行不行也行;下联:你说不行就不行行也不行;横批:不服不行。 ★上联:为你痴为你累为你受尽所有罪;下联:为你死为你狂为你咣咣撞大墙;横批:为爱疯狂。 ★上联:我爱的人名花有主;下联:爱我的人惨不忍睹;横批:命苦。 ★上联:在上为帅;下联:在下为猪;横批:天蓬元帅。 ★上联:假名假姓假地址;下联:骗吃骗喝骗感情;横批:愿者上钩。 ★上联:红米饭南瓜汤,老婆一个孩子一帮;下联:红米饭王八汤,孩子一个老婆一帮;横批:与时俱进。 ★上联:上压下层层加码,马到成功;下联:下骗上节节掺水,水到渠成;横批:皆大欢喜。 ★上联:爱与被爱都艰难;下联:有情有缘要时间;横批:情义无价 ★上联:羊在山坡晒不黑;下联:猪在猪圈捂不白! 横批:我就是我

微软笔试

        上回微软在北邮的笔试,因为我把周六记成功周日,结果错过了没能去成。不料没过几天,微软再次给我发来邀请邮件,邀请我参加11月4号在北航举行的最后一次笔试。 虽然微软的邮件里写明了是招应届毕业生,可是抱着“参与第一”的心态,我决定去考一下,就算体验一下微软的招聘题目也不错啊,毕竟机会难得么。 出门的时候已经比较晚了,小蔡于是加大油门往北航赶。曲曲折折的找到了考场,但还是没有来得及打印简历和邀请函。不过还好,看了身份证之后就让进去了。没有带眼镜,我只好走到最前排,站在黑板正下方去看黑板上写的注意事项。 题目全是英文的,整个将近20页的考卷上找不出几个中文字。题目分了4部分:第一部分选择题,有单选也有多选,分值还不一样,选错了也有不一样的倒扣分值;第二部分编程,就一道大题,让编一个 Notepad 的自动换行函数,函数原型(记忆中的,可能不完全准确) void TextWrap(const char* inText, char* outBuffer, int outBufferLength, int lineWidth) 分了2个小问,第一问是写出主要的 subroute (单词记得不是很清楚了),第二问才是实现这个函数;第三部分测试,要求写出 20 组测试用例,来测上一题写的函数;第四部分,也是最后一部分,design,应该翻译成设计吧,只是题目跟我理解的设计有点区别:要求设计一个全职父母在工作时可以查看在家的小孩的情况的系统,包括硬件和软件,类似于装备摄像头和麦克风,然后父母使用手持设备通过网络连接进行连线。问题问的比较诡异,问这个系统靠那些方面赚钱,应该具备那些特性,技术上有哪些难点,最后还问手持设备使用专用设备还是在普通手机上使用软件实现比较好,对比这两种实现方式,并说明你选择其中某一种的理由。 第一部分的选择题,考的东西比较零碎,大体来说,有网络(有一道题问TCP包里能看到哪些内容),编程(C#,C/C++,C++类的对象拷贝和指针拷贝的区别,以及每次都会出的C#代码在哪一行编译不过的问题),算法(二叉树,链表,汉诺塔,vector等),操作系统(给出文件系统的一些说明,问支持的最大单个文件的大小) 等。等到回过头来再去想想,当时很多题目是应该能做对的,只是当时想叉了。这些基础只是还是不能长久的不闻不问啊,稍不留神,便又生疏好多了。 回家,专心准备明天继续上班吧。