Author Archives: wolftankk - Page 3

如何获取php中被禁用的函数

为了安全, php.ini中提供了disable_functions. 在给予用户使用的时候, 如果某个函数被禁止, 可能此功能会出现异常. 排查也会非常的麻烦. 可以在安装的时候, 将需要的一些关键函数(例如: fsockopen, set_time_limit)进行检测.

在PHP中没有提供get_disable_functions这类函数. 但是我们可以用过phpinfo函数查看到被禁用的函数. 这个时候我们只需要使用ini_get函数就可以获取到disable_functions

error_reporting(E_ALL);
$disabled_functions = ini_get('disable_functions');
if ($disabled_functions!='') {
  $arr = explode(',', $disabled_functions);
  sort($arr);
  print_r($arr);
}else {
  echo 'No functions disabled';
}

chmod 644 for files and 755 for directories

将path路径下的所有文件夹改成755

find path -d | xargs chmod -v 755

将path路径下的所有文件改成644属性

find path -f | xargs chmod -v 644

新版wow解析库

对wow的数据分析已经有很长很长一段时间了. 其数据结构上大致能比较了解. 但是解析工具一直不如心愿. 当wow版本的升级, 很多数据变得多样化起来. 比如

  1. 一条数据中包含了一个子数据集(表现出来的形式是动态栏位).
  2. 有些数据栏位共享一个字节.

等等情况.

根据多年经验, 我对解析工作做了一个初步的改进.

Field

Field 栏位. 每个栏位我都建立了一个class. 用于表达此栏位的状态, 类型以及结构.

所有的栏位都是继承抽象类 AField.

abstract class AField {
    //unpack读取type, 比如Byte=> "b", int32=> "i"
    public $char;
    //读取长度
    public $size;
    //$name 字段名
    //$dynamic 如果位动态栏位,动态key
    //$group 所属父组
    //$primary_key 是否是主键?
    public function __construct($name = "", $dynamic=0, $group = null, $primary_key = false) {
	$this->name = $name;
	$this->dyn = $dynamic;
	$this->group = $group;
	$this->primary_key = $primary_key;
    }
    
    //重新命名栏位名称
    public function rename($name) {
	$this->name = $name;
	return $this;
    }
    
    //magic方法, 获取栏位名称
    public function __tostring(){
	return "[" . get_class($this).": ". $this->name . "]";
    }
}

AField中包含了栏位名称, 动态key, 动态组名, 主键?
接着创建一些基础栏位, 比如ByteField, UnsignedByteField, IntegerField, UnsignedIntegerField, StringField
再继承基础栏位, 延伸出一些特别栏位: IDField, UnknownField

Row

既然栏位已经写完了. 那么这个时候就要将栏目组成一条数组. 那就是Row.
为了能明确的表述该Row的性质, 我为此创建了DBRow. 其中包含了structures(Field集合), 每个栏位的数值.

DB

完成两个基础Field, Row之后. 这个时候就要组成一个抽象的DB.
这个DB是DBC(DB2), WDB的父类. 它包含了文件, 数据结构, 数据导入导出, 数据的读取地址库, 数据的header.
而它的子类就是实现父类这些方法.

结束

从上看来, 现在解析数据更加快捷方便. 同时能应对文章刚开始说的各种情况.

PHP内部Interfaces

可以使用get_declared_interfaces获得当前php中的interface

1. Traversable (遍历接口)
无法单独实现. 比如由 IteratorAggregate 或 Iterator 接口实现

2. IteratorAggregate (聚合式迭代器)
创建一个外部迭代器的接口

IteratorAggregate extends Traversable {
abstract public Traversable getIterator ( void )
}

3. Iterator (迭代器)
可在内部迭代自己的外部迭代器或类的接口。

Iterator extends Traversable {
abstract public mixed current ( void )
abstract public scalar key ( void )
abstract public void next ( void )
abstract public void rewind ( void )
abstract public boolean valid ( void )
}

4. ArrayAccess (数组式访问)
提供像访问数组一样访问对象的能力的接口。

ArrayAccess {
abstract public boolean offsetExists ( mixed $offset )
abstract public mixed offsetGet ( mixed $offset )
abstract public void offsetSet ( mixed $offset , mixed $value )
abstract public void offsetUnset ( mixed $offset )
}

