ASFはSwooleに基づいて開発したPHP Appサーバーフレームワーク

45566 ワード

App Server Framework(ASF)
概要
  • 現在のバージョン0.01試用版.
  • フレームワークはPHP-Swoole拡張に基づいて開発され、プロファイルを通じて各種アプリケーションプロトコルをカスタマイズすることができ、デフォルトではhttpプロトコルをサポートする.
  • フレームワーク自体は完全なtcp_serverは、apache、nginx、fpmなどを必要とせず、フレームワークにはlog処理、mysqlアクセスパッケージが含まれています.
  • フレームワークはfast-routeライブラリでhttp route処理を行い、コントローラに直接マッピングされ、使用者は具体的なコントローラメソッドを書くだけでrestスタイルのAPIを実現することができる.
  • パフォーマンスについては、かなり高いと言えます.具体的には、swoole関連ドキュメントを参照してください.http://www.swoole.com/

  • インストール運転
    環境:linux 2.6+、php5.5+、mysql5.5+、swoole1.7.20+ダウンロード:https://github.com/xtjsxtj/asf
    tar zxvf asf.tar.gz  
    cd asf  
    php ./bin/asf.php test_http start  
    
             server            :  
    cd asf/apps/test_http
    php ./index.php
    
        server    :
    php asf/bin/asf.php test_http status
    
        server    :
    php asf/bin/asf.php list

    ディレクトリ構造
    ASF
     ├── apps                             #  server     server(              )
     │   ├── test_http                    #    server  ,http_server
     │   │   ├── config                   #        
     │   │   │   ├── server_conf.php      #server        
     │   │   │   └── worker_conf.php      #worker        
     │   │   ├── controller               #       
     │   │   │   ├── base_controller.php  #          
     │   │   │   └── index_controller.php #          
     │   │   └── index.php                #       (      ),      ,    bin/asf.php     
     │   │
     │   └── test_tcp                     #    server  ,http_server
     │       ├── config                   #        
     │       │   ├── server_conf.php      #server        
     │       │   └── worker_conf.php      #worker        
     │       ├── controller               #       
     │       │   ├── base_controller.php  #          
     │       │   └── index_controller.php #          
     │       ├── protocol                 #TCP       
     │       │   └── voip_protocol.php    #VOIP        
     │       └── index.php                #       (      ),      ,    bin/asf.php      
     ├── bin
     │   ├── asf.php                      # server      shell  
     │   └── asf.ini                      # server      
     └── lib                              #ASF    
         ├── fast-route                   #fast-route   
         ├── autoload.php                 #      
         ├── config.php                   #route    
         ├── controller.php               #     
         ├── protocol.php                 #tcp    interface 
         ├── log.php                      #   
         ├── mysql.php                    #mysql   
         ├── route.php                    #http route   
         └── swoole.php                   #swoole      

    http_サーバ開発
    protocolがhttp(設定しないとデフォルトはhttp)の場合、serverはhttp_として実行されます.server、このモードではデフォルトで追加の構成は必要ありません.システムはデフォルトのルーティング規則に従って特定のコントローラに配布され、開発者は特定のコントローラと方法を書くだけでいいです.
    次はhttp_server,test_httpの開発プロセス:
  • serverプロファイル:apps/test_http/config/server_conf.php
    <?php
    
    class server_conf {
        public static $config=array(
            'server_name' => 'test_http',  //server   
            'log_level' => NOTICE,         //    
            'listen' => 9501,              //listen    
            'log_file' => '/asf/apps/test_http/index.log',  //log  
        );   
    }
  • workerプロファイル:apps/test_http/config/worker_conf.php
    <?php
    
    class worker_conf{
        public static $config=array(
            'log_level' => DEBUG,
            'mysql' => array(
                'socket' => '/tmp/mysql.sock',
                'host' => 'localhost',
                'port' => 3306,            
                'user' => 'user',
                'password' => 'password',
                'database' => 'test',
                'charset' => 'utf8',
            ),
    }
  • 唯一のプライマリ・エントリ・スクリプト:apps/test_http/index.php
    <?php>
    define('BASE_PATH', __DIR__);
    require_once BASE_PATH.'/../../lib/autoload.php';
    require_once BASE_PATH.'/config/server_conf.php';
    
    $server = new swoole();
    $server->start();
  • コントローラ:apps/test_http/controller/index_controller.php
    <?php
    
    class index_controller extends base_controller {       
        public function index() {
            log::prn_log(DEBUG, json_encode($this->content));
            log::prn_log(DEBUG, json_encode($this->param));         
    
            return 'ok';
        }
    }
    
    index_コントロールは親ベースbase_コントロールは実装され、base_コントローラはlib/controllerに基づいている必要があります.phpのcontroller実装.
  • このデフォルトの構成では、アクセスhttp://localhost:9501/index/index ルーティングは上のindex_を実行します.Controllerコントローラのindexメソッド、http呼び出しの結果、ok
  • tcp_サーバ開発
    protocolがhttpでない場合、serverはtcp_として実行されます.server,このモードでは開発者自身がTCPプロトコルパケットの解析を処理する必要がある.開発者はprotocol名をカスタマイズし、プロトコルの解析クラスを独自に実装する必要があります.
    次はtcp_server,test_tcpの開発プロセス:
  • serverプロファイル:apps/test_tcp/config/server_conf.php
    <?php
    
    class server_conf {
        public static $config=array(
            'server_name' => 'test_tcp',   //server   
            'protocol' => 'voip',          //       
            'log_level' => NOTICE,         //    
            'listen' => 9511,              //listen    
            'log_file' => '/asf/apps/test_tcp/index.log',  //log  
        );   
    }
  • workerプロファイル:apps/test_tcp/config/worker_conf.php
    <?php
    
    class worker_conf{
        public static $config=array(
            'log_level' => DEBUG,
            'mysql' => array(
                'socket' => '/tmp/mysql.sock',
                'host' => 'localhost',
                'port' => 3306,            
                'user' => 'user',
                'password' => 'password',
                'database' => 'test',
                'charset' => 'utf8',
            ),
    }
  • 唯一のプライマリ・エントリ・ファイル:apps/test_tcp/index.php
    <?php>
    
    define('BASE_PATH', __DIR__);
    
    require_once BASE_PATH.'/../../lib/autoload.php';
    require_once BASE_PATH.'/config/server_conf.php';
    
    $server = new swoole(server_conf::$config);
    $server->start();
  • カスタムvoipプロトコル解析クラスapps/test_tcp/protocol/voip_protocol.php
    <?php
    
    class voip_protocol implements protocol{
        public static function input($serv, $fd, $data){
            return strlen($data);
        }
    
        public static function decode($serv, $fd, $data){
            return $data;
        }
    
        public static function request($serv, $fd, $data){
            $db = $serv->mysql;
            $obj = new index_controller($serv, $data);
            return $obj->index();
        }
    
        public static function encode($serv, $fd, $data){
            return $data;
        }
    }
    クラス名とファイル名server_confの中の{protocol}protocol、lib/protocolに基づいていなければなりません.phpのinterface実装.

  • プロファイルの詳細
  • ASFフレームワークプログラムの構成は2つの部分に分けられ、1つはシステムプロセスの構成server_である.conf、動的に変更できません.
  • もう1つは、ワークプロセスの構成worker_です.confは、動的に修正することができ、修正後はasfを通過する.php server_name reloadが有効になります.
  • は、以下に分けて詳しく説明します.

  • server_conf.phpプロファイルの詳細
  • $config=array(
        'server_name' => 'test_http',  
        'protocol' => 'http',       
        'log_level' => NOTICE,         
        'is_sington' => true,          
        'listen' => ['0.0.0.0:9501', '172.16.18.116:9502'],  
        'worker_num' => 1,             
        'daemonize' => true,           
        'log_file' => '/asf/apps/test_http/index.log',  
    ); 
  • server_name sever名、構成する必要があります.複数のserverを起動すると、各server_が保証されます.nameの唯一.
  • protocol tcp_serverプロトコルタイプは、httpやvoipなどのさまざまなカスタムプロトコルを構成、サポートする必要があります.http以外のプロトコル名の場合、lib/protocolに基づいて開発する必要があります.php interfaceはカスタムプロトコル解析クラスを実現します.
  • log_レベルトレースレベルは、TRACE、DEBUG、INFO、NOTICE、WARNING、ERRORを構成する必要があります.
  • is_singtonが単一インスタンスで実行されるかどうか、オプション構成、デフォルトはtrue、すなわち単一インスタンスで実行されます.server_nameはtest_httpでは、serverが起動するとデフォルトで/var/localディレクトリの下で一意のpidファイルが生成されます:swoole_test_http.pid.
  • listenリスニングポートは、構成する必要があります.
  • の構成方法は次のとおりです.
    'listen' => 9501
    'listen' => [9501,9502]
    'listen' => ['0.0.0.0:9501', '172.16.18.116:9502']
  • worker_numワークプロセス数、オプション構成、デフォルトは6ワークプロセス
  • daemonizeがデーモンプロセスで実行されているかどうか、オプションで構成されています.デフォルトはtrueです.つまり、後で実行されます.
  • log_fileトレースファイルは、構成する必要があります.
  • 最も簡単な構成
    $config=array(
        'server_name' => 'test_http',  //server_name
        'log_level' => NOTICE,         //log_level
        'listen' => 9501,              //listen port
        'log_file' => '/asf/apps/test_http/index.log',  //logfile
    );
  • worker_conf.phpプロファイルの詳細
  • $config=array(
        'log_level' => DEBUG,
        'mysql' => array(
            'socket' => '/tmp/mysql.sock',
            'host' => 'localhost',
            'port' => 3306,            
            'user' => 'user',
            'password' => 'password',
            'database' => 'test',
            'charset' => 'utf8',
        ),
        'route' => [
            ['PUT', '/user/{number}/{id:\d+}',              'index.index'],
            ['GET', '/{controller}/{number}/{id:\d+}',    '_handler.controller_param'],
            ['GET', '/{controller}/{number}',             '_handler.controller_param'],
            ['POST', '/{controller}/{number}/{id:\d+}',   '_handler.controller_param'],
            ['DELETE', '/{controller}/{number}/{id:\d+}', '_handler.controller_param'],
        ],
    );

    このプロファイルは3つのセクションに分かれています.*log_レベルワークプロセスのトレースレベル、server_と値をとるconfでは同じで、reload後に再有効になります.
  • myqlデータベース接続プロパティ構成
  • 'socket'     => '/tmp/mysql.sock',//sock   
    'host'       => 'localhost',      //mysql   
    'port'       => 3306,             //mysql  
    'user'       => 'user',           //mysql  ,    
    'password'   => 'password',       //mysql  ,    
    'database'   => 'database',       //     ,    
    'charset'    => 'utf8',           //        
    'sqls'       => 'set wait_timeout=24*60*60*31;set wait_timeout=24*60*60*31'  
    //           SQL  , ';'       
  • routeこの構成項目はprotocol=httpでのみ有効であり、他のカスタムプロトコル名では無効です.下位層は、ここで構成された下げ幅規則に従って、httpの異なるuri要求を対応するコントローラ処理に割り当てる.具体的なルールは以下のhttp_serverセクションで詳細に説明します.
  • 最も簡単な構成
    $config=array(
        'log_level' => DEBUG,
        'mysql' => array(
            'socket' => '/tmp/mysql.sock',
            'host' => 'localhost',
            'port' => 3306,            
            'user' => 'user',
            'password' => 'password',
            'database' => 'test',
            'charset' => 'utf8',
        ),
    );
  • http_serverのrouteルール構成
  • のhttp_server開発プロセスでは,uriリクエストはシステムのデフォルトのルーティングに従ってコントローラに配布されて実行される.
  • 実はASFはhttp_サーバモードでは、開発者の特定のビジネス要件に従ってルーティングルールを特定のコントローラにカスタマイズして処理することもできます.
  • カスタムルーティング規則worker_confのrouteセグメントの下で設定します.http_について詳しく説明します.serverのrouteルール構成.
  • ルーティング構成例
  • $config=array(
        'route' => [
            ['PUT', '/user/{number}/{id:\d+}',              'index.index'],
            ['GET', '/{controller}/{number}/{id:\d+}',    '_handler.controller_param'],
            ['GET', '/{controller}/{number}',             '_handler.controller_param'],
            ['POST', '/{controller}/{number}/{id:\d+}',   '_handler.controller_param'],
            ['DELETE', '/{controller}/{number}/{id:\d+}', '_handler.controller_param'],
        ],
    );
  • 構成フォーマット各構成ルールは配列タイプ:
    ['Method', 'Route_reg', 'Controller.Action']  
    
    Method POSTGETPUTDELETE ,  ['POST','GET']   Route_reguri   Controller.Action             .  
  • コントローラ.メソッドの下部には、デフォルトのコントローラがあります.handler、このコントローラは4つの方法を提供します.
  • controller_Action解析'/index/index'uriから対応するコントローラへの対応する方法
  • controller解析'/index'uriから対応するコントローラへのデフォルトindexメソッド
  • controller_param解析'/index/name/id'uriを対応するコントローラのデフォルトindexメソッドに追加し、paramパラメータ
  • を追加
  • controller_action_param解析'/index/index/name/id'uriは、paramパラメータ
  • を付加しながら、対応するコントローラの対応する方法に適用される.
  • ユーザカスタムルール例
  • ['PUT', '/user/number/{id:\d+}',              'index.index'],
    ['PUT', '/user/{number}/{id:\d+}',            'index.index'],
     1           :
    PUT http://localhost/user/number,   index    index  ,      $this->param      :{"id":"123"}
    
     2           :
    PUT http://localhost/user/number,   index    index  ,      $this->param      :{"number":"number","id":"123"}
    
  • デフォルト・ルールの最下位レベルでは、ユーザーがカスタマイズしたルーティング・ルールの後に、lib/configの3つのデフォルト・ルールが追加されます.php
  • <?php
    
    /** * ASF http        * @author [email protected] * @date 2015-10-25 */
    
    class Route_config{
        public static $default_route = [
            //                  
    
            // POST http://localhost/index/index
            ['POST', '/{controller}/{action}[/]',        '_handler.controller_action'],
    
            // POST http://localhost/index
            ['POST', '/{controller}[/]',                 '_handler.controller'],         
    
            // POST http://localhost/index/index/prm/id
            [['GET','POST'], '/{controller}/{param:.+}', '_handler.controller_param'],
        ]; 
    }

    第1条規則は次の規則に適合することができる:POSThttp://localhost/index/test、indexコントローラに割り当てるtestメソッド.
    第2条規則は次の規則に適合することができる:POSThttp://localhost/index、indexコントローラに割り当てられたデフォルトのindexメソッド.
    第3条規則は以下の規則に一致することができる:POSThttp://localhost/index/test/name/idを選択し、indexコントローラに割り当てられたデフォルトのindexメソッドを、コントローラの$this->paramパラメータに保存します:[‘test’,‘name’,‘id’]
  • ルールマッチング順序システムは、まずルールをカスタマイズし、デフォルトルールの順序で実行し、上から順にマッチングし、マッチングしたら戻ります.したがって,ルールを定義する際には,具体的なマッチングルールが上にあり,汎用的なルールが下にあることを保証すべきである.

  • tcp serverプロトコル解析interface
  • lib/protocol.php
  • <?php
    
    /** * Protocol interface */
    interface protocol {
        /** *     ,     buffer          (  ) *      $recv_buffer               *     0,                      *     false    ,          ,       * @param swoole_srver $serv swoole_server   * @param int $fd TCP            * @param string $data        ,             * @return int|false */
        public static function input($serv, $fd, $data);
    
        /** *        * input     0,          ,     decode *     on_request  ,  decode         on_request         *                 ,     decode  ,            * @param swoole_srver $serv swoole_server   * @param int $fd TCP            * @param string $data          ,             * @return mixed */
        public static function decode($serv, $fd, $data);
    
        /** *         ,        encode          * @param swoole $serv server   * @param int $fd      fd * @param mixed $data decode       * @return mixed */
        public static function request($serv, $fd, $data);
    
        /** *        *       on_request      encode    ,            *                 encode  ,            * @param swoole_srver $serv swoole_server   * @param int $fd TCP            * @param mixed $data * @return string */
        public static function encode($serv, $fd, $data);
    }
    
  • カスタムプロトコルのtcp_serverは、interface protocolに基づいてカスタムプロトコルの解析クラスを実装する必要があります.

  • http_server最下位コントローラの親プロパティメソッド
  • lib/controller.php
  • <?php
    
    /** * http            * @author [email protected] * @date 2015-10-25 */
    
    class controller { 
        protected $server;    //swoole_server  
        protected $mysql;     //      
        protected $request;   //       
        protected $param;     //    
    
        /** * @param swoole $serv swoole   * @param mixed request * @param array $param      */    
        public function __construct($server, $request, $param=[]) {
            $this->server = $server;
            $this->mysql = $server->mysql;
            $this->request = $request;        
            $this->param = $param;
    
            if (method_exists($this, '_init')) $this->_init();
        }
    
        public function __destruct() {
            if (method_exists($this, '_deinit')) $this->_deinit ();
        }
    }
  • アプリケーションserverディレクトリ構造のcontrollerでの制御は、下位の親から継承されます.

  • システム起動スクリプトの使用
  • asf.iniファイル摘要
    [servers]
    test_http = /home/jfy/testprog/asf/apps/test_http/index.php
    test_tcp = /home/jfy/testprog/asf/apps/test_tcp/index.php
    各行フォーマット:server_name = path/index.phpここのserver_nameは各アプリケーションのserver_とconfプロファイルのserver_nameは同じです.
  • asf.phpスクリプトは
    php asf.php list
    を使用してasfをリストする.iniファイルで構成されているすべてのserver_name対応サービスの稼働状態
    php asf.php server_name start|stop|reload|restart|status|init
    reload:通常、ワークプロセスを再起動し、worker_を再ロードします.confプロファイル内容restart:server status全体の再起動:serverプロセスステータスinitの表示:test_によるhttpフレームワークアプリケーションディレクトリフレームワークserver_をコピーnameはasfでなければなりません.iniファイルで定義されています.

  • logクラスの使用方法
  • logクラスは静的クラスとして使用されます.
  • トレースレベルの設定:log::log_level = NOTICE; サポート:TRACE,DEBUG,INFO,NOTICE,WARNING,ERROR
  • 印刷トレースlog::prn_log(NOTICE, “message”); サポート:TRACE,DEBUG,INFO,NOTICE,WARNING,ERROR
  • mysqlクラスの使用方法
  • コントローラでmysqlデータベースを直接$this->mysqlで操作します.
  • select_one( sqlstr, flag=true)
    /** *        * @param string $sql    SQL   * @flag bool               ERROR log * @return row(array) | false */
  • select_more($sqlstr)
    /** *        * @param string $sql    SQL   * @return result(array) | false */
  • insert( data, flag=true)
    /**
     *       
     * @param array $data         ['id' => 123, 'name' => 'jfy']
     * @param bool $flag         ,   true
     * @return id | false         ID,    false
     * @see mysql->tabname->insert(['id' => 123, 'name' => 'jfy']);
     */
  • insert_one( sqlstr, flag=true)
    /** *        * @param string $sql    SQL   * @return true | false * $this->insert_id      ID */
  • update( data, cond)
    /**
     *       
     * @param array $data         ['name' => 'jfy']
     * @param array $cond         ['id' => 123],         
     * @return true | false
     * @see $this->affected_rows       
     * @see mysql->tabname->update(['name' => 'jfy'],['id' => 123]);
     */
  • update_one($sqlstr)
    /** *        * @param string $sql    SQL   * @return true | false * @see $this->affected_rows        */
  • update_more($sqlstr)
    /** *        * @param string $sql    SQL   * @return true | false * @see $this->affected_rows        */
  • delete($cond)
    /** *        * @param array $cond        ['id' => 123],          * @return true | false * @see $this->affected_rows        * @see mysql->tabname->delete(['id' => 123]); */
  • delete_one($sqlstr)
    /** *        * @param string $sql    SQL   * @return true | false * @see $this->affected_rows        */

  • コントローラ操作mysql
    apps/test_http/controller/index_controller.php
    <?php
    
    class index_controller extends base_controller {       
        public function index() {
            log::prn_log(DEBUG, json_encode($this->content));
            log::prn_log(DEBUG, json_encode($this->param));
    
            $db = $this->mysql;
    
            $result = $db->gearman_queue->insert([
                'unique_key' => 'd847233c-1ef2-11e5-9130-2c44fd7aee72',
                'function_name' => 'test',
                'priority' => 1,
                'data' => 'test',
                'when_to_run' => 0,
            ]);
            if ( $result === false ) return 'error';
    
            $result = $db->select_one("select * from gearman_queue where unique_key='d847233c-1ef2-11e5-9130-2c44fd7aee72'");
            if ( $result === false ) return 'error';
            var_dump($result);
    
            $result = $db->gearman_queue->update([
                'function_name' => 'testtest',
                'priority' => 100,
                'data' => 'testtesttesttest',
                'when_to_run' => 100,
            ],[
                'unique_key' => 'd847233c-1ef2-11e5-9130-2c44fd7aee72',
            ]);
            if ( $result === false ) return 'error';        
            var_dump($db->select_one("select * from gearman_queue where unique_key='d847233c-1ef2-11e5-9130-2c44fd7aee72'"));
    
            $result = $db->gearman_queue->delete([
                'unique_key' => 'd847233c-1ef2-11e5-9130-2c44fd7aee72',
            ]);         
            if ( $result === false ) return 'error';
    
            $result = $db->select_more("select * from gearman_queue limti 3");
            if ( $result === false ) return 'error';
            var_dump($result);
    
            return 'ok';
        }
    }