工作,学习,生活,这里将会有一些记录. 备用域名:http://meisw.wdlinux.cn 注册 | 登陆
浏览模式: 标准 | 列表全部文章

PHP检查URL地址是否合法的一个类

这个类可以用来检查URL地址的合法性,目前支持ftp,file,http,https,gopher,news,nntp,telnet,wais.功能:
检查URL的合法性

class urlcheck{
var $regex = array(//协议名(注意在这里必须写成小写) => 对应的正则表达式
'ftp' => '$this->ftpurl',
'file' => '$this->fileurl',
'http' => '$this->httpurl',
'https' => '$this->httpurl',
'gopher' => '$this->gopherurl',
'news' => '$this->newsurl',
'nntp' => '$this->nntpurl',
'telnet' => '$this->telneturl',
'wais' => '$this->waisurl'
);

var $lowalpha;
var $hialpha;
var $alpha;
var $digit;
var $safe;
var $extra;
var $national;
var $punctuation;
var $reserved;
var $hex;
var $escape;
var $unreserved;
var $uchar;
var $xchar;
var $digits;

var $urlpath;
var $password;
var $user;
var $port;
var $hostnumber;
var $alphadigit;
var $toplabel;
var $domainlabel;
var $hostname;
var $host;
var $hostport;
var $login;

//ftp
var $ftptype;
var $fsegment;
var $fpath;
var $ftpurl;

//file
var $fileurl;

//http,https
var $search;
var $hsegment;
var $hpath;
var $httpurl;

//gopher
var $gopher_string;
var $selector;
var $gtype;
var $gopherurl;

//news
var $article;
var $group;
var $grouppart;
var $newsurl;

//nntp
var $nntpurl;

//telnet
var $telneturl;

//wais
var $wpath;
var $wtype;
var $database;
var $waisdoc;
var $waisindex;
var $waisdatabase;
var $waisurl;

function check($url){
$pos = @strpos($url,':',1);
if($pos<1) return false;
$prot = substr($url,0,$pos);
if(!isset($this->regex[$prot])) return false;
eval('$regex = '.$this->regex[$prot].';');
return ereg('^'.$regex.'$',$url);
}

function urlcheck(){
$this->lowalpha = '[a-z]';
$this->hialpha = '[A-Z]';
$this->alpha = '('.$this->lowalpha.'|'.$this->hialpha.')';
$this->digit = '[0-9]';
$this->safe = '[$.+_-]';
$this->extra = '[*()\'!,]';
$this->national = '([{}|\^~`]|\\[|\\])';
$this->punctuation = '[<>#%"]';
$this->reserved = '[?;/:@&=]';
$this->hex = '('.$this->digit.'|[a-fA-F])';
$this->escape = '(%'.$this->hex.'{2})';
$this->unreserved = '('.$this->alpha.'|'.$this->digit.'|'.$this->safe.'|'.$this->extra.')';
$this->uchar = '('.$this->unreserved.'|'.$this->escape.')';
$this->xchar = '('.$this->unreserved.'|'.$this->reserved.'|'.$this->escape.')';
$this->digits = '('.$this->digit.'+)';

$this->urlpath = '('.$this->xchar.'*)';
$this->password = '(('.$this->uchar.'|[?;&=]'.')*)';
$this->user = '(('.$this->uchar.'|[?;&=]'.')*)';
$this->port = $this->digits;
$this->hostnumber = '('.$this->digits.'.'.$this->digits.'.'.$this->digits.'.'.$this->digits.')';
$this->alphadigit = '('.$this->alpha.'|'.$this->digit.')';
$this->toplabel = '('.$this->alpha.'|('.$this->alpha.'('.$this->alphadigit.'|-)*'.$this->alphadigit.'))';
$this->domainlabel = '('.$this->alphadigit.'|('.$this->alphadigit.'('.$this->alphadigit.'|-)*'.$this->alphadigit.'))';
$this->hostname = '(('.$this->domainlabel.'\\.)*'.$this->toplabel.')';
$this->host = '('.$this->hostname.'|'.$this->hostnumber.')';
$this->hostport = '('.$this->host.'(:'.$this->port.')?)';
$this->login = '(('.$this->user.'(:'.$this->password.')?@)?'.$this->hostport.')';

$this->ftptype = '[aidAID]';
$this->fsegment = '(('.$this->uchar.'|[?:@&=])*)';
$this->fpath = '('.$this->fsegment.'(/'.$this->fsegment.')*)';
$this->ftpurl = '([fF][tT][pP]://'.$this->login.'(/'.$this->fpath.'(;[tT][yY][pP][eE]='.$this->ftptype.')?)?)';

$this->fileurl = '([fF][iI][lL][eE]://('.$this->host.'|[lL][oO][cC][aA][lL][hH][oO][sS][tT])?/'.$this->fpath.')';

$this->search = '(('.$this->uchar.'|[;:@&=])*)';
$this->hsegment = '(('.$this->uchar.'|[;:@&=])*)';
$this->hpath = '('.$this->hsegment.'(/'.$this->hsegment.')*)';
$this->httpurl = '([hH][tT][tT][pP][sS]?://'.$this->hostport.'(/'.$this->hpath.'([?]'.$this->search.')?)?)';

$this->gopher_string = '('.$this->xchar.'*)';
$this->selector = '('.$this->xchar.'*)';
$this->gtype = $this->xchar;
$this->gopherurl = '([gG][oO][pP][hH][eE][rR]://'.$this->hostport.'(/('.$this->gtype.'('.$this->selector.'(%09'.$this->search.'(%09'.$this->gopher_string.')?)?)?)?)?)';

$this->article = '(('.$this->uchar.'|[;/?:&=])+@'.$this->host.')';
$this->group = '('.$this->alpha.'('.$this->alpha.'|'.$this->digit.'|[-.+_])*)';
$this->grouppart = '([*]|'.$this->group.'|'.$this->article.')';
$this->newsurl = '([nN][eE][wW][sS]:'.$this->grouppart.')';

$this->nntpurl = '([nN][nN][tT][pP]://'.$this->hostport.'/'.$this->group.'(/'.$this->digits.')?)';

$this->telneturl = '([tT][eE][lL][nN][eE][tT]://'.$this->login.'/?)';

$this->wpath = '('.$this->uchar.'*)';
$this->wtype = '('.$this->uchar.'*)';
$this->database = '('.$this->uchar.'*)';
$this->waisdoc = '([wW][aA][iI][sS]://'.$this->hostport.'/'.$this->database.'/'.$this->wtype.'/'.$this->wpath.')';
$this->waisindex = '([wW][aA][iI][sS]://'.$this->hostport.'/'.$this->database.'[?]'.$this->search.')';
$this->waisdatabase = '([wW][aA][iI][sS]://'.$this->hostport.'/'.$this->database.')';
$this->waisurl = '('.$this->waisdatabase.'|'.$this->waisindex.'|'.$this->waisdoc.')';
}
}

