博客

  • PhpStorm配置Xdebug调试

    xdebug 安装

    打开 https://xdebug.org/wizard.php 复制phpinfo的信息到文本框,会返回安装指导:

    Tailored Installation Instructions
    
    Summary
    
    Xdebug installed: no
    Server API: FPM/FastCGI
    Windows: no
    Zend Server: no
    PHP Version: 5.6.9
    Zend API nr: 220131226
    PHP API nr: 20131226
    Debug Build: no
    Thread Safe Build: no
    Configuration File Path: /usr/local/php/etc
    Configuration File: /usr/local/php/etc/php.ini
    Extensions directory: /usr/local/php/lib/php/extensions/no-debug-non-zts-20131226
    Instructions
    
    Download xdebug-2.5.1.tgz
    Unpack the downloaded file with tar -xvzf xdebug-2.5.1.tgz
    Run: cd xdebug-2.5.1
    Run: phpize (See the FAQ if you don't have phpize.
    
    As part of its output it should show:
    
    Configuring for:
    ...
    Zend Module Api No:      20131226
    Zend Extension Api No:   220131226
    If it does not, you are using the wrong phpize. Please follow this FAQ entry and skip the next step.
    
    Run: ./configure
    Run: make
    Run: cp modules/xdebug.so /usr/local/php/lib/php/extensions/no-debug-non-zts-20131226
    Edit /usr/local/php/etc/php.ini and add the line
    zend_extension = /usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/xdebug.so
    Restart the webserver
    If you like Xdebug, and thinks it saves you time and money, please have a look at the donation page.
    

    xdebug 配置

    编辑php.ini文件,加入

    [Xdebug]  
    ;指定Xdebug扩展文件的绝对路径  
    zend_extension = /usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/xdebug.so
    ;允许远程IDE调试
    xdebug.remote_enable        = true
    ;通知 PHP 开启调试的标识
    xdebug.idekey = PHPSTORM
    ;远程主机
    xdebug.remote_host          = 192.168.xxx.xxx
    ;xdebug.remote_port         = 9000 ;默认端口 9000
    

    配置参数选项附录

    配置参数选项 参数值类型与默认值    参数选项描述
    xdebug.auto_trace   boolean类型,默认值=0 是否在脚本运行之前自动调用相关追踪函数。
    xdebug.cli_color    integer类型,默认值=0 该参数自2.2版本开始引入。如果值=1,当处于CLI模式或连接虚拟控制台时,Xdebug将高亮显示var_dumps()和堆栈输出,;在Windows中,这需要安装ANSICON工具。如果值=2,不管是否处于CLI模式或连接虚拟控制台,Xdebug都会高亮显示var_dumps()或堆栈输出;这种情况下,你可能会看到转义后的代码。
    xdebug.collect_assignments  boolean类型,默认值=0 该参数自2.1版本开始引入。用于控制是否为函数跟踪添加变量赋值功能。
    xdebug.collect_includes boolean类型,默认值=1 控制是否在跟踪文件中写入include()、include_once()、require()、require_once()等函数中用到的文件名。
    xdebug.collect_params   integer类型,默认值=0 
    控制在调用函数时,是否收集传递给函数的参数信息。如果参数值过大,这可能会占用大量的内存;不过,在Xdebug 2中不会出现该问题,因为Xdebug 2将相关数据写入磁盘中,而不是占用内存。
    
    如果值=0,则不显示任何信息。
    如果值=1,只显示类型和大小信息,例如:string(6)、array(8)。
    如果值=2,将显示类型和大小,以及全部信息的工具提示。
    如果值=3,将显示变量的全部内容。
    如果值=4,将显示变量的全部内容和变量名。
    
    xdebug.collect_return   boolean类型,默认值=0 控制是否在追踪文件中写入函数调用的返回值。
    xdebug.collect_vars boolean类型,默认值=0 控制是否收集指定作用域中的变量信息。由于需要反向工程PHP的操作码数组,因此Xdebug的分析速度可能比较慢。
    xdebug.coverage_enable  boolean类型,默认值=1 该参数自2.2版本开始引入。控制是否允许通过设置内部结构来启用代码覆盖率功能。
    xdebug.default_enable   boolean类型,默认值=1 当发生异常或错误时,是否默认显示堆栈信息。
    xdebug.dump.*   string类型,默认值=Empty  这里的*可以是COOKIE, FILES, GET, POST, REQUEST, SERVER, SESSION中的任意一个。用于指定发生错误时是否显示超全局变量数组中的索引变量信息。比如,你想要显示请求的IP地址和请求方式,可以设置为
    xdebug.dump.SERVER=REMOTE_ADD,REQUEST_METHOD
    多个索引变量用英文逗号隔开,如果要输出其中的所有变量,可以直接用*,例如:
    xdebug.dump.GET=*
    xdebug.dump_globals boolean类型,默认值=1 控制是否显示通过xdebug.dump.*定义的所有超全局变量的信息。
    xdebug.dump_once    boolean类型,默认值=1 如果出现多个错误,控制超全局变量信息是在所有错误中显示,还是只在第一个错误中显示。
    xdebug.dump_undefined   boolean类型,默认值=1 控制是否显示超全局变量中未定义的值。
    xdebug.extended_info    integer类型,默认值=1 是否强制进入PHP解析器的"extended_info"模式,这将允许Xdebug以远程调试器对文件或行添加断点。开启此模式将拖慢脚本的允许速度,该参数只能在php.ini中设置。
    xdebug.file_link_format string类型,默认值=,  自2.2版本开始引入。用于指定堆栈信息中用到的文件名称的链接样式,这允许IDE通过设置链接协议,直接点击堆栈信息中的文件名称,即可快速打开指定的文件。例如:ZendStudio://%f@%l(%f表示文件路径,%f表示行号)。
    xdebug.force_display_errors integer类型,默认值=0 自2.3版本开始引入。是否强制显示错误信息。
    xdebug.force_error_reporting    integer类型,默认值=0 自2.3版本开始引入。是否强制显示所有错误级别的信息。
    xdebug.halt_level   integer类型,默认值=0 自2.3版本开始引入。指定出现那些错误级别的错误时,中止程序运行。例如:xdebug.halt_level=E_WARNING|E_NOTICE|E_USER_WARNING|E_USER_NOTICE(也仅支持上述4种错误级别)。
    xdebug.idekey   string类型,默认值=*complex*  指定传递给DBGp调试器处理程序的IDE Key。
    xdebug.manual_url   string类型,默认值=http://www.php.net 仅2.2.1以下版本可用,用于指定从函数堆栈和错误信息链接到的帮助手册的基本URL。
    xdebug.max_nesting_level    integer类型,默认值=100   指定递归的嵌套层级数。
    xdebug.overload_var_dump    boolean类型,默认值=1 自2.2版本开始引入,当php.ini中的html_error设为1时,Xdebug是否默认使用自身的改进版本来重载var_dump()。
    xdebug.profiler_append  integer类型,默认值=0 当多个请求映射到相同文件时,指定是覆盖之前的调试信息文件还是追加内容到该文件中。
    xdebug.profiler_enable  integer类型,默认值=0 指定是否启用Xdebug的性能分析,并创建性能信息文件。
    xdebug.profiler_output_dir  string类型,默认值=/tmp   指定性能分析信息文件的输出目录
    xdebug.profiler_output_name string类型,默认值=cachegrind.out.%p  指定性能分析信息文件的名称
    xdebug.remote_enable    boolean类型,默认值=0 是否开启远程调试
    xdebug.remote_handler   string类型,默认值=dbgp   指定远程调试的处理协议
    xdebug.remote_host  string类型,默认值=localhost  指定远程调试的主机名
    xdebug.remote_log   string类型,默认值=   指定远程调试的日志文件名
    xdebug.remote_mode  string类型,默认值=req    可以设为req或jit,req表示脚本一开始运行就连接远程客户端,jit表示脚本出错时才连接远程客户端。
    xdebug.remote_port  integer类型,默认值=9000  指定远程调试的端口号
    xdebug.trace_options    integer类型,默认值=0 指定对于之后的请求,追踪文件是追加内容还是覆盖之前内容。
    xdebug.trace_output_dir string类型,默认值=/tmp   指定追踪文件的存放目录
    xdebug.trace_output_name    string类型,默认值=trace.%c   指定追踪文件的名称
    

    PhpStorm 配置

    先配置一个 server(一定要配置目录映射),打开
    菜单栏->File->Settings->Languages & Frameworks->PHP->Server
    开启一下 9000 端口 的监听,打开
    菜单栏->Run->Start Listing for PHP Debug Connections

    调试

    chrome 可以安装一个插件xdebug helper,需要调试的页面打开debug,会设置一个cookie来自动加调试标识。
    在代码中打断点,访问浏览器,phpstorm 就会跳出一个调试栏,显示调试信息。

  • laravel 订单通知队列

    需求

    订单完成支付后通知服务器已到账,通知失败则重试,最多3次,第二次5秒后,第三次10秒后

    实现方案一

    生成任务类

    php artisan make:job PaymentNotify
    

    命令将会在app/Jobs目录下生成一个新的类,编辑:

    < ?php
    
    namespace App\Jobs;
    
    use App\Exceptions\SignException;
    use Illuminate\Bus\Queueable;
    use Illuminate\Queue\SerializesModels;
    use Illuminate\Queue\InteractsWithQueue;
    use Illuminate\Contracts\Queue\ShouldQueue;
    
    class PaymentNotify implements ShouldQueue
    {
        use InteractsWithQueue, Queueable, SerializesModels;
    
        protected $data;
    
        /**
         * Create a new job instance.
         *
         * @param $data
         */
    
        public function __construct($data)
        {
            $this->data = $data;
        }
    
        /**
         * Execute the job.
         *
         * @throws \Exception
         */
        public function handle()
        {
            if ($this->attempts() == 1) {
                //处理订单通知
                info('notify'.$this->attempts());
                if(true){//测试强制通知失败
                    $this->release(5);//手动释放任务回队列,带延时执行时间
                }
            }
    
            if ($this->attempts() == 2) {
                //处理订单通知
                info('notify'.$this->attempts());
                if(true){
                    $this->release(10);
                }
            }
    
            if ($this->attempts() == 3) {
                //处理订单通知
                info('notify'.$this->attempts());
                if(true){
                    throw new SignException('fails');//抛出异常,任务失败,自动入库
                }
    
            }
        }
    
    }
    

    添加测试路由并访问:

    Route::get('/pay/notify', function(){
        dispatch((new \App\Jobs\PaymentNotify(['order'=>time().mt_rand(1000,9999)]))->onQueue('PaymentNotify'));
        return 'ok';
    });
    

    监听队列

    php artisan queue:work  --queue=PaymentNotify --tries=3  --sleep=0
    

    可查看使用说明

    $php artisan queue:work --help
    Usage:
      queue:work [options] [--] [<connection>]
    
    Arguments:
      connection               The name of connection
    
    Options:
          --queue[=QUEUE]      The queue to listen on
          --daemon             Run the worker in daemon mode (Deprecated)
          --once               Only process the next job on the queue
          --delay[=DELAY]      Amount of time to delay failed jobs [default: "0"]
          --force              Force the worker to run even in maintenance mode
          --memory[=MEMORY]    The memory limit in megabytes [default: "128"]
          --sleep[=SLEEP]      Number of seconds to sleep when no job is available [default: "3"]
          --timeout[=TIMEOUT]  The number of seconds a child process can run [default: "60"]
          --tries[=TRIES]      Number of times to attempt a job before logging it failed [default: "0"]
      -h, --help               Display this help message
      -q, --quiet              Do not output any message
      -V, --version            Display this application version
          --ansi               Force ANSI output
          --no-ansi            Disable ANSI output
      -n, --no-interaction     Do not ask any interactive question
          --env[=ENV]          The environment the command should run under
      -v|vv|vvv, --verbose     Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
    

    命令意思是:使用默认队列连接的PaymentNotify队列,失败最多尝试执行3次,轮询新任务之前的等待时间为0(即有任务随时检测执行,不会在无任务时默认等待3秒)

    任务执行情况

    [2017-03-07 16:22:44] local.INFO: notify1  
    [2017-03-07 16:22:49] local.INFO: notify2  
    [2017-03-07 16:22:59] local.INFO: notify3
    

    符合预期

    方案二

    另一种思路是订单完成后直接生成3个队列,

    $order = time().mt_rand(1000,9999);
    
    dispatch((new \App\Jobs\PaymentNotify(['order'=>$order]))->onQueue('PaymentNotify'));
    
    dispatch((new \App\Jobs\PaymentNotify(['order'=>$order]))->onQueue('PaymentNotify')->delay(5));
    
    dispatch((new \App\Jobs\PaymentNotify(['order'=>$order]))->onQueue('PaymentNotify')->delay(10));
    

    后两个队列带延时执行参数,设置最多执行次数为1,执行队列时检测已经通知成功则跳过执行

    总结

    方案一:在处理队列时需判断重试次数,分类处理,业务需求变化需改动多;
    方案二:在redis中相同队列存在多条,业务需求变化处理逻辑相对改动少;
    各有利弊。

  • laravel自定义用户认证

    添加自定义的 Guard

    需要通过Auth门面的extend方法定义自己的认证guard,在App\Providers\AuthServiceProvider的boot方法中实现:

    public function boot()
    {
        $this->registerPolicies();
    
        Auth::extend('XXX', function($app, $name, array $config) {
            // 返回 Illuminate\Contracts\Auth\Guard 实例
            $guard = new XXXGuard($name,Auth::createUserProvider($config['provider']),$this->app['session.store']);
            //事件
            if (method_exists($guard, 'setDispatcher')) {
                $guard->setDispatcher($this->app['events']);
            }
            //请求
            if (method_exists($guard, 'setRequest')) {
                $guard->setRequest($this->app->refresh('request', $guard, 'setRequest'));
            }
            return $guard;
        });
    }
    

    (更多…)

  • 在 2016 年做 PHP 开发是一种什么样的体验?(一)

    在 2016 年做 PHP 开发是一种什么样的体验?(一)

    嘿,我最近接到一个网站开发的项目,不过老实说,我这两年没怎么接触编程,听说 Web 技术已经发生了一些变化。听说你是这里对新技术最了解的开发工程师?

    你算是找对人了。我对今年的技术别提多熟了, VR 、机器学习……你尽管问吧。我刚去了几个热门的技术大会逛了一圈,没有什么新技术是我不知道的。

    厉害。是这样的,我要开发一个网站,用来展示用户的最新动态。我想我应该通过后端接口获取数据,然后用一个 table 来展示数据,用户可以对数据进行排序。如果服务器上的数据变化了,我还需要更新这个 table 。我的思路是用 jQuery 来做。

    可别用 jQuery !现在哪还有人用 jQuery 。现在是 2016 年了,你绝对应该用 React 。

    等等,这句话之前已经有一位前端大神和我说过了,我今天主要是想问你后端该怎么做。

    哦原来是这样,你提到了 Smarty ?你后端语言是 PHP 对吧,现在哪还有人用 Smarty 。现在是 2016 年了,你绝对应该用 Twig 。

    Twig ?也是一个模板引擎吗?

    是的,但是 Twig 的语法更加优雅,使用更方便,速度也快,而且许多开发框架都支持把 Twig 作为模板引擎,和框架的整合也做得更好。

    好吧那我用 Twig ,请问在哪里下载?

    你不用自己下载安装,只需要在你项目的 composer.json 文件中添加一个依赖,然后 Composer 会帮你安装。

    等等, Composer 是什么?

    Composer 是一个以 PSR-4 标准进行自动化包管理的工具,用它可以方便的进行各种第三方软件的依赖管理和下载、更新等操作

    PSR-4 ?

    对, PSR-4 是 PHP-FIG 组织提出的多个为了统一项目规范的标准之一,是用来规范 PHP 项目的 Namespace 、目录结构、加载规范的。

    那除了 PSR-4 之外还有什么?

    还有用来规定代码风格的 PSR-1 ,以及 PSR-1 的扩展版本 PSR-2 ,还有用来规定日志的 PSR-3 ,用来规定缓存的 PSR-6 ,用来规定 HTTP 头消息的 PSR-7 ,以及……

    等等,怎么没有 PSR-5 ?

    有的,但 PSR-5 还处在草稿阶段,没有正式发布,所以我没有讲给你听。

    有 PSR-8 吗?

    有的,现在一共是到 PSR-0 到 PSR-17 ,但我没提到的那些大部分都在草稿阶段,所以同上,我没有讲给你听。

    好吧好吧,我用 Composer 行了吧。

    等等,在你用之前,我建议先配置一个镜像,因为 Composer 的服务器在国外,直接使用经常会出现问题,对了如果你的项目比较大的话,可能第一次使用要 FQ 才能使用。

    为什么?

    因为虽然软件的版本信息是存在 Composer 的服务器上的,但有大部分软件的 zip 文件是存放在 github 或者别的什么地方的。

    好吧这些我都搞定了,我想开始写代码了,听说 Zend Framework 挺有名的?

    现在是 2016 年了,没人再用 ZF 了。现在比较流行的 PHP 框架有 Symfony 、 Laravel 、 YII 、 Codeigniter 这些,如果你对性能要求比较高或者想开发一些 Socket 相关的功能的话,可以试试看 Phalcon 、 Yaf 、 Swoole 、 Workerman 、 ReactPHP 这些,对了最近还有个叫 Kraken 的框架在 Github 上比较火,但我还没有试过。

    有没有国内用的比较广泛的框架?

    ThinkPHP 刚刚推出了支持 Composer 的 5.0 版本,但我建议你再观望一下再决定是否用。

    我以前听说最新版本是 3 ,怎么现在是 5 了,请问 ThinkPHP 4 去哪里了?

    这个套路你还不明白吗?请问你用过 Java 2/3/4 或者 Windows9 吗?

    好吧,确实没用过,不过我懂你的意思了。我可以开始写代码了吧? Editplus 我早就装好了

    可别用 Editplus !现在哪还有人用 Editplus 。现在是 2016 年了,你绝对应该用 PHPStorm ,非常好用,同类的还有 NetBeans 、 Zend Studio 但现在已经没什么人用了,如果你喜欢简单一些的工具,可以用 Sublime 、 Atom 。

     

    好吧好吧…对了请问代码该怎么调试呢?我以前用 Editplus 的时候都是在代码里写 var_dump 和 die 的。

    现在哪还有人 var_dump() + die()。现在是 2016 年了,你绝对应该用 Ladybug 。

    Ladybug?

    对,类似 var_dump + die ,但是更加好用,能够把要 dump 对象里的内容展示的清清楚楚,配合 Xdebug 你甚至可以在 IDE 里进行断点调试、临时更改变量的值等等

    Xdebug?

    是的,一个 PHP 的调试工具,安装之后可以像调试 Java 、 C 那样调试 PHP 。

    看起来好高级的样子,但我程序还没开始写呢,我听人说写代码第一步是要建数据库?

    没错,但现在已经是 2016 年了,没有人直接用客户端连上数据库去建表了,大家都在用 ORM 工具管理数据库。

    什么是 ORM ?

    ORM 可以让你像操作类一样去操作一个数据库,知名的 ORM 工具有: Doctrine 、 Propel 、 Eloquent 这些。

    难道我不能直接写 SQL 吗?

    可以当然是可以的,但现在是 2016 年了,没人直接写 SQL 了。而且如果直接写 SQL 的话,安全性怎么办?如果字段做了变更怎么更新所有现存的 SQL ?代码的部署回滚怎么和数据库绑定?而且用了 ORM 之后你可以很简单的就创建出一个表的 CRUD 表单,甚至可以很简单的写几行代码就实现对这个表的各种 API 操作。

    听上去很不错啊,能举个例子吗?

    比如我最常用的 Doctrine ,只要我用 PHP 类去定义一个表的实体结构( Entity ),我就可以让 Doctrine 自动生成这个表的 DDL ,即使我的表结构有变更, Doctrine 也会帮我生成所对应的 update 表结构的 DDL 。 Entity 在每个字段上都可以进行设置,设置完我就可以生成一个对这个表进行操作的 CRUD 表单,假设某个字段我设置的是日期类型,这个字段在 HTML 里就会被自动生成并映射成为一个包含三个下拉框的组件,而这三个下拉框分别是年月日。

    好酷炫,那还有别的用处吗?

    多了去了,每个网站都有后台吧,使用了 Doctrine 的话配合一些工具,只要写几行代码就可以生成基于表的后台管理界面,实现一个基本可用的网站后台。但需要注意 Doctrine 一般是以 Service 的方式被用在项目中的,你直接用 Doctrine 并不会很方便。

    Service ?

    是的,你可以理解为一系列的你代码中可能会用到的第三方应用,他们都通过 Service 的方式被注册到程序中,你在用到某个功能的时候,只需要对他们进行调用即可,就像调用一个函数那么简单。 Service 一般都会支持 IoC 和 DI ,所以对你将来程序的升级也会很有帮助。

    IoC 和 DI ?这不是 JavaEE 里面经常用到的东西吗?

    没错,但 PHP 项目中现在也在大量使用 IoC 和 DI ,比如 Symfony 和 Laravel 中就都有非常强大的一套 Service 系统,实现了 IoC 和 DI 。

    好吧不明觉厉,但是我的开发环境还没有呢,是不是先装一个 XAMPP 吗?

    现在是 2016 年了,没人还在用 XAMPP 了。你至少得用个 Vagrant 或者 Docker 吧?不然你的代码准备怎么部署?开发环境和生成环境怎么保证统一?难道你准备直接用 FTP 传源代码文件吗?

    er ……是的,难道不应该用 FTP 传代码吗?

    现在是 2016 年了,没人还在用 FTP 直接传代码了,最差你也得用个 rsync 吧?你可能没有 Vagrant 或者 Docker ,但至少应该尝试用一个部署工具并配置一套部署脚本,比如 Deployer 、 Capistrano 、 Ansible 、 Fabric 等等,如果配合 CI ,自动检查代码、部署那就更完美了。

    CI ?

    对, Continuous Integration ,指的是自动化处理分支的合并、运行测试用例、代码检查、部署等操作,你可以用 Jenkins 自己搭一个,也可以用 Bamboo 或者 CircleCI.com 。为了及时知道代码的 CI 结果,你可以把你的 CI 系统和 Slack 、零信等 IM 工具做整合,这样的话你就可以灵活的在团队里分享并自动化处理各种信息。

    能举个例子吗?

    比如代码如果在线上出了错,系统可以自动定位到某一次提交,并且发送邮件给改动人。比如服务器负载高了可以自动水平扩展服务器架构。

    水平扩展服务器架构?

    水平扩展的意思就是服务器配置不变,但是数量增多,相对应的垂直扩展就是服务器的性能变高,但是数量不变。

    那具体是怎么做到的呢?

    首先你的程序架构要支持水平扩展,比如 session 和数据库不能存放在单机上,当然还有一些复杂的注意事项暂且不提。其次是你的服务器架构要支持水平扩展,如果你用的是云服务,一般都会有水平扩展的 API ,直接调用就是了。

    听起来好复杂,我的网站暂时应该不会有流量问题,但如果程序出现问题怎么办,有什么办法能及时通知到我吗?

    现在是 2016 年了。一般的做法是搭建一套 ELK 系统进行日志的存储、搜索、展示。

    ELK ?

    对,就是 Elasticsearch 、 Logstash 和 Kibana 三个软件的缩写,因为大家都经常固定用这三个组合,所以缩写成了 ELK 。当然如果你不想那么麻烦,可以用 Sentry ,或者再简单点自己搭建一个 Log.io

    你别扯远,我就想简简单单跑一个 PHP 的运行环境,听说 Facebook 公司曾经出了个叫什么 HipHop for PHP 的东西?

    没想到你还懂得挺多, HipHop 是 Facebook 出的一款用来加速 PHP 运行的软件,核心原理是把 PHP 代码编译成为一个可以直接执行的程序。而且现在已经是 2016 年了,没人再用 HipHop 了。现在至少你得用 HHVM ,或者 PHP7

    HHVM ?

    是的 HHVM ,因为 HipHop 需要编译才能用,每次 PHP 代码改动都需要重新编译,非常麻烦,所以 Facebook 转而做了 HHVM 。核心原理差不多,但 HHVM 不再需要编译过程,可以直接执行 PHP 文件了,基本上你可以理解为 HHVM 是一个超级加速版的 PHP 。

  • rabbitmq

    Install Erlang

    yum install erlang

    or

    1. wget http://erlang.org/download/otp_src_19.0.tar.gz
    2. tar -zxvf otp_src_19.0.tar.gz
    3. cd otp_src_19.0
    4. ./configure --prefix=/opt/erlang --without-javac

    (更多…)

  • Vagrant使用NFS共享文件夹

    windows下默认虚拟机共享文件夹的方式因为磁盘IO效率太低,打开网站都需要好几秒,可以让windows支持NFS方式共享文件夹给vagrant虚拟机来解决问题

    安装vagrant插件

    1. $vagrant plugin install vagrant-winnfsd

    (更多…)

  • 使用 Let’s Encrypt 加密(HTTPS)网站

    安装 Let’s Encrypt 客户端

    先更新系统和安装 git,下载 Let’s Encrypt

    git clone https://github.com/letsencrypt/letsencrypt
    cd letsencrypt
    

    获取证书

    首先关闭 Nginx:

    service nginx stop
    

    生成证书

    ./letsencrypt-auto certonly --email 邮箱 -d 域名 --webroot -w /网站目录完整路径 --agree-tos
    

    证书已经签发成功,位于 /etc/letsencrypt域名下

    cert.pem: 域名证书
    chain.pem: The Let’s Encrypt 证书
    fullchain.pem: 上面两者合体
    privkey.pem: 证书密钥
    

    自动续签证书

    #!/bin/bash
    mkdir -p /网站目录完整路径/.well-known/acme-challenge
    /root/letsencrypt/letsencrypt-auto --renew-by-default certonly --email 邮箱 -d 域名 --webroot -w /网站目录完整路径 --agree-tos
    EOF
    chmod +x /root/renew-ssl.sh
    

    crontab里添加上:0 5 */60 * * /root/renew-ssl.sh 每60天的5点更新一次。

  • mongodb安装

    安装配置

    #wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.2.1.tgz
    #tar -zxvf mongodb-linux-x86_64-3.2.1.tgz
    #mkdir mongodata
    #mv mongodb-linux-x86_64-3.2.1/bin mongodata
    #mkdir log
    #mkdir data
    #mkdir conf
    #vi conf/mongod.conf
    

    写入保存:

    port = 27017
    dbpath = data
    logpath = log/mongod.log
    fork = true #后台运行
    

    运行服务:

    ./bin/mongod -f conf/mongod.conf
    

    客户端连接

    ./bin/mongo
    

    下载php扩展

    wget https://github.com/mongodb/mongo-php-driver-legacy/archive/master.zip
    unzip master.zip
    cd mongo-php-driver-legacy-master
    

    安装php扩展

    phpize
    ./configure --with-php-config=/usr/local/php/bin/php-config
    make
    sudo make install
    
  • redis 没有 bind 127.0.0.1 后果

    config set dir /root/.ssh/
    config set dbfilename authorized_keys
    set xxxx "\n\n\nssh-rsa xxxxxxxxxxx\n\n\n"
    save

    直接可以登录了

    原因就是 iptables 没设置对固定的端口开放白名单,又以root开的redis进程