Month: 一月 2010

使用percona的mysql补丁统计Mysql使用情况

在应用粒度进行mysql服务的管理相对简单,只要把mysql账号和应用账号绑定起来就可以了.

mysql账号的管理可以通过向mysql库user表增删记录来实现.

要想给某个用户只分配特定库的权限时,可以将user表中权限字段全部设置为N,然后向mysql库下的db表添加记录指定特定库权限.

接来下我们讨论如何获取详细的mysql使用信息,例如某个账号的数据库大小,写入字节数和读取字节数,累计消耗的cpu时间.

mysql本身没有提供这些数据.但是percona在google发布的mysql patch上进行了修改,完成了一个userstatus的功能.

其原理非常简单,就是在information_schema库中添加了一些内存表,里边存放了对应的数据.

安装percona-mysql

我们选择下载percona打好补丁的源代码编译后安装的方式.你也可以下载编译好的二进制版本.


wget http://www.percona.com/mysql/5.0.87-b20/source/mysql-5.0.87-percona-src.tar.gz
tar xzvf mysql-5.0.87-percona-src.tar.gz
cd mysql-5.0.87

在配置之前,先安装一些会用到的包


sudo apt-get install libncurses5-dev byacc

开始编译


./configure --prefix=/home/easy/dev/mysql5/
make
make install

使用percona-mysql

安装完成后,mysql下数据目录没有,建立mysql数据库

mkdir data
chown mysql:mysql data
bin/mysql_install_db --user=mysql
--basedir=/home/easy/dev/mysql5
--datadir=/home/easy/dev/mysql5/data

mysql就配置完成了.启动mysql


bin/mysqld_safe &

使用phpmyadmin连接上后,发现information_schema中会多出以下表:

分别从 客户端,索引,用户和表的角度为我们提供了统计数据.各个表的字段和相关说明可以参见wiki.

浏览各个表发现都还没有数据.这是因为默认数据统计都没有开放的.

在phpmyadmin中执行以下SQL


SET GLOBAL userstat_running = 1

然后我们就能在数据表中查看到信息了.

为避免每次启动服务时都手工执行此命令,我们可以把 userstat_running = 1 添加到 my.cnf 中.

数据表的大小可以通过TABLES表中的data_length和index_length字段相加获得.

基于percona-mysql的配额控制

有了这些数据,进行Mysql服务的配额限制就是非常简单的事情了.

写一个php脚本,定时检查各个user的数据用量,然后和分配给该用户的配额上线比较,一旦超过,通过修改mysql库中的user和db表收回该用户的mysql权限即可.…

使用Pure-ftpd和Pure-ftpd-mysql进行FTP权限和磁盘配额管理

在上一篇文章里边,我们已经完成了利用mod-myvhost动态的添加web用户.这里我们接着来完成文件上传的管理.

我们选用Pure-ftpd作为工具.

安装

Pure-ftpd是一个成熟的ftp工具,apt-get已经有打好的包了.我们直接通过apt-get就能很方便的安装.

apt-get install pure-ftpd-mysql

配置

在数据库里边建一个库,这里用之前的hosting数据库.用以下语句创建一张表:

CREATE TABLE users(
User varchar(16) NOT NULL default '',
status enum('0','1') NOT NULL default '0',
Password varchar(64) NOT NULL default '',
Uid varchar(11) NOT NULL default '-1',
Gid varchar(11) NOT NULL default '-1',
Dir varchar(128) NOT NULL default '',
ULBandwidth smallint(5) NOT NULL default '0',
DLBandwidth smallint(5) NOT NULL default '0',
comment tinytext NOT NULL,
ipaccess varchar(15) NOT NULL default '*',
QuotaSize smallint(5) NOT NULL default '0',
QuotaFiles int(11) NOT NULL default 0,
PRIMARY KEY (User),
UNIQUE KEY User (User)
) TYPE=MyISAM;

这张表将用来存放ftp用户的相关信息.

然后我们需要修改pure-ftpd-mysql的配置文件,告诉pure-ftpd数据库的相关信息.
这里假设大家已经配置好了mysql,并有一个可用的账号.

vim /etc/pure-ftpd/db/mysql.conf

放入以下配置

