AICon 上海站|90%日程已就绪,解锁Al未来! 了解详情
写点什么

Composer 结合 Git 创建 “服务类库”

  • 2019-09-15
  • 本文字数:2432 字

    阅读完需:约 8 分钟

Composer 结合 Git 创建 “服务类库”

我一直认为,现在的 PHP 已经进展到了工程化的领域。以前的 PHP 开发者,以快为美,速度和规模永远都是矛盾体。现在的 PHP 项目,特别是稍微大型一点的项目中,已经在逐渐演化成为需要兼顾工程化和规模化的层次了。一个代码工程化,就意味着演化为逐渐复杂的架构。复杂的架构,微服务往往就是一个很好的选择。

我在最近的一个项目中,就需要这个问题。我需要开发一个地图服务,这个服务当然不是简单的类库形式,而是有自己的数据库,自己的服务接口。这种情况其实最优的选择就是服务化。服务化的方式当然有很多了,Thrift,Http 等。但是我评估了下当前的部门环境,PHP 是主流的语言,加上自己这个项目的进度也比较紧,在我眼中,Thrift,Http 等方式都是使用网络协议实现服务的解耦合,这在我看来已经是重度解决方案了。我觉得在项目没有明确清晰病入膏肓的情况下是没有必要这种方式的。使用网络协议服务化的劣势在于引入了强大的复杂度。这个复杂度往往意味着人力,物力,时间上的投入。所以我希望,能够提供一个 PHP 语言的 “服务类库” 的形式进行开发。

我想到的就是 PHP 的 Composer。

Composer 的修改

创建服务类库

首先,我需要把我的 “服务类库” 从我的应用程序(起名为 xxx/main1)中独立出来,这个独立,我不是选择在应用程序中创建一个目录(事实我想过创建一个诸如 Services 的目录)。但是,如果和业务程序在代码上耦合起来,我觉得以人的惰性,很难从始至终都控制住自己能坚持不使用应用程序中方便的各种函数。所以我的选择是在 Git 库中新创建一个项目,起名为 xxx/mapService 。

composer.json

现在两个 Git 项目(xxx/main1 和 xxx/mapService),我在 main1 中的 composer.json 文件中增加下面的语句:


"require": {        "xxx/mapService" : "dev-master"},"repositories" : [       {                "type": "vcs",        "url" : "git@git.xxxx.com:cloud/mapService.git"    } ],
复制代码


而在 mapService 的 composer.json 如下:


{  "description": "xxxxxx",  "name": "xxx/mapService",  "type": "library",  "authors": [      {          "name": "Yejianfeng",          "email": "yejianfeng@xxxx.com"      }  ],  "require": {      "php": ">=5.2.4",      "illuminate/database" : "*"  },  "autoload": {      "psr-4": {          "xxxx\\xxxx\\MapService\\": "src"      }  } }
复制代码


这个配置告诉 main1 项目,mapService 的 Git 地址,需要使用的版本。


当然需要注意下面几点:


  • dev-master 意思是直接使用 mapService 的 master 分支。如果 mapService 有其他的 tag,这里完全可以使用 tag 信息

  • repositories 是说明项目的地址

  • 我这里的这个服务是放在我们公司自己搭建的 GitLab 上的

  • mapService 下面的 src 文件夹的命名空间为 xxxx\xxxx\MapService\ 并且支持 PSR-4

  • mapService 使用了 illuminate/database


最后使用 composer update -vvv 可以把我们需要的 mapService 下载下来放在 vendor 目录下。

更新修改

我们现在编辑器在 main1 项目中,如果我们有对 mapService 这个项目有进行编辑修改,并且希望合并到 mapService 的 master 分支的化,就直接进入 vender/xxx/mapService 目录,进行 Git 对应的操作。这样就可以进行直接的代码修改了。

独立配置

这种结构的组合方式只是完成了万里长征的第一步。后续更为重要的是在编写这个服务的时候,我需要时刻记住不使用 main1 的所有东西,这样才能保持 mapService 的独立性(独立性是服务化的必要条件之一)。比如我第一个遇到的问题就是配置文件需要独立。


我的实现方式是直接在 mapService 中创建一个 Config 类,这个类中直接写死配置。


这里一直觉得这个配置文件的实现方式有点挫,因为这样,这个配置文件就进入到了 Git 库。但是确实没有想到更好的方案了。Laravel 中有通过实现 ServiceProvider 将 Config 创建在 Laravel 的 config 文件夹下的方式,但是这种方式仅仅只适用于 Laravel。没有通用性。在另外一个方向,我想服务使用哪个数据库这个本身也是服务的一部分,放在服务的 Git 库中貌似也没有什么。

目录结构


目录结构如上


  • Configs 提供配置文件

  • Contracts 提供接口协议

  • Exceptions 提供异常

  • Supports 提供第三方方法或者类库

  • Models 提供对数据库的交互

  • Node.php 实现具体的接口


服务最重要的事情是接口协议。所以创建一个 Contracts 文件夹,将提供的服务接口化。


