【原创】把 Nginx 创建为 Windows 的一个服务,关联PHP服务一起启动

参考把 Nginx 创建为 Windows 的一个服务 – Defonds 的专栏 – 博客频道 – CSDN.NET,我做了以下改变:
首先编写setupPhp.bat,作为PHP服务启动关闭的程序,内容如下:
  1. @echo off
  2. if "%1" == "-start" goto start
  3. if "%1" == "-stop"  goto stop
  4. :start
  5. set PHP_FCGI_MAX_REQUESTS=1000
  6. D:/WebSrv/php/php-cgi.exe -b 127.0.0.1:9000 -c D:/WebSrv/php/php.ini
  7. goto end
  8. :stop
  9. taskkill /F /IM php-cgi.exe > nul
  10. goto end
  11. :end
接下来安装Nginx服务,需要编写XML文件。除了更改路径和上文并无不同。
installNginx.xml
  1. <service>
  2.  <id>Nginx</id>
  3.  <name>Nginx</name>
  4.  <description>Nginx是一个高性能的HTTP和反向代理服务器,也是一个邮件服务器。Nginx是由Igor Sysoev为俄罗斯访问量第二的Rambler.ru站点开发的。</description>
  5.  <executable>D:\WebSrv\nginx\nginx.exe</executable>
  6.  <logpath>D:\WebSrv\Logs\</logpath>
  7.  <logmode>roll</logmode>
  8.  <depend></depend>
  9.  <startargument>-p D:\WebSrv\nginx</startargument>
  10.  <stopargument>-p D:\WebSrv\nginx -s stop</stopargument>
  11. </service>
接下来按照PHP服务,需要编写XML文件。
installPHP.xml
  1. <service>
  2.  <id>PHP-FPM</id>
  3.  <name>PHP-FPM</name>
  4.  <description>PHP-FPM</description>
  5.  <executable>D:\WebSrv\php\setupPhp.bat</executable>
  6.  <logpath>D:\WebSrv\Logs\</logpath>
  7.  <logmode>roll</logmode>
  8.  <depend>Nginx</depend>
  9.  <startargument>-start</startargument>
  10.  <stopargument>-stop</stopargument>
  11. </service>
重要的点在depend元素。
  1. <depend>Nginx</depend>
这样启动PHP服务后,Nginx也被带着一起启动了。但试过了,如果PHP服务
来自为知笔记(Wiz)

把 Nginx 创建为 Windows 的一个服务 – Defonds 的专栏 – 博客频道 – CSDN.NET

        译序:Nginx 不是为 Windows 而写。Nginx 是用在软件的工作环境中的。但软件开发环境一般都是 Windows,有时调试的需要也要装 Nginx,但 Nginx 并没给 Windows 提供服务支持。如何把 Nginx 创建为 Windows 的一个服务呢?百度一下,搜索结果的前几页基本都是同一篇文章,只是网址不同作者不同。根本分不清谁是原创,谁是转载。我想,如果先写那篇文章的人搞错了一点事情(但不能是影响使用的错误),那么这点错误的观点会被第二个,第三个…一直复制错下去。喟叹国内某些程序员们做事不够严谨哈。相对来说,印度程序员做事就相当较真了,如果读者有兴趣的话,可以去看一下印度人写的博客。比如安装 JDK,他们会先给你介绍 JDK 和 JRE 的区别,然后才介绍下载安装。中国软件为什么不如印度软件发达,程序员们做事不够严谨,许是其中一个重要的原因吧。——扯远了,反正看着那么多雷同的文章,我没有觉得它们有多么高的参考价值。索性去看老外的了。当然,老外写的也未必就是对的。但冲着他们的那份严谨,我看到了一种敬业的精神。敬业者的文章值得每一位读者仔细品读。
        把 Nginx 创建为 Windows 的一个服务,比较流行的一个做法就是用微软提供的 instsrv/servany。本文没有使用这种做法,并说明理由
        引言
        Nginx 是一个 web 服务器。它类似于 Lighttpd,作为轻量级的 web server,可以替代重量级的 Apache/IIS。Nginx 专为性能优化而开发,是一个快速且能经受高负载考验的 web server。它来自于 Linux 世界但同样可以运行在 Windows 上面(由本地语言构建)。唯一的问题就是它不支持 Windows Services。
        注
        尽管 Nginx 以快速和提供高性能而具有很大的声誉,但并非是在 Windows 平台上。访问官方网址 http://nginx.org/en/docs/windows.html,你会发现,对于 Windows 平台的支持被认为是测试版,根据 Nginx 的实现来看它并不提供(和 Linux 平台)相同的性能水平。
        也许你都没有意识到,WordPress 就是一个 Nginx 的用户,使用它提供大量的静态内容服务,并负载平衡请求到其他服务器。如果你想了解更多关于 Nginx 的内容请看本文底部的链接。
        Nginx 对比 Windows 服务
        Nginx 是绿色免安装的。这里我不去介绍它的管理配置,官方已经提供了一个很棒的 wiki,上面有丰富的服务器相关信息(参考文后链接)。可以使用默认的配置,它会使用 Nginx 目录下的 html 文件夹服务于端口 80。

        只需简单地执行 nginx.exe 即可启动 Nginx。但你想要停止它的时候问题来了,你需要执行以下命令

