Laravel项目概要

文件结构:

app业务功能逻辑 
bootstrap

框架启动入口,autoload.php比较重要,读环境变量,以匹配对应的配置文件,里面的cache目录需要被php进程可读写,否则框架运行有问题。 
app.php里的$app->conigureMonologUsing() 配置了monolog日志,影响全局的日志 Log::error/info/debug,值得详细看一下

autoload.php还生成了唯一的请求ID, 做完这些动作后, require了vendor/autoload.php这个文件,最终require_once了vender/composer/autoload_real.php, 这里面有一串类似于"99020184a024a1be726c1b1d********" 这个类(32位字符串),其实是为了保证应用的安全性,这里面加载了所有的class,要么是vendor/composer/autoload_static.php下面的,要么是vendor/composer/autoload_classmap.php或者vendor/composer/autoload_namespaces.php, 然后调用register方法进行注册,然后把每个class对应的类文件通过require逐个加载进来.

app.php中使用singleton方法加载了App\Http\Kernel, App\Console\Kernel, App\Exceptions\Handler这几个单例,同时引入了Monolog库,format, logHandle, processor对应日志格式,日志文件,上下文处理等数据

config

这里放置了整个项目的配置项

可以自定义的配置全部放到env目录中,并根据环境变量找对应的 .env.{APP_ENV},其他配置不要做自定义修改

app.php: 一些应用的配置如时区地点语言日志,还有一些将被自动加载的provider类(Auth,Broadcasting,Cookie,Hashing,Mail,Queue,Redis,Session,Validation,View等),  alias别名等

cache.php: 缓存的配置项, 默认的缓存driver, session缓存等

database.php: 数据库的配置项, 读写,host, port, 库名, user, password, 前缀, 严格模式等

session.php: session的配置项

queue.php: 队列的配置项

...

database目前没用,可以把数据库的变更放这里管起来,尽量用laravel的migration 
publicweb根目录,index.php是总的入口

注意执行业务逻辑脚本时,当前目录getcwd()即为public的目录,另外laravel中提供了很多目录的辅助函数 
https://laravel.com/docs/5.6/helpers#method-app-path

这里

require __DIR__ . '/../bootstrap/autoload.php';//注册自动加载器
$app = require_once __DIR__ . '/../bootstrap/app.php'; //开灯,生成应用实例
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); //让应用跑起来,返回结果,终止进程

$response = $kernel->handle($request = Illuminate\Http\Request::capture());

$response->send();

$kernel->terminate($request, $response);
resourceslang目录多语言没有用上,views目录保存了所有的邮件和短信模板AtsMail::makeContent() 是一个用模板+数据生成邮件内容的例子
routes没用上,基本都走模块里面的路由php artisan route:list 可以看到所有的路由,跑起来比较慢,因为子模块已经很多了
storage基本没用上,本地化里用来存上传的文件和图片,替代dfs 
tests单元测试,好像有其他同事用了,我这里没用上 
vendor第三方库,composer包管理的内容工程里带上了composer.phar文件,不用另行安装composer工具,如php composer.phar install 即可安装composer.json中的第三方包

 

app目录需要重点说一下:

Common

Base: 各个db连接的基础model,全局controller 全局service 全局exception的基类 
Constants: 全局配置,基本从be沿用来的 
Events/Jobs/Listeners/: 默认的,没用上,在模块里有另外在用的 
Helpers: 我没用上,不太了解 
Services:ES目录是同步基础数据到es搜索,Remote目录是各种rpc的client封装 
Support/Utils:是各种全局的辅助类 
VO:存放封装参数的数据结构

 
Console

