个人分析报告摘要
Posted in 生活感悟 on 2008/09/02 / 评论(0) »
检查员型——细致、谨慎地执行好现有规则


基本描述:
?  你是一个认真而严谨的人,勤奋而负有责任感,认准的事情很少会改变或气馁,做事深思熟虑,信守承诺并值得信赖。
?  你依靠理智的思考来做决定,总是采取客观、合乎逻辑的步骤,不会感情用事,甚至在遇到危机时都能够表现得平静。
?  你谨慎而传统,重视稳定性、合理性;你天生独立,需要把大量的精力倾注到工作中,并希望其它人也是如此,善于聆听并喜欢将事情清晰而条理的安排好。
?  你喜欢先充分收集各种信息,然后根据信息去综合考虑实际的解决方法,而不是运用理论去解决。你对细节非常敏感,有很实际的判断力,决定时能够运用精确的证据和过去的经验来支持自己的观点,并且非常系统有条不紊,对那些不这样做的人没有耐心。


可能的盲点:
?  你非常固执,一旦决定的事情,会对其他的观点置之不理,并经常沉浸于具体的细节和日常的操作中。
?  你看问题有很强的批判性,通常持怀疑态度,你需要时常的换位思考,更广泛的收集信息,并理智的评估自己的行为带来的可能后果。
?  你非常独立,我行我素,不能理解不合逻辑的事情,忽视他人的情感,并对与你风格不同的人不能理解,非常挑剔;你要学会欣赏他人的优点并及时表达出来。
?  你非常有主见,时常会将自己的观点和标准强加给别人,而且无视那些不自信的人的建议。在处理问题时,强求别人按照自己的想法来做,对于未经检验或非常规的方法不加考虑。若能在以后多尝试和接受新颖的、有创造性的方法,你就能做出更有效的决策。
谈一谈模拟浏览器登陆技术
Posted in PHP on 2008/07/17 / 评论(5) »
    用PHP开发模拟浏览器的应用,首选技术是CURL函数库。但是php官方提供的技术文档资料很少,相关的示例代码也很少。

    最近由于项目需要,开发了一系列免费邮箱的导出用户自己联系人的功能,包括国内外知名邮箱,163,sina,sohu,yahoo,hotmail,gmail,qq mail等。还开发了一些方便用户嵌入代码到各大博客,个人门户的应用。比如嵌入flash代码到Qzone,网易的blog,百度的个人门户等。

    当然,最原始的技术手段是采用fsockopen函数,然后深入去学习http协议,写出标准的http头信息,也是可以完成开发的。不过麻烦的地方就出在标准。如果对http协议标准认识不深,经常会因碰到少了一个空格或者少了一个换行符号而debug很久。

    OK,还是进入正题。工欲善其事,必先利其器。要模拟浏览器访问网站,首选要学会观察浏览器是如何发送http报文的,以及网站服务器返回给浏览器是什么样的内容。我推荐安装一个国外人开发的httpwatch的软件,最好搞个破解的版本,否则有些功能是使用不了的。这个软件安装完成之后是嵌入在IE里的,启动Record,在地址栏输入网址后回车,它就会将浏览器和服务器之间的所有通讯扫描出来,让你一览无遗。关于这个软件的使用在本文不做介绍。

    模拟浏览器登陆应用开发,最关键的地方是突破登陆验证。CURL技术不只支持http,还支持https。区别就在多了一层SSL加密传输。如果是要登陆https网站,php记得要支持openssl。还是先拿一个例子来分析。


        //用户名
        $login = 'username';
        //密码
        $password = 'password';
        
        //163的用户登陆地址
        $url = "https://reg.163.com/logins.jsp";
        
        //post 要提交的数据
        $fields = "verifycookie=1&style=16&product=mail163&username=".$login."&password=".$password."&selType=jy&remUser=&secure=on&%B5%C7%C2%BC%D3%CA%CF%E4=%B5%C7%C2%BC%D3%CA%CF%E4";
        
        //用来存放cookie的文件
        $cookie_file = dirname(__FILE__)."/cookie.txt";


        //启动一个CURL会话
        $ch = curl_init();

        // 要访问的地址
        curl_setopt($ch, CURLOPT_URL, $url);

        // 对认证证书来源的检查,0表示阻止对证书的合法性的检查。
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);

        // 从证书中检查SSL加密算法是否存在
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
    
        //模拟用户使用的浏览器,在HTTP请求中包含一个”user-agent”头的字符串。
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");

        //发送一个常规的POST请求,类型为:application/x-www-form-urlencoded,就像表单提交的一样。
        curl_setopt($ch, CURLOPT_POST, 1);

        //要传送的所有数据,如果要传送一个文件,需要一个@开头的文件名
        curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);

        //连接关闭以后,存放cookie信息的文件名称
        curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);

        // 包含cookie信息的文件名称,这个cookie文件可以是Netscape格式或者HTTP风格的header信息。
        curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);

        // 设置curl允许执行的最长秒数
        //curl_setopt($ch, CURLOPT_TIMEOUT, 6);

       // 获取的信息以文件流的形式返回,而不是直接输出。
        curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);

       // 执行操作
       $result = curl_exec($ch);

      
        if ($result == NULL) {
           echo "Error:<br>";
           echo curl_errno($ch) . " - " . curl_error($ch) . "<br>";
        }

       // 关闭CURL会话
        curl_close($ch);


    
    上面这个例子相对简单,因为用户名和密码可以明文传输,而且登陆也不需要验证码。qq.com的模拟登陆相对就麻烦多了,首先要突破验证码这关,然后由于QQ密码是经过javascript加密后传输的,登陆界面也要模拟出来,下一篇文章再继续深入谈谈QQ的模拟登陆。

     参考资料:
CURL详解  http://www.21andy.com/blog/20080507/1095.html
写点什么呢
Posted in 网海拾贝 on 2008/07/06 / 评论(1) »
      连续两个月没有记下点东西了。并不是没东西可些,这段时间实在是太忙了。

      从5月份开始项目的准备,到6月份疯狂的代码开发,目标很明确在7月1日完成项目的正式上线。当一切都顺利进行到6月24日的时候,投资人初看了我们的产品,发现设计风格和发展方向跟他们的想法不一致,结果令人非常痛苦,一个字“改”。最后当7月1日到来的时候,虽然我们准备好了产品,但是我们的产品需求策划组却在进行第二轮的设计。无赖之下,我们的开发人员选择了休息一周,重新准备开发二次升级版本。过去一周就是在debug中度过的。

      回顾一下这两个月,从技术角度来讲,我有很多东西可以记录下来。比如模拟登陆采用的curl技术。等项目完成上线之后,我再一一记录下来,积累技术沉淀。
第一种方法:

ls -l|grep “^-”|wc -l

ls -l 长列表输出该目录下文件信息(注意这里的文件,不同于一般的文件,可能是目录、链接、设备文件等)。如果ls -lR|grep “^-”|wc-l则可以连子目录下的文件一起统计。

grep ^- 这里将长列表输出信息过滤一部分,只保留一般文件,如果只保留目录就是 ^d

wc -l 统计输出信息的行数,因为已经过滤得只剩一般文件了,所以统计结果就是一般文件信息的行数,又由于一行信息对应一个文件,所以也就是文件的个数。

第二种方法:

find ./ -type f|wc -l

由于默认find会去子目录查找,如果只想查找当前目录的文件用find ./ -maxdepth 1 -type f|wc -l即可。

需要说明的是第二种方法会比第一种方法快很多,尤其是也统计子目录时。
KFL是之前KFC框架的轻量级版本,框架KFL目录下所有文件大小35k,主要去除了KFC的组件概念,保留了MVC的开发模式,特别适合前台的网站开发。
主要特点:
1、使用MVC开发模式。
2、引入文件少,启动快速。
3、具备针对访问路径的页面自动缓存功能;
4、模板本身就是使用php语法,简单友好;
5、采用pdo进行数据库访问,高速易用;
6、session 支持 file,mysql,memcache存储功能;
7、单一入口访问网站,安全。
缺点:
只能在php5以上版本使用。

下载地址:(使用右键->另存为)


欢迎交流!:)
      php没有数据库连接池的概念,一般情况下程序中使用mysql_connect()连接数据库,在php脚本执行完毕之后进程会释放掉连接资源所占的内存。访问每个php网页都会出现一个解析脚本的进程,那么数据库服务端也会出现一个connect连接。当然前提是只有一个数据库设计的系统。在高并发高流量的情况下,基于数据库驱动的应用系统很容易出现瓶颈,这个瓶颈首先就是max_connections,即数据库的同时最大连接数,在MySQL安装的时候默认只有100个。增大这个连接数能马上起到效果。但是并不是能无限量增加,我在window服务器下和linux服务器下分别做了实验。

实验准备:

我分别使用了php的MySQL客户端工具mysql_connect()和pdo做实验。本实验故意不采用长连接方式。关于长连接的作用会在以后讨论。以下是知识准备:
    resource mysql_connect ( [string $server [, string $username [, string $password [, bool $new_link [, int $client_flags]]]]] )

    mysql_connect()在4.2.0版本后添加 new_link 参数。如果用同样的参数第二次调用 mysql_connect(),将不会建立新连接,而将返回已经打开的连接标识。如果让new_link=true, 会使 mysql_connect() 总是打开新的连接,甚至当 mysql_connect() 曾在前面被用同样的参数调用过。

    pdo是PHP5内置的一个轻量级,统一接口访问数据库的抽象类。

