2015.4.21流水日记
起得颇早,乘公交,8点半到公司。
9点开始准备,与jser联调的测试数据~
10点联调
12点去吃午饭,回来坐一会。
14点正式开工,自己调试。
调调歇歇,19点下班,乘公交回学校。
东门买些小吃,回到宿舍。
歇会,9点用室友电脑,玩了一把LOL。
快10点躺床休息下,逗比室友们玩起了成语接龙。
十多分钟后,产生的一个结论是:重庆的语文教育止于小学。hiahia
下床准备一下明天的《系统工程学》考试,没多久困得不行,躺床睡了~~~~
起得颇早,乘公交,8点半到公司。
9点开始准备,与jser联调的测试数据~
10点联调
12点去吃午饭,回来坐一会。
14点正式开工,自己调试。
调调歇歇,19点下班,乘公交回学校。
东门买些小吃,回到宿舍。
歇会,9点用室友电脑,玩了一把LOL。
快10点躺床休息下,逗比室友们玩起了成语接龙。
十多分钟后,产生的一个结论是:重庆的语文教育止于小学。hiahia
下床准备一下明天的《系统工程学》考试,没多久困得不行,躺床睡了~~~~
分页实现是网站应用最常用的功能,需要注意的是,要和网站的url模式相一致,且不丢失其他GET参数。再次就是要可以配置你的分页主题。这里我整理了一个分页类,调用非常简单,demo如下:
场景:写了一个微信精选的文摘,有分页功能,URL模式就是普通模式"?a=bc&page=2",若你的程序是PATHINTO模式的,实例化Page类时配置一下$urlmode=1就可以生成形如"./a/bc/page/2"的URL。分页类首要知道你的总数和每页的个数就可以了。话不多说,直接看代码加注释
应用代码摘取:
require './DMysqli.php';//数据库类
$dbconfig = array('hostname'=>SAE_MYSQL_HOST_M,'username'=>SAE_MYSQL_USER,'password'=>SAE_MYSQL_PASS,'database'=>SAE_MYSQL_DB,'hostport'=>SAE_MYSQL_PORT,'tablePrefix'=>'wx_');
$dmysqli = new DMysqli($dbconfig);
header('Content-type: text/html; charset=utf-8');
require 'Util/page.class.php';//引入Page分页类
$sql = 'select count(*) from wx_article';
$count = $dmysqli->query($sql);//总数
$totalRow = intval(current($count[0]));
$Page = new Page($totalRow,10);//实例化分页类:配置总数、每页个数
$sql = 'select * from wx_article ORDER BY posttime,id desc LIMIT $Page->firstRow'.','.'$Page->listRows';//取出当前页的数据,关键在sql语句的limit语法
$res = $dmysqli->query($sql);
/*
//分页语种自定义
$Page->setConfig('header','items');
$Page->setConfig('prev','Prev Page');
$Page->setConfig('next','Next Page');
$Page->setConfig('first','First Page');
$Page->setConfig('last','Last Page');
$Page->setConfig('theme',' %totalRow% %header% %nowPage%/%totalPage% Page %upPage% %downPage% %first% %prePage% %linkPage% %nextPage% %end%');
*/
$show = $Page->show();//分页类可以生成分页字符串,然后赋值给变量,在模版里输出就好了!
include('template/index.html');
Page类源码如下:
class Page {
// 分页栏每页显示的页数
public $rollPage = 4;
// 页数跳转时要带的参数
public $parameter;
// 当url模式为PATHINFO时,此配置项有效
public $depr = '/';
// 分页URL地址
public $url = '';
// 默认列表每页显示行数
public $listRows = 20;
// 起始行数
public $firstRow;
// 分页总页面数
protected $totalPages;
// 总行数
protected $totalRows;
// 当前页数
protected $nowPage;
// 分页的栏的总页数
protected $coolPages;
// 分页显示定制
protected $config = array (
'header' => '条',
'prev' => '上一页',
'next' => '下一页',
'first' => '第一页',
'last' => '最后一页',
'theme' => ' %totalRow% %header% %nowPage%/%totalPage% 页 %upPage% %downPage% %first% %prePage% %linkPage% %nextPage% %end%'
);
// 默认分页变量名
protected $varPage;
// url模式:0 普通模式 1 PATHINFO模式
protected $urlmode;
/**
* 架构函数
*
* @access public
* @param array $totalRows
* 总的记录数
* @param array $listRows
* 每页显示记录数
* @param array $parameter
* 分页跳转的参数
*
*/
public function __construct($totalRows, $listRows = '', $parameter = '', $url = '', $urlmode = 0) {
$this->totalRows = $totalRows;
$this->parameter = $parameter;
$this->varPage = 'page';
if (! empty ( $listRows )) {
$this->listRows = intval ( $listRows );
}
$this->totalPages = ceil ( $this->totalRows / $this->listRows ); // 总页数
$this->coolPages = ceil ( $this->totalPages / $this->rollPage );
$this->nowPage = ! empty ( $_GET [$this->varPage] ) ? intval ( $_GET [$this->varPage] ) : 1;
if (! empty ( $this->totalPages ) && $this->nowPage > $this->totalPages) {
$this->nowPage = $this->totalPages;
}
$this->firstRow = $this->listRows * ($this->nowPage - 1);
$this->urlmode = $urlmode;
}
public function setConfig($name, $value) {
if (isset ( $this->config [$name] )) {
$this->config [$name] = $value;
}
}
/**
* 分页显示输出
*
* @access public
*
*/
public function show() {
if (0 == $this->totalRows)
return '';
$p = $this->varPage;
$nowCoolPage = ceil ( $this->nowPage / $this->rollPage );
// 分析分页参数
if ($this->parameter && is_string ( $this->parameter )) {
parse_str ( $this->parameter, $parameter );
} elseif (empty ( $this->parameter )) {
// unset($_GET[C('VAR_URL_PARAMS')]);
if (empty ( $_GET )) {
$parameter = array ();
} else {
$parameter = $_GET;
}
}
$parameter [$p] = '__PAGE__';
if ($this->urlmode == 0) { // 普通模式URL转换
$url = "?" . http_build_query ( $parameter );
} else { // PATHINFO模式或者兼容URL模式
$url = ".$this->depr";
if (! empty ( $parameter )) { // 添加参数
foreach ( $parameter as $var => $val ) {
if ('' !== trim ( $val ))
$url .= $var . $this->depr . urlencode ( $val );
}
}
}
// 上下翻页字符串
$upRow = $this->nowPage - 1;
$downRow = $this->nowPage + 1;
if ($upRow > 0) {
$upPage = "<a href='" . str_replace ( '__PAGE__', $upRow, $url ) . "'>" . $this->config ['prev'] . "</a>";
} else {
$upPage = '';
}
if ($downRow <= $this->totalPages) {
$downPage = "<a href='" . str_replace ( '__PAGE__', $downRow, $url ) . "'>" . $this->config ['next'] . "</a>";
} else {
$downPage = '';
}
unset ( $upPage );
unset ( $downPage );
// << < > >>
if ($nowCoolPage == 1) {
$theFirst = '';
$prePage = '';
} else {
$preRow = $this->nowPage - $this->rollPage;
$prePage = "<a href='" . str_replace ( '__PAGE__', $preRow, $url ) . "' >上" . $this->rollPage . "页</a>";
$theFirst = "<a href='" . str_replace ( '__PAGE__', 1, $url ) . "' >" . $this->config ['first'] . "</a>";
}
if ($nowCoolPage == $this->coolPages) {
$nextPage = '';
$theEnd = '';
} else {
$nextRow = $this->nowPage + $this->rollPage;
$theEndRow = $this->totalPages;
$nextPage = "<a href='" . str_replace ( '__PAGE__', $nextRow, $url ) . "' >下" . $this->rollPage . "页</a>";
$theEnd = "<a href='" . str_replace ( '__PAGE__', $theEndRow, $url ) . "' >" . $this->config ['last'] . "</a>";
}
// 1 2 3 4 5
$linkPage = "";
for($i = 1; $i <= $this->rollPage; $i ++) {
$page = ($nowCoolPage - 1) * $this->rollPage + $i;
if ($page != $this->nowPage) {
if ($page <= $this->totalPages) {
$linkPage .= " <a href='" . str_replace ( '__PAGE__', $page, $url ) . "'> " . $page . " </a>";
} else {
break;
}
} else {
if ($this->totalPages != 1) {
$linkPage .= " <span class='current'>" . $page . "</span>";
}
}
}
$pageStr = str_replace ( array (
'%header%',
'%nowPage%',
'%totalRow%',
'%totalPage%',
'%upPage%',
'%downPage%',
'%first%',
'%prePage%',
'%linkPage%',
'%nextPage%',
'%end%'
), array (
$this->config ['header'],
$this->nowPage,
$this->totalRows,
$this->totalPages,
$upPage,
$downPage,
$theFirst,
$prePage,
$linkPage,
$nextPage,
$theEnd
), $this->config ['theme'] );
return $pageStr;
}
}
本文为实战操作过程的全程记录,采用一台新创建的linode vps(512M内存)环境,操作系统采用centos 6.2,以从源码编译的方式安装配置nginx, php(fast-cgi模式)web环境。
我们的目标:配置一台高性能、安全的web服务器。所需软件如下:
Nginx(英文) Nginx(简体中文) 公认的高性能web服务器[下载 http://nginx.org/en/download.html]
PHP 应用最广泛的web开发语言[下载 http://www.php.net/downloads.php]
MySQL 广泛应用于web服务器上的数据库,速度快[下载http://www.mysql.com/downloads/mysql/]
phpMyAdmin 使用php开发的基于web的MySQL管理工具 [下载http://www.phpmyadmin.net/home_page/downloads.php]
我的这台vps主机名为fsvps,有一个普通用户名为feng,通常我就使用这个用户登录管理,只有需要使用root身份时才su切换到管理员,只要不再需要使用root权限就退回到普通用户下。建议你也这样操作,以免误操作造成不可挽回的灾难。
通过ssh(windows下可以使用putty,建议去官方下载英文原版)登录服务器,确保已经安装过过如下的必要的软件(linux下软件编译环境)
我们先做最简单的,安装mysql. 因为我们不打算自己编译它,使用centos的yum安装就可以了。当然,如果你愿意,完全是可以的,参看这里
{从源码编译并安装mysql数据库[本文待写]}centos下,只需要一条命令就可以安装mysql服务器,执行
su,按提示输入root密码,切换到root身份,然后运行yum install mysql-server
[feng@fsvps ~]$ su [root@fsvps feng]# yum install mysql-server mysql-devel -y
yum安装了好几个包,其中
mysql-server-5.1.61-1.el6_2.1.i686.rpm才是我们平时说的mysql;
mysql-5.1.61-1.el6_2.1.i686.rpm是命令行界面的mysql客户端,我们可以用它在服务器上创建数据库,管理mysql用户等,但我们通常使用更好用的phpMyAdmin;
mysql-devel-5.1.61-1.el6_2.1.i686.rpm则是mysql客户端源码的开发头文件,接下来编译php时要用的,所以安装mysql这一步要先做。
yum还安装好几个依赖包,如
mysql-5.1.61-1.el6_2.1.i686.rpm,
openssl-1.0.0-20.el6_2.5.i686.rpm,
zlib-devel-1.2.3-27.el6.i686.rpm,
openssl-devel-1.0.0-20.el6_2.5.i686.rpm等几个在php编译也会用到。
注:这里的几个包,你在操作时,其版本号可能不完全一致,这是因为yum源里的包会不定期升级,但不影响我们接下来的编译过程。
我们启动mysql服务,mysqld将完成初始化操作。运行
/etc/init.d/mysqld start如下
[root@fsvps feng]# /etc/init.d/mysqld start ..... /usr/bin/mysqladmin -u root password 'new-password' /usr/bin/mysqladmin -u root -h fsvps password 'new-password' ..... [确定] 正在启动 mysqld: [确定]
注意消息里有如上斜体显示的部分。这时候,你的mysql的root用户还是空密码的,这非常不安全的,斜体行就是修改root密码的命令。假设我要把mysql 的 root密码修改成
Path8.net,执行命令如下:
[root@fsvps feng]# /usr/bin/mysqladmin -u root password 'Path8.net'[tips] 注意,mysql的root用户与linux系统的root用户是没有任何关系的,mysql 的root用户只用于登录mysql服务器。最好给他们设置成不同的密码,这样会安全一点。
试着登录一下,确认root密码已修改成功:
[root@fsvps feng]# mysql -uroot -pPath8.net Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 3 Server version: 5.1.61 Source distribution Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>
你没看错,
mysql -uroot -pPath8.net这行命令里, -u 与 -p 后面不必要加空格
如果你看到上面最后一行的
mysql>提示符,说明已经成功登录。输入执行
show variables;感受一下mysql
mysql> show variables; +-----------------------------------------+------------------+ | Variable_name | Value | +-----------------------------------------+------------------+ | auto_increment_increment | 1 | | auto_increment_offset | 1 | | autocommit | ON | .......(下略)
列出了很多变量,我们优化MySQL,主要是就是靠修改这些参数实现的。
输入exit ,退出mysql客户端。mysql安装配置至此结束,这一步简单吧!
接下来编译Nginx,稍微复杂一点,照着做,肯定可以很顺利完成。
[强烈建议]如果你还在使用root用户,建议你执行exit退出root身份,使用普通用户的身份继续操作。
进入该普通用户的家目录,建两个目录 source 与 build ,分别用于存储下载的源代码及作为编译的工作目录。当然放到其它目录下也可以,名字也可以任意取,只要方便使用管理。
[root@fsvps feng]# mkdir source build
你没看错,一条命令就建了这两个目录。进入build目录
[root@fsvps feng]# cd build/
因为nginx需要安装一个叫PCRE的软件,在centos上可能找不到。笔者的经验是,就算你通过yum 安装了这个包,nginx也不认。 编译nginx事实上需要的依赖包是pcre-devel,可以执行yum install pcre-devel 安装它。不过这个包的编译安装很简单,正好我们拿它练练手,熟悉熟悉linux编译安装软件的一般过程。
在build目录下创建子目录pcre
[feng@fsvps build]$ mkdir pcre [feng@fsvps build]$ cd pcre
使用wget 工具从pcre官方下载 pcre 包,下载链接为 ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.21.zip,将它解压缩到pcre目录下
[feng@fsvps build]$ wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.21.zip
几秒钟就可以下载完成。(如果提示 bash: wget: command not found 那是你还没有安装wget,切换到root用户,
yum install wget -y安装之)
[feng@fsvps pcre]$ ls pcre-8.21.zip
看一下,刚下载的 pcre源码包,这是个zip包,使用unzip命令解压缩之
[feng@fsvps pcre]$ unzip pcre-8.21.zip [feng@fsvps pcre]$ ll 总用量 1680 drwxr-xr-x 6 feng feng 4096 12月 12 2011 pcre-8.21 -rw-rw-r-- 1 feng feng 1709377 6月 30 13:50 pcre-8.21.zip [feng@fsvps pcre]$ cd pcre-8.21
进去看看里面都是些什么文件,特别注意一下
configure文件
[feng@fsvps pcre-8.21]$ ll 总用量 3716 -rwxr-xr-x 1 feng feng 6961 10月 5 2009 132html -rw-r--r-- 1 feng feng 338277 12月 11 2011 aclocal.m4 ........ (略) -rwxr-xr-x 1 feng feng 595700 12月 11 2011 configure ........ (略) -rw-r--r-- 1 feng feng 3460 8月 2 2011 ucp.h
这个
configure文件,就是“源码安装三步曲”的第一步的configure,它将检查你的系统是否具备了编译pcre必要的软件包,配置出用于编译pcre的环境,供第二步用。如果缺少某些软件,它会给出提示。
[tips] 另外,注意这个目录里还有几个文件README, INSALL,LICENCE,它们都是普通的文本文件,供使用人阅读,分别是 自述文件,安装说明,授权协议。通常linux/unix世界的源码包里都有这几个文件(有时作者会把INSTALL并成到README里),建议阅读一下,尤其是README与INSTALL。执行第一步
configure[feng@fsvps pcre-8.21]$ ./configure
注意
configure命令前面要带上 ./ ,因为我们要执行的是在当前目录下的configure文件,。
configure过程中可能出现的几个报错,及原因:
yum install gcc gcc-c++ autoconf make
[root@fsvps nginx-1.2.1]# chown -R feng:feng ./ [root@fsvps nginx-1.2.1]# exit
开始编译,这步非常简单,运行
make就可以,可能要花费几分钟时间,你可以干点其它,比如起身活动一下。
[feng@fsvps pcre-8.21]$ make
完了如果看到下面的消息:
make[1]: Leaving directory `/home/feng/build/pcre/pcre-8.21'说明编译完成了,那么开始安装。安装很简单,使用root用户权限,运行
make install就可以了。所以su,按提示输入root密码,切换到root身份
[feng@fsvps pcre-8.21]$ su
[feng@fsvps pcre-8.21]# make install
完了消息应该是
make[1]: Leaving directory `/home/feng/build/pcre/pcre-8.21'这样pcre就安装好了。然后exit退回到普通用户状态下。
接下来才是真正安装nginx,过程差不多,但我们要多配置几个参数选项。
到 nginx官网上 http://nginx.org/en/download.html 找最新的稳定版的下载链接,写本文时2012-06-30 最新版本为
nginx-1.2.1下载链接为
http://nginx.org/download/nginx-1.2.1.tar.gz使用wget 将其下载到vps上。
[root@fsvps build]$ wget http://nginx.org/download/nginx-1.2.1.tar.gz
几秒钟就可以下载完成。(如果提示 bash: wget: command not found 那是你还没有安装wget,切换到root用户,
yum install wget -y安装之)
解压缩,然后把压缩包移动到source目录,以备不时之需。
[root@fsvps build]$ ll 总用量 708 -rw-r--r-- 1 root root 718161 6月 5 14:10 nginx-1.2.1.tar.gz [root@fsvps build]$ tar xf nginx-1.2.1.tar.gz [root@fsvps build]$ ll 总用量 712 drwxr-xr-x 8 1001 1001 4096 6月 5 14:02 nginx-1.2.1 -rw-r--r-- 1 root root 718161 6月 5 14:10 nginx-1.2.1.tar.gz [root@fsvps build]$ mv nginx-1.2.1.tar.gz ../source/[tips] 文件名很长,打字太累? 试试tab键,比如先打出 mv ngi 然后按tab 键一次,没反应,再按一次,看有什么变化;然后继续打一个句点,再按一次tab键。相信你已经能悟出点什么了。
进入nginx源码目录,浏览一下里面的文件
[root@fsvps build]$ cd nginx-1.2.1/ [root@fsvps nginx-1.2.1]$ ll 总用量 560 drwxr-xr-x 6 1001 1001 4096 6月 30 11:39 auto -rw-r--r-- 1 1001 1001 207988 6月 5 14:02 CHANGES -rw-r--r-- 1 1001 1001 317085 6月 5 14:02 CHANGES.ru drwxr-xr-x 2 1001 1001 4096 6月 30 11:39 conf -rwxr-xr-x 1 1001 1001 2345 1月 18 15:07 configure drwxr-xr-x 3 1001 1001 4096 6月 30 11:39 contrib drwxr-xr-x 2 1001 1001 4096 6月 30 11:39 html -rw-r--r-- 1 1001 1001 1365 1月 18 15:07 LICENSE drwxr-xr-x 2 1001 1001 4096 6月 30 11:39 man -rw-r--r-- 1 1001 1001 49 10月 31 2011 README drwxr-xr-x 8 1001 1001 4096 6月 30 11:39 src
运行
configure,就是本目录下的该文件,上面标红加;目录是配置nginx的编译环境,运行如下命令,参数比较长,可以直接复制帖。
[root@fsvps nginx-1.2.1]$ ./configure --prefix=/usr/local/nginx --sbin-path=/usr/local/sbin/nginx --conf-path=/usr/local/conf/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --with-http_stub_status_module --with-http_gzip_static_module --with-http_sub_module --with-http_flv_module --with-http_mp4_module --with-http_random_index_module --with-cpu-opt=pentium4注意
configure命令要带上./ ,上面已经标红显示。大致讲一下是什么意思 [注]如果你仅仅想编译一个web环境用,而不想学习编译linux程序的一般方法,这部分那可以跳过不用看。
把参数重排下版,一行一个参数,简单注释一下
--prefix=/usr/local/nginx #编译后安装到目录 /usr/local/nginx --sbin-path=/usr/local/sbin/nginx # --conf-path=/usr/local/conf/nginx/nginx.conf #主配置文件路径 --error-log-path=/var/log/nginx/error.log #错误日志目录 --pid-path=/var/run/nginx.pid #nginx程序启用后,自动将其进程号写到该文件 --lock-path=/var/run/nginx.lock #lock文件路径 --with-http_stub_status_module #通过web查看nginx运行状态 --with-http_gzip_static_module #gzip压缩支持 --with-http_sub_module #加入ngx_http_sub_module模块 --with-http_flv_module #加入flv模块 --with-http_mp4_module #mp4模块 --with-http_random_index_module #http_random_index_module模块 --with-cpu-opt=pentium4 #针对intel cpu优化
--with-xxxx_module的那些模块,如果你确定不需要,那就可以不要加入。那就这样指定参数
./configure --prefix=/usr/local/nginx --sbin-path=/usr/local/sbin/nginx --conf-path=/usr/local/conf/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --with-http_stub_status_module --with-http_gzip_static_module只带两个比较有用的模块。事实上这些参数一个都不指定,也是可以,这样就是按nginx的默认配置编译了。如果你想查看ngix的configure都有哪些参数选项可以运行
./configure --help查看,这里不多讲了。
如果报错:./configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source with nginx by using --with-pcre=<path> option.
这是因为没有找到PCRE包,请检查是否正确安装了PCRE包:
不出意外,应该能看到这样报告消息:
Configuration summary + using system PCRE library + OpenSSL library is not used + md5: using system crypto library + sha1: using system crypto library + using system zlib library nginx path prefix: "/usr/local/nginx" nginx binary file: "/usr/local/sbin/nginx" nginx configuration prefix: "/usr/local/conf/nginx" nginx configuration file: "/usr/local/conf/nginx/nginx.conf" nginx pid file: "/var/run/nginx.pid" nginx error log file: "/var/log/nginx/error.log" nginx http access log file: "/usr/local/nginx/logs/access.log" nginx http client request body temporary files: "client_body_temp" nginx http proxy temporary files: "proxy_temp" nginx http fastcgi temporary files: "fastcgi_temp" nginx http uwsgi temporary files: "uwsgi_temp" nginx http scgi temporary files: "scgi_temp"
有些软件的configure完成后会给出类似的一个配置报告,供我们检查配置选项是否正确。如果有不正确处,或还想改改,那就再运行一次configure --xx --yyy.
确认无误,开始编译
[feng@fsvps nginx-1.2.1]$ make
开始编译,非常快,可能一分钟就编译完成,最后消息大致如:
make[1]: Leaving directory `/home/feng/build/nginx-1.2.1'接下来,你应该知道了,切换到
root身份,
make install安装。
下面的操作要在root身份下操作。
我们测试一下nginx是否正常工作。因为我们把nginx的二进制执行文件配置安装在 /usr/local/sbin/nginx (前面的configure参数 --sbin-path=/usr/local/sbin/nginx ),目录/usr/local/sbin/默认在linux的PATH环境变量里,所以我们可以省略路径执行它:
[root@fsvps nginx-1.2.1]# nginx
它不会有任何信息显示。打开浏览器,通过IP地址访问你的nginx站点,如果看到这样一行大黑字,就证明nginx已经工作了:
Welcome to nginx!
看上去很简陋,只是因为没有给它做漂亮的页面。我们来简单配置一下它的运行配置。我们configure的参数
--conf-path=/usr/local/conf/nginx/nginx.conf这就是它的配置文件。我们去看看。
[root@fsvps nginx-1.2.1]# cd /usr/local/conf/nginx/ [root@fsvps nginx]# ls fastcgi.conf fastcgi_params.default mime.types nginx.conf.default uwsgi_params fastcgi.conf.default koi-utf mime.types.default scgi_params uwsgi_params.default fastcgi_params koi-win nginx.conf scgi_params.default win-utf
如果这里没有
nginx.conf,但有个
nginx.conf.default,我们用它复制个副本
nginx.conf(早期版本默认是没有nginx.conf的)
用你熟悉的编辑器打开它,推荐使用vim;如果不会用,那可以使用nano, 功能简单,但一看就会用:
nano nginx.conf找到如下的部分,大概在35行,
server { listen 80default; server_name localhost; root /var/www/html/default; #charset koi8-r; #access_log logs/host.access.log main; location / { # root html; index index.html index.htm; } ................ }
如上红色加粗显示部分,做三处修改:
上面的server{....}是定义的一台虚拟主机,我们刚加入的一行是定义这个虚假主机的web目录。listen 行的default是表示这一个server{...}节点是默认的虚假主机(默认站点)
执行
nginx -t测试刚才的nginx配置文件是否有语法错误:
[root@fsvps nginx]# nginx -t nginx: the configuration file /usr/local/conf/nginx/nginx.conf syntax is ok nginx: configuration file /usr/local/conf/nginx/nginx.conf test is successful
显示没有错误,检测通过。如果不是这样,请返回仔细检查你的配置文件是否哪里写错了,注意行尾要有英文分号。
我们在硬盘上创建这个目录:
[root@fsvps nginx]# mkdir -p /var/www/html/default
写一个html文件
index.html到
/var/www/html/default目录里,使用你熟悉的编辑器,随便写什么内容、怎么排版。
然后让nginx重新加载配置文件,看看刚才创作的html页面效果如何。
1) 如果通常访问时看到还是
Welcome to nginx!,请返回检查,重点在这几处:
2) 如果看到的是
404 Not Found或者“找不到该页面”类似的提示:
3) 如果访问时,显示“找不到服务器”、“无法连接到服务器”这样的错误:
location / {...} 节点里的
# root html;一行,不注释掉也可以:请把你创造的index.html 放到
/var/www/html/default/html目录下。
至此,我们的nginx也可以正常工作了。是否在纳闷“nginx怎么这么简陋?只能显示几个干巴巴的页面”,这是因为我们还没有给它装备PHP这个核动力引擎。
建议你稍微休息一下,然后进入下一步的“php安装”,要做好持久战的准备,它比前面所有要花费时间都长。
php官方提供了很多版本,我们照例使用最新稳定版,http://www.php.net/downloads.php
本文写作时[2012-07-01],php最新版本有两个分支,分别是是PHP 5.4.4 (Current stable) 与 PHP 5.3.14 (Old stable),据说php 5.4分支的改动,会不支持比较旧的php程序,所以我们选择php 5.3分支(当前为php-5.3.14)。虽然仍会有极少数非常古老的程序,必须在更旧版下才能运行,但我们这里不迁就它们了,因为我们要使用fast-cgi,而5.2版本本身不带FPM (fast-cgi process manager),要打fpm补丁,会麻烦一些。如有兴趣,可参阅张宴的 Nginx 0.8.x + PHP 5.2.13(FastCGI)搭建胜过Apache十倍的Web服务器(第6版) http://blog.s135.com/nginx_php_v6/
从php官方下载页面上http://www.php.net/downloads.php 点所选的版本,选择距离最近的下载镜像。如果是美国vps,就选个美国的镜像,这样更快。我选择yahoo! inc.镜像,应该全球访问速度都比较快(php.net官方似乎就是yahoo! inc.镜像)。复制所选下载地址,通过wget下载到build/php目录下,并解压缩,然后把原始压缩包移动到source目录存档。
[root@fsvps php]$ wget http://cn.php.net/get/php-5.3.14.tar.bz2/from/www.php.net/mirror [root@fsvps php]$ ll 总用量 11160 -rw-r--r-- 1 root root 11408016 6月 14 16:10 php-5.3.14.tar.bz2 [root@fsvps php]$ tar xf php-5.3.14.tar.bz2 [root@fsvps php]$ mv php-5.3.14.tar.bz2 ../../source [root@fsvps php]$ cd php-5.3.14/
进入php源码目录,浏览一下,里面文件相当多,注意里面也有configure, README等文件,还有其它的几个大写文件名的文件,有兴趣参阅一下。
[root@fsvps php-5.3.14]$ ll 总用量 4796 -rw-r--r-- 1 101 101 3460 6月 13 08:20 acconfig.h -rw-r--r-- 1 101 101 28 6月 13 08:18 acconfig.h.in -rw-r--r-- 1 101 101 76103 6月 13 08:18 acinclude.m4 -rw-r--r-- 1 101 101 306427 6月 13 08:20 aclocal.m4 drwxr-xr-x 2 101 101 4096 6月 13 08:18 build -rwxr-xr-x 1 101 101 668 6月 13 08:18 buildconf -rw-r--r-- 1 101 101 334 6月 13 08:18 buildconf.bat -rw-r--r-- 1 101 101 11166 6月 13 08:18 CODING_STANDARDS -rw-r--r-- 1 101 101 44892 6月 13 08:18 config.guess -rw-r--r-- 1 101 101 33387 6月 13 08:18 config.sub -rwxr-xr-x 1 101 101 3044114 6月 13 08:20 configure -rw-r--r-- 1 101 101 45450 6月 13 08:18 configure.in -rw-r--r-- 1 101 101 91 6月 13 08:18 CREDITS drwxr-xr-x 79 101 101 4096 6月 13 08:18 ext -rw-r--r-- 1 101 101 24801 6月 13 08:18 EXTENSIONS -rw-r--r-- 1 101 101 137 6月 13 08:18 footer -rw-r--r-- 1 101 101 2233 6月 13 08:20 generated_lists -rwxr-xr-x 1 101 101 486 6月 13 08:18 genfiles -rw-r--r-- 1 101 101 1143 6月 13 08:18 header -rw-r--r-- 1 101 101 93778 6月 13 08:18 INSTALL -rw-r--r-- 1 101 101 0 6月 13 08:20 install-sh -rw-r--r-- 1 101 101 3218 6月 13 08:18 LICENSE -rw-r--r-- 1 101 101 199728 6月 13 08:18 ltmain.sh drwxr-xr-x 3 101 101 4096 6月 13 08:20 main -rwxr-xr-x 1 101 101 3023 6月 13 08:18 makedist -rw-r--r-- 1 101 101 1073 6月 13 08:18 Makefile.frag -rw-r--r-- 1 101 101 2263 6月 13 08:18 Makefile.gcov -rw-r--r-- 1 101 101 5498 6月 13 08:18 Makefile.global -rw-r--r-- 1 101 101 5317 6月 13 08:18 makerpm -rw-r--r-- 1 101 101 0 6月 13 08:20 missing -rw-r--r-- 1 101 101 0 6月 13 08:20 mkinstalldirs drwxr-xr-x 2 101 101 4096 6月 13 08:18 netware -rw-r--r-- 1 101 101 347865 6月 13 08:18 NEWS drwxr-xr-x 2 101 101 4096 6月 13 08:20 pear -rw-r--r-- 1 101 101 1489 6月 13 08:18 php5.spec.in -rw-r--r-- 1 101 101 2523 6月 13 08:18 php.gif -rw-r--r-- 1 101 101 69609 6月 13 08:18 php.ini-development -rw-r--r-- 1 101 101 69631 6月 13 08:18 php.ini-production -rw-r--r-- 1 101 101 1570 6月 13 08:18 README.EXTENSIONS -rw-r--r-- 1 101 101 6249 6月 13 08:18 README.EXT_SKEL -rw-r--r-- 1 101 101 4618 6月 13 08:18 README.GIT-RULES -rw-r--r-- 1 101 101 5954 6月 13 08:18 README.input_filter -rw-r--r-- 1 101 101 3426 6月 13 08:18 README.MAILINGLIST_RULES -rwxr-xr-x 1 101 101 6040 6月 13 08:18 README.namespaces -rw-r--r-- 1 101 101 6848 6月 13 08:18 README.PARAMETER_PARSING_API -rw-r--r-- 1 101 101 4740 6月 13 08:18 README.PHP4-TO-PHP5-THIN-CHANGES -rw-r--r-- 1 101 101 20918 6月 13 08:18 README.REDIST.BINS -rw-r--r-- 1 101 101 11244 6月 13 08:18 README.RELEASE_PROCESS -rw-r--r-- 1 101 101 4698 6月 13 08:18 README.SELF-CONTAINED-EXTENSIONS -rw-r--r-- 1 101 101 15373 6月 13 08:18 README.STREAMS -rw-r--r-- 1 101 101 7605 6月 13 08:18 README.SUBMITTING_PATCH -rw-r--r-- 1 101 101 6677 6月 13 08:18 README.TESTING -rw-r--r-- 1 101 101 4957 6月 13 08:18 README.TESTING2 -rw-r--r-- 1 101 101 4261 6月 13 08:18 README.UNIX-BUILD-SYSTEM -rw-r--r-- 1 101 101 109 6月 13 08:18 README.WIN32-BUILD-SYSTEM -rwxr-xr-x 1 101 101 78241 6月 13 08:18 run-tests.php drwxr-xr-x 24 101 101 4096 6月 13 08:18 sapi drwxr-xr-x 5 101 101 4096 6月 13 08:18 scripts -rwxr-xr-x 1 101 101 2105 6月 13 08:18 server-tests-config.php -rwxr-xr-x 1 101 101 51718 6月 13 08:18 server-tests.php -rwxr-xr-x 1 101 101 108 6月 13 08:18 snapshot -rw-r--r-- 1 101 101 10 6月 13 08:18 stamp-h.in -rw-r--r-- 1 101 101 1 6月 13 08:18 stub.c -rwxr-xr-x 1 101 101 50 6月 13 08:18 svnclean.bat drwxr-xr-x 10 101 101 4096 6月 13 08:18 tests -rw-r--r-- 1 101 101 5109 6月 13 08:18 TODO -rw-r--r-- 1 101 101 163 6月 13 08:18 TODO-5.1 -rw-r--r-- 1 101 101 3746 6月 13 08:18 TODO-PHP5 drwxr-xr-x 2 101 101 4096 6月 13 08:18 TSRM -rwxr-xr-x 1 101 101 23267 6月 13 08:18 UPGRADING -rw-r--r-- 1 101 101 737 6月 13 08:18 UPGRADING.INTERNALS -rwxr-xr-x 1 101 101 297 6月 13 08:18 vcsclean drwxr-xr-x 3 101 101 4096 6月 13 08:18 win32 drwxr-xr-x 4 101 101 4096 6月 13 08:20 Zend
查看configure参数选项,
[root@fsvps php-5.3.14]$ ./configure --help
参数非常多,因为php功能实在太强大了。你熟悉php的话,就知道它有上百个模块,我们常用大概有几十个。通常离不开的模块,是默认被配置进去的,不需要我们通过configure指定,我们在configure步骤主要做两件事:
如果没有特殊需求,建议你按下面的选项来配置(为方便阅读,拆成多行了)
./configure --prefix=/usr/local/php53 --with-config-file-path=/usr/local/etc --with-config-file-scan-dir=/usr/local/etc/php.d --mandir=/usr/local/man --enable-fpm --enable-calendar --with-mcrypt --enable-ftp --with-zlib --with-bz2 --with-curl --with-gd --enable-exif --with-jpeg-dir --with-png-dir --with-freetype-dir --enable-mbstring --with-mysql --with-mysqli --with-pdo-mysql --enable-zip --enable-bcmath --with-bz2
注意其中的
--enable-fpm就是指定我们要启用php的fpm功能,一定要不能省的。
先不要急着运行./configure,现在运行几乎一定要报错:
configure: error: xxx not found. Please check your xxx installation.原因你应该想到了,我们的centos中缺少依赖包。
我们回过头来解决依赖包问题。我们的系统上缺少哪些包呢?按我在上面的configure 选项,下面几行命令中的包即是:
[root@fsvps feng]# yum -y install libxml2-devel [root@fsvps feng]# yum -y install bzip2-devel [root@fsvps feng]# yum -y install libcurl-devel [root@fsvps feng]# yum -y install libjpeg-devel libpng-devel
这个依赖列表是怎么知道的呢?运行configure,看提示什么错误,就安装相应包,记录下来这些包名就知道了。或者检查configure文档或源码,也是可以的,不过这个工作量更庞大。
另外mcrype包centos源里没有的,要我们手工编译安装,步骤如下:
cd build/ mkdir mcrypt cd mcrypt wget http://nchc.dl.sourceforge.net/project/mcrypt/Libmcrypt/2.5.8/libmcrypt-2.5.8.tar.bz2 tar xf libmcrypt-2.5.8.tar.bz2 cd libmcrypt-2.5.8 ./configure make make install
其中 sourceforge.net 上的地址,如果不能下载,请点此从本站(path8.net)下载:libmcrypt-2.5.8.tar.bz2.zip [注]本文件是再次zip压缩的,使用时需先unzip 再tar x]
或者你可以到http://mcrypt.sourceforge.net/下载,但要注意,我们需要的是
libmcrypt而不是
mcrypt,这里很容易搞错。
现在应该对configure很熟悉了吧,用普通用户执行
[feng@fsvps php-5.3.14]$ ./configure --prefix=/usr/local/php53 --with-config-file-path=/usr/local/etc --with-config-file-scan-dir=/usr/local/etc/php.d --mandir=/usr/local/man --enable-fpm --enable-calendar --with-mcrypt --enable-ftp --with-zlib --with-bz2 --with-curl --with-gd --enable-exif --with-jpeg-dir --with-png-dir --with-freetype-dir --enable-mbstring --with-mysql --with-mysqli --with-pdo-mysql --enable-zip --enable-bcmath --with-bz2这一步要花几分钟时间,不出意外将出现如下消息:
+--------------------------------------------------------------------+ | License: | | This software is subject to the PHP License, available in this | | distribution in the file LICENSE. By continuing this installation | | process, you are bound by the terms of this license agreement. | | If you do not agree with the terms of this license, you must abort | | the installation process at this point. | +--------------------------------------------------------------------+ Thank you for using PHP.
按下来,make,这一步更慢,可能要二十分钟,耐心等,或者做点其它事情。
看到如下消息,就是完成了。
Build complete. Don't forget to run 'make test'.
可以执行一下make test 检测一下,不过一般没有必要,切换到root身份运行make install安装。
[feng@fsvps php-5.3.14]$ su 密码: [root@fsvps php-5.3.14]# make install Installing PHP SAPI module: fpm Installing PHP CLI binary: /usr/local/php53/bin/ Installing PHP CLI man page: /usr/local/man/man1/ Installing PHP FPM binary: /usr/local/php53/sbin/ Installing PHP FPM config: /usr/local/php53/etc/ Installing PHP FPM man page: /usr/local/man/man8/ Installing PHP FPM status page: /usr/local/php53/share/php/fpm/ Installing build environment: /usr/local/php53/lib/php/build/ Installing header files: /usr/local/php53/include/php/ Installing helper programs: /usr/local/php53/bin/ program: phpize program: php-config Installing man pages: /usr/local/man/man1/ page: phpize.1 page: php-config.1 Installing PEAR environment: /usr/local/php53/lib/php/ [PEAR] Archive_Tar - installed: 1.3.7 [PEAR] Console_Getopt - installed: 1.3.0 [PEAR] Structures_Graph- installed: 1.0.4 [PEAR] XML_Util - installed: 1.2.1 [PEAR] PEAR - installed: 1.9.4 Wrote PEAR system config file at: /usr/local/php53/etc/pear.conf You may want to add: /usr/local/php53/lib/php to your php.ini include_path /home/feng/build/php/php-5.3.14/build/shtool install -c ext/phar/phar.phar /usr/local/php53/bin ln -s -f /usr/local/php53/bin/phar.phar /usr/local/php53/bin/phar Installing PDO headers: /usr/local/php53/include/php/ext/pdo/
最好记下来这里的消息,它是php的几个重要配置文件的默认路径,下面用得着。
php-fpm的配置文件位于
/usr/local/php53/etc/,这里有个php-fpm.conf.default,用它复制出php-fpm.conf
[root@fsvps php-5.3.14]# ls -l /usr/local/php53/etc/ 总用量 28 -rw-r--r-- 1 root root 1172 7月 1 07:20 pear.conf -rw-r--r-- 1 root root 20891 7月 1 07:20 php-fpm.conf.default [root@fsvps php-5.3.14]# cp /usr/local/php53/etc/php-fpm.conf{.default,}
修改php-fpm.conf如下几处:
(约第25行) pid = /var/run/php-fpm.pid
(约第32行) error_log = /var/log/php-fpm.log
(约第190行) pm = static
启动php-fpm进程
[root@fsvps php-5.3.14]# /usr/local/php53/sbin/php-fpm
执行后,没有任何输出。如果有错误请查看php-fpm的日志文件
/var/log/php-fpm.log
执行
ps aux|grep php将显示有6个
php-fpm进程,其中一个是root用户,另外5个是nobody用户。
直到现在,我们的nginx还是只能处理静态文件,我们接下来要做的是:让nginx把对.php文件的请求,转给php-fpm来处理。
打开nginx配置文件,在server{...}节点里面,有这样一行
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 ,下面的 location ...{...}节点取消注释,改成如下形式(修改部分使用红字加粗):
location ~ \.php$ { root html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /var/www/html/default$fastcgi_script_name; include fastcgi_params; }
保存,检查配置
nginx -t,无误后重新加载nginx配置
nginx -s reload写一个php程序文件 /var/www/html/default/phpinfo.php 内容为
<?php phpinfo(); ?>
用浏览器通过ip地址访问
phpinfo.php,看到你亲自编译的nginx+php-fpm在工作了吧。
先别太高兴,事实还没有完。
有些读者已经已经发现,phpinfo页面里显示没有加载
php.ini文件,是的,我们还没有把php.ini文件放到配置路径里。在php编译目录里,有两个,因为是生产环境,我们使用./php.ini-production
[root@fsvps php-5.3.14]# cp php.ini-production /usr/local/etc/php.ini
如果需要的话,请对php.ini作相应修改配置。发进程信号给php-fpm重新加载配置
kill -SIGUSR2 `cat /var/run/php-fpm.pid`
或者
ps aux |grep php-fpm查出来
php-fpm主进程号,然后
kill -SIGUSR2 进程号php-fpm.conf
(约第200行) pm.max_children = 5
(约第226行) pm.max_requests = 100
(约第325行) pm.status_path = /status.php
这是php-fpm启动后的php-fpm子进程数,512M内存以下,推荐设置在5左右。设为5,也说是说,最多接受5个并发的php请求。
pm.max_requests 是一个php-fpm子进程最多处理多少次请求后被关闭回收,小内存的主机,推荐设置小一点(100或者更小),避免处理一个占用内存大的请求后、进程没被回收而长时间占用内存。但是也不要设置得太小,否则频繁的创建php-fpm子进程,从而影响效率。
pm.status_path 是用于查看当前php-fpm的状态。修改保存后,重新加载php-fpm配置,使用浏览器打开 http://you-host-address/status.php ,可以看到一组php-fpm的状态数据,可以用来检查通常php-fpm并发进程数有多大,以及其它一些有用数据。
nginx配置文件 /usr/local/conf/nginx/nginx.conf
worker_processes 1; #nginx子进程数,512M内存以下推荐设置为1就够了,nginx并发能力很强 keepalive_timeout 25; #连接保持的超时秒数 gzip on; #启用静态内容http请求的gzip压缩
你的站点里,如果有文件上传目录、图片目录等,那我们就不要允许这里的php文件请求传递给php-fpm,或直接拒绝访问。可以将下面一段代码加入到
location ~ \.php$ {....}节点前面,nginx发现这种请求,就直接deny,而不再传给php-fpm了
location ~ ^/(uploads|images)/.*\.php { deny all; }
如果你需要在nginx上绑定多个域名,就把server{...} 节点复制一份,修改里面server_name(域名)参数、root参数(站点目录)
server { server_name www.path8.net; root /var/chroot/home/pcobbs/www; ...... }
把多个域名绑定到同一目录上,就用空格分隔跟在后面,如
server_name host1a.path8.net host2.path8.net;Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器。
想要Linux下安装Nginx作为WEB服务器,要先准备些必要的库和工具,通常必须安装的是:PERC库和Openssl。
分四步走,让你的Nginx迅速跑起来!
1. 安装PCRE库(Nginx的rewrite模块和HTTP核心模块会用到PCRE正则表达式语法)
不用考虑是否已安装,直接上命令:
使用yum来安装:
[root@example.com ~]# yum install pcre pcre-devel
或者用apt-get:
[root@example.com ~]# apt-get install libpcre3 libpcre3-dev
如果这些安装包已经安装在系统上,你会收到Nothing to do 的信息,就是已安装过了的意思。
2.安装OpenSSL(若服务器提供安全网页(https://)时,会用到OpenSSL库)
使用yum:
[root@localhost example]# yum install openssl openssl-devel
或者用apt-get:
[root@localhost example]# apt-get install openssl openssl-dev
3.下载、解压Nginx
去http://nginx.org/下载你要使用的版本,放到home目录,然后解压
[root@localhost example]# tar zxf nginx-0.7.66.tar.gz
4.安装Nginx
创建一个应用程序通常分为三步:从源代码到配置、编译和安装编译。每一步都有很多配置项,但对于初学者,我们只是让它能跑起来,可以先忽略这些配置项。最容易的办法依次执行下面三个命令:
[root@localhost nginx-0.7.66]# ./configure //有一个重要的配置项是 --prefix=...指定安装Nginx的基础目录,比如你想把它安装在 /home/jiang/www/下,这个完整的命令应该是:[root@localhost nginx-0.7.66]# ./configure --prefix=/home/jiang/www
configure过程中可能出现的几个报错,及原因:
yum install gcc gcc-c++ autoconf make
[jiang@localhost nginx-0.7.66]# chown -R jiang:jiang ./ [jiang@localhost nginx-0.7.66]# exit然后exit退出到普通用户状态下。 chown 后的 feng:feng 分别是所使用的普通账号的用户名,及其用户组名。
[root@localhost nginx-0.7.66]# make
[root@localhost nginx-0.7.66]# make install
至此安装成功,去安装Nginx的基础目录下的sbin/,注意,我这里的目录是/home/jiang/www/sbin,执行命令:
[root@localhost sbin]# ./nginx //效果见下图
屏幕上不会出现任何文本信息,这是个好迹象,意味着正在正确运行。
打开浏览器,输入localhost,done done done done ~~~
昨夜睡前,照旧网络阅读,移动互联网真谛、3W深度分析等人云亦云的文章。随即想到自己的职业生涯,扪心自问我想要的是什么。结合我现在在做的、和关于以后想做什么的想法,又想到了 偶像雷军。武大计算机专业,两年修完大学四年的功课,毕业做软件失利,92年入职金山,风雨16载,直至IPO。后急流勇退,转做天使投资,后因发烧,而生小米。
一步步走来,从雷军的成功,似乎给了很多程序人希望、路子。从大学毕业到作为CEO完成金山在香港上市的16年,是他从优秀程序员到高层管理者的蜕变。急流勇退是他打拼、历练多年,事业有所成后,给自己的一个调整。再到小米手机的孕育,是他对手机产品的热爱。
回头一看,雷军的每一步,似乎都成为了下一步成功的基石。但我敢肯定,这每一步绝不是为了下一步,他刚大学毕业时,并没有想要成为CEO,而是想成为一名知名的程序员。再到后来的CEO 、天使投资、小米手机等等,都是在身处环境下,听自己的心声,做他最爱做的事情,并全力以赴。这是成功的原因。
对于技术的崇拜,我选择了程序员这个职位,然而岂止于此,梦想就不再说。所以作为初级程序员的自己,我想我能从他身上学到的,不是他职业生涯的路子,而是他做每一件事时的原因、专注、追求极致。首先是做事的原因,这时想到一句话“为了将事情做好,首先你得喜欢做这件事,而不是喜欢这件事的结果,那仅仅是第二位”,能找到自己热爱的事情,这是比较幸运的。然后是做事的的态度,一定要专注、追求极致,严格要求自己,才能不慨叹别人之牛逼,而自己黯然神伤。
希望给对于曾经的自己和有职业困惑的朋友们一点启发:
当我们没有找到自己热衷的事情,做好手头的事才不会让自己后悔。 当我们有幸找到了自己热衷的事情,一定全力以赴,追求完美去把它做好! 不意淫几年几年之后,自己会成为很牛逼、或成功人士; 严格要求自己,做好时下你爱做的、该做的事!