5. Serializable (序列化)
自定义序列化的接口。

实现此接口的类将不再支持 __sleep() 和 __wakeup()。不论何时,只要有实例需要被序列化,serialize 方法都将被调用。它将不会调用 __destruct() 或有其他影响,除非程序化地调用此方法。当数据被反序列化时,类将被感知并且调用合适的 unserialize() 方法而不是调用 __construct()。如果需要执行标准的构造器,你应该在这个方法中进行处理。

Serializable {
abstract public string serialize ( void )
abstract public mixed unserialize ( string $serialized )
}

6. Reflector (反射接口)
反射接口实现导出类

Reflector {
abstract public static string export ( void )
abstract public string __toString ( void )
}

7. RecursiveIterator (递归式迭代)

RecursiveIterator extends Iterator {
//Returns an iterator for the current entry.
public RecursiveIterator getChildren ( void )
//Returns if an iterator can be created fot the current entry.
public bool hasChildren ( void )

abstract public mixed Iterator::current ( void )
abstract public scalar Iterator::key ( void )
abstract public void Iterator::next ( void )
abstract public void Iterator::rewind ( void )
abstract public boolean Iterator::valid ( void )
}

8. OuterIterator (外层迭代器)

OuterIterator extends Iterator {

//Returns the inner iterator for the current entry.
public Iterator getInnerIterator ( void )

abstract public mixed Iterator::current ( void )
abstract public scalar Iterator::key ( void )
abstract public void Iterator::next ( void )
abstract public void Iterator::rewind ( void )
abstract public boolean Iterator::valid ( void )
}

9. Countable
当使用count函数式, 将被调用

Countable {
abstract public int count ( void )
}

10. SeekableIterator(可寻迭代器)

SeekableIterator extends Iterator {
//seek position
abstract public void seek ( int $position )

abstract public mixed Iterator::current ( void )
abstract public scalar Iterator::key ( void )
abstract public void Iterator::next ( void )
abstract public void Iterator::rewind ( void )
abstract public boolean Iterator::valid ( void )
}

11. ArrayObject
Object像array一样工作

ArrayObject implements IteratorAggregate , Traversable , ArrayAccess , Serializable , Countable {

const integer STD_PROP_LIST = 1 ;
const integer ARRAY_AS_PROPS = 2 ;

public __construct ([ mixed $input [, int $flags = 0 [, string $iterator_class = "ArrayIterator" ]]] )
public void append ( mixed $value )
public void asort ( void )
public int count ( void )
public array exchangeArray ( mixed $input )
public array getArrayCopy ( void )
public int getFlags ( void )
public ArrayIterator getIterator ( void )
public string getIteratorClass ( void )
public void ksort ( void )
public void natcasesort ( void )
public void natsort ( void )
public bool offsetExists ( mixed $index )
public mixed offsetGet ( mixed $index )
public void offsetSet ( mixed $index , mixed $newval )
public void offsetUnset ( mixed $index )
public void serialize ( void )
public void setFlags ( int $flags )
public void setIteratorClass ( string $iterator_class )
public void uasort ( callable $cmp_function )
public void uksort ( callable $cmp_function )
public void unserialize ( string $serialized )
}

更详细参考http://us.php.net/manual/zh/intro.spl.php

定时备份mysql数据

#!/bin/bash

DB_USER=root
DB_PASSWD=""
#需要备份的数据库名
DATABASES="bigamer bigamer_ucenter bigamer_anwsion bigamer_passport"
BACKUP_DIR="/home/backup/mysql/"
DATE=`date '+%Y%m%d'`
DUMPFILE=$DATE.sql
ARCHIVEFILE=$DUMPFILE.tar.gz
DUMP_ARGS="-u $DB_USER -p $DB_PASSWD --add-drop-table --add-drop-database -B $DATABASES"
DUMP_BIN=`which mysqldump`

if [ ! -d $BACKUP_DIR ]; then
mkdir -p "$BACKUP_DIR"
fi

cd $BACKUP_DIR

$DUMP_BIN $DUMP_ARGS > $DUMPFILE

if [[ $? == 0 ]]; then
tar czf $ARCHIVEFILE $DUMPFILE
    rm -f $DUMPFILE
fi

