美文网首页
Write once, run anywhere

Write once, run anywhere

作者: linice | 来源:发表于2016-10-06 13:50 被阅读0次

    Write once, run anywhere

    概述

    环境:LNMP(CentOS7.2 + Nginx1.10 + MariaDB10.0 + PHP5.6),Laravel5.1,Yar;

    用户Api项目:项目名:example_user_api(example可替换为具体公司的名字,代表公司的user项目,下同),域名:api.user.example.com,对应数据:user;

    订单Api项目:项目名:example_order_api,域名:api.order.example.com,对应数据:order;

    订单项目:项目名:example_order,域名:order.example.com;

    正文

    作为一名PHP后端开发工程师,时常感受到来自项目deadline的压力,而且还有需求在开发过程中的变更。

    如何应对需求的变更和来自项目deadline的压力,那就要考虑系统的架构了,然后,才是编码——为何这样说,我喜欢用一个比喻解释,大厦的架构搭建好了,垒砖就容易多了。

    系统架构从项目的角度来讲有两个方面,一方面是项目与项目之间的搭配,另一方面是项目本身的分层。

    本文主要讲项目与项目之间的搭配这一方面的架构,也就是实现Write once, run anywhere的基础。先下结论:项目与项目之间通过RPC接口调用。

    如环境描述和项目清单所述,环境为LNMP,用户相关项目有用户Api项目,订单相关项目有订单Api项目和订单项目。

    读者或许有疑问了,这里用户相关的只有一个项目,为何订单相关的项目有两个,它们之间有什么区别?其实,这就是Write once, run anywhere的关键。

    用户Api项目能够为订单项目提供Rpc服务,订单Api项目更是主要是为订单项目提供Rpc服务,这两者本身都是没有界面的,这也是它们为何被定义为Api项目的原因。而订单项目通过调用用户Api项目和订单Api项目的Rpc服务,为用户提供查看、修改等操作自己订单的服务,因此是有界面的。
    然而,这也不足以要把订单划分成订单Api项目和订单项目两个项目。进一步的原因是订单Api项目不仅用于(用户查询、修改订单等操作的)订单项目,也可以为公司内部的ERP系统提供订单相关的Rpc服务。

    代码

    Talk is easy, show me the code.
    用户Api项目,有t_user表,其对应的Model为User,文件名为User.php,内容如下:

    <?php
    namespace App\Model;
    
    use DB;
    use Log;
    use Redis;
    
    /**
     * 用户表
     * @author los_gsy
     */
    class User {
        /**
         * 查询一条记录,根据id
         * @param int $id
         * @return null | object
         */
        static public function getById($id) {
            $result = DB::connection('user')->table('user')
                ->where('id', $id)
                ->first();
            if (!$result) {
                Log::warning(__METHOD__ . ': $param = ' . var_export(func_get_args(), true));
            }
            return $result;
        }
    
    }
    

    通过Controller封装成Rpc服务,这里取文件名为ModelController.php,内容如下:

    <?php
    namespace App\Http\Controllers\Rpc;
    
    use App\Http\Controllers\Controller;
    use App\Model\User;
    use Illuminate\Http\Request;
    use Log;
    use Yar_Server;
    
    /**
     * 模型
     * @author los_gsy
     */
    class ModelController extends Controller {
        /**
         * 构造函数
         */
        public function __construct(Request $req) {
            parent::__construct();
        }
    
    
        /**
         * 用户
         */
        public function user(Request $req) {
            $service = new Yar_Server(new User());
            $service->handle();
        }
    
    }
    

    类似的,订单Api项目,有t_order表,其对应的Model为Order,文件名为Order.php,内容如下:

    <?php
    namespace App\Model;
    
    use DB;
    use Log;
    use Redis;
    
    /**
     * 订单表
     * @author los_gsy
     */
    class Order {
        /**
         * 查询一条记录,根据id
         * @param int $id
         * @return null | object
         */
        static public function getById($id) {
            $result = DB::connection('order')->table('order')
                ->where('id', $id)
                ->first();
            if (!$result) {
                Log::warning(__METHOD__ . ': $param = ' . var_export(func_get_args(), true));
            }
            return $result;
        }
    
    }
    

    通过Controller封装成Rpc服务,这里同样取文件名为ModelController.php,内容如下:

    <?php
    namespace App\Http\Controllers\Rpc;
    
    use App\Http\Controllers\Controller;
    use App\Model\Order;
    use Illuminate\Http\Request;
    use Log;
    use Yar_Server;
    
    /**
     * 模型
     * @author los_gsy
     */
    class ModelController extends Controller {
        /**
         * 构造函数
         */
        public function __construct(Request $req) {
            parent::__construct();
        }
    
    
        /**
         * 订单
         */
        public function order(Request $req) {
            $service = new Yar_Server(new Order());
            $service->handle();
        }
    
    }
    

    订单项目,在这里用户需要查询自己的一个订单详情,于是通过调用用户Api项目和订单Api项目的Rpc服务来实现,代码如下:

    <?php
    namespace App\Http\Controllers;
    
    use App\Http\Controllers\Controller;
    use Illuminate\Http\Request;
    use Yar_Client;
    
    /**
     * 订单
     * @author los_gsy
     */
    class OrderController extends Controller {
        /**
         * 构造函数
         */
        public function __construct(Request $req) {
            parent::__construct();
        }
    
    
        /**
         * tmp
         * @param Request $req
         */
        public function tmp(Request $req) {
            //定义变量
            $oUser = new Yar_Client('http://api.user.example.com/Rpc/Model/user');
            $oOrder = new Yar_Client('http://api.order.example.com/Rpc/Model/order');
    
            //查询用户和订单
            $user = $oUser->getById(1);
            $order = $oOrder->getById(1);
    
            //打印用户和订单信息
            var_export($user);
            var_export($order);
        }
    
    }
    

    结尾

    Write once, run anywhere主要的思路就如上所述,以及代码示例了。仅用于学习参考,如果是生产使用,还需考虑安全、性能等因素。
    刚开始在简书上写日志,不足之处,还请各位不吝赐教。

    相关文章

      网友评论

          本文标题:Write once, run anywhere

          本文链接:https://www.haomeiwen.com/subject/vsmeyttx.html