利用DRBD+heartbeat实现NFS文件共享服务高可用

一.目的:二台NFS服务器互为冗余(系统切换时间约为2x ms左右),保证NFS文件共享服务的可用

二.系统为CentOS 5.3
    二个节点 主节点node1(192.168.10.111) 备用节点node2(192.168.10.112) 虚拟IP:192.168.10.113对外提供服务
node1 /etc/hosts如下
[root@node1 ha.d]# cat /etc/hosts
# Do not remove the following line, or various programs
# that require network functionality will fail.
192.168.10.111          node1
192.168.10.112          node2
127.0.0.1               node1 localhost.localdomain localhost
::1             localhost6.localdomain6 localhost6

node2 /etc/hosts如下
[root@node2 ~]# cat /etc/hosts
# Do not remove the following line, or various programs
# that require network functionality will fail.
192.168.10.111          node1
192.168.10.112          node2
127.0.0.1               node2 localhost.localdomain localhost
::1             localhost6.localdomain6 localhost6

二台机将/dev/hda5互为镜相
二台机/etc/export相同
cat /etc/exports
/u1 192.168.10.0/255.255.255.0(rw,no_root_squash,no_all_squash,sync)
确定二台机的portmap服务为启动状态

三.所需软件:使用DRBD作为网络磁盘镜相,Heartbeart为管理由提供NFS服务及服务失效节点转移
安装所需的软件DRBD及Heartbeat均从http://mirror.centos.org/centos/5.3/extras/i386/RPMS 此目录下载,省去安装过程
drbd需要手动加载内核模块,安装好rpm执行如下指令
insmod /lib/modules/2.6.9-78.ELsmp/extra/drbd.ko
modprobe drbd

四.配置过程
1.DRBD配置 配置文件只有一个/etc/drbd.conf 二个内容都是一样 global { usage-count yes; }

common { syncer { rate 10M; } }

resource r0 {

        protocol C;

        startup {

 

        }

        disk {

                on-io-error   detach;

        }

        net {

        }

        on node1 {

                device    /dev/drbd0;

                disk      /dev/hda5;

                address   192.168.10.111:7789;

                meta-disk internal;

        }

        on node2 {

                device    /dev/drbd0;

                disk      /dev/hda5;

                address   192.168.10.112:7789;

                meta-disk internal;

        }

}
复制代码在二台机执行
drbdadm create-md r0 #创建ro的资源
/etc/init.d/drbd start #启动drbd
cat /proc/drbd #查看状态正常显示为
version: 8.0.13 (api:86/proto:86)
GIT-hash: ee3ad77563d2e87171a3da17cc002ddfd1677dbe build by buildsvn@c5-i386-build, 2008-10-02 13:31:44
0: cs:Connected st:Secondary/Primary ds:UpToDate/UpToDate C r---
    ns:1848 nr:14357752 dw:14359600 dr:653 al:6 bm:901 lo:0 pe:0 ua:0 ap:0
        resync: used:0/61 hits:928654 misses:1079 starving:0 dirty:0 changed:1079
        act_log: used:0/127 hits:456 misses:6 starving:0 dirty:0 changed:6