interface NodeInterface
{
/*
* 获取某个城市某个坐标点某个范围内的nodes
* @params int $cityId 城市id
* @params int $lat 纬度
* @params int $lng 经度
* @params int $distance 坐标点范围,单位:米
*
* @return array(Models/Node)
*
* @throws
*/
public function gets($cityId, $lat, $lng, $distance);
}
复制代码


接口的异常处理尽量使用异常,而不是错误码的方式进行交互。而且这些异常尽量要自定义。这样,在上层就有了统一处理的可能性。

思考

这个架构模式我定位为 PHP 代码层面服务化的模式。适用的场景应该是:


  • 后期计划服务化

  • 前期人力和思维都希望维持快速开发

  • 的场景

和 Git 的 SubTree 、SubModule 的区别

其实这三种方式说到底都是将一个项目作为另外一个项目的类库来使用的。SubTree 和 SubModule 是 Git 的解决方案。而 Composer 是 PHP 语言的解决方案,它除了将某个项目加入到另外一个项目的功能之外,还提供了加入版本,依赖解决等方案。如果你的项目是 PHP 的,那么无疑,使用 Composer 是更优的选择。

后期协议服务化

如果后期我的这个 mapService 想要协议服务化,那么这个 mapService 项目就可以简化成为一个 SDK,对于上层业务逻辑,只需要使用 composer update 进行更新就行。

服务注册和发现

我这里所谓的 “服务类库” 确实没有解决服务注册的问题,我无法知道到底有几个项目使用了我的服务。这个可能需要额外的流程的工作了。


本文转载自公众号滴滴技术(ID:didi_tech)。


原文链接:


https://mp.weixin.qq.com/s/6rKaqRgttESAB57tUiCpvg


2019-09-15 23:17649

评论

发布
暂无评论
发现更多内容

身为程序员还记得C语言经典算法(附带答案)吗?

ShenDu_Linux

c c++ 算法 编程语言

第十周学习总结

饭桶

Kubernetes初体验--用Kubernetes部署一个Web服务

网管

Kubernetes k8s Web 服务 Go 语言

排查指南 | mPaaS 小程序提示“网络不给力”时该如何排查?

蚂蚁集团移动开发平台 mPaaS

小程序 网络 小程序生态 mPaaS

使用 Jira Service Management 管理资产,您需要知道的5件事

Atlassian

数字化转型 Atlassian Jira ITSM ITIL

第十周课后练习

饭桶

接口测试如何在json中引用mock变量

测试人生路

json 接口测试 Mock

Mysql数据备份与恢复

张攀钦

MySQL

“摸爬滚打”多年,从月薪3K到30Kjava大神,我是怎么蜕变的?

比伯

Java 编程 架构 面试 计算机

源码 | 浅谈Webpack原理,以及loader和plugin实现。

梁龙先森

大前端 webpack

揭秘11.11监控排障利器 京东高稳定日志服务深度解析

京东科技开发者

云计算 DevOps 日志监控

「面试必备」最新整理出的腾讯C++后台开发面试笔记

linux大本营

c++ Linux 后台开发 架构师

Spring Boot 2.4.0正式发布,全新的配置文件加载机制(不向下兼容)

YourBatman

云原生 Spring Boot 新特性

Linux 笔记(三): 软件安装

Leo

Linux 学习 大前端

不懂源码?来看看阿里P8亲自手码的Spring源码解析整套笔记,高薪offer唾手可得!

比伯

Java 编程 架构 面试 计算机

一线大厂欺负程序员?京东单方面辞退38岁P7员工三次败诉

Java架构师迁哥

一点就透的二分查找算法

比伯

Java 编程 程序员 面试 计算机

架构师训练营第 1 期第 10 周总结

owl

极客大学架构师训练营

CAP理论

DL

Mac下Docker Desktop配置阿里云镜像加速器

jiangling500

Docker 阿里云镜像加速器

什么是物联网?常见IoT 物联网协议最全讲解

华章IT

物联网 IoT

深度剖析,为何C语言在开发领域的地位如此稳固

Philips

Python .net rust C语言 Go 语言

《我想进大厂》之Spring夺命连环10问

艾小仙

Java spring 程序员 面试 大厂

Canal 组件简介与 vivo 帐号实践

vivo互联网技术

数据库 分布式 数据存储

架构师训练营第十周作业

文智

极客大学架构师训练营

薇娅携手中国航天基金会与我们的太空 带你“益起探月,共舞九天“

C++语言中std::array的神奇用法总结,你需要知道!

华为云开发者联盟

容器 数组 函数

使用resilio实现多集群的k8s pod数据双向非实时同步

东风微鸣

Kubernetes 探索与实践 openshift

架构师第一期作业(第 11 周)

Cheer

作业

产业新基建,撬动数字经济发展新机遇

京东科技开发者

人工智能 新基建 京东

什么是低代码(Low-Code)?

阿里巴巴云原生

程序员 云原生 代码

Composer 结合 Git 创建 “服务类库”_文化 & 方法_轩脉刃_InfoQ精选文章