Python time模块

下面是几个python中常用的利用time模块对时间处理:

#!/usr/bin/python
# -*- coding=utf-8 -*-
# time

import time

# 当前时间戳
nowtime = time.time()
print nowtime

# 当前时间
print time.strftime("%Y-%m-%d %X", time.localtime())

# 将一个时间戳转换为当前时区的struct_time
nowtime = time.localtime(time.time())

# 取当前周的周一和下周一
start_tm_mday = nowtime.tm_mday - nowtime.tm_wday
starttime = str(nowtime.tm_year) + "-" + str(nowtime.tm_mon) + "-" + str(start_tm_mday) + " 00:00:00"
print starttime
end_tm_mday = start_tm_mday + 7
endtime = str(nowtime.tm_year) + "-" + str(nowtime.tm_mon) + "-" + str(end_tm_mday) + " 00:00:00"
print endtime

# 把一个格式化时间字符串转化为struct_time。和strftime()逆操作
starttime = time.strptime(starttime, "%Y-%m-%d %X")
print starttime
endtime = time.strptime(endtime, "%Y-%m-%d %X")
print endtime

# 将一个struct_time转化成时间戳
print time.mktime(starttime)
print time.mktime(endtime)

#得到当前时间前一天的时间Date型
import datetime
dt_obj = time.localtime()
datetime_obj = datetime.datetime(*dt_obj[:3])  #在参数名之前使用一个星号,就是让函数接受任意多的位置参数
yesterday = datetime_obj + datetime.timedelta(days=-1)
print yesterday

Python Mako 模板引擎

安装:

$ wget http://www.makotemplates.org/download.html
$ tar -zxvf Mako-0.7.0.tar.gz
$ cd Mako-0.7.0/
$ python setup.py build
$ python setup.py install

使用:
1.表达式替换:

from mak.template import Template
print Template("hello ${data}!").render(data="world")

2.基于文件的模板、数组循环
脚本文件

from mak.template import Template
name = 'super'
testlist = [(123,'abc',1),(456,'def',1)]
mytemplate = Template(filename='home/python/tpl/mytmpl.tpl')
# 如果模板编码是utf-8
# mytemplate = Template(filename='home/python/tpl/mytmpl.tpl',default_filters=['decode.utf8'],input_encoding='utf-8',output_encoding='utf-8')
print mytemplate.render(name=name,testlist=testlist)

模板文件

% if name != ''
Hi ${name},
% endif
<table>
% for item in testlist:
    <tr>
        <td>id:${item[0]}</td>
        <td>id:${item[0]}</td>
        <td>id:${item[0]}</td>
    </tr>
% endfor
</table>

Python Mysql 操作

首先需要安装Python的MySQLdb库,下载链接:http://sourceforge.net/projects/mysql-python

#!/usr/bin/env python
# -*- coding=utf-8 -*-

import MySQLdb  #需要安装python的Mysql扩展

conn = MySQLdb.connect(user='root', passwd='123456', host='127.0.0.1', port=3306)
conn.select_db('shop')
cursor = conn.cursor(MySQLdb.cursors.DictCursor)  #MySQLdb.cursors.DictCursor用数据库字段名为key
cursor.execute("SET NAMES 'utf8'")

cursor.execute('SELECT * FROM cate')
res = cursor.fetchall()  #返回所有结果集
for row in res:
    print "%s" % (unicode(row["name"], 'utf-8'))

cursor.execute('SELECT * FROM cate LIMIT 1')
res = cursor.fetchone()  #返回一条记录
print "%s" % (unicode(res["ca_Name"], 'utf-8'))

cursor.execute('SELECT * FROM cate')
res = cursor.fetchmany(5)  #接收5条返回结果行.如果5的值大于返回的结果行的数量,则会返回cursor.arraysize条数据.
for row in res:
    print "%s" % (unicode(row["ca_Name"], 'utf-8'))

cursor.execute("UPDATE cate SET flag = '0' WHERE id = '1' LIMIT 1")
#如果Mysql表的存储引擎是InnoDB的话,需要执行以下操作才能操作成功
conn.commit()

cursor.close()

Apache 压力测试工具 ab test

