分页: 2/12 第一页 上页 1 2 3 4 5 6 7 8 9 10 下页 最后页 [ 显示模式: 摘要 | 列表 ]
  [文章作者:张宴 本文版本:v1.0 最后修改:2011.08.05 转载请注明原文链接:http://blog.zyan.cc/file_get_contents/]

  有时候,运行 Nginx、PHP-CGI(php-fpm) Web服务的 Linux 服务器,突然系统负载上升,使用 top 命令查看,很多 php-cgi 进程 CPU 使用率接近100%。后来,我通过跟踪发现,这类情况的出现,跟 PHP 的 file_get_contents() 函数有着密切的关系。

  大、中型网站中,基于 HTTP 协议的 API 接口调用,是家常便饭。PHP 程序员们喜欢使用简单便捷的 file_get_contents("http://example.com/") 函数,来获取一个 URL 的返回内容,但是,如果 http://example.com/ 这个网站响应缓慢,file_get_contents() 就会一直卡在那儿,不会超时。

  我们知道,在 php.ini 中,有一个参数 max_execution_time 可以设置 PHP 脚本的最大执行时间,但是,在 php-cgi(php-fpm) 中,该参数不会起效。真正能够控制 PHP 脚本最大执行时间的是 php-fpm.conf 配置文件中的以下参数:
  默认值为 0 秒,也就是说,PHP 脚本会一直执行下去。这样,当所有的 php-cgi 进程都卡在 file_get_contents() 函数时,这台 Nginx+PHP 的 WebServer 已经无法再处理新的 PHP 请求了,Nginx 将给用户返回“502 Bad Gateway”。修改该参数,设置一个 PHP 脚本最大执行时间是必要的,但是,治标不治本。例如改成 <value name="request_terminate_timeout">30s</value>,如果发生 file_get_contents() 获取网页内容较慢的情况,这就意味着 150 个 php-cgi 进程,每秒钟只能处理 5 个请求,WebServer 同样很难避免“502 Bad Gateway”。

  要做到彻底解决,只能让 PHP 程序员们改掉直接使用 file_get_contents("http://example.com/") 的习惯,而是稍微修改一下,加个超时时间,用以下方式来实现 HTTP GET 请求。要是觉得麻烦,可以自行将以下代码封装成一个函数。
  当然,导致 php-cgi 进程 CPU 100% 的原因不只有这一种,那么,怎么确定是 file_get_contents() 函数导致的呢?

  首先,使用 top 命令查看 CPU 使用率较高的 php-cgi 进程。

top - 10:34:18 up 724 days, 21:01,  3 users,  load average: 17.86, 11.16, 7.69
Tasks: 561 total,  15 running, 546 sleeping,   0 stopped,   0 zombie
Cpu(s):  5.9%us,  4.2%sy,  0.0%ni, 89.4%id,  0.2%wa,  0.0%hi,  0.2%si,  0.0%st
Mem:   8100996k total,  4320108k used,  3780888k free,   772572k buffers
Swap:  8193108k total,    50776k used,  8142332k free,   412088k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                              
10747 www       18   0  360m  22m  12m R 100.6 0.3    0:02.60 php-cgi                                                                                                              
10709 www       16   0  359m  28m  17m R 96.8  0.4    0:11.34 php-cgi                                                                                                              
10745 www       18   0  360m  24m  14m R 94.8  0.3    0:39.51 php-cgi                                                                                                              
10707 www       18   0  360m  25m  14m S 77.4  0.3    0:33.48 php-cgi                                                                                                              
10782 www       20   0  360m  26m  15m R 75.5  0.3    0:10.93 php-cgi                                                                                                              
10708 www       25   0  360m  22m  12m R 69.7  0.3    0:45.16 php-cgi                                                                                                              
10683 www       25   0  362m  28m  15m R 54.2  0.4    0:32.65 php-cgi                                                                                                              
10711 www       25   0  360m  25m  15m R 52.2  0.3    0:44.25 php-cgi                                                                                                              
10688 www       25   0  359m  25m  15m R 38.7  0.3    0:10.44 php-cgi                                                                                                              
10719 www       25   0  360m  26m  16m R  7.7  0.3    0:40.59 php-cgi

  找其中一个 CPU 100% 的 php-cgi 进程的 PID,用以下命令跟踪一下:
strace -p 10747

  如果屏幕显示:
select(7, [6], [6], [], {15, 0})        = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0)     = 0 (Timeout)
select(7, [6], [6], [], {15, 0})        = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0)     = 0 (Timeout)
select(7, [6], [6], [], {15, 0})        = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0)     = 0 (Timeout)
select(7, [6], [6], [], {15, 0})        = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0)     = 0 (Timeout)
select(7, [6], [6], [], {15, 0})        = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0)     = 0 (Timeout)
select(7, [6], [6], [], {15, 0})        = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0)     = 0 (Timeout)
select(7, [6], [6], [], {15, 0})        = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0)     = 0 (Timeout)
select(7, [6], [6], [], {15, 0})        = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0)     = 0 (Timeout)
select(7, [6], [6], [], {15, 0})        = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0)     = 0 (Timeout)
select(7, [6], [6], [], {15, 0})        = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0)     = 0 (Timeout)

  那么,就可以确定是 file_get_contents() 导致的问题了。
  [文章作者:张宴 本文版本:v1.0 最后修改:2011.07.26 转载请注明原文链接:http://blog.zyan.cc/httpsqs_1_7/]

  HTTPSQS(HTTP Simple Queue Service)是一款基于 HTTP GET/POST 协议的轻量级开源简单消息队列服务,使用 Tokyo Cabinet 的 B+Tree Key/Value 数据库来做数据的持久化存储。

  项目网址http://code.google.com/p/httpsqs/
  使用文档http://blog.zyan.cc/httpsqs/
  使用环境:Linux(同时支持32位、64位操作系统,推荐使用64位操作系统)
  软件作者:张宴



  HTTPSQS 1.7 版本更新内容:

  下面的内容不只是介绍 HTTPSQS 1.7 更新了哪些东西,更多的介绍在于:如何绕开 Libevent 2.0.x evhttp 使用过程中,无法正常处理包含“|”字符的 URI 参数的问题;提供了一份比 Libevent 官方网站更新的在线文档;Linux 下如何动态编译程序,运行时不用在 /etc/ld.so.conf 文件中添加动态链接库路径。

  1、针对 Libevent 2.0.x 版本 evhttp_parse_query 函数的 BUG。

  网友发邮件,反应了一个 HTTPSQS 的 BUG,见下图,data 的值为NULL。我查找发现,这不是 HTTPSQS 的 BUG,而是 Libevent 2.0.x 版本的 BUG。在 Libevent 1.4.14b 版本中,evhttp_parse_query 函数是能够正常处理包含“|”字符的 URI 的,而在 Libevent 2.0.12 版本中,同样使用 evhttp_parse_query 函数,包含“|”字符的 URI  处理后的结果是 NULL。

  点击在新窗口中浏览此图片

  对比 Libevent 2.0.12 和 1.4.14b 版本的 evhttp_parse_query 函数代码,发现在 2.0.12 版本中,evhttp_parse_query(const char *uri, struct evkeyvalq *headers) 实际变成了调用 evhttp_parse_query_impl(uri, headers, 1) 函数,该函数内再调用的一个 2.0.x 版本新增的函数 evhttp_uri_parse(const char *source_uri),逻辑处理代码在 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags) 函数中。evhttp_uri_parse(const char *source_uri) 无法正确解析含有“|”的URL,遇到类似“http://127.0.0.1:1218/?opt=get&name=aaa|bbb”的URL,直接返回NULL,也就是 BUG 所在。

  libevent-2.0.12-stable/http.c
  点击在新窗口中浏览此图片

  点击在新窗口中浏览此图片

  点击在新窗口中浏览此图片

  不建议修改第三方库,这个 BUG 还是留给 Libevent 自己去解决吧。使用 Libevent 2.0.x evhttp 作开发的同学,遇到URI参数中包含“|”的问题,注意一下吧。

  我修改了 HTTPSQS 代码,在 HTTPSQS 1.7 版本,采用以下方式来绕开evhttp_uri_parse(const char *source_uri)函数,解决这个问题。其中用到了 Libevent 2.0.x  evhttp_request 结构体中新增的 struct evhttp_uri *uri_elems,以及新增的函数 evhttp_parse_query_str (const char *uri, struct evkeyvalq *headers)。

  Libevent 的官方文档只有 1.4.10-stable2.0.1-alpha 版本的,2.0.1x 很多新增的函数、结构体都没有。

  我这里提供一份最新的 Libevent 在线文档: http://blog.zyan.cc/book/libevent/



  2、静态编译改为动态编译,并指定程序运行时查找的动态链接库路径

  一些网友反映,CentOS 6.0、Fedora 等系统没有默认安装lz、lbz2、lrt、...等静态链接库,出现无法编译HTTPSQS的情况:
