Beanstalkd任务列队/消息列队

简介

Beanstalkd是一个轻量级高性能的任务列队系统,主要特性有优先级设置,持久化,分布式容错,超时控制

安装

sudo yum install beanstalkd

启动

sudo beanstalkd -d ./DIR

常用的启动参数

  • -d  指定binlog路径,用于断电后自动恢复
  • -f  同步时间 -f0为实时同步
  • -F  不同步 默认

使用简介

生产者通过put命令将一个job推动到一个指定的tube列队中,消费者从指定的tube列队中获取job通过通过reserve/release/bury/delete进行操作,改变job状态

如果有多个消费者在同一个tube不会收到相同的任务请求

发送任务

<?php
//发送任务
require_once 'Client.php';
//实例化beanstalk
$beanstalk = new \Beanstalk\Client();
$beanstalk->connect();
//选择使用的tube
$beanstalk->useTube('test');
//往tube中增加数据
$put = $beanstalk->put(
    23, // 任务的优先级.
    0,  // 不等待直接放到ready队列中.
    60, // 处理任务的时间.
    'hello, beanstalk'  // 任务内容
);
if (!$put) {
    exit('commit job fail');
}
$beanstalk->disconnect();

处理任务

<?php

require_once 'Client.php';
//实例化beanstalk
$beanstalk = new \Beanstalk\Client();
$beanstalk->connect();

//查看beanstalkd状态
//var_dump($beanstalk->stats());
//查看有多少个tube
//var_dump($beanstalk->listTubes());
$beanstalk->useTube('test');
//设置要监听的tube
$beanstalk->watch('test');
//取消对默认tube的监听,可以省略
$beanstalk->ignore('default');
//查看监听的tube列表
//var_dump($beanstalk->listTubesWatched());
//查看test的tube当前的状态
//var_dump($beanstalk->statsTube('test'));

while (true) {
//获取任务,此为阻塞获取,直到获取有用的任务为止
    $job = $beanstalk->reserve(); //返回格式array('id' => 123, 'body' => 'hello, beanstalk')
    //处理任务
    $result = ($job['body']);
    if ($result) {
        //删除任务
        $beanstalk->delete($job['id']);
    } else {
        //休眠任务
        $beanstalk->bury($job['id']);
    }
    //跳出无限循环
    if (file_exists('shutdown')) {
        file_put_contents('shutdown', 'beanstalkd在' . date('Y-m-d H:i:s') . '关闭');
        break;
    }
}
$beanstalk->disconnect();

 

继续阅读“Beanstalkd任务列队/消息列队”

PHP 自动加载机制的实现

前言

现在很多php框架都使用了命名空间来实现autoloader自动加载机制,配合编辑器的自动use避免了平凡include文件,开发起来十分方便,之前自己尝试写框架时候也使用到了autoloader机制,这里特意记录下.

实现过程

php有个__autoload() 函数,实现了在加载一个文件失败后尝试调用__autoload() 函数进行最后一次加载,因此通过一个有规律的命名规则就可以实现简单的自动加载机制

<?php
//实现自动加载当前目录下以类名命名的所有文件
function __autoload($classname) {
    $filename = "./". $classname .".php";
    include_once($filename);
}
$obj = new myClass();
?>

这种方式的缺点也显而易见,__autoload() 只能注册一个,如果项目有引用其他模块并且也使用到了__autoload() 就有冲突了,这个时候就需要使用spl_autoload_register 来注册自己的autoload方法

升级版

<?php

/**
 * 自动载入
 * Class autoloader
 */
class autoloader
{

    private static $class_map = array();  //namespace => dir


    public function __construct()
    {
        spl_autoload_register('self::my_autoload');  //or spl_autoload_register(array('autoloader', 'my_autoload'));
    }

    private function my_autoload($class)
    {
        $filename = self::getfilename($class);
        include $filename;
    }

    //根据命名空间获得文件路径
    private static function getfilename($namespace)
    {
        $name_paths = explode('\\', $namespace);
        if (!isset(self::$class_map[$name_paths[0]])) {
            exit("`{$name_paths[0]}` 命名空间未注册,请使用addClassMap注册");
        } else {
            $filename = self::$class_map[$name_paths[0]] . '/';
            unset($name_paths[0]);
            $filename .= implode('/', $name_paths);
        }
        return $filename . '.php';
    }