在主服务器上执行
drbdsetup /dev/drbd0 primary -o #定义为主节点
mkfs.ext3 /dev/drbd0           #格式化
mount /dev/drbd0 /u1           #挂载
cat /proc/drbd #此时查看状态正常显示为
[root@node1 ha.d]# cat /proc/drbd
version: 8.0.13 (api:86/proto:86)
GIT-hash: ee3ad77563d2e87171a3da17cc002ddfd1677dbe build by buildsvn@c5-i386-build, 2008-10-02 13:31:44
0: cs:Connected strimary/Secondary ds:UpToDate/UpToDate C r---
    ns:14357752 nr:1848 dw:361872 dr:13998555 al:264 bm:3581 lo:0 pe:0 ua:0 ap:0
        resync: used:0/61 hits:928654 misses:1079 starving:0 dirty:0 changed:1079
        act_log: used:0/127 hits:89742 misses:268 starving:0 dirty:4 changed:264

2.Heartbeat配置共涉及4个文件
/etc/ha.d/ha.cf
/etc/ha.d/haresources
/etc/ha.d/authkeys
/etc/ha.d/resource.d/killnfsd
二个节的配置的配置文件都是一样,文件内容如下
[root@node1 ha.d]# cat /etc/ha.d/ha.cf
debugfile /var/log/ha-debug
logfile /var/log/ha-log
logfacility     local0
keepalive 2
deadtime 20
bcast eth0
auto_failback off
node    node1 node2
[root@node1 ha.d]# cat /etc/ha.d/haresources
node1 IPaddr::192.168.10.113/24/eth0 drbddisk::r0 Filesystem::/dev/drbd0::/u1::ext3 killnfsd
[root@node1 ha.d]# cat /etc/ha.d/authkeys
auth 1
1 crc
#2 sha1 HI!
#3 md5 Hello!
[root@node1 ha.d]# cat /etc/ha.d/resource.d/killnfsd
killall -9 nfsd ; /etc/init.d/nfs restart ; exit 0

需要将 /etc/ha.d/authkeys设为600的权限 将cat /etc/ha.d/resource.d/killnfsd设为755的权限
chmod 600 /etc/ha.d/authkeys
chmod 755 /etc/ha.d/resource.d/killnfsd

为什么要使用这个killnfsd的原因,使用/etc/inin.d/nfs stop 不能停掉nfsd,所有我使用了killall -9 nfsd再加了一个/etc/inin.d/nfs restart确保万一
在二个节点启动Heartbeat即可,先在主节点启动
/etc/init.d/heartbeat start

五.测试
将192.168.10.113:/u1挂到本地/mnt
mount 192.168.10.113:/u1 /mnt
创建测试shell,二秒一个
cat /mnt/test.sh
while true
do
  echo     ---\> trying touch x : `date`
  touch x
  echo     \<----- done touch x : `date`
  echo
  sleep 2

done

将主节点的heartbeat服务停止,则备节点node2接管服务
/etc/init.d/heartbeat stop

测试脚本终端显示如下
---> trying touch x : ?t 6?? 30 15:17:16 CST 2009
<----- done touch x : ?t 6?? 30 15:17:16 CST 2009

---> trying touch x : ?t 6?? 30 15:17:19 CST 2009
<----- done touch x : ?t 6?? 30 15:17:19 CST 2009

---> trying touch x : ?t 6?? 30 15:17:21 CST 2009
<----- done touch x : ?t 6?? 30 15:17:21 CST 2009

---> trying touch x : ?t 6?? 30 15:17:23 CST 2009
<----- done touch x : ?t 6?? 30 15:17:23 CST 2009

---> trying touch x : ?t 6?? 30 15:17:25 CST 2009
<----- done touch x : ?t 6?? 30 15:17:25 CST 2009

---> trying touch x : ?t 6?? 30 15:17:27 CST 2009
touch: cannot touch ??x?ˉ: Stale NFS file handle
<----- done touch x : ?t 6?? 30 15:17:42 CST 2009

---> trying touch x : ?t 6?? 30 15:17:44 CST 2009
touch: cannot touch ??x?ˉ: Stale NFS file handle
<----- done touch x : ?t 6?? 30 15:17:44 CST 2009

