为适应2022年新解决方案场景开发,考虑到团队实际情况,将使用Laravel后端开发框架。
框架使用核心扩展:
- 主框架:Laravel 8.*
- 主接口扩展:dingo/api 3.*
- 授权校验:tymon/jwt-auth JWT
- id加密码处理:vinkla/hashids
- Mqtt客户端:workman/mqtt 、Mosquitto-php(C扩展)
服务:Nginx、Redis、Mqtt服务(EMQX,客户端18083)、Supervisor
Laravel 开发规范
Laravel的路由将全由 Dingo/api 接管,所以环境部署后最好是生成api的路由缓存,开发环境中不用作何缓存(路由、配置等),同时建议开发人员统一开发环境使用 Homestead,使用Deployer构建自动化部署。
核心模块开发
项目结构
引入单一动作类开发方式,即
控制器,只接收请求和响应请求,所有逻辑处理都在单一类里。
比如一个用户信息接口请求案例如下:
- 路由:xx/auth/user_info
- 控制器:app/Http/Controllers/Api/AuthController.php ```go <?php namespace App\Http\Controllers\Api; //用户信息单一类 use App\Actions\Auth\UserInfo; …
//方法 public function info(Request $request, UserInfo $action) { … $response = $action->handle($xxx);
return $this->response->array(formats('成功', $response));
}
3. 单一类:app/Actions/Auth/UserInfo.php```go<?phpnamespace App\Actions\Auth;/*** 单一类只有一个方法handle,主要处理逻辑*/...class SMSCode{public function handle($){//表单校验//数据模型//服务类....
路由
统一在 routes/api.php 文件下,必须按照模块分组路由,如:
<?php//定义基于 Dingo 路由器的 API 路由$api = app(\Dingo\Api\Routing\Router::class);//定义 API 的版本分组,从而支持为多版本API接口,创建同样的路由以便后续回滚$api->version('v1', ['namespace' => 'App\Http\Controllers\Api', 'domain' => Config('app.api_domain')], function ($api) {//公用路由$api->group(['prefix' => 'pub'], function ($api) {//$api->post('/upload', 'CommonalityController@upload'); //文件上传});//企业设置$api->group(['prefix' => 'setting','middleware' => 'jwtauth.check:user'], function ($api) {$api->post('/info', 'Setting\EnterpriseController@info'); //用户信息});});
企业设置就属于一个基础模块,相关路由写进这个模块。
暴露出来的地址必须全部小写,组合词必须下划线分开,对应的控制器方法遵循驼峰式写法。如:user_info对应方法为userInfo。
独立模块化开发
一个模块为一个解决方案场景,统一在modules结构里,是一个完整的应用且依赖于基础模块。
如一个排队叫号解决方案:
按laravel扩展包方式开发,自动加载模式,需要在根项目composer.json里,通过PSR-4方式,执行composer du
..."autoload": {"psr-4": {..."Modules\\": "modules/"},},...
deployer构建自动化部署[项目发布]
1.本地开发机无密登录服务器
在开发机生成 deployer 专用密钥,然后拷贝公钥到服务器
ssh-keygen -t rsa -b 4096 -f ~/.ssh/deployerkey//拷贝公钥到服务器ssh-copy-id -i ~/.ssh/deployerkey.pub root@10.10.20.200//在开发机上以 root 用户免密码登录到服务器ssh root@10.10.20.200 -i ~/.ssh/deployerkey
服务器 /root/.ssh/authorized_keys 文件就会有开发机deployerkey文件里公钥内容,这样就实现免密登录。
2.本地开发机配置deployer
//全局安装deployercomposer global require deployer/deployer -vvv//查看版本dep --version//如果提示 dep 命令不存在,将 composer 的 bin 目录//即 ~/.composer/vendor/bin/,加到你的 PATH 环境变量里面//家目录下 .bash_profile(或.profile)文件vim ~/.bash_profile//添加到文件中export PATH=/usr/local/bin:/Users/maclechan/.composer/vendor/bin:$PATH//让其生效source .bash_profile//查看环境变量echo $PATH//有出现下面即添加成功//Users/maclechan/.composer/vendor/bin//重新打开终端窗口dep --version
3.deployer的使用
在开发机的项目目录中
//Deployer初始化,注意在deploy.php加到.gitignore里dep init<?phpnamespace Deployer;/*** 部署到测试* dep deploy dev -vvv** 部署到正式* dep deploy prod -vvv*/require 'recipe/laravel.php';// Project nameset('application', '芮廷出品');// Project repositoryset('repository', 'http://101.69.231.68:8889/ITC_FRAME/API/CORE.git');// [Optional] Allocate tty for git clone. Default value is false.set('git_tty', true);// 保存最近五次部署,这样的话回滚最多也只能回滚到前 3 个版本set('keep_releases', 3);//出现权限相关的问题,也可将此项设置为 true 后尝试set('writable_use_sudo', true);//set('cleanup_use_sudo', true);// Shared files/dirs between deploysadd('shared_files', []);add('shared_dirs', ['public/uploads','config','bootstrap/cache','storage','vendor']);// Writable dirs by web serveradd('writable_dirs', []);// 生产用的主机host('10.10.20.200')->stage('prod')->user('root')->port(22)->set('branch', 'master') // 最新的主分支部署到生产机->set('deploy_path', '/var/www/core') //服务器上项目地址->identityFile('~/.ssh/deployerkey') //公钥的位置->forwardAgent(true)->multiplexing(true);//->set('http_user', 'www') // 这个与 nginx 里的配置一致//->addSshOption('UserKnownHostsFile', '/dev/null')//->addSshOption('StrictHostKeyChecking', 'no');// 自定义任务:重置 opcache 缓存task('opcache_reset', function () {run('{{bin/php}} -r \'opcache_reset();\'');});// 自定义任务:重启 php-fpm 服务task('php-fpm:reload', function () {run('sudo service php7.4-fpm reload');});// 自定义任务:supervisor reload/*task('supervisor:reload', function () {run('sudo supervisorctl reload');});*/// 自定义任务:使用dingo路由task('route:clear', function () {run('php /var/www/core/current/artisan route:clear');});//执行自定义任务,注意时间点是 current 已经成功链向新部署的目录之后after('deploy:symlink', 'route:clear');after('deploy:symlink', 'php-fpm:reload'); // 执行自定义任务,注意时间点是 current 已经成功链向新部署的目录之后after('deploy:symlink', 'opcache_reset'); // 部署成功后重置 opcache 缓存//after('deploy:symlink', 'supervisor:reload');
代码提交到仓库后,执行 dep deploy prod -vvv,代码就发布到服务器了。