    public static function addClassMap($namespace, $dir)
    {
        self::$class_map[$namespace] = $dir;
    }

    public static function getClassMap()
    {
        return self::$class_map;
    }
}

只需要在程序入口处引入此文件,就可以实现对其他文件的自动载入,如下

<?php
use Test\Image;

include 'autoloader.php';

$autoloader = new \autoloader();
$autoloader->addClassMap('Test', './Test');  //注册命名空间,路径是相当于当前目录,而不是autoloader.php

$a = new Image();

其中命名空间注册只需要对顶级目录进行注册后,就可以对所有子目录下的文件实现自动加载,namespace的命名规则必须与目录和文件的命名一一对应

如文件在Test目录下,那么namespace 为 Test,class为Image,那么使用时就是

use Test\Image; 
$image=  new Image();

或者

$image = new \Test\Image();

 

开发环境配置清单

编辑器

  1. intellij idea
  2. Notepad++
  3. Adobe Dreamweaver
  4. Photoshop
  5. XMind

代码管理

  1. Git
  2. source tree

虚拟机

  1. VM VirtualBox

服务器环境

  1. nginx    反向代理
  2. php php-fpm
  3. mysql
  4. redis 缓存服务,key-value数据库
  5. mongodb  NoSql
  6. swoole   异步,并行,分布式,长连接
  7. Beanstalkd  分布式任务列队

数据库管理

  1. Navicat for Mysql    实用的mysql客户端
  2. Rjobomongo    MongoDB客户端

其他工具

  1. charles or  fiddler  http协议调试代理工具
  2. htop    linux下方便的进程管理工具
  3. linux下安装wine qq ,收取消息使用快捷键ctrl+alt+z
  4. ss-qt5 or ss-win
  5. Chrome

使用APIDOC自动生成api接口文档

安装nodejs和npm

Centos参考这个链接安装nodejs和npm

apidoc依赖node.js的npm管理工具,安装方法如下

sudo apt-get install nodejs
curl http://npmjs.org/install.sh | sudo sh

安装apidoc

sudo npm install apidoc -g

使用

<?php
class test{

/**
 * @api {get} /aaa/user 获取用户
 * @apiHeader {String} access-key Users unique access-key.
 * @apiName GetUser
 * @apiGroup User
 * 
 * @apiParam {Number} id 用户id

 * @apiSuccess {String} firstname Firstname of the User.
 * @apiSuccess {String} lastname  Lastname of the User.
 * @apiSuccessExample {json} Success-Response:
 *     HTTP/1.1 200 OK
 *     {
 *       "firstname": "John",
 *       "lastname": "Doe"
 *     }
 */
function user(){

}

}

apidoc.json

{
  "name": "api",
  "version": "0.1.0",
  "description": "这里是描述",
  "title": "这里是title",
  "url" : "这里是url"
}

 

生成命令

apidoc -i ./  -o apidoc/

生成的文档如下所示

QQ截图20151020143809

参考链接

PHP下Composer依赖包管理工具使用

简介

Composer是一个可以用来安装管理指定依赖包的工具

安装Composer

方法1

curl -sS https://getcomposer.org/installer | php

方法2

php -r "readfile('https://getcomposer.org/installer');" | php

使用

确保当前目录存在composer.json 依赖配置文件,例如

{
    "require": {
        "monolog/monolog": "1.2.*"
    }
}

其中,版本号可以使用>、>=、<、<=、!= ,或使用* 通配符

php composer.phar install

或者将composer.phar 复制到/usr/bin/composer ,执行composer install

安装完成后会自动创建composer.lock 锁文件,里面包含确切的版本号。下次执行install会下载相同的版本使环境保持一致。

如果如要更新依赖库的版本号,执行php composer.phar update ,将根据composer.json 文件配置更新依赖包,并重新生成composer.lock 锁文件

自动加载机制使用与配置

composer会自生成一个自动加载的支持,只需加入如下代码

require 'vendor/autoload.php';

也可以在composer.json的autoload字段添加自己的autoloader