---> trying touch x : ?t 6?? 30 15:17:46 CST 2009
touch: cannot touch ??x?ˉ: Stale NFS file handle
<----- done touch x : ?t 6?? 30 15:17:46 CST 2009

---> trying touch x : ?t 6?? 30 15:18:03 CST 2009
<----- done touch x : ?t 6?? 30 15:18:03 CST 2009

---> trying touch x : ?t 6?? 30 15:18:05 CST 2009
<----- done touch x : ?t 6?? 30 15:18:05 CST 2009

至此,测试已实现所需的功能

六.参考文档
Setup of High-Availability NFS servers (HA-NFS)  http://www.linux-ha.org/HaNFS
DRBD Heartbeat and NFS on Debian HowTo http://www.linux-ha.org/DRBD/NFS

top信息

Tasks: 29 total 进程总数
1 running 正在运行的进程数
28 sleeping 睡眠的进程数
0 stopped 停止的进程数
0 zombie 僵尸进程数
Cpu(s): 0.3% us 用户空间占用CPU百分比
1.0% sy 内核空间占用CPU百分比
0.0% ni 用户进程空间内改变过优先级的进程占用CPU百分比
98.7% id 空闲CPU百分比
0.0% wa 等待输入输出的CPU时间百分比
0.0% hi   硬件中断
0.0% si   软件中断

Mem: 191272k total 物理内存总量
173656k used 使用的物理内存总量
17616k free 空闲内存总量
22052k buffers 用作内核缓存的内存量
Swap: 192772k total 交换区总量
0k used 使用的交换区总量
192772k free 空闲交换区总量
123988k cached 缓冲的交换区总量。
内存中的内容被换出到交换区,而后又被换入到内存,但使用过的交换区尚未被覆盖,
该数值即为这些内容已存在于内存中的交换区的大小。
相应的内存再次被换出时可不必再对交换区写入。

进程信息区统计信息区域的下方显示了各个进程的详细信息。首先来认识一下各列的含义。
序号 列名 含义
a PID 进程id
b PPID 父进程id
c RUSER Real user name
d UID 进程所有者的用户id
e USER 进程所有者的用户名
f GROUP 进程所有者的组名
g TTY 启动进程的终端名。不是从终端启动的进程则显示为 ?
h PR 优先级
i NI nice值。负值表示高优先级,正值表示低优先级
j P 最后使用的CPU,仅在多CPU环境下有意义
k %CPU 上次更新到现在的CPU时间占用百分比
l TIME 进程使用的CPU时间总计,单位秒
m TIME+ 进程使用的CPU时间总计,单位1/100秒
n %MEM 进程使用的物理内存百分比
o VIRT 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
p SWAP 进程使用的虚拟内存中,被换出的大小,单位kb。
q RES 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
r CODE 可执行代码占用的物理内存大小,单位kb
s DATA 可执行代码以外的部分(数据段+栈)占用的物理内存大小,单位kb
t SHR 共享内存大小,单位kb
u nFLT 页面错误次数
v nDRT 最后一次写入到现在,被修改过的页面数。
w S 进程状态。
D=不可中断的睡眠状态
R=运行
S=睡眠
T=跟踪/停止
Z=僵尸进程
x COMMAND 命令名/命令行
y WCHAN 若该进程在睡眠,则显示睡眠中的系统函数名
z Flags 任务标志,参考 sched.h

PHP导出Excel 之 Spreadsheet_Excel_Writer

之前看到过好多关于PHP导出Excel的文章,自己也通过不少方法实现过,
例如,echo一个Table,然后将header修改为Excel即可。
其实在众多方法中感觉Pear中的Spreadsheet_Excel_Writer很是好用。
关于Spreadsheet_Excel_Writer的安装本文不予介绍,可通过Google找到
答案:) 也可参考: http://pear.php.net/package/Spreadsheet_Excel_Writer/download

<?php
//调用Writer.php
require_once 'Spreadsheet/Excel/Writer.php';
//创建Workbook
$workbook = new Spreadsheet_Excel_Writer();
//定义导出Excel文件名
$workbook->send('test.xls');
//创建Worksheet
$worksheet =& $workbook->addWorksheet('My first worksheet');
//设置字体大小
$format_column = & $workbook->addformat(array('Size'=>9,'Bold'=>1));
//数据写入
//标题行(第一行)
$worksheet->write(0, 0, 'Name', $format_column);
$worksheet->write(0, 1, 'Age', $format_column);
//第一个人(第二行)
$worksheet->write(1, 0, 'John Smith');
$worksheet->write(1, 1, 30);
//第二个人(第三行)
$worksheet->write(2, 0, 'Johann Schmidt');
$worksheet->write(2, 1, 31);
//第三个人(第四行)
$worksheet->write(3, 0, 'Juan Herrera');
$worksheet->write(3, 1, 32);
//关闭Workbook
$workbook->close();
?>