ab的全称是ApacheBench,是 Apache 附带的一个小工具,专门用于 HTTP Server 的benchmark testing,可以同时模拟多个并发请求。

$ /usr/local/apache2/bin/ab --help  #查看下ab帮助文档相关参数

#-n:请求次数
#-c:同一时间发出多少个请求(并行连接)
$ /usr/local/apache2/bin/ab -n 10 -c 10 http://www.google.com/ # 表示同时处理10个请求并运行10次http://www.google.com/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking www.google.com (be patient).....done

Server Software:        gws
Server Hostname:        www.google.com
Server Port:            80

Document Path:          /
Document Length:        376 bytes

Concurrency Level:      10
Time taken for tests:   0.256 seconds  # 整个测试持续的时间
Complete requests:      10  # 完成的请求总数量
Failed requests:        0  # 失败的请求总数量
Write errors:           0
Non-2xx responses:      10
Total transferred:      9240 bytes  # 整个测试过程的网络传输量
HTML transferred:       3760 bytes  # 整个测试过程的HTML内容传输量
Requests per second:    39.12 [#/sec] (mean)  # 每秒请求数 ( 平均 )
Time per request:       255.616 [ms] (mean)  # 每次并发请求时间 ( 所有并发 )
Time per request:       25.562 [ms] (mean, across all concurrent requests) # 每一请求时间 ( 并发平均 )
Transfer rate:          35.30 [Kbytes/sec] received  # 平均每秒网络上的流量,可以帮助排除是否存在网络流量过大导致响应时间延长的问题

 # 网络上消耗的时间的分解
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       30   32   1.2     31      33
Processing:    32   33   0.8     33      35
Waiting:       32   33   0.8     33      35
Total:         63   64   0.9     64      65

# 下面的内容为整个场景中所有请求的响应情况。
# 在场景中每个请求都有一个响应时间,其中 50% 的用户响应时间小于 64 毫秒,
# 66 % 的用户响应时间小于 65 毫秒,最大的响应时间小于 65 毫秒
Percentage of the requests served within a certain time (ms)
  50%     64
  66%     65
  75%     65
  80%     65
  90%     65
  95%     65
  98%     65
  99%     65
 100%     65 (longest request)

遇到问题:
1.$ /usr/local/apache2/bin/ab -n2000 -c2000 http://www.google.com/
socket too many open files

$ ulimit -n  #查询当前终端的文件句柄数:一般的系统默认的1024
$ ulimit -n 65535  #修改文件句柄数为65535
$ echo ulimit -n 65535 >>/etc/profile  #为了每次系统重新启动时,都可以获取更大的ulimit值,将ulimit加入到/etc/profile文件底部
$ source /etc/profile  #加载修改后的profile
$ ulimit -n  #显示65535,修改完毕!

2.$ /usr/local/apache2/bin/ab -n2000 -c2000 http://www.google.com/
apr_socket_recv: Connection reset by peer (104)

$ cd /home/super/httpd-2.4.2/support/
$ vim ab.c
return;
} else {
# 注释原来报错代码
//apr_err("apr_socket_recv", status);
# 新增内容
bad++;
close_connection(c);
return;
}
# 最后重新编译apache

为phpMyAdmin 增加安全口令

由于phpMyAdmin没有设置口令,任何人都可以控制数据库,所以增加一个安全口令,提高安全性。

$ vim /usr/local/apache2/conf/http.conf
#增加以下配置
<Directory "/var/www/html/phpMyAdmin">
    Options Includes FollowSymLinks
    AllowOverride all
    Allow from all
        AuthName "Administrator Auth"
        AuthType Basic
        AuthUserFile /etc/superzc.pwd
        require valid-user
    Order allow,deny
</Directory>
#增加用户以及密码
$ /usr/local/apache2/bin/htpasswd -c /etc/superzc.pwd superzc
password:  #输入安全口令的密码
$ /usr/local/apache2/bin/apachectl restart

重启apache之后,访问phpMyAdmin,搞定~已经需要安全验证。

Xdebug 安装与应用

之前,一直在用Xdebug,但是自己还没有尝试过安装,也没尝试过对Xdebug的应用提升,今天正好有空尝试了下。

Xdebug:是一个开放源代码的PHP程序调试器(即一个Debug工具),可以用来跟踪,调试和分析PHP程序的运行状况。

