Rootop 服务器运维与web架构

2014-03-06
发表者 Venus
暂无评论

pscp的用法

pscp是windows下往linux中安全传输文件的一个软件。其官方网站是http://www.putty.org/
pscp通过ssh协议传输,方便管理员进行系统间的数据传输。
下载地址:http://the.earth.li/~sgtatham/putty/latest/x86/pscp.exe

其参数为:
C:\>pscp.exe
PuTTY Secure Copy client
Release 0.60
Usage: pscp [options] [user@]host:source target
pscp [options] source [user@]host:target
pscp [options] -ls [user@]host:filespec
Options:
-V print version information and exit 显示版本信息
-pgpfp print PGP key fingerprints and exit 显示PGP加密指纹信息
-p preserve file attributes 保留文件属性
-q quiet, don’t show statistics 静默,不显示统计信息
-r copy directories recursively 拷贝子目录
-v show verbose messages 显示详细信息
-load sessname Load settings from saved session
-P port connect to specified port 端口
-l user connect with specified username 用户
-pw passw login with specified password 密码
-1 -2 force use of particular SSH protocol version ssh协议版本
-4 -6 force use of IPv4 or IPv6 使用ipv4或者是ipv6
-C enable compression 开启压缩
-i key private key file for authentication 指定密钥
-noagent disable use of Pageant
-agent enable use of Pageant
-batch disable all interactive prompts
-unsafe allow server-side wildcards (DANGEROUS)
-sftp force use of SFTP protocol
-scp force use of SCP protocol

EG:
复制c盘下iisdos.rar文件至远程主机的/tmp下:
C:\>pscp.exe -P 22 -pw redhat c:\IISDos.rar root@192.168.1.105:/tmp
IISDos.rar | 15 kB | 15.5 kB/s | ETA: 00:00:00 | 100%

复制c盘下的pscp文件夹包括子目录子文件到远程主机的/tmp下
C:\>pscp -P 22 -pw redhat -r c:\pscp root@192.168.1.105:/tmp
pscp.txt | 0 kB | 0.0 kB/s | ETA: 00:00:00 | 100%

2014-03-06
发表者 Venus
暂无评论

.net中Session的配置

一.摘要

所有Web程序都会使用Session保存数据. 使用独立的Session服务器可以解决负载均衡场景中的Session共享问题.本文介绍.NET平台下建立Session服务器的几种办法, 并介绍在使用Session时的各种经验和技巧.

二.关于Session,SessionID和Cookies

Session数据保存在服务器端, 但是每一个客户端都需要保存一个SessionID, SessionID保存在Cookies中, 关闭浏览器时过期.

在向服务器发送的HTTP请求中会包含SessionID, 服务器端根据SessionID获取获取此用户的Session信息.

很多初级开发人员不知道SessionID和Cookies的关系, 所以常常认为两者没有联系. 这是不正确的. 正是因为SessionID保存在Cookies中, 所以在我们保存Cookies的时候,一定要注意不要因为Cookies的大小和个数问题而导致SessionID对象. 在我们的程序中, 对SessionID的Cookies有特殊的处理:

/// <summary> /// 写入cookie. /// </summary> /// <param name=”day”></param> /// <returns></returns> public bool SetCookie(int day) { string CookieName = GetType().ToString(); HttpCookie SessionCookie = null; //对 SessionId 进行备份. if (HttpContext.Current.Request.Cookies[“ASP.NET_SessionId”] != null) { string SesssionId = HttpContext.Current.Request.Cookies[“ASP.NET_SessionId”].Value.ToString(); SessionCookie = new HttpCookie(“ASP.NET_SessionId”); SessionCookie.Value = SesssionId; }

//省略掉中间的代码部分.只保留备份SessionID和找回SessionID的逻辑

//如果cookie总数超过20 个, 重写ASP.NET_SessionId, 以防Session 丢失. if (HttpContext.Current.Request.Cookies.Count > 20 && SessionCookie != null) { if (SessionCookie.Value != string.Empty) { HttpContext.Current.Response.Cookies.Remove(“ASP.NET_SessionId”); HttpContext.Current.Response.Cookies.Add(SessionCookie); } } return true; }