-------------------me
直接导出,会乱码
保存再下载,就正常

增加
  $workbook->setVersion(8); 
  $worksheet->setInputEncoding("utf-8");

再将中文转为UTF8
$lqzy=iconv("GBK","UTF-8",$r['lqzy']);

因为页面本身是gb2312

如果页面本身是utf8,应该不用转,感觉excel只支持utf8

-------------------------------
1.在根目录下建立文件夹,名为”Spreadsheet\Excel

2.在http://pear.php.net/package/PEAR/download下载PEAR,然后安装:也可执行PHP目录里的go-pear.bat

3.把 PEAR解压后的pear.php 复制到 “Spreadsheet\Excel” 路径下

4.在http://pear.php.net/package/Spreadsheet_Excel_Writer/download下载Spreadsheet_Excel_Writer

5.在http://pear.php.net/package/OLE/download下载 OLE-1.0.0RC1.gz ,安装:cmd进入php目录,我的是D:\php   运行命令“OLE-1.0.0RC1 ”。

6.把Spreadsheet_Excel_Writer 中的“Writer.php” 和 “Writer” 文件夹复制到“Spreadsheet/Excel/” 路径下

7.把OLE-1.0.0RC1 中的 “OLE.php” 复制到“Spreadsheet/Excel/” 路径下,“PPS.php” 和 “PPS” 文件夹复制到“Spreadsheet/Excel/OLE路径下

8.把Console、System.php都复制到Spreadsheet\Excel路径下

centos下 MySQL 5.5.11 CMake 安装笔记

mysql 最新的版本都需要cmake编译安装,估计以后的版本也会采用这种方式,所以特地记录一下安装步骤及过程,以供参考。

注意:此安装是默认centos下已经安装了最新工具包,比如GNU make, GCC, Perl, libncurses5-dev,如果在编译安装过程中发现有缺失的工具包,先yum install 单独下载安装再继续即可。

 


一. Centos 用 wget 下载需要的软件,保存到目录 /usr/local/src/ 下


wget http://dev.mysql.com/get/Downloads/MySQL-5.5/mysql-5.5.11.tar.gz/from/http://mysql.he.net/

wget http://www.cmake.org/files/v2.8/cmake-2.8.4.tar.gz

wget http://ftp.gnu.org/gnu/bison/bison-2.4.3.tar.gz

 

二. 安装 cmake

cd /usr/local/src

 


tar zxvf cmake-2.8.4.tar.gz
cd cmake-2.8.4
./bootstrap
gmake
gmake install
cd ../

tar zxvf bison-2.4.3.tar.gz
cd bison-2.4.3
./configure
make
make install

cd ../

 

三. 编译安装 MySQL 5.5.11


/usr/sbin/groupadd mysql
/usr/sbin/useradd -g mysql mysql

tar xvf mysql-5.5.11.tar.gz
cd mysql-5.5.11/

cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYSQL_UNIX_ADDR=/tmp/mysql.sock \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_EXTRA_CHARSETS:STRING=utf8,gbk \
-DWITH_MYISAM_STORAGE_ENGINE=1 \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_MEMORY_STORAGE_ENGINE=1 \
-DWITH_READLINE=1 \
-DENABLED_LOCAL_INFILE=1 \
-DMYSQL_DATADIR=/var/mysql/data \
-DMYSQL_USER=mysql

make
make install

chmod +w /usr/local/mysql
chown -R mysql:mysql /usr/local/mysql

ln -s /usr/local/mysql/lib/libmysqlclient.so.16 /usr/lib/libmysqlclient.so.16

 

mkdir -p /var/mysql/
mkdir -p /var/mysql/data/
mkdir -p /var/mysql/log/
chown -R mysql:mysql /var/mysql/


cdsupport-files/

cpmy-large.cnf /var/mysql/my.cnf

cp mysql.server /etc/init.d/mysqld


四. 配置启动MySQL 5.5.11

1. 若有需要请先修改 mysql 的配置 my.cnf

vi /var/mysql/my.cnf

 

2. mysql 初始化安装

/usr/local/mysql/scripts/mysql_install_db \
--defaults-file=/var/mysql/my.cnf \
--basedir=/usr/local/mysql \
--datadir=/var/mysql/data \
--user=mysql


3. 将 mysql 加入开机启动

chmod +x /etc/init.d/mysqld
vi /etc/init.d/mysqld (编辑此文件,查找并修改以下变量内容:)
basedir=/usr/local/mysql
datadir=/var/mysql/data

chkconfig --add mysqld
chkconfig --level 345 mysqld on

4. 启动 mysql

service mysqld start

