为适应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
<?php
namespace 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
//全局安装deployer
composer 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
<?php
namespace Deployer;
/**
* 部署到测试
* dep deploy dev -vvv
*
* 部署到正式
* dep deploy prod -vvv
*/
require 'recipe/laravel.php';
// Project name
set('application', '芮廷出品');
// Project repository
set('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 deploys
add('shared_files', []);
add('shared_dirs', ['public/uploads','config','bootstrap/cache','storage','vendor']);
// Writable dirs by web server
add('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
,代码就发布到服务器了。