三.搭建Session服务器的几种方式

将Session保存在独立的服务器中可以实现在多台Web服务器之间共享Session.虽然我们也可以自己开发Session存储系统, 但是使用ASP.NET自带的存储机制将更加便捷.

.NET提供了5种保存Seission的方式:

方式名称 存储方式 性能
Off 设置为不使用Session功能
InProc 设置为将Session存储在进程内,就是ASP中的存储方式,这是默认值。 性能最高
StateServer 设置为将Session存储在独立的状态服务中。通常是aspnet_state.exe进程. 性能损失10-15%
SQLServer 设置将Session存储在SQL Server中。 性能损失10-20%
Customer 自定制的存储方案 由实现方式确定

我们可以在Web.Config中配置程序使用的Session存储方式.默认情况下是InProc, 即保存在IIS进程中. 关于Off, InProc和Customer本文不做讲解. 相关文章大家都可以在网上搜索到.

下面主要讲解 StateServer 和 SQLServer 的应用.

四.使用 StateServer 模式搭建Session服务器

(1)服务器端配置

1.启动 Asp.net State service服务.(这个服务默认的状态为手动.修改为自动并启动.)

2.修改注册表: [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\aspnet_state\Parameters]

设置 AllowRemoteConnection = 1 , 设置 Port = 42424 (十进制,默认即为42424)

Port是服务的端口号

AllowRemoteConnection 表示是否允许其他机器连接,0为仅能本机使用,1为可以供其他机器使用.

(2)客户端设置

在Web应用程序的Web.Config中, 我们需要修改 <configuration> / <system.web> 的<sessionState>节点.如果没有

没有则添加(默认使用的是InProc方式)

<sessionState mode=”StateServer” stateConnectionString=”tcpip=服务器ip:42424″ cookieless=”false” timeout=”60″/>

上面的参数我们可以根据需要修改.

五.使用SqlServer模式搭建Session服务器

(1)服务器端配置

使用SqlServer模式搭建Session服务器端有两种方式. ASP.NET 1.0和1.1版本请使用方式a, 2.0即以上版本请使用方式b.

a.使用SQL文件创建Session数据库

在ASP.NET 1.0和1.1 版本中, 只能使用这种方式.对于2.0及其以上版本,请使用aspnet_regsql.exe工具.(当然此方法也通用2.0版本)

.net提供了数据库安装脚本,可以在机器的windows文件夹中找到:

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ InstallSqlState.sql

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ InstallSqlStateTemplate.sql

根据ASP.NET的版本不同, 需要使用不同的SQL脚本. ASP.NET主要有1.1和2.0两个版本,可以在不同的版本文件夹找到这两个SQL.

InstallSqlState.sql 是创建默认名称的数据库”[ASPState]”.此SQL可以直接运行.

InstallSqlStateTemplate.sql 可以使用自己指定的数据库保存数据.此SQL需要自己修改后运行, 打开SQL文件将其中 [DatabaseNamePlaceHolder] 替换为自己指定的数据库名称.

执行installsqlstate.sql时不需要指定数据库,可以在任意数据库上执行.此SQL会自己创建新的数据库

b. 使用aspnet_regsql.exe工具

ASP.NET 2.0版本后微软提供了aspnet_regsql.exe工具可以方便的配置Session数据库.该工具位于 Web 服务器上的”系统根目录\Microsoft.NET\Framework\版本号”文件夹中.

使用举例:

aspnet_regsql.exe -S . -U sa -P 123456 -ssadd -sstype p

-S参数:

表示数据库实例名称. 可以用”.”表示本机.

-U和-P参数:

表示用户名和密码.

-E参数:

可以再-U –P 与 -E中选择一组. –E表示以当前系统用户通过windows身份验证登录数据库, -U -P则是使用SqlServer用户登录数据库.

-ssadd / –ssremove 参数:

-ssadd表示是添加Session数据库, -ssremove表示移除Session数据库.

sstype 参数:

选项 说明
t 将会话数据存储到 SQL Server tempdb 数据库中。这是默认设置。如果将会话数据存储到 tempdb 数据库中,则在重新启动 SQL Server 时将丢失会话数据。
p 将会话数据存储到 ASPState 数据库中,而不是存储到 tempdb 数据库中。
c 将会话数据存储到自定义数据库中。如果指定 c 选项,则还必须使用 -d 选项包括自定义数据库的名称。

(2)Session客户端设置

此房是同样需要Web应用程序修改Web.Config中的<sessionState>节点.如果使用默认的数据库(ASPState库), 则配置如下:

<sessionState mode=”SQLServer” sqlConnectionString=”server=192.168.9.151; uid=sa; pwd=123456;” />

如果使用了自定义的数据库名称,则还需要制定allowCustomSqlDatabase属性并在数据库连接串中指定数据库:

<sessionState mode=”SQLServer” allowCustomSqlDatabase=”true” sqlConnectionString=”server=192.168.9.151; DataBase=MyAspState;uid=sa; pwd=123456;” />

六.使用经验与技巧总结

下面是SessionID, Session_End时间, StatServer模式 和 SqlServer模式的各种经验和技巧总结.

(1)StateServer模式:

1.在web farm中,请确认在所有的web服务器上有相同的<machineKey>

2. 要保存在Session中的对象是可序列化的。

3.为了在web farm中的不同web服务器上维护session state,IIS Metabase中的网站应用程序路径(如\LM\W3SVC\2)应该在所有的服务器上保持一致(大小写敏感).

4. ASP.NET处理Session是在Machine.Config中配置的HttpModuel模块, 在.NET的安装目录下的Config文件夹中, 查看Web.Config(1.1版本是在Machine.Config):

<httpModules> …

<add name=”Session” type=”System.Web.SessionState.SessionStateModule”/>

</httpModules>

确认此模块是否存在.

5.StateServer不支持负载均衡, 所以如果大并发推荐使用SqlServer模式, 可以享受到SqlServer的高性能和安全性.虽然存储效率会有下降.

6.需要让所有机器的MachineKey相同.在Machine.Config中配置:

<machineKey validationKey=”1234567890123456789012345678901234567890AAAAAAAAAA” decryptionKey=”123456789012345678901234567890123456789012345678″ validation=”SHA1″ decryption=”Auto” />

(2)SqlServer模式:

1. 要保存在Session中的对象是可序列化的。

2. 如果使用了默认是数据库, 则在客户端配置文件中的数据库链接字符串的用户,需要拥有ASPState和tempdb两个库的dbowner权限.

3. 在SQLServer模式下,session过期是由SQL Agent使用一个注册任务完成的,要确认SQL Agent已经运行。否则无法清理过期的Session数据, 会导致数据库数据一直增加.

4. 如果使用SqlServer模式时, 对于Web场中的各服务器的 ASP.NET 应用程序路径必须是相同的。请在 IIS 配置数据库中对 Web 场中的所有 Web 服务器进行 Web 站点的应用程序路径同步。大小写一定要相同,因为 Web 站点的应用程序路径是区分大小写的。

5.需要让所有机器的MachineKey相同.在Machine.Config中配置:

<machineKey validationKey=”1234567890123456789012345678901234567890AAAAAAAAAA” decryptionKey=”123456789012345678901234567890123456789012345678″ validation=”SHA1″ decryption=”Auto” />

(3)Session:

1. 不能直接通过Session服务器在ASP.NET和ASP之间共享Session. 请使用微软提供的解决方案:
http://msdn.microsoft.com/zh-cn/library/aa479313.aspx

2. 在不同的应用程序或一个网站的不同虚拟目录之间无法共享Session

3. Session的过期时间是滑动时间.

4. Session存储.NET自带的值类型性能最优. 存储对象会降低性能.

(4)SessionID:

1.SessionID 还可以保存在URL上, 设置Web.Config文件中的System.Web/sessionState节点的Cookiesless属性即可:

<sessionState cookieless=”UseUri” />

2. 一般在Session超时或删除之后,SessionID保持不变. 因为Session过期后会在服务器端清除数据, 但是SessionID保存在用户浏览器上, 所以只要浏览器不关闭则HTTP头中的SessionID保持不变.

3.关闭浏览器后再访问, SessionID会不同.

4.每打开一个IE6窗口, SessionID都不同, 在IE6中两个窗口的Session不能共享.

5.FireFox的标签页和新的FireFox窗口, SessionID都相同, 在FF的窗口和标签页上Session能共享.

6.对于包含FrameSet的页面,比如:

<frameset cols=”25%,50%,25%”> <frame src=”SessionID.aspx”> <frame src=”SessionID.aspx”> <frame src=”SessionID.aspx”> </frameset>

如果后缀名是.htm并且.htm文件没有交给ASP.NET的ISAPI处理, 那么根据服务器速度在每个Frame页面生成不同的SessionID, 再刷新后相同都等于最后一个SessionID.

解决办法是将.htm后缀改成.aspx, 或者将.htm文件交给ASP.NET的ISAPI处理.

(5)Session_End事件:

1. Session_End仅在InProc模式中可用

2. 关闭浏览器,Session_End是不会触发的。HTTP是一种无状态协议,服务器没有办法知道你的浏览器是否已经关闭。

3. 当Session因为时间过期或调用Session.Abandon时,Session_End才会触发.Session.Clear()仅仅是清除数据,但没有删除session。

4. Session_End由一个后台线程触发,使用工作者进程账号运行. 所以程序不会通知发生的错误.

5. 在Session_End访问数据库要考虑权限问题. Session_End是用运行工作者进程(aspnet_wp.exe)的帐号运行的,这个账号可以在machine.config中指定。因此,在Session_End中,如果使用integrity security连接SQL,它将使用工作者进程账号身份连接,这可能会引起登录失败.

6.因为Session_End是有独立线程出发的, 所以在Session_End中无法使用HttpContext对象(Request,Response,Server等对象都在HttpContext中),  即无法使用 Response.Redirect 和Server.Transfer等方法.

七.总结

我已经使用SqlServer模式对公司的多台服务器实现了Session共享, 服务器重启也不会导致用户预定过程重新开始(预定过程需要的Session不会丢失).  希望本文对具体的Session服务器搭建人员有所帮助.

参考文献:

使用一个 SQL 数据库 SQL Server 会话状态的所有应用程序可能导致瓶颈

http://support.microsoft.com/kb/836680/zh-cn

ASP.NET 中 Session 实现原理浅析 [1] /[2]

http://www.cnblogs.com/flier/archive/2004/08/04/30226.html

http://www.cnblogs.com/flier/archive/2004/08/07/30902.html

2014-03-05
发表者 Venus
暂无评论

lnmp源码编译过程

主要安装包:(自行下载)
目前全部软件的最新版本:
mysql-5.6.16.tar.gz
nginx-1.4.5.tar.gz
php-5.5.9.tar.gz

系统环境:centos6.5 x64
附加包:(自行下载)
cmake-2.8.10.2.tar.gz
bison-2.5.tar.gz
pcre-8.12.tar.gz

1、安装mysql:

首先安装cmake和bison:

[root@localhost smb]# tar zxvf cmake-2.8.10.2.tar.gz
[root@localhost smb]# cd cmake-2.8.10.2
[root@localhost cmake-2.8.10.2]# ./configure
[root@localhost cmake-2.8.10.2]# gmake
[root@localhost cmake-2.8.10.2]# make install

[root@localhost smb]# tar zxvf bison-2.5.tar.gz
[root@localhost smb]# cd bison-2.5
[root@localhost bison-2.5]# ./configure
[root@localhost bison-2.5]# make
[root@localhost bison-2.5]# make install

[root@localhost ~]# cd mysql-5.6.16
[root@localhost mysql-5.6.16]# useradd mysql -s /sbin/nologin