{
    "autoload": {
        "psr-4": {"Acme\\": "src/"}
    }
}

Composer 将注册一个 PSR-4 autoloader 到 Acme 命名空间。

你可以定义一个从命名空间到目录的映射。此时 src 会在你项目的根目录,与 vendor 文件夹同级。例如 src/Foo.php 文件应该包含 Acme\Foo 类。

添加 autoload 字段后,你应该再次运行 install 命令来生成 vendor/autoload.php 文件。

引用这个文件也将返回 autoloader 的实例,你可以将包含调用的返回值存储在变量中,并添加更多的命名空间。这对于在一个测试套件中自动加载类文件是非常有用的,例如。

$loader = require 'vendor/autoload.php';
$loader->add('Acme\\Test\\', __DIR__);

除了 PSR-4 自动加载,classmap 也是支持的。这允许类被自动加载,即使不符合 PSR-0 规范。详细请查看 自动加载-参考

注意: Composer 提供了自己的 autoloader。如果你不想使用它,你可以仅仅引入 vendor/composer/autoload_*.php 文件,它返回一个关联数组,你可以通过这个关联数组配置自己的 autoloader。

配置使用更快的源

1,使用全局配置,执行如下命令

composer config -g repositories.packagist composer http://packagist.phpcomposer.com

2,在composer.json 追加如下配置,其中“packagist”: false 表示不使用Packagist ,Packagist 是 Composer 主要的一个包信息存储库,它默认是启用的

"repositories": [
        {"type": "composer", "url": "http://packagist.phpcomposer.com"},
        {"packagist": false}
]

composer.json配置文件说明

参考 库(资源包)

所有在 composer.json 中可用的字段

命令列表

 

Linux服务器配置PPTP类型VPN

步骤

  1. 安装PPTP
  2. 配置客户端IP地址
  3. 配置客户端DNS
  4. 添加VPN账号
  5. 开放端口,添加流量转发规则
  6. 启动服务

一 安装PPTP

yum install pptpd

如果提示未找到相关软件,添加软件源参考链接

二 配置客户端IP地址

修改/etc/pptpd.conf 文件,去掉如下两行的注释

localip 192.168.0.1
remoteip 192.168.0.234-238,192.168.0.245

localip表示分配给服务器的内部网关地址,remoteip 为分配给客户端的地址段

三 配置客户端DNS

查看/etc/pptpd.conf中指定的option文件(默认为/etc/ppp/options.pptpd ),修改文件中的ms-dns 记录

ms-dns 114.114.114.114
ms-dns 8.8.8.8

四 添加VPS账号

编辑/etc/ppp/chap-secrets 文件,添加账号配置,格式为账号 协议 密码 ip地址 ,ip填*为自动分配

# Secrets for authentication using CHAP
# client        server  secret                  IP addresses
username pptpd password *

启动服务

service pptpd restart

查看服务是否监听了1723端口

[root@localhost ~]# netstat -antp |grep 1723
tcp        0      0 0.0.0.0:1723                0.0.0.0:*                   LISTEN      1586/pptpd          
[root@localhost ~]# 

五 开放端口,添加流量转发

开放需要使用的端口

iptables -A INPUT -p tcp --dport 1723 -j ACCEPT
iptables -A INPUT -p 47 -j ACCEPT

现在的VPN服务可以连上,但是不能通过VPN服务器进行转发,也就是不能够上网或者访问其他服务器等,需要开启系统转发和NAT。编辑系统配置文件/etc/sysctl.conf,设置如下值为

net.ipv4.ip_forward = 1

使配置生效

sysctl -p

添加流量转发规则,后面的ip为服务器外网ip

iptables -t nat -A POSTROUTING -s 192.168.0.0/255.255.255.0 -j SNAT --to-source 45.78.40.111

保存设置

service iptables save

重启服务

service iptables restart
service pptpd start

连接说明

经实测,windows10 下和ios下只需选择连接类型为pptp,然后配置vpn地址和用户名密码即可连接成功,其他配置均为默认即可。

开启日志

  1. 取消/etc/pptpd.conf下的 debug注释
  2. /etc/ppp/options.pptpd 配置文件添加 logfile /var/log/ppp.log