ysapi:由 Swoole + yaf 实现 socket 服务基础框架

zhengbohan 8年前
   <h2>简介</h2>    <ul>     <li>ysapi是一个由 swoole + yaf 实现socket服务基础框架.</li>     <li>由swoole实现socket服务,对外提供API接口, yaf负责api对应的业务逻辑.</li>    </ul>    <h3>功能介绍</h3>    <ul>     <li>基于socket提供更快的数据返回</li>     <li>基于swoole多进程task模型,实现多任务并行处理</li>     <li>客户端单次调用,服务端自动拆分任务给多个task进程并发处理,并一次返回给客户端</li>     <li>每次调用生成唯一ID,此ID可把当次所有请求,任务串联起来,依此分析程序问题</li>     <li>DB, REDIS, MQ均长连接常驻,减少网络IO</li>     <li>基于yaf,提供可靠,快速,简单的业务开发</li>     <li>基于MQ异步收集请求日志(这个是可选的)</li>     <li>这是一个裸的,基础的,可以在这基础上修改成适合自己业务的服务.</li>    </ul>    <h3>主要解决的问题</h3>    <ul>     <li>基于swoole开发servers时,每次修改业务代码,或调试,都要重启整个服务或reload,才能看到调试信息或结果</li>     <li>这种开发体验是很难受的,很影响工作效率.</li>     <li>那能不能像传统开发一样,用浏览器来调试业务逻辑呢?</li>     <li>每次只用修改->保存->刷新浏览器就能看到调试信息和结果,和以往的工作方式一样.</li>     <li>答案是肯定的.</li>     <li>基于yaf的特点,很方便的实现.</li>     <li>当业务逻辑实现以后,只要发布或重启servers即可.</li>    </ul>    <h2>安装</h2>    <h3>必要的扩展</h3>    <ul>     <li>nginx</li>     <li>mysql 5.7</li>     <li>PHP 7.1</li>     <li>extension=/usr/local/php7/lib/php/extensions/no-debug-non-zts-20160303/yaf.so</li>     <li>extension=/usr/local/php7/lib/php/extensions/no-debug-non-zts-20160303/yaconf.so</li>     <li>extension=/usr/local/php7/lib/php/extensions/no-debug-non-zts-20160303/swoole.so</li>     <li>extension=/usr/local/php7/lib/php/extensions/no-debug-non-zts-20160303/msgpack.so</li>     <li>extension=/usr/local/php7/lib/php/extensions/no-debug-non-zts-20160303/amqp.so</li>     <li>extension=/usr/local/php7/lib/php/extensions/no-debug-non-zts-20160303/igbinary.so</li>     <li>extension=/usr/local/php7/lib/php/extensions/no-debug-non-zts-20160303/redis.so</li>     <li>extension=/usr/local/php7/lib/php/extensions/no-debug-non-zts-20160303/donkeyid.so</li>    </ul>    <p>php.ini扩展配置</p>    <pre>  <code class="language-php">[DonkeyId]  ;0-4095  donkeyid.node_id=0  ;0-Timestamp  donkeyid.epoch=0    [yaconf]  yaconf.directory=/tmp/yaconf  ; yaconf.check_delay=0    [yaf]  yaf.environ = product           ; develop test  yaf.use_namespace = 1  ; yaf.action_prefer = 0  ; yaf.lowcase_path = 0  ; yaf.library = NULL  ; yaf.cache_config = 0  ; yaf.name_suffix = 1  ; yaf.name_separator = ""  ; yaf.forward_limit = 5  ; yaf.use_spl_autoload = 0</code></pre>    <p>代码安装</p>    <p>把文件放到</p>    <pre>  <code class="language-php">/wwwroot/data_site/ysapi</code></pre>    <p>nginx.conf配置</p>    <pre>  <code class="language-php">server {          listen       80;          server_name  api.local.com;          index index.html index.htm index.php;          root /wwwroot/data_site/ysapi/service;            if (!-e $request_filename) {                  rewrite ^/(.*)  /index.php/$1 last;          }            location / {                  try_files $uri $uri/ /index.php?$query_string;          }            location ~ \.php$ {                  fastcgi_pass  127.0.0.1:9000;                  fastcgi_index index.php;                  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;                  include       fastcgi_params;          }      }</code></pre>    <ul>     <li>重启Nginx,修改本机host文件</li>    </ul>    <pre>  <code class="language-php">127.0.0.1 api.local.com</code></pre>    <h3>浏览器访问</h3>    <ul>     <li>保存后,重启浏览器打开(以下是yaf默认路由方式):</li>    </ul>    <pre>  <code class="language-php">http://api.local.com/index/index/index/data/def    http://api.local.com/ index/  index/  index/ data/def                  域名/  模块/ 控制器/  方法 / 参数/值</code></pre>    <p>若无问题,将看到: <img src="https://simg.open-open.com/show/1cf688c552a26d8c4bccf3fbb3fd6776.png"></p>    <p>之后就可以按yaf的方式开发API业务逻辑</p>    <h3>启动 servers</h3>    <p>业务代码开发完成后,我们可以reload或重启servers,来提供最新的接口</p>    <pre>  <code class="language-php">php /wwwroot/data_site/ysapi/run.php</code></pre>    <p>服务启动无异常,可以使用api调用方法来尝试调用:</p>    <pre>  <code class="language-php">php /wwwroot/data_site/ysapi/call.php</code></pre>    <h3>客户端接口调用代码用例</h3>    <ul>     <li>用例中我们同时调用3个接口获得不同的数据</li>    </ul>    <pre>  <code class="language-php">try {      $api = new apicall();      $api->add('pagelist','index/index/index',['page'=>1]);      $api->add('user','index/index/index2',['user'=>1]);      $api->add('mess','index/index/index3',['mess'=>1]);      $rs=$api->exec('www');      $code=$rs['code'];      if($code!=200){          if($code==500){              // 全错          }elseif($code==300){              // 部份错          }else{              // 异常          }      }        $pagelist=$rs['pagelist'];      $user=$rs['user'];      $mess=$rs['mess'];        echo(print_r($pagelist,1));  }catch (Exception $e){      echo $e->getMessage().PHP_EOL;      die('ERROR-------------------------------'.PHP_EOL);  }</code></pre>    <h3>业务开发</h3>    <ul>     <li>按照YAF的方式去开发接口业务逻辑</li>     <li>新建模块->建控制器->建方法->浏览器访问你的方法进行调试</li>     <li>方法传入的参数可到/_data/模块/控制器文件中定义,如:</li>    </ul>    <pre>  <code class="language-php">// /ysapi/_data/Index/Index.php  // 路径及名字按YAF的方式定义  class IndexData{      public static $indexAction=[          'def'=>[              'page'=>1          ],          'p1'=>[              'page'=>1          ],          'p2'=>[              'page'=>2          ],      ];        public static $index2Action=[          'def'=>[              'id'=>1          ],          'u1'=>[              'id'=>1          ],          'u2'=>[              'id'=>2          ],      ];        public static $index3Action=[          'def'=>[              'id'=>1          ],          'm1'=>[              'id'=>1          ],          'm2'=>[              'id'=>2          ],      ];    // http://api.local.com/index/index/index3/  // http://api.local.com/index/index/index3/data/def  // http://api.local.com/index/index/index3/data/m1  // http://api.local.com/index/index/index3/data/m2  </code></pre>    <p> </p>