[root@localhost mysql-5.6.16]# cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql\
> -DMYSQL_UNIX_ADDR=/tmp/mysql.sock\
> -DDEFAULT_CHARSET=utf8\
> -DDEFAULT_COLLATION=utf8_general_ci\
> -DWITH_EXTRA_CHARSETS=all\
> -DWITH_INNOBASE_STORAGE_ENGINE=1\
> -DWITH_MYISAM_STORAGE_ENGINE=1\
> -DWITH_MEMORY_STORAGE_ENGINE=1\
> -DWITH_READLINE=1\
> -DENABLED_LOCAL_INFILE=1\
> -DMYSQL_DATADIR=/usr/local/mysql/data\
> -DMYSQL_USER=mysql\
> -DMYSQL_TCP_PORT=3306

(前面的大于号不是手动敲上去的,是在每一句参数后面有个斜杠\,回车以后自动生成,完整的参数如下:

 cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_UNIX_ADDR=/tmp/mysql.sock -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS=all -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_MEMORY_STORAGE_ENGINE=1 -DWITH_READLINE=1 -DENABLED_LOCAL_INFILE=1 -DMYSQL_DATADIR=/usr/local/mysql/data -DMYSQL_USER=mysql

不要误认为大于号是编译参数)

[root@localhost mysql-5.6.16]# make && make install
[root@localhost mysql-5.6.16]# cp support-files/my-default.cnf /etc/my.cnf
(打开配置文件发现基本没参数,不知道高版本为何这样?还是我编译的问题?)
[root@localhost mysql-5.6.16]# cp support-files/mysql.server /etc/init.d/mysqld
[root@localhost mysql-5.6.16]# chmod 755 /etc/init.d/mysqld

以上主要是添加启动脚本,添加 权限,方便用service + 服务名管理。

[root@localhost ~]# chown -R root.mysql /usr/local/mysql/
[root@localhost ~]# chown -R mysql /usr/local/mysql/data/


[root@localhost ~]# /usr/local/mysql/scripts/mysql_install_db --defaults-file=/etc/my.cnf --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data/ --user=mysql

[root@localhost ~]# service mysqld start
Starting MySQL.. [确定]

初始化mysql,mysql编译完成。

2、安装nginx:

首先安装pcre:

 [root@localhost smb]# tar zxvf pcre-8.12.tar.gz
 [root@localhost smb]# cd pcre-8.12
 [root@localhost pcre-8.12]# ./configure
 [root@localhost pcre-8.12]# make
 [root@localhost pcre-8.12]# make install
 [root@localhost pcre-8.12]# cd
 [root@localhost ~]# cd nginx-1.4.5
 [root@localhost nginx-1.4.5]# useradd www -s /sbin/nologin
 [root@localhost nginx-1.4.5]# yum install -y openssl-devel
 [root@localhost nginx-1.4.5]# ./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module
 [root@localhost nginx-1.4.5]# make && make install

添加启动脚本:
[root@localhost ~]# vi /etc/init.d/nginx

这个脚本从一键lnmp安装脚本中获取,写的不错。

#! /bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="nginx daemon"
NAME=nginx
DAEMON=/usr/local/nginx/sbin/$NAME
CONFIGFILE=/usr/local/nginx/conf/$NAME.conf
PIDFILE=/usr/local/nginx/logs/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

set -e
[ -x "$DAEMON" ] || exit 0

do_start() {
 $DAEMON -c $CONFIGFILE || echo -n "nginx already running"
}

do_stop() {
 kill -INT `cat $PIDFILE` || echo -n "nginx not running"
}

do_reload() {
 kill -HUP `cat $PIDFILE` || echo -n "nginx can't reload"
}

case "$1" in
 start)
 echo -n "Starting $DESC: $NAME"
 do_start
 echo "."
 ;;
 stop)
 echo -n "Stopping $DESC: $NAME"
 do_stop
 echo "."
 ;;
 reload|graceful)
 echo -n "Reloading $DESC configuration..."
 do_reload
 echo "."
 ;;
 restart)
 echo -n "Restarting $DESC: $NAME"
 do_stop
 do_start
 echo "."
 ;;
 *)
 echo "Usage: $SCRIPTNAME {start|stop|reload|restart}" >&2
 exit 3
 ;;