安装:

$ wget http://xdebug.org/files/xdebug-2.1.3.tgz
$ tar -zxvf xdebug-2.1.3.tgz
$ cd xdebug-2.1.3/
$ /usr/local/php/bin/phpize
$ ./configure --enable-xdebug --with-php-config=/usr/local/php/bin/php-config
$ make
$ make install
$ cd /usr/local/php/lib
$ vim php.ini
[Xdebug]
extension="xdebug.so"
xdebug.auto_trace=0
xdebug.collect_params=4
xdebug.collect_return=on
xdebug.show_mem_delta=1  #查看内存使用量
xdebug.profiler_enable=0  #只对指定的页面调试,和‍xdebug.profiler_enable_trigger连用
xdebug.profiler_output_dir="/tmp/"
xdebug.profiler_enable_trigger=1  #通过XDEBUG_PROFILE的get/post请求触发页面调试
$ /usr/local/apache2/bin/apachectl restart

安装成功后,显示如下截图:

应用

随便写了个php,测试下报错信息是否已经是应用Xdebug,截图如下:

应用提升:

register_shutdown_function('xdebug_stop_trace');

xdebug_start_trace("/tmp/xLog_test");

/*此处省略过程代码*/

xdebug_stop_trace();

生成的Xdebug日志文件/tmp/xLog_test.xt,部分内容截图如下:

通过Xdebug的日志,我们可以了解到时间和内存的使用情况,也可以了解陌生产品架构的方式,还可以通过执行时间快速的定位问题。

运用WinCacheGrind.exe:
1.WinCacheGrind.exe,下载地址:http://sourceforge.net/projects/wincachegrind/
2.如果xdebug.profiler_enable_trigger = 1开启状态,可以用游览器+调试参数XDEBUG_PROFILE来生成cachegrind.out.xxxx的文件,比如用游览器访问:http://www.superzc.com/index.php?id=1&XDEBUG_PROFILE。然后在xdebug.profiler_output_dir=”/tmp/”设置的目录下就生成了一个cachegrind.out.xxxx的文件;
3.最后用WinCacheGrind来解读这个文件,点击菜单栏的”File” –> “Open…”,选择cachegrind.out.xxxx文件,然后打开,如下图:

PHP APC 安装与应用

APC:Alternative PHP Cache (APC)是一种对PHP有效的开放源高速缓冲储存器工具,他能够缓存opcode的php中间码。

PHP APC提供两种缓存功能,即缓存Opcode(目标文件),我们称之为apc_compiler_cache。同时它还提供一些接口用于PHP开发人员将用户数据驻留在内存中,我们称之为apc_user_cache。

安装:

$ wget http://pecl.php.net/get/APC-3.1.9.tgz
$ tar -zxvf APC-3.1.9.tgz
$ cd APC-3.1.9/
$ /usr/local/php/bin/phpize
$ ./configure --enable-apc --enable-mmap --enable-apc-spinlocks --disable-apc-pthreadmutex --with-php-config=/usr/local/php/bin/php-config
$ make
$ make install
$ vim php.ini
#增加以下APC配置
[apc]
extension="apc.so"
apc.enabled=1
apc.cache_by_default=on  #对所有文件启用缓冲
apc.shm_segments=1  #apc.shm_segments指定了使用共享内存块数
apc.shm_size=64  #apc.shm_size指定一块共享内存空间大小,单位是M
apc.ttl=7200  #缓存条目在缓冲区中允许逗留的秒数
apc.user_ttl=7200
apc.num_files_hint=0
apc.write_lock=on  #启用写入锁
$ cd /home/super/APC-3.1.9/
$ cp apc.php /var/www/html/
$ /usr/local/apache2/bin/apachectl restart

调用phpinfo(),安装完成了,显示如下图:

访问apc.php,显示如下图:

PS:APC提供了apc.php,用于监控与管理APC缓存。不要忘记修改管理员名和密码:

defaults('ADMIN_USERNAME','super');
defaults('ADMIN_PASSWORD','123456');

应用:
1.函数说明:
apc_clear_cache() 清除apc缓存内容
默认(无参数)时,只清除系统缓存,要清除用户缓存,需用’user’参数

