SOA 面向服务架构,是一个架构思想,是跨语言和平台的。SOA宗旨简单明了,根据项目服务完成架构搭建,以服务为基准点完成组件化和模块化。提供服务是项目的基本内容,其他的controller层和View层,只是体现服务的一种形式而已,目标是服务。
那么到底什么是服务呢?以电商为例子,提供商品浏览服务,商品收藏服务,账号服务,商品购买服务等等。这些事项目提供的服务,服务是由一个一个的业务点构成的,也就是说一个服务内容就是一条业务线。整改项目的服务体系可以说就是有各种各样的业务点组成的,由业务线串联的。
项目的组成方式了解之后,再来了解SOA面向服务架构。SOA面向服务的架构,面向服务,那么服务就是主要项目内容,服务是一条业务线,多个业务点组成的。业务点我们用Model表示,数据层(http)是业务的数据层,view层是业务的展示层,controller层是view/Model层级的控制层,这个分层实际上是剔除业务辅助项,只关注业务点。这个时候我们再去理解和构架SOA的时候,关注的元素就会变少,思考的方式亦会更加高效。这个概念其实也很普通,大家都这么说,但是做出来的框架却远不能及,还伴随着各种问题,需要用其他的中间件去解决问题。基础框架的不完善,势必造成上层建筑的不牢固。
SOA架构在现在衍生微服务的思想,本质是细化服务,分布式部署。但是多数确实服务模块的拆分,模块内含有多个相关服务,基本上属于简单的暴力拆分。然后就会出现模块间的通信,调用,数据库的分布管理,一致性问题,部署运维压力山大等等。细分到编码层级,微服务反倒是增加了编码难度。模块分组之后只是开发人员关注的模块少了,但是编码复杂度是上升了,调用其他模块服务(服务交叉性),数据库一致性问题。我想说的是服务是细分,不是模块分组,架构是细化服务,编码也需要遵循细化服务的原则。服务细化到底是什么呢?什么样的架构才算是服务细化和分离呢?上边讲到,服务是由业务点构成的业务线,那么服务细化的就是业务点,如何从服务中细化到业务点呢?
我们以商品浏览服务为例子,商品服务包含以下几个业务点:
1.商品分类
2.商品筛选
3.商品关注
4.商品详情
5.商品评价
6.商品店铺
7.商品推荐
8.商品对比
9.商品收藏
10.商品演示(视频/图文)
这是我们提供商品浏览服务的业务点,当用户使用项目时,一次只会提供一个业务点或多个业务点,用户一系列的操作完成一条业务线,一项服务。我们提供了多个服务,但是在用户使用过程中只对业务点感兴趣,在一项服务中,用户很可能去看其他服务的业务点。比如在支付服务中,或退货环节中,可以进行商品推荐和商品对比业务。这里我想指出服务的细化,是业务点的分离与松耦合,模块的划分是没有考量的,只会让项目变得难以扩展和维护。无论是前端,后端,移动端,都是一样的,都需要业务点分离与细化,才能够做好SOA。SOA并不是服务的体系分离的纵深内聚,而应该是业务点的松耦和分离,服务是相对用户而言的,用用户来完成一套属于自己的服务,而不是我们纵深完成服务流程,用户按照我们的剧本来体验服务,这种被牵着走的服务是不会得到好的用户体验的。开始没有被发现问题,只是开始而已。
SOA讲清楚了,该如何完成架构和编码呢?
架构我认为就是一个结构,一种规范和完善的逻辑。这样一个规范和逻辑会指导程序员如何编写高效和完善的代码。在这架构里,程序员只需要关注当前业务点,业务model,数据层,view层,controller层,全然不去关心。我想造个轮毂,先把汽车轮毂的接口标准拿来,再去实现具体内容。话多屁臭,代码走起:
class CarController{ //车架,里面放了各种接口,等待对应的零件装入。一个controller 可以提供多个业务点
var m:CarInterFace
func load(){
var view = CarView()
var tires = m.getTires()
var engines = m.getEngines()
var transmissions = m.getTransmissions()
m.run()
}
}
interface CarInterFace{ //定义接口,完成汽车的零件,还要能跑
func getTires():CarTires
func getEngines():CarEngines
func getTransmissions():CarTransmissions
func run()
}
class CarView{ //车内装饰 类似组件
}
class CarModel:CarInterFace{ //汽车零件,轮胎,发动机,变速器等待Tires, Engines, Transmissions
//model 完成零件的生产,然后在controller中组装。具体会更复杂和细化
func getTires():CarTires{
return CarTires
}
func getEngines():CarEngines{
return CarEngines
}
func getTransmissions():CarTransmissions{
return CarTransmissions
}
func run(){
}
}
class CarTires{
}
class CarEngines{
}
class CarTransmissions{
}
这段代码,就是一种规范,必须定义接口,细化功能,降低耦合提高重用。
说到这里我们仍然使用的单体架构,所有业务点全部在一个项目中编写,项目变大之后业务点几百个也是非常头疼的,再加上大数据系统,推荐系统等等。SOA的单体架构已不能满足需求,微服务就是SOA的一种思想完善和升级,本质和SOA没有区别的。微服务就是SOA的的分布式,SOA本事就是一种思想,微服务只是一种相对落地的一种实现。
以模块划分的微服务,是伪服务。把几个服务分离,分组放到多个服务器上边并不是微服务的核心机制。我更想用另一个概念,来自硬件,大家很熟悉的分层结构。分层结构以硬件层常用的一种结构,层与层通过接口完成通讯和交互,互不影响,显示器坏掉但是系统仍然运行(端端分离的概念)。那么在移动端和前端的机制就是数据和显示分层,后端的机制就是数据处理和数据库的分层。但是我们可能会把它们写到controller层,这样的依赖严重,无法重用,一个项目不大但是代码奇多就是这个原因了。上边的的代码让我们知道业务的时候如何分层,但是如何完成SOA的分层呢?我这里说的还是单体架构,没有涉及到微服务架构。分层的主要依据不在是业务类型的集合,而是依据数据库的分表。
还是电商为例:
1.用户表的分层,普通用户表,信用用户表,VIP用户表,店主表之类的细分
2.商品表的分层,食品表,电子产品表,商品推荐表之类的细分
3.店铺表的分层,等级店铺表,流量店铺表,名牌店铺表之类的细分
如果还是把所有商品全部放到一个表或者多个表,没有分层,相当说就是混乱的,复杂度是随着项目的复杂几何上升的。数据库表的没有做到细分,只是一味的添加字段关联,性能随着数据的上升而下降。当我们吧数据库完成细分,相当于完成业务点的细分。
那么一个用户登录的状态需要去手机号的表单找到用户的ID和等级然后去等级用户表查询用户的信息吗?当然不行了,用户的ID不能用只用自增主键了,需要我们从新定义规则,用户ID可以是特定字母或者数据开头,结尾拼接ID。比如UVIP100 VIP用户表的ID为100的用户,当然业务点不要直接使用SQL语句,应该对整个用户表定义接口完成调用。
SOA架构服务的体系,就是对服务的细分到业务点的细分,完成项目的业务的重用,动态完成业务线,提供服务。