gcc -o httpsqs httpsqs.c prename.c -L/usr/local/libevent-2.0.10-stable/lib/ -levent -L/usr/local/tokyocabinet-1.4.47/lib/ -ltokyocabinet -I/usr/local/libevent-2.0.10-stable/include/ -I/usr/local/tokyocabinet-1.4.47/include/ -lz -lbz2 -lrt -lpthread -lm -lc -O2 -g --static  
/usr/bin/ld: cannot find -lz  
/usr/bin/ld: cannot find -lbz2  
/usr/bin/ld: cannot find -lrt  
/usr/bin/ld: cannot find -lpthread  
/usr/bin/ld: cannot find -lm  
/usr/bin/ld: cannot find -lc  
/usr/bin/ld: cannot find -lc  
collect2: ld 返回 1  
make: *** [httpsqs] 错误 1


  HTTPSQS 1.7 版本改为动态编译,编译时使用“-Wl,-rpath”参数指定了程序运行时的动态库搜索路径。这样就不需要在 /etc/ld.so.conf 中 添加 HTTPSQS 程序运行时需要的 libevent、tokyocabinet 动态链接库路径了,可以避免与其他软件(例如:Memcached、TT)使用的 libevent、tokyocabinet 动态链接库版本相冲突。详情请见 Makefile 文件:
# Makefile for httpsqs
CC=gcc
CFLAGS=-Wl,-rpath,/usr/local/libevent-2.0.12-stable/lib/:/usr/local/tokyocabinet-1.4.47/lib/ -L/usr/local/libevent-2.0.12-stable/lib/ -levent -L/usr/local/tokyocabinet-1.4.47/lib/ -ltokyocabinet -I/usr/local/libevent-2.0.12-stable/include/ -I/usr/local/tokyocabinet-1.4.47/include/ -lz -lbz2 -lrt -lpthread -lm -lc -O2 -g