虚拟化基础架构之使用openfiler搭建iSCSI网络共享存储(IPSAN)

随着虚拟化架构的不断完善与扩充,后台集中的网络存储已开始成为虚拟化整体解决方案中的一部分(尤其是对VDI、高可用性群集等架构),实现网络存储的方法有以下几种:
      直接向EMC、NetApp等厂商购买存储设备:性能较好,价格高昂
      在Windows平台安装模拟器:配制简单,但性能一般,且由于商业软件的试用期限制较难以长期使用  
      使用FreeNAS、Openfiler等Linux核心的iSCSI Target端程序:基于Linux内核的裸金属服务器端,性能较为理想,免费可自由下载,比较适合于系统测试或评估使用。
  
  这里将介绍使用Openfiler2.3来搭建基于iSCSI的网络共享存储
  首先来看下基本架构与一些基本概念,了解基本概念的请跳过。。。

  在整个架构中,所有的设备都通过以太网相连,两台需要连接存储的服务器分别为两个节点,称之为Initiator端(也可只有一个节点或多个节点),存储设备可以是专门的硬件存储设备,也可以由普通服务器充当,只需安装上述所说的模拟软件或者Openfiler等精简版Linux来充当,称之为Target端。
  所以整个iSCSI架构其实也是类似于C/S架构,Target段为存储服务器,Initiator端为客户端,通过iSCSI协议将存储设备上的逻辑卷作为自己的存储设备使用。

    下面切入正题,整个配置过程分为三大步骤:
  在存储服务器上安装Openfiler
   通过Web方式远程配置Openfiler存储设备
  配置客户端服务器连接Openfiler存储设备

一、在存储服务器上安装Openfile(基本的只有下一步可按的页面就跳过了~)
首先在http://www.openfiler.com/community/download/中下载合适的版本,从光驱引导后是典型的Linux安装界面
直接回车进入图形化安装界面
  
在磁盘设置这里如果不熟悉Linux磁盘分区的话可以直接选择自动分区,但是为了增强对磁盘分区的可控性,这里选择手动分区。

系统询问是否初始化磁盘并删除所有数据,选择YES,连续选择两次No的话则Restart。。。

进入磁盘分区页面,在这个系统中我有两个磁盘,我的规划是较小的磁盘安装Openfiler,并且划分一个区作为群集的仲裁磁盘,较大的磁盘作为共享数据磁盘(当然这是后话了,并且Linux系统的安装并不局限于一块物理磁盘,这里只是根据惯有的思路做一个预先规划)

安装Openfiler本身的推荐分区方法则根常规的Linux分区方法是一样的,需要一个引导分区,一个根分区,一个交换分区
点击较小的磁盘的Free空间,选择新建,在挂载点中择/boot,文件类型为ext3,只选择较小的磁盘(还是那句话,根据惯有思维,实在不习惯将一个分区横跨两个无力磁盘),大小设为100M即可,确定下方为固定大小,勾选强制为主分区选项。

用同样的方法建立根分区,挂载点位/,文件格式为ext3,挂载在较小的物理磁盘,大小为1GB-2GB即可,因为是精简版的Linux,且以后也不大会安装其它软件,所以1GB足矣(又是那句话,按照惯性思维,我设了2G,被微软惯性坏了。。。),下面则同样是固定大小,强制为主分区。
最后建立一个交换分区,不需要选择挂载点,文件类型为swap,第一块无力磁盘,大小为内存的两倍即可,其余设置一样,这里发现少截张图。。。

分区完成后最终的效果应该是这样的,其余的分区保持为Free状态,不然在Openfiler中可能无法分配。

配置网络属性,建议设为固定IP,因为Openfiler安装完成之后没有图形界面,所有的配置都通过web方式完成,没有固定的IP会给以后的配置造成不必要的麻烦。

接下来是选择时区,设置Root帐户密码,然后光盘中的文件拷贝至硬盘中开始正式安装,都比较简单,安装完成后取出光盘,按下Restart,整个安装过程就算完成了,其实跟安装普通的Linux没有任何区别。


二、通过Web方式远程配置Openfiler存储设备
启动Openfiler之后会显示他的Web管理的URL:
https://IP:446

通过远程客户端浏览器登录,用户名为openfiler,密码为password
进入管理界面之后首先看到是一些常规设备信息,关系不大,在上方导航栏中选择system,拉到页面下方,在Network Access Configuration中添加Initiator客户端所在的网段地址,用以在之后选择是否授权这个网段的计算机能够连接本台存储,可以通过子网掩码进一步控制数量,类型保留为share,点击Update。

在导航栏中选择Volumes,点击右侧的Block Devices,可以查看到当前存储服务器所拥有的物理磁盘,选择某一个物理磁盘的view,可以查看这块物理磁盘上已有的分区。