#清理五天前备份的数据
find $BACKUP_DIR -name "*.sql.tar.gz" -type f -mtime +5 -exec rm {} \; > /dev/null 2>&1

echo "Backup Process Done"

Apache mod_ssl通过PoisitveSSL认证


由于前几天国内大断网之后, 现在安装的三方twitter客户端dabr和twip, 每次都会重置链接. 通过测试服务器上设定ssl链接后, 就不会被我们伟大的GFW重置链接. 但没有第三方机构认证的ssl, 在twitter for iphone客户端上将会无法使用. 首先我尝试了免费的startssl, 但是无法进入控制面板. 然后就在cheapssls.com找到了一个单域名ssl认证, 每年只需要$8. (这里的单域名, 只能用在一次域名地址上, 比如你注册的是wolftankk.com, 那么用在t.wolftankk.com上, 浏览器会警告你证书错误). 聊了这么多, 我们来讲讲具体步骤.

在此之前请确保mod_ssl模块已经加载.

生产.csr文件与.key文件

openssl req -nodes -newkey rsa:2048 -keyout server.key -out server.csr

根据选项输入国家, 城市, 邮件地址以及域名地址 (Common Name 域名地址一定要填写正确)
我这里注册的是t.wolftankk.com

在cheapssls上选购poisitiveSSL

然后在选购面板中填写你需要申请的域名地址,email, 电话 以及联系地址.
并且在csr选择 apache + mod_ssl, 并且将你服务器上csr文本内容黏贴在文本框中
在过不了多久, 你就会收到邮件, 此邮件里面包含域名的crt和ca-bundle
将server.key, wolftankk_com.crt, wolftankk_com.ca-bundle 全部放在 apache2/conf目录下

mod_ssl设定

修改mod_ssl配置, 修订apache2/conf/extra/httpd-ssl.conf

Listen 443

AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl .crl

SSLPassPhraseDialog builtin

SSLSessionCache "shmcb:/usr/local/apache2/logs/ssl_scache(512000)"
SSLSessionCacheTimeout 300

SSLMutex "file:/usr/local/apache2/logs/ssl_mutex"

同时将下面的这段全部注释.

设定httpd-vhost.conf

NameVirtualHost *:443

ServerAdmin wolftankk@gmail.com
DocumentRoot "/home/htdocs/dabr/wwwroot"
ServerName t.wolftankk.com:443
ErrorLog "/home/htdocs/dabr/logs/error.log"
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
SSLProtocol all -SSLv2
#poisitiveSSL 发给你的crt文件
SSLCertificateFile "/usr/local/apache2/conf/wolftankk_com.crt"
#生产server.key文件
SSLCertificateKeyFile "/usr/local/apache2/conf/server.key"
#poisitiveSSL 发给你的ca-bundle
SSLCertificateChainFile "/usr/local/apache2/conf/wolftankk_com.ca-bundle"
SSLCACertificateFile "/usr/local/apache2/conf/wolftankk_com.ca-bundle"
SSLOptions +StdEnvVars

SSLOptions +StdEnvVars

BrowserMatch ".*MSIE.*" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0

CustomLog "/home/htdocs/dabr/logs/access.log" \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

设定完之后, 重启apache, 现在你访问t.wolftankk.com 就不会在显示不信任的认证, 在浏览器的地址栏上会显示第三方认证的标志.

现在你就不怕你搭建的第三方twitter客户端被重置链接了.

rsync配置以及一些小提示

最近搞镜像同步, 用到了rsync. 这里做一些简单的备忘记录.

Rsyncd

1 安装
在服务器上安装rsync,
在debian, ubuntu 服务器上可以使用apt-get install rsync
在centos, redhat 服务器上可以使用yum install rsync
或者直接下载rsync源代码: http://www.samba.org/ftp/rsync/rsync-3.0.9.tar.gz (目前最新版本3.0.9)
然后./configure and make and make install

2 配置rsyncd.conf

uid = nobody
gid = nobody
use chroot = no
max connections = 25
read only = yes
port = 873
[MODNAME]
path = /home/htdocs/res
comment = Website static resource (~30G)
list = yes
auth users = wolftankk
ignore errors
secrets file = /etc/rsyncd/MODNAME.scr
exclude = tmp/