httpsqs: httpsqs.c
  $(CC) -o httpsqs httpsqs.c prename.c $(CFLAGS)
  @echo ""
  @echo "httpsqs build complete."
  @echo ""  

clean: httpsqs
  rm -f httpsqs

install: httpsqs
  install $(INSTALL_FLAGS) -m 4755 -o root httpsqs $(DESTDIR)/usr/bin

  [文章作者:张宴 本文版本:v1.0 最后修改:2011.06.28 转载请注明原文链接:http://blog.zyan.cc/windows_mstsc/]

  个人不喜欢服务端程序,以 Windows 操作系统作为运行平台,但是,很多时候,迫于环境现状,需要让自己的程序实现跨平台。

  在开发全新的金山游戏运营平台时,发现:虽然大部分游戏,服务端程序运行在 Linux 服务器,但是,仍有例外。几款最近代理的游戏,服务端运行在 Windows 服务器上。西山居开发的游戏,服务端集群架构,既有 Windows 服务器,又有 Linux 服务器。

  点击在新窗口中浏览此图片


  游戏运行系统的 Knose 程序,我最初是在 Linux 下开发的,后来才实现了兼容 Windows 的跨平台版本。

  点击在新窗口中浏览此图片


  在 Linux 下,Knose 为“父子进程+指令处理线程池+独立功能多线程”结构;在 Windows 上,将 Knose 父子进程结构,拆分成了 knose_daemon.exe(Service 服务程序)和 knose.exe(主程序),由 knose_daemon.exe 启动 knose.exe。

  点击在新窗口中浏览此图片


  遇到了问题:按照运营维护需求,knose.exe 以及通过它启动的游戏服务端进程,需要有“窗口界面”,显示在桌面中。而 knose_daemon.exe 是以服务方式运行的,无窗口界面,knose_daemon.exe 启动的 knose.exe,窗口界面没有弹出来。

  为了解决这个问题,我在 install.bat 中,用了 Windows 的 sc 命令,将 knose_daemon.exe 启动为系统服务,“type= interact type= own”设置了“允许桌面与服务交互”。在本机(Windows XP SP3)测试,knose.exe 的窗口界面以及通过它启动的游戏进程窗口界面,都弹出来了。

@echo off
sc create "KingeyesKnose" binPath= "%CD%\knose_daemon.exe" DisplayName= "Kingeyes Knose Daemon" start= auto type= interact type= own
sc description KingeyesKnose "金山游戏运营系统 KingEyes Knose 守护进程。"
sc start KingeyesKnose


  点击在新窗口中浏览此图片


  于是将程序发布到 Windows Server 2003 服务器上,远程桌面连接上去,发现 knose.exe 的窗口界面始终弹不出来。

  后来,同事发现,原来是“远程桌面”惹的祸:

  远程桌面客户端 mstsc 有一个 /console 参数,模式等同于本地终端显示器登录,/console 不会去占用非 /console 远程桌面,远程桌面允许两个正常连接和一个控制台/console方式连接,并且正常连接和 /console 连接的桌面操作不能相互看见,只有通过 /console 参数远程桌面连接到 Windows 2003 服务器,才能够看到弹出的 knose.exe 窗口界面。

  在 Windows XP SP3 以上版本,/console 参数改名为 /admin,需要用 mstsc /admin 启动远程桌面:

  点击在新窗口中浏览此图片

  连上后,终于能够看到由 knose_daemon.exe 启动的 knose.exe 程序窗口,以及由 knose.exe 启动的游戏服务端进程窗口了。
  5月7日,我在北京长城饭店“2011中国PHP技术高峰论坛”上的演讲PPT:

  下载地址1(国外服务器):http://blog.zyan.cc/attachment/201105/2011phptc_zy.zip

  下载地址2(国内服务器):http://ishare.iask.sina.com.cn/f/15231659.html



  点击在新窗口中浏览此图片

  以下是我在会议主办方对演讲文字速录的基础上,修正错漏内容,整理之后,对应到每页PPT的文字内容:

  [PPT No.1]
  大家下午好,现在我来跟大家分享的是PHP在金山游戏运营中的应用,包括团队协助开发实现方式、网站Web架构设计、游戏运营平台设计这些信息。

  [PPT No.2]
  我议题主要有两个,一个是金山游戏官方网站的一些应用,另一个是金山游戏运营系统Keyes中的架构设计。

  [PPT No.3]
  金山游戏官方网站包括用户中心客服系统论坛视频、各游戏官网,以及其他跟游戏相关的一些产品,主要采用64位CentOS Linux系统、Nginx、PHP 5.2版本、MySQL 5.5。

  [PPT No.4]
  首先来看团队协作开发。我们肯定遇到过这样一种情况,在很多项目中,都是多个人同时开发,涉及到开发环境和测试环境不一样。我们很多PHP工程师,都是在Windows上开发代码,虽然Windows上也可以配置Nginx+PHP+MySQL环境,但是,由于测试环境、生产环境都是Linux系统,而且一些功能只能在Linux下运行,还有一些PHP扩展(例如:分布式图片处理、金山通行证加密扩展),也只能运行在Linux环境中。当我们在Windows上修改完几行PHP代码,想马上看一下执行结果,如果利用FTP之类的工具传到Linux测试服务器上再测试,就太慢了。如果同一台Linux测试服务器上,有多少人同时开发,你上传上去PHP文件,可能会覆盖别人上传的同名文件,就没有办法做到版本控制。

  [PPT No.5]
  我们从图中可以看到,假如是程序员A和B都在Windows上开发代码,由于Nginx与PHP之间采用的是TCP FastCGI协议通讯,因此,两者可以分离到不同的服务器上。我们可以把Nginx安装在程序员各自的Windows PC机上,用本机的Nginx处理HTTP请求,用Linux测试服务器上的php-cgi程序,处理PHP请求。程序员在Windows上开发程序,保存之后,不用做任何上传操作,即可用Linux上的php-cgi调试程序。从图中这个流程可以看到,首先,两个程序员分别从SVN版本库,获取到一个项目的最新版本,各自进行一些修改。两人修改程序时,采用的是同一台Linux测试服务器的php-cgi,对各自PC机上的PHP程序进行调试。在PC机上本地测试没有问题,可以提交到SVN版本库。我们做了一个自动同步程序,利用SVN钩子,在每次发生svn commit提交时,在对应的测试服务器的对应项目路径内,执行svn update,将最新修改到文件同步到测试服务器。后来发现有一些问题,如果我们一个项目的目录、程序文件特别多的话,svn update需要遍历扫描目录列表,非常慢。因为我们的SVN是和Apache结合起来使用的,Apache可以记录日志,于是,我们进行了改进,将SVN提交日志记录到Linux下的命名管道内,再用一个程序从命名管道内读取日志,只svn update每次修改的几个文件,这样,速度就非常快了。设置hosts为Linux测试服务器的IP,就可以测试多位程序员代码合并后的效果了。
Tags:
  [文章作者:张宴 本文版本:v1.0 最后修改:2011.04.21 转载请注明原文链接:http://blog.zyan.cc/httpsqs_1_6/]

  HTTPSQS(HTTP Simple Queue Service)是一款基于 HTTP GET/POST 协议的轻量级开源简单消息队列服务,使用 Tokyo Cabinet 的 B+Tree Key/Value 数据库来做数据的持久化存储。

  项目网址http://code.google.com/p/httpsqs/
  使用文档http://blog.zyan.cc/httpsqs/
  使用环境:Linux(同时支持32位、64位操作系统,推荐使用64位操作系统)
  软件作者:张宴

  队列(Queue)又称先进先出表(First In First Out),即先进入队列的元素,先从队列中取出。加入元素的一头叫“队头”,取出元素的一头叫“队尾”。利用消息队列可以很好地异步处理数据传送和存储,当你频繁地向数据库中插入数据、频繁地向搜索引擎提交数据,就可采取消息队列来异步插入。另外,还可以将较慢的处理逻辑、有并发数量限制的处理逻辑,通过消息队列放在后台处理,例如FLV视频转换、发送手机短信、发送电子邮件等。

  HTTPSQS 具有以下特征:

  ● 非常简单,基于 HTTP GET/POST 协议。PHP、Java、Perl、Shell、Python、Ruby等支持HTTP协议的编程语言均可调用。
  ● 非常快速,入队列、出队列速度超过10000次/秒。
  ● 高并发,支持上万的并发连接,C10K不成问题。
  ● 支持多队列。
  ● 单个队列支持的最大队列数量高达10亿条。
  ● 低内存消耗,海量数据存储,存储几十GB的数据只需不到100MB的物理内存缓冲区。
  ● 可以在不停止服务的情况下便捷地修改单个队列的最大队列数量。
  ● 可以实时查看队列状态(入队列位置、出队列位置、未读队列数量、最大队列数量)。
  ● 可以查看指定队列ID(队列点)的内容,包括未出、已出的队列内容。
  ● 查看队列内容时,支持多字符集编码。
  ● 源代码不超过800行,适合二次开发。



  HTTPSQS 1.6 版本更新内容:

  一、服务器端:

  1、修正了定时将内存缓冲区内容同步到磁盘,有时候出现段错误,导致进程崩溃的BUG。感谢以下网友的反馈:

  点击在新窗口中浏览此图片

  点击在新窗口中浏览此图片

  点击在新窗口中浏览此图片



  2、修正了判断队列已满,遗漏的一种情况。感谢以下网友的反馈:

  点击在新窗口中浏览此图片

  点击在新窗口中浏览此图片



  3、改为父子进程模式,生产环境稳定性更高。

  4、改进了 ps 命令查看 httpsqs 的用户体验:

  点击在新窗口中浏览此图片



  5、增加了密码校验功能(通过以下启动参数设置密码,通过URL参数“/?auth=密码”访问):

  点击在新窗口中浏览此图片



  6、改为静态编译,编译完成后的 HTTPSQS 二进制文件,运行不再依赖 Libevent、Tokyocabinet 动态链接库。



  7、HTTPSQS 旧版本如何升级到 HTTPSQS 1.6 版本:

  HTTPSQS 1.6 版本完全兼容以前版本:编译安装 HTTPSQS 1.6,替换旧的 HTTPSQS,然后“kill httpsqs的进程ID”,按原来的启动参数启动 HTTPSQS 即可,数据完全兼容。



  二、客户端:

  1、客户端代码不再集成在 HTTPSQS 源码包中,可通过链接自行查看。



  HTTPSQS 1.6 版本的详细使用说明,请访问: http://blog.zyan.cc/httpsqs/

  [文章作者:张宴 本文版本:v1.0 最后修改:2011.04.08 转载请注明原文链接:http://blog.zyan.cc/samba_linux_windows/]

  一、局域网内的 Linux 服务器上操作步骤:

  1、安装samba(CentOS Linux):
yum install samba system-config-samba samba-client samba-common


  2、创建www账号
/usr/sbin/groupadd www
/usr/sbin/useradd -g www www

mkdir -p /data0/knose/
chmod 777 /data0/knose/

mkdir -p /data0/htdocs/
chown -R www:www /data0/htdocs/
chmod 777 /data0/htdocs/

cat /etc/passwd | mksmbpasswd.sh> /etc/samba/smbpasswd


  3、创建samba配置文件
mv -f /etc/samba/smb.conf /etc/samba/smb.conf.bak
vi /etc/samba/smb.conf

  输入以下内容:
引用
[global]
server string = Samba Server
security = user
encrypt passwords = yes
smb passwd file = /etc/samba/smbpasswd

[knose]
workgroup = root
netbios name = root
path = /data0/knose
browseable = yes
writeable = yes

[web]
workgroup = www
netbios name = www
path = /data0/htdocs
browseable = yes
writeable = yes


  4、为samba用户www、root设立一个密码:
smbpasswd -a www
smbpasswd -a root


  5、启动samba:
/sbin/service smb start




  二、局域网内的 Windows 服务器上操作步骤:
Tags: , ,
  [文章作者:张宴 本文版本:v1.0 最后修改:2011.03.30 转载请注明原文链接:http://blog.zyan.cc/libevent_windows/]

  本文介绍了如何在 Windows 操作系统中,利用微软 Visual Studio 2005 编译生成 Libevent 2.0.10 静态链接库,并利用 Libevent 静态链接库,实现一个简单的 HTTP Web服务器程序:httpd.exe。

  假设 Visual Studio 2005 的安装路径为“D:\Program Files\Microsoft Visual Studio 8\”,Libevent 2.0.10 解压后的路径为“D:\libevent-2.0.10-stable”。



  一、编译生成 Libevent 2.0.10 静态链接库。
  
  1、修改“D:\libevent-2.0.10-stable\event_iocp.c”、“D:\libevent-2.0.10-stable\evthread_win32.c”、“D:\libevent-2.0.10-stable\listener.c”三个文件,在文件开头分别加上一行:
#define _WIN32_WINNT 0x0500


  2、鼠标点击Windows左下角的【开始】-【所有程序】,找到【Microsoft Visual Studio 2005】,执行下图中的脚本:

  点击在新窗口中浏览此图片


  3、按照下图中的方法编译Libevent 2.0.10:

  点击在新窗口中浏览此图片


  4、生成的“libevent.lib”、“libevent_core.lib”、“libevent_extras.lib”三个文件就是我们需要的 Libevent 静态链接库。

  点击在新窗口中浏览此图片



  二、利用 Libevent 静态链接库,实现一个简单的 HTTP Web服务器程序

  1、打开 Visual Studio 2005,新建一个项目

  点击在新窗口中浏览此图片
  在 Windows、Linux 操作系统,分别利用BAT批处理文件和Shell脚本,生成类似“20110228_082905.txt”以“年月日_时分秒”命名的文件。

  Windows BAT批处理文件:
@echo off
set time_hh=%time:~0,2%
if /i %time_hh% LSS 10 (set time_hh=0%time:~1,1%)
set filename=%date:~,4%%date:~5,2%%date:~8,2%_%time_hh%%time:~3,2%%time:~6,2%
echo test >> %filename%.txt


  Linux Shell 脚本:
#!/bin/sh
echo test >> $(date -d "today" +"%Y%m%d_%H%M%S").txt

  [文章作者:张宴 本文版本:v1.0 最后修改:2010.01.29 转载请注明原文链接:http://blog.zyan.cc/truecrypt]

  QQ、MSN、RTX的聊天历史记录,有时候在处理问题时,想查看一下,但换台电脑,就查看不到了,怎么办?Foxmail在公司收取的邮件,在家就看不到了,怎么解决?SecureCRT存放大量服务器SSH密码信息,换台电脑,如何不在新电脑上保存信息,同时又使用起来又方便、安全?存放在U盘上的机密文件,如何避免U盘丢失、被盗后,文件泄漏?

  市面上有很多加密软件,但由于未开源,可能存在后门,或者漏洞,导致加密的文件可破解。因此,对于加密软件来说,还是开源的比较靠谱。源码都公开,留有后门的可能性不存在了。在源码都可以查看的情况下,如果能够破解,早就可以破解了。

  TrueCrypt(http://www.truecrypt.org/)是一款开源的绿色加密软件。它可以在硬盘或闪存上创建一个或多个虚拟磁盘,所有虚拟磁盘上的文件都被自动加密,加密后需要通过密码来进行访问,由于加入了AES-256加密算法,使得加密数据几乎不可能被,对于没有商务安全功能的普通电脑,或者不舍得购买加密闪存的商务用户,TrueCrypt可以让他们的数据存储安全可靠。

  前几天公司发了两个2GB的金山毒霸版U盘,我将我的QQ、MSN、公司内部通讯工具RTX、SSH客户端SecureCRT、OpenSSL VPN、Foxmail、一些文档都装在了其中一个U盘上。

  点击在新窗口中浏览此图片

  关于TrueCrypt的安全性,有一则外电新闻:http://www.security.nl/artikel/33724
  
  FBI在经过一年的尝试后,还是未能破译被巴西执法机构指控金融犯罪的巴西银行家的加密文件。巴西一家葡萄牙语报纸报道(葡萄牙语),巴西联邦警察在2008年7月展开的Satyagraha行动中,在银行家Daniel Dantas位于里约热内卢的公寓内收缴了5个硬盘。文章提到硬盘使用了两种加密程序,一种是TrueCrypt,另一种是不知名的256位AES加密软件。在专家未能破解密码后,巴西政府在2009年初请求美国提供帮助,然而美国联邦警察在一年不成功的尝试后,退还了硬盘。巴西现有的法律中不存在强制要求Dantas交出密码的规定。



  使用步骤:将TrueCrypt拷贝到U盘上,然后运行TrueCrypt.exe。

  1、创建文件加密卷
Tags: , , ,
  [文章作者:张宴 本文版本:v1.0 最后修改:2010.01.20 转载请注明原文链接:http://blog.zyan.cc/android_apk_zip]

  前天,金山网络的一位同事向我咨询了一个问题:很多用户反映,网站上提供的Android手机应用程序文件“xxx.apk”,用IE浏览器下载,扩展名就被自动被重命名成了“xxx.zip”,拷贝到手机上无法安装。我发现,由于APK文件本身就是压缩包,如果用户的电脑上装了WinRAR(85%的装机量),用IE下载APK文件,扩展名就会被自动改为“.zip”。

  如果你的下载服务器为Nginx服务器,那么,在Nginx安装目录下的conf/mime.types文件的对应位置,加上以下一行语句,指定APK文件的MIME类型为 application/vnd.android.package-archive 即可:

application/vnd.android.package-archive     apk;


  截至本文发布时,存在“xxx.apk”下载时被自动重命名为“xxx.zip”问题的网站很多,其中不乏一些提供 Android 程序下载的知名网站,例如:新浪微博、街旁网。

  新浪微博官方 Android 手机客户端下载页:http://t.sina.com.cn/mobile/android.php

  点击在新窗口中浏览此图片

  点击在新窗口中浏览此图片

  街旁 Android 版客户端下载页:http://we.jiepang.com/client-android/
Tags: , , , ,
  (本文来自《程序员》杂志2011年01期,《程序员》官网地址:http://www.programmer.com.cn/4544/

  主持人:冯大辉,现任丁香园 (http://www.dxy.cn)网站CTO。曾历任支付宝架构师、数据库团队负责人等职。

点击在新窗口中浏览此图片  许式伟:作为系统架构师,您一般会从哪些方面来保证网站的高可用性(降低故障时间)?

  张宴:很多因素都会导致网站发生故障,从而影响网站的高可用性,比如服务器硬件故障、软件系统故障、IDC机房故障、程序上线前测试未发现的Bug、遭受分布式攻击、突发访问人数剧增等。

  一套良好的网站系统架构,应该尽可能地避免只有一台服务器、一个数据库、一套软件节点等单点故障的存在。单点故障一旦发生,将直接导致网站服务不可用,恢复正常服务所需的时间也比较长,甚至还可能无法恢复。负载均衡集群、双节点热备、分布式处理等都可以用来解决单点故障,比如提供相同业务的Web服务器、MySQL数据库从库,都可以构建负载均衡集群。一旦集群中的一台服务器、一个服务出现故障,自动实时摘除,对用户来说是不可感知的,不会影响到整个网站的访问,可以为运维工程师留下足够的时间去排查和解决故障。

  对于重要的MySQL数据库主库,我们习惯于从硬件层和软件层来实现热备,避免单点。越是复杂的设备,发生故障的概率越大。在磁盘没有损坏的情况下,应用程序导致服务器宕机的概率,远高于简单的磁盘阵列宕机的概率。所以,从硬件层解决的话,可以在两台服务器上安装相同的数据库版本、进行相同的配置,用SAS或SCSI线连接一台磁盘阵列,将数据库数据文件存放到盘阵上。正常情况下用服务器A挂载盘阵分区,启动MySQL,绑定虚拟IP;如果服务器A宕机,则用服务器B挂载盘阵分区,启动MySQL,接管虚拟IP。从软件层解决的话,则可以借助DRBD等软件做镜像。

  IDC机房发生故障的概率较小,但如果发生的话,影响面也是最大的。如果所有服务器都托管在一个IDC机房,一旦该机房遭遇长时间流量攻击、断电、断网、地方政策性封网等,通常只能联系IDC去处理,除此之外束手无策,解决时间也比较长。如果成本允许,将网站服务器分布在两个以上的IDC机房,当某个IDC发生故障时,可以临时切换DNS域名解析来优先恢复服务。

  虽然程序代码上线前,经过了测试人员的严格测试,但测试环境和生产环境毕竟有差异,所以一些会急剧影响性能、正常服务的Bug往往在程序上线之后,才会被发现,这就要求我们在发现Bug后,能够迅速回滚到上一正常版本。我们在SVN的基础上,开发了Web代码发布系统,会将每个发布版本之间的文件变更记录下来,一键实现程序代码在多台Web服务器上的发布和回滚。

  遭遇DDOS分布式拒绝服务攻击,使用防火墙来对付半连接、假IP,还算比较容易。而那种专挑复杂动态应用程序URL进行的分布式CC攻击,来源为真实IP、真实HTTP请求,具有模拟正规浏览器User-Agent、单个IP的每秒请求数不高、有成千上万个攻击源等特征,很难与正常访问区分开,比较难对付。但是,正常通过浏览器访问一个URL,会加载该URL中引入的JavaScript脚本、CSS样式、图片等文件。遇到CC攻击,需要及时分析日志,找出访问量异常上涨的URL,然后用事先写好的shell脚本找出哪些IP的请求只访问了该URL,而不加载该URL引入的文件,对这些IP进行自动封锁。

  系统架构设计时,需要事先考虑到高于目前访问量多少倍的突发访问。对于网游站点来说,访问量受广告集中时间段投放、线上活动的影响较大,带宽峰值时间不固定,对于静态内容,可以使用商业CDN,按实际使用量计费。对于动态内容,如果遇到突发访问人数剧增,超过现有服务器处理能力,最简单的临时处理办法就是增加服务器。上架新服务器需要时间,但是,同一个IDC机房内,可以借助其他业务的服务器,在不同端口开启一组新进程,加入到原有负载均衡池中。另外,可以临时关闭一些Web中的次要功能,来减少服务器消耗。



  许式伟:您在任务切分上,有什么经验分享?您通过哪些手段保证任务的独立性?

  张宴:相信很多人都遇到过这种情况:在一个老项目上修改、增加一些新功能所花费的时间,不比重新来做一个包含所有功能的新项目时间用得少。一个需要长期维护的项目,不可避免地会面临老员工的离职、新员工的接手,很多时候,项目代码的可维护性将决定一个项目的生存周期。让一个新员工在规定开发时间的压力下,去面对一个文档不够详细、陌生的、功能复杂的庞大项目,短时间弄明白所有功能逻辑不是一件容易的事。所以,任务需要切分,将一个大的任务切分成一个个小模块之后,各模块之间可以做到代码独立,互不影响,可维护性也大大增强。

  关于任务切分,我以本人今年负责的两个重要项目架构设计为例来介绍一下。在第一个项目:金山游戏官网的《用户行为分析系统》中,由于数据挖掘计算需要消耗较高的内存、CPU资源,一台服务器的处理能力不够,而商业的分布式数据仓库价格又太贵,所以,只有从程序应用中下手,进行任务切分。我们先按需要挖掘的数据指标,将整个数据挖掘任务切分成多个数据挖掘插件,每个插件可以在不同的服务器上运行,多个插件可以同时在多台服务器上。多个数据挖掘插件之间,如果用到相同的某项数据,那么,就将该项数据以冗余方式,复制几份提供给需要的插件,从而实现插件之间无交互、无关联,保证了超大数据量下插件的运算速度。

  在第二个项目:金山游戏新版运营管理系统中,则将整个任务切分成了PHP Web管理界面、PHP Web API功能接口、C/C++中间件引擎三部分。这是一种分层结构切分,最上层的“PHP Web管理界面”调用“PHP Web API功能接口”,“PHP Web API功能接口”调用运行在游戏服务器端的“C/C++中间件引擎”,“C/C++中间件引擎”与“游戏服务器端进程”通过TCP、UDP二进制协议、信号、命令行等多种方式通信。四者之间相对独立,代码无关联,通过一层层API接口实现交互。“PHP Web管理界面”负责通用界面实现。“PHP Web API功能接口”内部,又按接入的游戏模块、子功能模块进行了更细的切分,各功能模块之间通过内部API交互。“C/C++中间件引擎”大而全,不处理具体指令,但兼容TCP、UDP、HTTP、HTTPS/SSL、信号、命令行等大多数通信方式,负责和各种类型的游戏服务端交互。这是一套完全由API接口驱动的系统架构,一款新游戏接入运营管理系统时,只需在“PHP Web API功能接口”中增加一个模块;一个游戏新管理功能的增加,只需要在“PHP Web API功能接口”中增加一个子模块。通过任务切分,将复杂功能简单化,也将原来接入一款新游戏所需要的几个月时间,缩短为1~2周。



  许式伟:您通过哪些手段,来保障产品的质量?您倾向于多久更新一次您的网站?
  很多网站都通过User-Agent来判断浏览器类型,如果是3G手机,显示手机页面内容,如果是普通浏览器,显示普通网页内容。

  谷歌Chrome浏览器,可以很方便地用来当3G手机模拟器。在Windows的【开始】-->【运行】中输入以下命令,启动谷歌浏览器,即可模拟相应手机的浏览器去访问3G手机网页:

  谷歌Android:
chrome.exe --user-agent="Mozilla/5.0 (Linux; U; Android 2.2; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"


  苹果iPhone 4:
chrome.exe --user-agent="Mozilla/5.0 (iPhone; CPU iPhone OS 5_0_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9A405"


  苹果iPad 2:
chrome.exe --user-agent="Mozilla/5.0 (iPad; CPU OS 5_0_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9A405"


  诺基亚N97:
chrome.exe --user-agent="Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/20.0.019; Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebKit/525 (KHTML, like Gecko) BrowserNG/7.1.18124"


  试一试,分别用Android、iPhone、诺基亚访问http://www.163.com/http://blog.zyan.cc/http://www.google.com.hk/http://3g.qq.comhttp://t.sina.cn这些3G手机网页,看看有什么不同。

  更多款手机的User-Agent:http://www.zytrax.com/tech/web/mobile_ids.html

  10月11日备注:如果想切换回普通浏览器模式,关掉所有Chrome浏览器,重开即可。如果不想关闭浏览器,切回普通浏览器模式,则访问:
chrome.exe --user-agent="Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.77 Safari/535.7"
Tags: , ,
  [文章作者:张宴 本文版本:v1.0 最后修改:2010.09.08 转载请注明原文链接:http://blog.zyan.cc/mysql-udf-http/]

  Mysql-udf-http 是一款简单的MySQL用户自定义函数(UDF, User-Defined Functions),具有http_get()、http_post()、http_put()、http_delete()四个函数,可以在MySQL数据库中利用HTTP协议进行REST相关操作。

  项目网址http://code.google.com/p/mysql-udf-http/
  中文说明http://blog.zyan.cc/mysql-udf-http/
  使用环境:Linux操作系统,支持的MySQL版本:5.1.x 和 5.5.x。5.0.x未经测试。
  软件作者:张宴



  一、REST架构风格:

  REST(Representational State Transfer)是一种轻量级的Web Service架构风格,其实现和操作明显比SOAP和XML-RPC更为简洁,可以完全通过HTTP协议实现,还可以利用缓存Cache来提高响应速度,性能、效率和易用性上都优于SOAP协议。REST最早是由 Roy Thomas Fielding 博士2000年在论文《Architectural Styles and the Design of Network-based Software Architectures》中提出的,中文译文全文PDF点此下载。另外,有篇译文对REST做了一个简化说明。

  目前,REST架构风格的常见实现是基于HTTP协议及其四种基本方法(如POST、GET、PUT和DELETE)的。有人将HTTP协议的四种方法与CRUD原则相对应,CRUD原则对于资源只需要四种行为:Create(创建)、Read(读取)、Update(更新)和Delete(删除)就可以完成对其操作和处理。

  点击在新窗口中浏览此图片

  点击在新窗口中浏览此图片

  在Mysql-udf-http中,四个函数http_post()、http_get()、http_put()、http_delete()分别对应HTTP协议的POST、GET、PUT、DELETE四种方法。

  REST是一种架构风格,而不是协议或标准。HTTP协议“POST、GET、PUT、DELET”四种方法与CRUD原则“Create、Read、Update、Delete”四种行为的一一对应关系只是一种架构设计习惯,而不是规范。因此,POST方法也可以用来更新资源,PUT方法也可以用来创建资源,这就要看具体应用程序作者的定义了。例如Tokyo Tyrant除了支持Memcached协议外,还支持REST方式存取,PUT代表创建和更新,GET代表读取,DELETE代表删除(关于Tokyo Tyrant的安装使用请点击这儿)。

  目前国内外流行的Web 2.0应用API接口中,很多都支持REST架构风格。例如:新浪微博开放平台人人网API、Google OpenID、Flickr、Twitter、eBay、Facebook、Last.fm、del.icio.us、Yahoo Search、Amazon S3、Amazon EC2、Digg、Microsoft Bing、FriendFeed、PayPal、Foursquare,更多...

  当记录数成百上千万条时,通常采用 MySQL 分表减低数据库压力。但是,全部数据按点击数、精华、积分排序显示等功能,在MySQL 分表中则无法实现。编写 Mysql-udf-http 的最初目的,是为了在项目开发中,将 MySQL 各分表的数据自动同步到我们的 TCSQL 高速列表数据库,用来做列表查询、显示,内容页则根据ID直接查询各 MySQL 分表的内容。由于HTTP协议的通用性,通过 Mysql-udf-http 可以做更多的事情。

  通过Mysql-udf-http,你可以在MySQL中利用触发器,将MySQL的数据同步到支持REST的应用上。例如你有一个独立博客,你可以在文章表创建MySQL触发器,这样,在发表文章时,就可以将文章标题、URL自动同步到新浪微博、Twitter。你想用 Tokyo Tyrant 做缓存,也可以利用MySQL触发器在发生增、删、改时,将数据自动同步到 Tokyo Tyrant。详细配置方法本文第4节中会有介绍。



  二、Mysql-udf-http的安装与使用:

  1. 在Linux系统上安装Mysql-udf-http

  注意:“/usr/local/webserver/mysql/”是你的MySQL安装路径,如果你的MySQL安装路径不同,请自行修改。
  此文为《程序员》杂志约稿,发表在2010年6月刊。

  文章以“KBI用户行为分析”的项目架构为原型,对Web商业智能平台的架构设计进行了概要介绍。实现海量数据的分析挖掘计算相对较易,如何以灵活的可扩展性框架,来便捷地应对项目开发周期中,来自众多项目干系人的需求变更,才是难点。
  同事下午遇到一问题,MySQL 和 Memcached 对于同一个key,不能对应起来。最终原因是:PHP将key写入MySQL数据库之前,没有经过trim()过滤首尾空格(关键是尾部空格),结果:

  1、MySQL的varchar、char类型字段,SELECT .... WHERE 查询时忽略字段的尾部空格。例如varchar类型字段uidcode中,存储的含有尾部空格的内容“rewinx ”,通过以下三种方式均可查询到:

  点击在新窗口中浏览此图片

  在MySQL手册第“11.4.1. CHAR和VARCHAR类型”节中写道(http://dev.mysql.com/doc/refman/5.1/zh/column-types.html#char):请注意所有MySQL校对规则属于PADSPACE类。这说明在MySQL中的所有CHAR和VARCHAR值比较时不需要考虑任何尾部空格。请注意所有MySQL版本均如此,并且它不受SQL服务器模式的影响。



  2、PHP 的 Memcache 扩展,则在set、get时,自动将key中的空格,转换成了半角下划线“_”。当然,直接通过 Memcached 协议来读取,key值“rewinx ”就要写成“rewinx_”了。
分页: 2/12 第一页 上页 1 2 3 4 5 6 7 8 9 10 下页 最后页 [ 显示模式: 摘要 | 列表 ]