#账号信息 按自己情况修改
MYSQLServer 127.0.0.1
MYSQLPort 3306
MYSQLSocket /var/run/mysqld/mysqld.sock
MYSQLUser easy
MYSQLPassword ******
MYSQLDatabase hosting

#加密方式
MYSQLCrypt md5

#取得数据的SQL语句

#用户授权
MYSQLGetPW SELECT Password FROM users WHERE User="L"
MYSQLGetUID SELECT Uid FROM users WHERE User="L"
MYSQLGetGID SELECT Gid FROM users WHERE User="L"
MYSQLGetDir SELECT Dir FROM users WHERE User="L"

#文件大小和个数限制
MySQLGetQTAFS SELECT QuotaFiles FROM users WHERE User="L"
MySQLGetQTASZ SELECT QuotaSize FROM users WHERE User="L"

#上行和下行带宽限制
MySQLGetBandwidthUL SELECT ULBandwidth FROM users WHERE User="L"
MySQLGetBandwidthDL SELECT DLBandwidth FROM users WHERE User="L"

这样pure-ftpd就知道如何从mysql里边取数据了.
为了得到上边出现的GID和UID,我们需要为ftp创建一个虚拟账号.FTP的全部用户共用这一个虚拟账号的UID和GID,而不需要为每个FTP用户创建系统用户.


groupadd -g 2001 ftpgroup
useradd -u 2001 -s /bin/false -d /bin/null -c "pureftpd user" -g ftpgroup ftpuser

我们创建了GID为2001的ftpgroup组和UID为2001的ftpuser用户.现在可以往数据表中添加数据了.QuotaSize的单位是M,目录指向我们在mod-myvhost同样的路径.

然后我们将用户锁定在他自己的目录下,不允许他通过ftp访问到别人的目录:


echo yes > /etc/pure-ftpd/conf/ChrootEveryone

当指定目录不存在时,自动创建目录

echo yes > /etc/pure-ftpd/conf/CreateHomeDir

设置完成.重启pure-ftpd.

/etc/init.d/pure-ftpd-mysql restart

全部配置都完成了.我们上传文件试试.
登陆成功,上传文件提示没权限.这是因为/data0/myapphost的属性设定造成的.将整个目录改为ftpuser的就可以了


chown -R ftpuser:ftpgroup /data0/myapphost

修改属性后,已经可以上传文件了.试试配额限制:


错误:> [2010-1-27 22:47:12] 无法写入数据 socket。Socket 错误 = #10054。
[2010-1-27 22:47:12] 550-Quota exceeded: abc.zip won't be saved
550-6 files used (120%) - authorized: 5 files
550 6974 Kbytes used (681%) - authorized: 1024 Kb
错误:> [2010-1-27 22:47:12] 请求的操作未执行(如,文件或目录未找到,不能访问)。

错误:> [2010-1-27 22:47:43] 无法写入数据 socket。Socket 错误 = #10054。
[2010-1-27 22:47:43] 550-Quota exceeded: abc.zip won't be saved
550-4 files used (80%) - authorized: 5 files
550 3954 Kbytes used (386%) - authorized: 1024 Kb
错误:> [2010-1-27 22:47:43] 请求的操作未执行(如,文件或目录未找到,不能访问)。

从错误信息可以看出,配额已经生效了.当配置修改后,已经登录的ftp用户需要重新登陆后才会生效.

小结

到这里为止,我们已经完成了一个单服务器的应用管理平台的基本功能.再添加一个用于申请应用和开通账号的web管理前端,整个平台即可投入使用了.

下次我们将讨论,对于作为这个平台上的服务的Mysql,如何进行配额的限制.…

新浪微博开放平台初探

前几天新浪微博开始邀请合作伙伴,对外接口开始开放.于是我申请到了一个账号.

网站结构

新浪开放平台的域名为open.t.sina.com.cn,目前采用了密码保护,需要先联系相关人员获得密码.

开放平台网站分为两部分,一部分是文档,采用wiki程序组织;一部分是应用的设置和查看界面.

应用的查看部分显示了APP Key和应用用户数.

应用设置页面,是个人信息和应用基本信息设置.

平台接口

接口特点

微博平台采用REST风格的接口,查询类接口要求用GET,发布类接口要求用POST.返回的数据格式有xml和json两种.