apc_define_constants ( string key, array constants [, bool case_sensitive] )
将数组constants以常量加入缓存

apc_load_constants (string Key)
取出常量缓存

apc_store ( string key, mixed var [, int ttl] )
在缓存中保存数据

apc_fetch ( string key )
获得apc_store保存的缓存内容

apc_delete ( string key )
删除apc_store保存的内容

<?php
$test=array(
'abc'=>'super',
'def'=>'hello world'
);

apc_define_constants('test_const',$test);

apc_load_constants('test_const');

echo 'test_const:'.abc;  //注意abc前面没有$
?>

输出:test_const:super

<?php
$bar = 'BAR';
apc_store('foo', $bar);
var_dump(apc_fetch('foo'));
?>

[转]用CodeIgniter搭建RESTful API

REST (REpresentation State Transfer) 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。

用CodeIgniter整合好的RESTful框架:http://github.com/philsturgeon/codeigniter-restserver

请求URL格式:index.php/example_api/user/id/1/format/json。
其中,可以看到这种形式很象CodeIgniter中的MVC架构的链接,但要注意到,传统的CodeIgniter中的有点不同,在链接的最后一部分,我们称为Resource资源。

RESTful架构中的四类关于资源的操作:
GET:使用GET去获得一个已经存在的资源的信息。通常我们在浏览器中输入url其实即发出了一个GET的请求。
POST:使用POST去更新一个已经存在的资源。比如表单中的提交数据行为,都属于POST类型。
PUT:使用HTTP的报文头的PUT,可以去新建一种资源,目前不是所有浏览器支持,所以本文不作讨论。
DELETE:使用DELETE去删除一种资源,同样目前不是所有浏览器都支持。

现在我们可以根据四种HTTP RESTful语义去形成如下框架:

<?php
require(APPPATH'.libraries/REST_Controller.php'); 

class Example_api extends REST_Controller {
    function user_get(){
        // 获得一个用户的信息
        $data = array('returned: '. $this->get('id'));
        $this->response($data);
    }

    function user_post()
    {
        // 更新用户信息
        $data = array('returned: '. $this->post('id'));
        $this->response($data);
    }

    function user_put()
    {
        // 创建一个新用户
        $data = array('returned: '. $this->put('id'));
        $this->response($data);
    }

    function user_delete()
    {
        // 删除用户信息
        $data = array('returned: '. $this->delete('id'));
        $this->response($data);
    }
}
?>

以上代码中包含了如下几个片段,下面逐一讲解:
$this->get() —— 其中,使用这个从形如index.php/example_api/user?id=1或者如index.php/example_api/user/id/1的连接中获得资源,比如这里就获得其id的值,然后在数组中返回该id对应的数值。
$this->post() —— 其实是CodeIgniter中调用了其框架的$this->input->post()方法,进行提交操作,并且利用了XSS保护特性。
$this->put() —— 取curl中提交的或者HTTP协议头的PUT参数的内容。
$this->delete() —— 取curl中提交的或者HTTP协议头的delete参数的内容。
$this->response() —— 个方法中,主要是将处理的数据返回给浏览器,你可以指定一个HTTP状态码去表示该次返回结果的状态,比如在数据库中找不到某个记录,可以使用如$this->response(array(‘error’ => ‘User not found.’)去返回结果。

保护RESTful API

为了保护RESTful API,可以在application/config/rest.php中设置安全保护级别,如下所示:
$config['rest_auth'] = ‘basic’; //默认值为false
1)最简单的调用RESTful:

$user = json_decode(file_get_contents('http://example.com/index.php/api/user/id/1/format/json'));
echo $user->name;

2)要是访问一个受密码保护的RESTful的话,需要用如下形式访问:

$user = json_decode(file_get_contents('http://admin:1234@example.com/index.php/api/user/id/1/format/json'));
echo $user->name;

3)使用cUrl访问RESTful

function native_curl($new_name, $new_email)
{
$username = 'admin';
$password = '1234';

// Alternative JSON version
// $url = 'http://twitter.com/statuses/update.json';
// Set up and execute the curl process
$curl_handle = curl_init();
curl_setopt($curl_handle, CURLOPT_URL, 'http://localhost/restserver/index.php/example_api/user/id/1/format/json');
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_handle, CURLOPT_POST, 1);
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, array(
'name' => $new_name,
'email' => $new_email
));