下面就开始正式划分我们所需要的共享仲裁磁盘和数据磁盘。
单击第一块物理磁盘:  /dev/sda
拉到页面下方(如果要说Openfiler有什么很让人火大的地方就是这里了,很多页面都设计的很长,要拉到很下面才能进行设置),在这里划分一个物理分区出来,注意将PartitionType设置为物理卷,类型为主要,通过设置开始柱面和结束柱面,系统会计算出划分的区为多大,调整到满意的值后点击Creat

接下来点击右侧的Volume Group,拉到页面下方,创建一个新的卷组,设置卷组名为Quorum,包含刚才创建的物理分区,点击Add Volume Group。

点击右侧的Add Volume,选择刚才创建的卷组,在这个卷组所包含的空间上创建一个真正的会挂接到Initiator客户端服务器上的逻辑卷(Lun),什么?你在这个页面中没看到创建?看到右侧的滚动条了么?对了。。。往下拉。。。

在创建逻辑Lun的时候可以选择所需要的大小,而不是选择整个卷组,Openfiler对磁盘的灵活性体现出来了,一个卷组可以划分多个逻辑Lun,卷组本身又可以来自多个物理磁盘,好了,被我说乱了?等下我来整理思路。这里定义完了卷名后在文件类型列表中选择iSCSI,点击Creat。

用同样的方法在第二块磁盘上创建一个物理分区,包含在data这个卷组中。

点击右侧的Add Volume,注意选择需要在哪个卷组上创建逻辑卷,选择data卷组后需要点击change,才能在data这个卷组中操作,和上面一样,拉到页面下方,创建一个用于data的逻辑卷。

在导航栏中选择Service,将下方服务中的iSCSI Target Server修改为Enable状态。
  
回到Volumes标签,点击右侧的iSCSI Targets,点击Add添加iSCSI Target。
  
单击导航栏下方的Lun Mapping,可以看到之前划出来可用于挂载的逻辑Lun,将两个逻辑卷全部Map至该Target。
  
最后单击Network ACL,可以看到先前设置的Initiator端所在的网段,在Access下选择Allow,单击Update,大功告成。
  

三、配置客户端服务器连接Openfiler存储设备

这个步骤比较简单,跟所有的连接iSCSI设备客户端所需的操作一样(硬件HBA卡除外),安装微软的iSCSI Initiator 2.0(如果是Server08的话不需要安装,系统自带)

在Discovery标签中,单击Add,填入Openfiler服务器的地址,端口默认,确认。

在Targets标签,单击Log On,勾选系统启动时自动恢复连接,确定,Target中的信息会由Inactive变为Connected。

打开磁盘管理,系统发现新的可初始化的磁盘,网络存储配置完成,只需在第二台节点进行同样的操作即可(第一台节点最好关闭,但实际坐下来问题不大,反正最后是由群集控制)。

在设备管理器中的磁盘驱动器下可以看到,有两个OpnFiler..SCSI的设备驱动器。

回到web控制台,进入Status标签,单击右侧的iSCSI Target,可以看到连上来的Initiator,选择View可以看到IP信息。




    整个配置到这里算是全部完成了,最后简单整理下Openfiler创建逻辑卷的整个过程:
1.首先在物理磁盘上创建物理分区,不能跨越物理磁盘
2.创建卷组,在卷组中可以包含任意的未被分配的物理分区,可以跨越物理磁盘,可以理解为将多个物理上的空间整合为一个可用的空间
3.在卷组中创建用于被连接的逻辑Lun,一个卷组可以创建一个逻辑Lun,也可以创建多个逻辑Lun,一个逻辑Lun被连接到客户端服务器后在磁盘管理器中最终看到的即是一个物理磁盘。
   
    在这里容易搞混得是卷组的名字是Volume Group,逻辑Lun的名字是Volume,在创建过程中是先创建VolumeGroup,最后才在相应的VolumeGroup中Add Volume的。

Openfiler 之Linux 安装ISCSI initiator和自动挂载

Openfiler 之Linux 安装ISCSI initiator和自动挂载
 
OPENFILER做TARGET,RED HAT做客户端,如果默认没有安装ISCSI initiator的话,可以在光盘上找到RPM包直接安装。service iscsi start,启动服务,service iscsi restart重启服务。用以下命令去发现ISCSI目标:

[root@localhost ~]# iscsiadm -m discovery -t sendtargets -p 10.10.1.110:3260
10.10.1.110:3260,1 iqn.2006-01.com.openfiler:tsn.2a5ab8637059


登录target :
 

iscsiadm -m node -p 10.10.1.110:3260 -l

登录所有的目标:

[root@localhost ~]# iscsiadm -m node --loginall=all
Login session [10.10.1.110:3260 iqn.2006-01.com.openfiler:tsn.2a5ab8637059]