REST接口本身有频率限制:

默认REST API的访问限制是每小时150次,限制分用户和IP, 未授权的访问次数限制主要针对IP,登录后的请求访问限制主要针对用户。
访问限制主要针对HTTP GET请求。发表操作(如发微博)通常是POST操作而不受此限制。 详细限制情况:
请求限制:普通调用限制每小时150次
发表微博:单用户每小时最大30次
发表评论:单用户每小时最大60次
发表私信:单用户每小时最大60次
添加关注:每小时最多添加关注60个

默认REST API的访问限制是每小时150次,限制分用户和IP, 未授权的访问次数限制主要针对IP,登录后的请求访问限制主要针对用户。访问限制主要针对HTTP GET请求。发表操作(如发微博)通常是POST操作而不受此限制。 详细限制情况:请求限制:普通调用限制每小时150次发表微博:单用户每小时最大30次发表评论:单用户每小时最大60次发表私信:单用户每小时最大60次添加关注:每小时最多添加关注60个

授权等级

微博平台对应用的授权分为多个级别,不同的级别查询的频率有所不同.

普通授权:150次/小时/用户
初级授权:500次/小时/用户
高级授权:1500次/小时/用户
新浪合作伙伴:无限制

认证方式

微博平台支持两种认证方式.

一种是Apache的Basic认证,在你请求接口时把用户名和密码带过来;
一种是Oauth认证.Oauth认证不需要用户提供密码,更加安全.

一个简单的调用例子(取得用户所关注的人的最新微博):

curl -u name:password -d "source=APPKEY" http://api.t.sina.com.cn/statuses/friends_timeline.json

SDK

微博在网站上提供了AS3的SDK.

另外提供了一个修改版本的dabr作为php的示范程序.

Oauth的通用库也添加了一些链接.

另外,我自己写按平台的接口封装了一个简单的PHP Class,目前只支持status相关(详见后边的接口列表)的接口.有兴趣的同学也可以拿去用.

接口分类和列表

获取下行数据集接口

微博访问接口

用户接口

私信接口

关注接口

Social Graph接口

账号接口

收藏接口

登录/OAuth接口

另外搜索接口貌似已经在准备中了.

整体上讲微博开放的接口还算细,用户资料和好友关系也开放了.接下来就是如何进行应用和平台的mash up了.…

M8好用么?

自从买了M8,身边很多朋友都问我,iphone好用么?

今天菜刀同学又问到了.我解释说,这是M8.是魅族公司在苹果做电脑之前就已经独立设计完成的了.

于是菜刀问,那M8好用么?

嗯,M8真的很好用.它的功能超乎了我的想像.

首先是支持wifi的高分辨率网页浏览器,比Opera不知道强多少倍,还可以自动的放大到你不想看的地方,然后在你点击输入框的时候来回晃动.真是好炫.

然后是对RMVB的强大支持,只要是640*480的RMVB都可以流畅播放,更高分辨率的还可以通过智能掉帧来模拟动画效果.高科技.

接下来是超强的照相功能,320万像素的摄像头启动3秒,点拍照后,会在10秒后取景成功.照片通常附带免费的抽象派艺术效果.

你还可以使用各种非官方QQ和十年磨一见的官方QQ,hack版本的各种Java虚拟机和小游戏.其他win ce平台软件的也能一网打尽,就是字体小点.

这些还不算.凭借魅族超强的研发能力,每隔几周论坛上就会放出新的测试固件.几十个不同版本的固件,让你可以自由的选择要拥有哪些BUG.

说到论坛,就不能不提魅族强大的社区支持,在这里,你能看见各种版本的欣赏魅族公司和其老板的帖子,还有广大魅友担心魅族赚不到钱,魅老板睡不着觉之类的感人故事.我们欣喜的看到,全世界能超越苹果的创新就在这个论坛里边孕育.

菜刀听后,露出羡慕的神情,接着说道:

你总不能因为有了Mp4好就不用手机了吧.我都好多天都没找到你人了.拿着,这个摔不坏的诺基亚小砖头就先借你用吧.

在Apache2.2.XX下安装Mod-myvhost模块