my.cnf设置如下


[mysqld]
skip-name-resolve
port            = 3306
socket          = /opt/lampp/var/mysql/mysql.sock
skip-locking
key_buffer = 16M
max_allowed_packet = 1M
table_cache = 64
sort_buffer_size = 512K
net_buffer_length = 8K
read_buffer_size = 256K
read_rnd_buffer_size = 512K
myisam_sort_buffer_size = 8M
max_connections = 10000


注意max_connections = 10000;

实验代码


<?php
set_time_limit(0);
function getmicrotime()
  {
    list($usec, $sec) = explode(" ",microtime());
    return ((float)$usec + (float)$sec);
  }
$time = getmicrotime();
error_reporting(E_ALL);
//pdo
$dbsettings = array(
      'host' => 'localhost',                            
      'port'=> '3306',
      'type' => 'mysql',
      'user' => 'root',
      'passwd' => '',
      'dbname' => 'cdcol',
      'charset'=> 'utf8',
      'cache_time' => 3600
      );
$i = 0;
$db = array();
$d1 = '';
$dsn = $dbsettings['type'].":host=".$dbsettings['host'].";port=".$dbsettings['port'].";dbname=".$dbsettings['dbname'];
for($i=0;$i<10500;$i++){

           /**mysql_connect()的测试***/
//  $link = mysql_connect($dbsettings['host'], $dbsettings['user'], $dbsettings['passwd'],true);
//  
//  if (!$link) {
//     $error = mysql_error();
//      @fwrite(@fopen(dirname(__FILE__)."/tmp/dberror.txt",'a'),date("Y-m-d H:i:s")." ".$dsn.'|'.$error."\n");
//  }else{
//    //mysql_select_db($dbsettings['dbname'], $link) or die ('Can\'t use foo : ' . mysql_error());
//    //$result = mysql_query("SELECT * FROM cds");
//    $db[] = $link;
//  }

               /***pdo的测试***/
  try{          
    $d = new pdo($dsn,$dbsettings['user'],$dbsettings['passwd'],array(PDO::ATTR_PERSISTENT => false));
    if($d!=$d1){
      $db[] = $d;
    }
    $d1=$d;
    
    //$db -> getOne();
    
  }catch (PDOException $e){        
    $error = $e->getMessage();
    echo $error."<br>";
//    $fp =fopen(dirname(__FILE__)."/tmp/dberror.txt",'a');  
//    fwrite($fp  ,date("Y-m-d H:i:s")." ".$dsn.'|'.$error."\n");    
//    fclose($fp);  
  }

}

echo count($db);
echo "<hr>";
echo getmicrotime() - time();
?>



实验结果:

在window下执行发现平均能到达平均1860个连接,然后报错
Can't create a new thread (errno 12); if you are not out of available memory, you can consult the manual for a possible OS-dependent bug。执行时间0.685220003128s

在linux下执行能达到8168个连接,然后报错,Can't create UNIX socket (24); 执行时间 0.406996965408 s

    由于不是使用长连接,php脚本执行完成之后资源马上被释放掉。php短连接数据库的执行效率还是相当不错的。但是本实验脚本还没有做实际的查询等操作,不能真实的模拟到用户的并发访问环境。但是从单独的创建连接数来看,单个MySQL服务器最多能支持8000个并发连接。如果是几万用户在线的网站,就需要想办法解决数据库的这个瓶颈了。虽然php提供了长连接这个选择,但是长连接的弊端也很明显,详细见这篇文章《PHP使用数据库永久连接方式操作MySQL的是与非》

    至于window下跟linux下数据为什么差别会那么大呢?在MySQL官方文档中有这个说明:
The maximum number of connections MySQL can support depends on the quality of the thread library on a given platform.
跟MySQL运行平台操作系统的线程数量控制有关系。

解决方案:

    在数据库方面的解决方案主要是采用Master-Slaver的Cluster数据库集群方案,这个方案解决负载均衡,使连接数分流到 Slaver。另一个在php方面的解决方案是借助第三方软件SQL Relay来创建一个数据库连接池,从而减少单台MySQL服务器的并发连接数量,大大提高了数据库的访问效率。





分页: 4/26 第一页 上页 1 2 3 4 5 6 7 8 9 10 下页 最后页 [ 显示模式: 摘要 | 列表 ]