查看目标的状态:

[root@localhost ~]# iscsiadm -m session -i
iscsiadm version 2.0-742
************************************
Session (sid 0) using module tcp:
************************************
TargetName: iqn.2006-01.com.openfiler:tsn.2a5ab8637059
Portal Group Tag: 1
Network Portal: 10.10.1.110:3260
iSCSI Connection State: LOGGED IN
Internal iscsid Session State: NO CHANGE

此时执行FDISK-L可以查看到当前挂载的硬盘,此时应该可以看到OPENFILER上的LUN。我们需要对其进行分区和格式化才能挂载使用,使用FDISK命令:

[root@rhel5 /]# fdisk /dev/sda

键入P进行分区,根据提示划分一个区出来,最好输入W保存。格式化分区:

mkfs.ext3 /dev/sda1


最后是挂载使用:

[root@rhel5 /]# mkdir /media/sda1 //创建挂载点

[root@rhel5 /]# mount /dev/sda1 /media/sda1/ //将新建的分区挂载使用。


做到这里,基本上就可以使用了,但我们要保证这个ISCSI盘重起后能自动挂载,那就需要修改/ETC/FSTAB:

[root@localhost ~]# vi /etc/fstab

 

LABEL=/ / ext3 defaults 1 1
LABEL=/boot /boot ext3 defaults 1 2
devpts /dev/pts devpts gid=5,mode=620 0 0
tmpfs /dev/shm tmpfs defaults 0 0
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
LABEL=SWAP-sda2 swap swap defaults 0 0
/dev/sdd1 /mnt/sdd1 ext3 defaults 0 0

这里要做个记录,开始的时候一不小心,设为了1,2,以至开机时检查系统文件无法跳过,因为此时ISCSI网络还没有启动,须改为0,0。在启动时输入管理员密码后,输入:mount -n -o remount,rw /
,然后再重新编辑/etc/fstab 修改掉里面不正确挂载的分区参数,保存后重起即可。

另外一种更可靠的方法是使用卷分区的UUID来挂载卷,此时/etc/fstab.iscsi文件的格式如下:iSCSI服务重启后,会按照分区的UUID将设备挂载到指定的节点上。 

UUID=fb032900-9113-1213-fc09-086734fac1c1 /mnt/t0 ext3 defaults 0 0


UUID的查看:

[root@localhost ~]# sudo blkid /dev/sdd1
/dev/sdd1: UUID="da0907e8-7eda-46ec-b28f-3180c061cf3e" SEC_TYPE="ext2" TYPE="ext3"


保险一点,可以使用“_netdev”这个参数来等待网络连接后再挂载。

 

#/dev/sdd1 /mnt/sdd1 ext3 _netdev 0 0
UUID=da0907e8-7eda-46ec-b28f-3180c061cf3e /mnt/sdd1 ext3 _netdev 0 0

 

最后是注销ISCSI:

iscsiadm --mode node --targetname iqn.2006-01.com.openfiler:tsn.2a5ab8637059 --portal 10.10.1.110:3260 --logout


这里一定要加T即目标参数。登陆:

 

iscsiadm --mode node --targetname iqn.2006-01.com.openfiler:tsn.2a5ab8637059 --portal 10.10.1.110:3260 -l

 

linux iscsiadm的用法:
linux下iscsiadm命令的基本用法:
发现target,询问target名称
[root@RedHat5 ~]# iscsiadm -m discovery -t sendtargets -p targetIP地址:端口号
该命令将报告出target名称
建立连接
得到了target名称后,使用下面命令建立连接
[root@RedHat5 ~]# iscsiadm -m node -T target名称 -p targetIP地址:端口号 --login
这时应该看到映射到的逻辑磁盘名号,使用fdisk -l 可以看到有关逻辑磁盘的详细内容,可以象使用本地硬盘一样对其进行分区、创建文件系统、挂载、卸载等操作。
断开连接
如果逻辑磁盘已经挂载,断开连接前应先卸载,然后使用下面命令
[root@RedHat5 ~]# iscsiadm -m node -T target名称 -p targetIP地址:端口号 --logout
关机之前应该正确的卸载和断开逻辑磁盘,否则会在target服务器上留下僵死的进程,造成服务器资源的浪费。

使用php隐藏下载文件的真实地址

  1. $fileURL=;   
  2.   
  3. $filename=;   
  4. $file = @ fopen($fileURL,"r");   
  5. if (!$file) {   
  6.     echo "文件找不到";   
  7. else {   
  8.     Header("Content-type: application/octet-stream");   
  9.     Header("Content-Disposition: attachment; filename=" . $filename);   
  10.     while (!feof ($file)) {   
  11.         echo fread($file,50000);   
  12.     }   
  13.     fclose (file);   
  14. }