然后设置MODNAME.scr
[注意] 一定要将MODNAME.scr 设置为600属性

wolftankk:mypass

更具体的配置 可以参考http://www.samba.org/ftp/rsync/rsyncd.conf.html

3 启动

/usr/bin/rsync --daemon --config=/etc/rsyncd/rsyncd.conf

将此命令加入启动脚本中, 服务器将会在每次启动时候自动启动rsyncd

Rsync

在镜像服务器上设置同步

测试链接

rsync -avzP wolftankk@172.16.1.30::
如果链接成功, 将会列出此服务器上的 模块以及注释, 如下

[MODNAME]
comment = Website static resource (~30G)

[备注]
-a参数: 相当于-rlptgoD,-r 是递归 -l 是链接文件,意思是拷贝链接文件;-p 表示保持文件原有权限;-t 保持文件原有时间;-g 保持文件原有用户组;-o 保持文件原有属主;-D 相当于块设备文件

在使用-a参数的时候, 会将服务器A的owner以及group同步到本地, 有可能会导致你镜像文件的读写权限导致问题.
我们可以使用–no-OPTIONS 参数,比如我不需要同步文件(夹)的owner和group, 那么加入参数 –no-o 和 –no-g

屏蔽列表, 屏蔽方式用两种一种是直接写在配置里面, 另一种是写在一个但是的配置文件中.
1. exclude
不包含文件夹 –exclude=tmp/
不包含文件 –exclude=include/database.php

2. exclude-from
vim /etc/rsync.ignore

tmp/
include/database.php
download/test/*
static/css/*.sass

设置cron

* */1 * * * /usr/bin/rsync -az --password-file=/etc/rsync.pass --exclude-from=/etc/rsync.ignore --no-o --no-g wolftankk@172.16.1.30::MODNAME /home/htdocs/res

每小时同步一次.

在rsync.pass种设定密码, 并且必须要设置为600权限

mypass

详细参数可以参考: http://www.samba.org/ftp/rsync/rsync.html

500,000 requests/sec – Modern HTTP servers are fast

翻译自: http://lowlatencyweb.wordpress.com/2012/03/20/500000-requestssec-modern-http-servers-are-fast/

现在的HTTP服务器运行在某些计算上, 表现很差, 连接过长, 连接时间过慢, 等等原因. 下面一张图就是在Unbutu系统中安装了Nginx 1.0.14, 测试并发访问index.html的一些数据.以及下表的测试环境.

软件

这里只讨论Linux, 首先我们需要设置下系统网络层的参数

echo "2048 64512" > /proc/sys/net/ipv4/ip_local_port_range
echo "1" > /proc/sys/net/ipv4/tcp_tw_recycle
echo "1" > /proc/sys/net/ipv4/tcp_tw_reuse
echo "10" > /proc/sys/net/ipv4/tcp_fin_timeout

echo "65536" > /proc/sys/net/core/somaxconn
echo "65536" > /proc/sys/net/ipv4/tcp_max_syn_backlog

echo "262144" > /proc/sys/net/netfilter/nf_conntrack_max

HTTP服务器为nginx 1.0.14, configure & build

worker_processes     16;
worker_rlimit_nofile 262144;

daemon off;

events {
  use epoll;
  worker_connections 16384;
}

error_log error.log;
pid /dev/null;

http {
  sendfile   on;
  tcp_nopush on;

  keepalive_requests 100;

  open_file_cache max=100;

  gzip            off;
  gzip_min_length 1024;

  access_log off;

  server {
    listen *:8080 backlog=16384;

    location / {
      root   html;
      index  index.html;
    }
  }
}

硬件部分

是双核Intel至强5670, 24G内存. The X5670 has 6 cores @ 2.93 GHz, 2 threads per core, /proc/cpuinfo shows 24 CPUs.

Advanced HTML5 JavaScript down ‘n dirty

Python mysql fetch_row 手记

在python的mysql中, fetch_row 默认是不传递参数的, 只返回一条且没有column的数据tuple.

但是在仔细看了API文档之后, 发现有两个参数: num_results和display_column

num_result: 默认只显示一条, 当传入0时, 将显示全部数据. 否则根据你的数字显示数据条数
display_column: 默认不显示
1. 只显示column名
2. 显示格式为 table.column