命令行工具,很多不用的可以删了 
LoadBatchData: ats4月份上线时使用的导数据脚本,具体的导数据逻辑都在TobData模块下,Load*的脚本基本都是导数据时候用的 
EsClient: 配合es导数据使用的,里面dataDelivery/dataCandidate/dataStep仍然在,需要批量刷es数据时可使用 
DbTool: 为了批量给tob_ats_*库执行sql,只有开发环境在用,运维不需要这个 
Tool/ToolCommon: php artisan tool:common list 可以看到可用的命令,我自己在用的一些小工具 
Temp/*:配合上线变更的临时脚本

命令行工具有时间迭代最好清理一下,不用的删掉,在用的归归类
ExceptionsHandler 很重要,全局的异常处理,封装后输出

有优化空间: 
1 检查和屏蔽不应暴露给前端的异常信息 
2 优化异常的日志,确保方便查问题

Events/Jobs/Mail/Traits没啥用 
Providers

框架层面全局注册的一些类 
EventServiceProvider: debug打开时,记录所有执行的sql 
CollectionServiceProvider: 往laravel的Collection注入自定义的方法,这里只是个举例,deprecated

 
HttpKernel.php很重要,注入了所有路由的middleware,这里几乎没使用laravel的middleware,主要用到的路由现在都在模块TobAts的Http/Middleware/下面,值得重点看下路由这里随着业务演进,不断增加新的进来,有整理优化空间

模块: 
在app/Modules/*

TobAccount 
账号相关

AccountController 获取账号列表和组织结构 
AccountSettingController 获取账号设置相关

 

TobApp 
对接沈旭的App端的接口

 

面试签到等对接了,其他很多没用上,也有一些对接接口没写在这里 
有优化空间

TobAts 
流程相关

Events/Subscribers  业务触发的事件,流程是(举例)

  • app/Modules/TobAts/Providers/ModuleServiceProvider.php 中注册 EventServiceProvider
  • EventServiceProvider中注册业务的AtsSubscriber
  • AtsSubscriber中绑定了event和对应的handle方法
  • 这里触发event和event的处理是同步的

Helpers
  • AtsConfig/DeliverySourceConfig/EstimateConfig 流程相关配置
  • AtsException 子模块自定义的异常
  • AtsHelper 一些辅助函数

Http 
Jobs 分两类
  • 一类配合定时任务,检查发邮件之类
  • 一类是发起异步任务,通过消息队列供长进程在后台处理,如同步es搜索、主投评分之类
  • 配置很多从be代码里照搬,可能有一些用不到的或者重复定义的,有整理和优化的空间。
  • AtsSubscriber中注册的处理event的handle方法也写在这个类里了,可以重构优化到独立的handler类。
  • laravel中event和job的概念有点容易混淆,我们这个工程中event更偏业务概念,如做完一个流程,触发发放积分的动作。因为event是同步,需注意事务的范围。
  • 定时任务经常需要轮询tob_ats_*的数据库,轮询在基类AtsCronJob中,需要注意通过AtsMap::listByType(),防止在通用中访问到定制,或定制中访问到通用的数据库
  • 处理异步任务的长进程,需要注意:1 异常处理,不应被异常导致退出。2 资源泄漏,至少包括内存和文件句柄。
TobCampusAts校招,不熟悉 
TobCandidate候选人管理,不太熟悉 
TobData

数据迁移的业务逻辑。数据迁移因表结构和各部分业务逻辑差异较大,不能简单的用sql转换数据导入。大致概念是 
1 从be和其他老的库,数据转为业务上抽象的model 
2 按model再插入回新库 
遇到的问题是 
1 插入效率,按单个model逻辑上比较清晰,但数据量大时必须批量处理,此时model的批量处理脚本写起来比较繁琐

业务数据在业务之外的作用: 
1 反映了系统运行的状况 
2 为迭代扩展的功能提供支撑 
3 成后续功能迭代的累赘和负担

TobForm

面试登记表,包含了一个表单设计器,对应表 form_tpl_*, form_module_*, form_field_* 
- 一个module包括多个field 
- tpl为表单模板,一个tpl包括多个module 
- 具体结合业务后的数据存在 form_user_*  
- form_user_tpl 为从默认的tpl生成客户自己使用的表单 
- form_user_tpl_data 为从表单保存的数据

 
TobHomepage主页,不熟悉 
TobPosition职位模块 
TobResume简历模块 


代码风格

分库的设计

1 tobusiness.ats_map 定义了tob_ats_*业务库 
2 tobusiness.account_map 定义了账号和业务库的对应关系,新用户第一次登录时在这里新增记录 
3 ats_map目前只包括了通用和绿城,定制线其他项目好像有别的方式管理

请求处理的一般过程:

1 请求的url匹配模块的Routes/api.php 
2 对应的middleware处理认证和鉴权等 
3 走对应的controller,controller中只处理参数校验,然后调service完成业务逻辑 
4 调service,service调用其他service和model来处理主要业务逻辑 
5 model映射到表,model可有自定义的方法处理自身表范围内的逻辑,但不可调用其他service

参数校验 (抄阿里的)

下列情形,需要进行参数校验: 
1) 调用频次低的方法。  
2) 执行时间开销很大的方法。此情形中,参数校验时间几乎可以忽略不计,但如果因为参数错误导致中间执行回退,或者错误,那得不偿失。  
3) 需要极高稳定性和可用性的方法。  
4) 对外提供的开放接口,不管是 RPC/API/HTTP 接口。  
5) 敏感权限入口。  
下列情形,不需要进行参数校验:  
1) 极有可能被循环调用的方法。但在方法说明里必须注明外部参数检查要求。  
2) 底层调用频度比较高的方法。毕竟是像纯净水过滤的最后一道,参数错误不太可能到底 层才会暴露问题。一般 DAO 层与 Service 层都在同一个应用中,部署在同一台服务器中,所 以 DAO 的参数校验,可以省略。  
3) 被声明成 private 只会被自己代码所调用的方法,如果能够确定调用方法的代码传入参 数已经做过检查或者肯定不会有问题,此时可以不校验参数。

参数封装
  1. controller的处理请求的函数参数都从Request或FormRequest及继承类开始
  2. service的函数参数不允许直接传入外层的Requst,需根据业务逻辑传入明确的参数
  3. 参数数量过多时,为service的参数单独封装RequestVO
middleware相关

中间件这里跟安全通常有很大关系,也会影响到一些业务逻辑

  1. 所有的API接口应在各个模块的route.php中使用相应场景下的middleware
  2. 几个比较重要的middleware:
    1. TobAuth 要求用户经过登录认证
    2. TobCsrf 对post请求进行csrf校验,这里逻辑是登录时在browser记录csrf token,前端框架里封装所有的post请求时都会http header里带上,然后供后端比对校验
    3. TobToken 邮件、短信打开链接时使用,逻辑是业务场景生成链接时包含一个根据当前上下文生成的token,在TobToken中根据token查找当时的上下文,用于判断访问权限和业务逻辑
    4. TobInterviewAssistant/TobWechatReviewAuth 这两个是微信场景的,我不太熟
    5. noLoginAuth 直接信任链接中传入的user_id,并授权。一般为内部系统之间的调用
  3. 存在的问题:
    1. 登录日志审计目前好像是跨部门,可定期确认安全性上是否有疏忽
    2. TobCsrf没有对所有子模块使用,有安全隐患
    3. TobToken存在滥用,如从token打开的链接所包含的列表之类,目前也没对存token数据的表审计和过期清理,有优化空间。
      1. TobToken中增加独立的session维护token上下文 
      2. 考虑某些场景,相同的上下文的token可允许被重复使用,减少token的生成
      3. 审计和过期清理线上的token表数据
    4. noLoginAuth 有安全隐患,应尽量往内部rpc上迁移,有很大的优化空间
日志的管理

1 日志使用了laravel+monolog,配置在bootstrap/app.php中,日志格式需要对照配置看下 
2 本项目日志级别包括 debug/info/warning/error, debug日志和其他日志分开 
3 记日志并没有很要求规范,总结一个大致的要求:

  1. 处理一个完整请求(web的、计划任务的、异步任务长进程的、命令行工具的),无论正常还是异常都应有日志,包括输入输出的概要、处理时长、上下文(请求来源/登录用户等)。
  2. 发生外部调用时(包括rpc和其他方式的外部调用)
  3. 发生数据库写操作时
  4. 发生比较耗时的操作,如批量读数据时
  5. 代码中比较重要的条件分支(如:if(缓存命中){返回缓存}else{执行其他逻辑})
  6. 业务场景屏蔽异常时

4 日志方面本项目当前以能够查找问题为基准,很有优化空间
Service

本项目中Service大概分为三类:

  1. 对接controller调用,完成业务逻辑
  2. 供其他模块调用,作为全局公共service
  3. 供同模块其他service调用,作为模块内的公共service

这个分类并不严格,一个service类可能同时提供这些功用。一些大致的原则:
  1. 单个函数不能太长,需充分考虑业务逻辑的含义,划分子函数调用
  2. 注意子函数调用的层次关系
  3. 该设为private的设为private
  4. 重复逻辑该抽成公共函数的抽成公共函数
  5. 可能发生变化的地方抽出来成为函数
  6. 用laravel的依赖注入处理service之间的依赖关系,需注意循环依赖问题,因为脚本语言的限制,出现此问题时报错并不明显,暂时只能人为检查避免
数据库相关 
异常的管理:
  1. 全局异常的基类在 app/Common/Base/TobException.php ,定义了一些全局通用的错误码
  2. 按子模块定义自己的异常,举例:TobAts的 app/Modules/TobAts/Helpers/AtsException.php ,定义自己的错误码和内容
  3. 调用 error 方法,用错误码、错误内容、自定义的错误内容,构造异常并抛出
  4. 在全局的 app/Exceptions/Handler.php render() 中会统一处理异常,这里对异常的日志处理有点繁琐,包括异常的文件、行号、栈信息等,有优化空间,直接调 Log::error($exception) 可能会更好
  5. 一些屏蔽异常的场景 ,也应Log::error($e),日志记录完整异常

 

转载于:https://my.oschina.net/u/3412738/blog/3009278

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值