esac

exit 0

[root@localhost ~]# chmod 755 /etc/init.d/nginx
[root@localhost ~]# service nginx start
Starting nginx daemon: nginx.
[root@localhost ~]# lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 12351 root 6u IPv4 1197244 0t0 TCP *:http (LISTEN)
nginx 12352 www 6u IPv4 1197244 0t0 TCP *:http (LISTEN)

3、安装php:

先安装一些所需的库文件
[root@localhost ~]# yum install -y libxml2-devel libcurl-devel libjpeg-devel libpng-devel freetype-devel
安装 mhash-0.9.9.9 libmcrypt-2.5.8 mcrypt-2.6.8,直接./configure make make install即可,过程略过。

[root@localhost php-5.5.9]# ./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --enable-fpm --with-fpm-user=www --with-fpm-group=www --with-mysql=mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-iconv-dir --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib --with-libxml-dir=/usr --enable-xml --disable-rpath --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --enable-mbregex --enable-mbstring --with-mcrypt --enable-ftp --with-gd --enable-gd-native-ttf --with-openssl --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --enable-zip --enable-soap --without-pear --with-gettext --disable-fileinfo

[root@localhost php-5.5.9]# make && make install
模块被安装在/usr/local/php/lib/php/extensions/no-debug-non-zts-20121212/下。

[root@localhost php-5.5.9]# mkdir -p /usr/local/php/etc
[root@localhost php-5.5.9]# cp php.ini-production /usr/local/php/etc/php.ini //复制配置文件
[root@localhost php-5.5.9]# ln -s /usr/local/php/etc/php.ini /etc/php.ini //方便编辑

[root@localhost ~]# cd /usr/local/php/etc/
[root@localhost etc]# cp php-fpm.conf.default php-fpm.conf

pid = run/php-fpm.pid
user = www
group = www
listen = 127.0.0.1:9000

主要定义上面三行参数

拷贝启动文件,设置开机启动。
[root@localhost etc]# cd
[root@localhost ~]# cd tar_gz/php-5.5.9
[root@localhost php-5.5.9]# cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
[root@localhost php-5.5.9]# chmod 755 /etc/init.d/php-fpm
[root@localhost php-5.5.9]# chkconfig php-fpm on

启动php-fpm:
[root@localhost php-5.5.9]# service php-fpm start
Starting php-fpm done
[root@localhost php-5.5.9]# lsof -i:9000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
php-fpm 3046 root 7u IPv4 267783 0t0 TCP localhost:cslistener (LISTEN)
php-fpm 3047 www 0u IPv4 267783 0t0 TCP localhost:cslistener (LISTEN)
php-fpm 3048 www 0u IPv4 267783 0t0 TCP localhost:cslistener (LISTEN)

4、测试:

配置nginx,支持php,并添加测试页面测试。
[root@localhost php-5.5.9]# vi /usr/local/nginx/conf/nginx.conf
在最后一个大括号上面添加一行:

include vhost_*.conf

因为一般情况下不再去修改主配置文件,通过include参数,在启动nginx的时候根据定义值去加载vhost开头的配置文件。
[root@localhost ~]# vi /usr/local/nginx/conf/vhost_rootop.conf

server
 {
 listen 80;
 server_name 192.168.1.105;
 index index.html index.htm index.php;
 root /mnt/data/web/rootop/;

 location ~ .*\.(php|php5)?$
 {
 try_files $uri =404;
 fastcgi_pass 127.0.0.1:9000;
 fastcgi_index index.php;
 include fastcgi.conf;
 }

 location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
 {
 expires 30d;
 }

 location ~ .*\.(js|css)?$
 {
 expires 12h;
 }

 access_log off;
 }

重启nginx,写一个phpinfo测试页测试。