//本行可选,如果你的RESTful API是开放的,则请删除该行
curl_setopt($curl_handle, CURLOPT_USERPWD, $username . ':' . $password);

$buffer = curl_exec($curl_handle);
curl_close($curl_handle);

$result = json_decode($buffer);

if(isset($result->status) && $result->status == 'success')
{
echo 'User has been updated.';
}
else
{
echo 'Something has gone wrong';
}
}

另外,强大的CodeIgniter为我们封装了更强大的cUrl类库cUrl library(http://codeigniter.com/wiki/Curl_library/),上面的代码可以简化如下:

function ci_curl($new_name, $new_email)
{
$username = 'admin';
$password = '1234';
$this->load->library('curl');
$this->curl->create('http://localhost/restserver/index.php/example_api/user/id/1/format/json');
$this->curl->http_login($username, $password); //本行可选,如果你的RESTful API是开放的,则请删除该行
$this->curl->post(array(
'name' => $new_name,
'email' => $new_email
));
$result = json_decode($this->curl->execute());
if(isset($result->status) && $result->status == 'success')
{
echo 'User has been updated.';
}
else
{
echo 'Something has gone wrong';
}
}

Python SocketServer

这几天在搞2台服务器同步文件的问题,由于公司文件传送限制用户权限,导致写好的传送脚本scp.exp用apache用户无法执行脚本同步。所以另外想办法,参照相关文档用python写了一个SocketServer,在后台跑然后接受php的命令去执行脚本($ nohup python server.py > nohup.out &或者$ python server.py &,然后#exit,再ssh登陆,查看后台进程#ps -ef | grep py,能查到server.py的进程就OK了。)
server端:server.py

import os
import SocketServer
class MyHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        while 1:
            dataReceived = self.request.recv(1024)
            if not dataReceived: break
            #self.request.send(dataReceived)
            #print dataReceived
            if dataReceived == 'cmd=1':
                os.system('/home/cgi/scp.exp')
                self.request.send(dataReceived+'&result=1\n')
            else:
                self.request.send(dataReceived+'&result=0\n')
myServer = SocketServer.ThreadingTCPServer(('localhost',6000), MyHandler)
myServer.serve_forever()

client端:client.py

import socket
remote_host = '127.0.0.1'
remote_port = 6000
send_buf = raw_input()
#send_buf = open('test.txt', 'rb').read()
#send_buf = send_buf.replace('\x0D\x0A', '')
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((remote_host, remote_port))
sock.send(send_buf)
response_data = sock.recv(1024)
print response_data
sock.close()

或者用PHP写client端:client.php

$fp = fsockopen("127.0.0.1", 6000, $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)<br />\n";exit;
} else {
    $out = "cmd=1";
    fwrite($fp, $out);
    while (!feof($fp)) {
        $str .= fgets($fp, 4096);
    if(strpos($str, "\n") !== FALSE){
        if(strpos($str, "&result=1") != FALSE){
            break;
        }else{
    }
    }
}
fclose($fp);

启动apache 报错:libphp5.so:undefined symbol: zend_parse_parameters

今天在PHP扩展ssh2的时候,重启apache时候,发现报错,网上找了好久资料,一种是关闭selinux,怕安全性问题没这么做,后来又找到了一个解决方案(http://www.linuxforums.org/forum/red-hat-fedora-linux/87975-configuring-php-work-apache.html),如下:

$ /usr/local/apache2/bin/apachectl start
httpd: Syntax error on line 203 of /etc/httpd/conf/httpd.conf: Cannot load /usr/lib/httpd/modules/libphp5.so into server: /usr/lib/httpd/modules/libphp5.so: undefined symbol: zend_parse_parameters

解决方法:
首先,安装bison,bison 是替代yacc的语法分析程序生成器。

$ wget http://ftp.gnu.org/gnu/bison/bison-2.5.tar.gz
$ tar -zxvf bison-2.5.tar.gz
$ cd bison-2.5
$ ./configure
$ make
$ make install

然后,重新编译php

$ make install distclean
$ /usr/local/apache2/bin/apachectl start
第 2 页,共 5 页12345