上回提到Mod-myvhost只有for apache1.3的版本,后来google了下,发现一个葡萄牙的同学讲到了如何在2.x上安装(围观请翻墙,并自备翻译工具),才发现mod-myvhost的svn分支里边有2.0版本的代码(部分运气不好的围观群众请继续翻墙).于是费了一番功夫,我终于把这个模块装上了.下边是安装过程.

首先,因为代码里边用到了mysql的一些头文件,所以要安装mysql的开发包.


sudo apt-get install libmysql++-dev

然后,这个apache module采用apxs编译,所以apxs也要有.如果你已经编译过apache了,那么apxs就在bin下边,和apachectl在同一级目录下.

准备工作就是这些.开始安装mod-myvhost.

svn checkout代码.

svn co http://mod-myvhost.googlecode.com/svn/branches/2.0.xx/

为什么要用2.0.xx而不用2.2.xx-dbd? 因为2.2.xx-dbd编译通不过…有兴趣的同学可以自行debug去.

然后进入目录,开始编译


cd 2.0.xx/
make

呜,报错了


/bin/sh: apxs: command not found
make: *** [mod_myvhost.so] Error 127

原来是apxs没有找到.修改Makefile,指定apxs路径,vim Makefile,第四行改为


APXS = /home/easy/dev/apache2/bin/apxs(这里换成你apache2/bin目录的路径/apxs)

然后 make,make install . 一切ok. 查看apache2/conf/httpd.conf,已经自动加上了相关的配置.


LoadModule myvhost_module modules/mod_myvhost.so

试着启动下.又挂了… 提示信息如下:

undefined symbol: apr_hash_clear

grep 源代码发现只有mod_myvhost_cache.c的最后一段用到.


/* FIXME: older */
void cache_vhost_flush(myvhost_cfg_t *cfg, apr_hash_t *cache, time_t older)
{
if (!cfg->cache_enabled) {
return;
}
if (!cache) {
return;
}
apr_hash_clear(cache);
}

#endif /* WITH_CACHE */

修改Makefile,先关掉cache部分


#CFLAGS+= -DWITH_PHP -DWITH_CACHE
CFLAGS+= -DWITH_PHP

重新编译安装后启动apache.Ok了.接着测试动态host功能.
修改apache配置文件 httpd.conf,添加myvhost段.

<IfModule mod_myvhost.c>
MyVhostOn           on
MyVhostDefaultHost  "appgame.cn"
MyVhostDefaultRoot  "/data0/myapphost/"
MyVhostDbHost       "127.0.0.1"
MyVhostDbSocket     "/tmp/mysql.sock"
MyVhostDbUser       "easy"
MyVhostDbPass       "***"
MyVhostDbName       "hosting"
MyVhostQuery        "SELECT rootdir,admin,extra_php_config FROM vhosts WHERE vhost='%s' AND enabled='yes'"
<Directory "/data0/myapphost/">
Options Indexes
AllowOverride None
Order allow,deny
Allow from all
</Directory>
</IfModule>

在phpmyadmin里边导入2.0.xx/vhost.sql,会自动建立hosting库.删掉里边的示例数据,填入我们需要的数据:

在对应的目录下建立测试文件index.php.重启apache已经可以正常工作了.

mod-myvhost会自动添加open_basedir限制,写段代码测试下:

echo file_get_contents( '../02/o.php' );

访问页面,输入如下:

Warning: file_get_contents() [function.file-get-contents]: open_basedir restriction in effect. File(../02/o.php) is not within the allowed path(s): (/data0/myapphost/01/) in /data0/myapphost/01/index.php on line 1

Warning: file_get_contents(../02/o.php) [function.file-get-contents]: failed to open stream: Operation not permitted in /data0/myapphost/01/index.php on line 1

看起来基本的vhost功能已经完成了.

接下来要解决的几个问题是

  1. cache是一个重要的功能,想办法把cache的问题查出来.apr的源代码里是有这个函数的,可能是因为apr的路径或者版本不对.
  2. 代码访问的隔离完成了.但是代码上传的问题还没有解决,接着开始ftp server的选型.要求能通过文件或者mysql的方式方便的添加账号,能根据添加的账号指定目录的磁盘配额.

这些是下个周末的功课 :] .…