nginx.exe -s stop  

        虽然这很简单,但是如果它能够像 apache 或 IIS 那样作为一个服务工作的话会更漂亮。那样的话,我们就可以设置机器启动时 Nginx 自动启动,还可以方便地启动、停止或者重启服务,设置恢复选项、依赖的服务,等等。

        为什么不使用 instsrv/servany、FireDaemon 或者其他办法呢
        已经有介绍如何通过 FireDaemon 使用 Nginx,但它有一个很重要的问题。Nginx 启动以后,它会创建一个次级进程。所以会有两个 nginx.exe 在运行。对于这个官方可能有一个很合理的理由,但你最好到 Nginx 论坛去问为什么:-)
        通过 instsrv/srvany(微软官方创建服务的方法) 或者 FireDaemon 的方式(来创建 Nginx 为服务),只是启动进程,当你想要停止它时,将关闭这个进程。但这些方式都无法关闭多余的那个 nginx.exe 进程。所以每次你停止/启动/重启服务都会产生一个多余的 nginx.exe 进程。不怎么好!
        把 Nginx 创建为 Windows 的一个服务(一个较好的做法)    
        多亏了一个叫做 “Windows Service Wrapper” 的小项目,我们有了一个办法来恰当地启动和停止 Nginx。首先从http://download.java.net/maven/2/com/sun/winsw/winsw/ 下载最新的 exe 程序(Misterdai 写本文时最新的是 “winsw-1.8-bin.exe”。译者已经上传了一个 winsw-1.8-bin.exe 到 CSDN 资源,下载地址:http://download.csdn.net/detail/defonds/4517957)。
        得到该程序后,将其放在 Nginx 安装目录下,并重命名为 myapp.exe。
        然后是告诉 WinSw 我们想要它做什么。这将使用一个 XML 配置文件,我们将在文件中指出 Nginx 需要一个 shutdown 命令。

        (在 Nginx 安装目录下)新建一个名为 myapp.xml 的文件,编辑其内容如下:

<service>  
 <id>nginx</id>  
 <name>nginx</name>  
 <description>nginx</description>  
 <executable>c:\nginx\nginx.exe</executable>  
 <logpath>c:\nginx\</logpath>  
 <logmode>roll</logmode>  
 <depend></depend>  
 <startargument>-p c:\nginx</startargument>  
 <stopargument>-p c:\nginx -s stop</stopargument>  
</service>  
        很明显,你应该稍微更改文件,这取决于你自己的文件路径。对于有更多技术需求的朋友,你也可以在该文件中设置 Nginx 依赖的服务。

        最后,我们要安装服务了。只需要简单地执行以下语句,你将在你的服务列表里找到 “Nginx” 服务:

c:\nginx\myapp.exe install  

        就这些!
        结束语
        根据我的经验,到目前为止这种做法的效果很完美。你得到了 Windows 服务的支持,而且在服务重启时没有遗留孤立的 “nginx.exe”。两全其美。
        如果 Nginx 自己可以做到这样的话会更好,但 Nginx 的作者当下正在专注于其他更重要的开发。我敢肯定还有其他人有足够的编程知识来贡献这块所需的代码,所以,如果你是这样的一个人,请尽力来帮助大家。
        资料链接

  • Nginx Wiki – http://wiki.nginx.org/Main
  • Nginx 论坛 – http://forum.nginx.org/
  • Windows Service Wrapper – http://projectkenai.com/projects/winsw
  • http://download.java.net/maven/2/com/sun/winsw/winsw/
    原文链接:http://misterdai.yougeezer.co.uk/2009/10/16/nginx-windows-service/
  • 来自为知笔记(Wiz)

    Windows下搭建nginx+php+MariaDB开发环境

    准备工作

    Nginx 1.10.1 D:\WebSrv\nginx
    PHP 5.6.23 X64版 D:\WebSrv\php
    MariaDB 1.10.1 D:\WebSrv\MariaDB

    注意: nginx下php是以FastCGI的方式运行,所以我们下载非线程安全也就是nts的php包

    统一安装到D:\WebSrv底下。

    PHP安装与配置

    解压PHP压缩包到指定目录

    如:

     

     

    找到php.ini-development更名为php.ini并打开(建议使用Notepad2或Notepad++)

    首先找到 extension_dir

     

    去掉前面的分号,改为

    extension_dir=”D:/wnmp/php5/ext”

    接下来是一些常用扩展启用(去掉其前面的分号)

    extension=php_curl.dll
    extension=php_gd2.dll
    extension=php_mbstring.dll
    extension=php_mysql.dll
    extension=php_mysqli.dll
    extension=php_pdo_mysql.dll
    extension=php_pdo_sqlite.dll
    extension=php_sockets.dll
    extension=php_sqlite.dll
    extension=php_sqlite3.dll
    extension=php_exif.dll

    CGI设置(去掉其前面的分号)

    cgi.force_redirect = 1

    cgi.fix_pathinfo=1(重要,设置之后PHP文件才能被编译)

    cgi.rfc2616_headers =1

    PHP部分设置完成

    Nginx安装与配置

    解压压缩包

    找到nginx.conf文件

     

    打开后修改

     

    包含文件 include     D:/wnmp/ww/conf/*.conf; 记得有 分号 结尾

    若没有多个域名指定多个虚拟目录的需求,则修改server部分。

    示例conf,只含有server部分

     

     

    Server_name   xxx.xxx # 绑定域名

    可以通过修改hosts文件 将域名指向本地就可以使用了

     

     

    下载RunHiddenConsole:http://redmine.lighttpd.net/attachments/660/RunHiddenConsole.zip

    解压到nginx目录下

    RunHiddenConsole 执行的程序进程不会随着命令提示符窗口关闭而结束

    创建start.bat批处理

    @echo off & title 启动Nginx服务器

    color 0A

    REM Windows 下无效

    REM set PHP_FCGI_CHILDREN=5

    call stop.bat

    REM 每个进程处理的最大请求数,或设置为 Windows 环境变量

    set PHP_FCGI_MAX_REQUESTS=1000

    echo 启动 php-5.4.19 FastCGI …

    RunHiddenConsole D:/wnmp/php5/php-cgi.exe -b 127.0.0.1:9000 -c D:/wnmp/php5/php.ini

    echo 启动 Nginx 1.4

    RunHiddenConsole  D:/wnmp/nginx/nginx.exe -p D:/wnmp/nginx

    echo 启动完成…

    Cls

    创建stop.bat批处理

    @echo off & title 停止Nginx

    color 0A

    echo Stopping Nginx…  

    taskkill /F /IM nginx.exe > nul

    echo Stopping PHP FastCGI…

    taskkill /F /IM php-cgi.exe > nul

    Cls

     

    如下: 运行start.bat

     

    启动成功后如下图

     

    打开浏览器

     

     

    接下安装Mariadb

    Mariadb安装与配置

    除了指定安装目录外,按照安装顺序下一步即可。找到 my-small.ini文件打开

     

    修改(添加红色部分):

    [client]

    #password = your_password

    port = 3306

    socket = /tmp/mysql.sock

    default-character-set=utf8 # 字符集编码

    # Here follows entries for some specific programs

    # The MySQL server

    [mysqld]

    port = 3306

    socket = /tmp/mysql.sock

    # 5.5及以后版本用character_set_server=utf8 取代default-character-set=utf8  

    character_set_server=utf8 # 字符集编码

    collation-server=utf8_general_ci # 字符集

    skip-external-locking

    key_buffer_size = 16K

    max_allowed_packet = 1M

    table_open_cache = 4

    sort_buffer_size = 64K

    read_buffer_size = 256K

    read_rnd_buffer_size = 256K

    net_buffer_length = 2K

    thread_stack = 128K

     

    basedir=D:/wnmp/MySQL # MySQL安装目录

    datadir=D:/wnmp/MySQL/data # 数据库文件存放目录

     

    另存为my.ini

    备注:

    按照上面的方法开始使用nginx的时候,会跳出一个提示,说程序无法使用,这是因为我们使用的是64位的PHP,如果是32位的PHP,就不会有这个情况。

    解决方法是:安装MSVC12,x86版和x64版都装,就可以解决了。

    来自为知笔记(Wiz)

    [原创]scp无需输入密码,批量拷贝数据的方法

    以前觉得scp除了两端建密钥的方法,就没有无需输入密码,自动化拷贝文件的方法了

    今天仔细搜索,发现还是有的,用expect,详情参见我的两个附件sh文件。
    iscp.sh是循环读取文件列表中的每一行,将其中的每一行作为文件、调用scpf.sh进行scp拷贝。
    scpf.sh是利用expect自动输入密码进行拷贝。
    要点:
    1、用[lindex $argv 0]表示参数,0表示参数的顺序,0是第一个,以此类推。
    2、timeout 后面的是秒数,意味着等你设定的若干秒后进行下一步。
    来自为知笔记(Wiz)

    附件列表

     

    如何在BootStrap模态框中消失后确保播放中的视频也停止播放

    目前的项目需要在模态框中播放视频,但是按ESC键后,希望模态框消失,视频也停止播放。但一直无果。

    首先想的是用jquery捕捉键盘事件,判断是ESC键之后,暂停播放,然后关闭模态框。
    但这一想法,由于被BootStrap封装而失败。
    于是想,能不能拦截BootStrap对ESC键的封装。
    首先考虑,停止BootStrap自动按ESC退出的功能,于是尝试以下代码
    1. $("#myModal").modal({keyboard:false});
    但这一代码使用后,对键盘事件完全无感。
    于是就考虑,通过代码拦截,结果发现下面这篇文章。恍然大悟。
    Bootstrap- Modal对话框如何在关闭时触发事件
    于是将暂停播放的代码放在关闭后的on事件的处理代码中,于是OK。
    以下是原文的内容
    •  下表列出了模态框中要用到事件。这些事件可在函数中当钩子使用。
      事件 描述 实例
      show.bs.modal 在调用 show 方法后触发。
      $('#identifier').on('show.bs.modal', function () {// 执行一些动作...})
      shown.bs.modal 当模态框对用户可见时触发(将等待 CSS 过渡效果完成)。
      $('#identifier').on('shown.bs.modal', function () {// 执行一些动作...})
      hide.bs.modal 当调用 hide 实例方法时触发。
      $('#identifier').on('hide.bs.modal', function () {// 执行一些动作...})
      hidden.bs.modal 当模态框完全对用户隐藏时触发。
      $('#identifier').on('hidden.bs.modal', function () {// 执行一些动作...})

      实例

      下面的实例演示了事件的用法:

      1. <!DOCTYPE html>
      2. <html>
      3. <head>
      4.    <title>Bootstrap 实例 - 模态框(Modal)插件事件</title>
      5.    <link href="/bootstrap/css/bootstrap.min.css" rel="stylesheet">
      6.    <script src="/scripts/jquery.min.js"></script>
      7.    <script src="/bootstrap/js/bootstrap.min.js"></script>
      8. </head>
      9. <body>
      10.  
      11. <h2>模态框(Modal)插件事件</h2>
      12.  
      13. <!-- 按钮触发模态框 -->
      14. <button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
      15.    开始演示模态框
      16. </button>
      17.  
      18. <!-- 模态框(Modal) -->
      19. <div class="modal fade" id="myModal" tabindex="-1" role="dialog" 
      20.    aria-labelledby="myModalLabel" aria-hidden="true">
      21.    <div class="modal-dialog">
      22.       <div class="modal-content">
      23.          <div class="modal-header">
      24.             <button type="button" class="close" data-dismiss="modal" 
      25.                aria-hidden="true">×
      26.             </button>
      27.             <h4 class="modal-title" id="myModalLabel">
      28.                模态框(Modal)标题
      29.             </h4>
      30.          </div>
      31.          <div class="modal-body">
      32.             点击关闭按钮检查事件功能。
      33.          </div>
      34.          <div class="modal-footer">
      35.             <button type="button" class="btn btn-default" 
      36.                data-dismiss="modal">
      37.                关闭
      38.             </button>
      39.             <button type="button" class="btn btn-primary">
      40.                提交更改
      41.             </button>
      42.          </div>
      43.       </div><!-- /.modal-content -->
      44.    </div><!-- /.modal-dialog -->
      45. </div><!-- /.modal -->
      46. <script>
      47.    $(function () { $('#myModal').modal('hide')})});
      48. </script>
      49. <script>
      50.    $(function () { $('#myModal').on('hide.bs.modal', function () {
      51.       alert('嘿,我听说您喜欢模态框...');})
      52.    });
      53. </script>
      54.  
      55. </body>
      56. </html>

    来自为知笔记(Wiz)

    修复mysql 的BUG: Cannot load from mysql.proc

    来自:百度经验:jingyan.baidu.com

    1. LINUX下将mysql从5.1升级至5.5后,发现存储过程不能用了。创建和使用存储过程时就会提示Cannot load from mysql.proc. The table is probably corrupted。

      解决方法非常简单,运行mysql_upgrade命令即可。此命令会在数据目录下生成一个文本文件mysql_upgrade_info,里面的内容为升级后的数据库版本。

      但不知道什么原因,在我这里无效,升级后各种升级OK,但仍然报这个错误。

    2. http://bugs.mysql.com/bug.php?id=50183

      原因是mysql.proc升级时有个字段没有升级成功。

      在5.1中mysql.proc表的comment字段是varchar(64):

      1. `comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
      但在5.5中应该是text:

      1. `comment` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
    3. So,执行下面的语句,把这个字段修改为text,就彻底OK了:

      1. ALTER TABLE `proc`MODIFY COLUMN `comment`  text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL AFTER `sql_mode`;
    来自为知笔记(Wiz)

    indexof查不到指定字符串

    1. $(function() {
    2. var cls;
    3. $("img").each(function(){
    4. cls = $(this).attr("class");
    5. if (typeof(cls) == "undefined") {
    6. $(this).addClass("img-responsive");
    7. } else{
    8. if (cls.match("img-responsive") != null) {
    9. $(this).addClass("img-responsive");
    10. }
    11. }
    12. });
    13. });
    原来使用indexof,结果查不到指定字符串,改用match来判断才可以得到结果,在浏览器里报错,说cls.indexof不是一个已经定义的方法。但match没问题。
    难道js的indexof方法被废弃了?
    来自为知笔记(Wiz)