最近使用微服务和触发器的场景较多,想着结合一些理论知识和实践做一些梳理和总结,从最开始的云里雾里,到现在的使用倒也经历了一段时间。刚接触这两个概念的时候感觉很乱,触发器和微服务有什么区别呢,好像都是起个过滤器的作用,在代码执行到一定逻辑的时候来调用,如果非要说区别,可能就是:
- 触发器粒度大一些?微服务粒度小一些?
- 微服务通过url调用,触发器通过脚本调用
通过后来查阅资料学习到的一些东西发现,上述区别并不尽然,甚至有些谬误,首先粒度大小并不绝对,其次调用方式并不能从根本上区分二者关系。
在接下来分析之前,先说个自我总结发言性的结论:微服务的主要作用就是解耦合,将服务拆分,易于维护和扩展。触发器的作用就是由操作行为自动触发的数据变化,不需要我们手动去更改。今天这篇就来仔细谈谈微服务,之后对触发器应用接触多了,完成这个系列,写这篇博客的时候参照了以下博客的一些内容:
SOA面向服务架构 https://www.jdon.com/soa.html
微服务与SOA之间差了一个ESB http://cloud.51cto.com/art/201512/500474.htm
微服务感觉看的最详实的叙述了 https://blog.csdn.net/wuxiaobingandbob/article/details/78642020?locationNum=1&fps=1
初一接触微服务,感觉莫名其妙,要在类的头上加标签,要在方法的头上加标签,和接口类似,但又不是接口,然后上线的时候还要各种操作ESB,不过最后能操作成功,所以到头来只是会用而已,不知道为什么这样用,只知道微服务怎么调用,部署,不知道为什么要调用、部署,于是决定探究探究。
微服务是干嘛的
我对于微服务最大的体会就是:对于云平台来说,如果元数据驱动的平台组件是骨骼,那么微服务和触发器就是串联骨骼的经络和血脉没有经络和血脉,一堆组件仅仅是静态的,不能变化,没有反馈,更何谈交互。而一个PaaS平台可以孵化无数个SaaS应用,每个应用都需要使用一套小服务来开发,而为了防止应用搭建复杂化和避免后期难以维护,所以每个服务运行在自己的进程中,并使用轻量级机制通信,通常是HTTP AP(Rest的方式,这就是为什么我能看到那些标签的存在)。好处体现在以下方面:
- 这些服务基于业务能力构建,并能够通过自动化部署机制来独立部署(体现在平台就是微服务站点部署和独立微服务站点部署)
- 这些服务可以使用不同的编程语言实现(只要实现结果,无所谓编程语言,这是我认为现在平台没有充分使用到微服务的地方,也可能是我平时使用其它语言的业务场景较少)
- 这些服务可以使用不同数据存储技术(“非结构化数据和结构化数据都可以按需存储”)
- 这些服务可以保持最低限度的集中式管理(这个厉害了,相当于接口不仅可以在一个项目里复用,甚至在不同项目间复用)
官方有个2pizza理论很有趣: 微 狭义来讲就是体积小、著名的"2 pizza 团队"很好的诠释了这一解释(2 pizza 团队最早是亚马逊 CEO Bezos提出来的,意思是说单个服务的设计,所有参与人从设计、开发、测试、运维所有人加起来 只需要2个披萨就够了 )。 而所谓服务,一定要区别于系统,服务一个或者一组相对较小且独立的功能单元,是用户可以感知最小功能集。
为什么用微服务
在谈这一块儿的时候,我决定用一个故事作为先导,增加博客的可读性。
一个开店的故事
怎么解释微服务的使用由来呢,我准备讲个故事:森林里有只大老虎一开始开了一家水果摊,用来对外售卖水果,并且为水果摊投资了如下几个部分(水果店铺租赁(小兔子负责),水果进货及运输(从小鹿子负责),水果销售(雇佣了一个土拨鼠)),注意,现在大老虎的投资都是点对点的服务(租赁,进货及运输,水果销售)。生意特别好,过了段时间,有些顾客向大老虎提出了买肉的需求,于是大老虎看到了商机又开了一家肉铺,同样进行投资(肉铺租赁(考拉负责),肉类进货及运输(仓鼠负责),肉类销售(雇佣了猴子)),同样生意火爆,接下来大老虎开了一家海鲜店,又消耗了一套投资,再之后是蔬菜铺,文具店等等,每开一个店铺,就消耗一套投资,维护一拨点对点的服务,大老虎发现自己的机构开始臃肿了,出现了以下问题:
- 肉的价格怎么定,蔬菜的价格怎么定,各个店铺独立为政,难以统计
- 哪个店铺到期,哪个店铺没到期;水果的淡季,肉类的旺季的时候,土拨鼠没事儿干,猴子忙不过来;运输的时候有时候运菜忙,有时候运肉忙,运输车辆不能复用。
- 主管进货的小鹿子突然离职,这样,一段时间,水果都供应不上,很多事情都是小鹿子自己维护的,走的时候也没好好交接
思考了问题后,大老虎做出如下调整,将所有单独的店铺整合为一个超市,中间有一根ESB的数据总线来对接消息(肉价涨了,菜价该怎么调之类的消息互动),前边是各类店铺(应用),后台则是一堆服务(所有关于定价的整合为定价服务,所有关于运输的整合为运输服务,所有关于租赁的整合为仓储服务),这样整合之后,产生了以下好处:
- 各类服务可复用了,例如运输车辆可以依据哪个地方忙闲灵活调配,小鹿子离职也不怕,谁都懂运输业务。
- 不必去单独维护独立应用去耗费大量精力,扩展性大大增加,再开多少个店也木有问题
- 之前水果的标价是精确到小数点后2位,肉是3位,之前菜铺通过电话沟通,价格记录在纸上,肉铺通过电子录入,杂七杂八的,很难结算,现在通过ESB统一控制,财务结算的时候不再混乱。
到了这里其实就完成了面向服务的SOA架构,后端封装了一系列自治的服务,前端是一系列应用,中间通过数据总线交互信息,统一格式配置和管理,让大老虎的店扩展起来越来越容易,越来越方便。但是在超市运营了一段时间后,大老虎又发现了如下问题:
- 运输服务部分越来越庞大,有的需要及时运送,有的需要加保鲜膜,各种不同场景的运输衍生出来。
- 仓库中心越来越庞大,集中在一个越来越大的仓库里,存取货都很不方便,各种食品需要存储条件又不一样,温度高了不行(肉类要腐烂),温度低了也不行(鲜花要被冻死)。
- 原来的定价服务是用野狗财务公司提供的标准,但现在收费越来越高,想换又不能换。
这个时候大老虎召集超市的高管们商量了下,决定采用如下措施:
- 将运输服务拆成一个个小的独立服务,例如为了方便肉菜蛋奶的新鲜,拆分了一个宅急送服务,对于不着急的水果,零食等拆分了一个普通运输服务,这些微小的服务不依赖于一个应用,但能保证提供更好的更有针对性的服务。
- 仓库拆分为冷鲜库(mysql),温室(redis)等,依据需求做更多的拆分(SOA虽然也能保证,但没有更细化的处理)
- 定价服务有的用野狗公司的,有的用豺狼公司的,实现最大化的随意
到了这里其实就完成了简单的微服务架构微服务架构里,服务拆分的更细,不仅能达到服务自治,还能实现团队自治,即一个服务模块可以拆分的更细,由不同团队去维护。自治服务内部的耦合更加松了。
以上这个瞎编的故事就是我对微服务的一些理解,从传统软件的开发,到面向服务的SOA+ESB总线模式,再到微服务架构,这个故事可能表述不清楚所有的概念,但能有个大概了解吧。
谈谈这个故事
首先大老虎的开店模式是传统的IT软件开发流程,在传统的IT行业软件大多都是各种独立系统的堆砌,这些系统的问题总结来说就是扩展性差,可靠性不高,维护成本高。一间间店铺各自独立为政,扩展性极差。体现在:
- 复杂性逐渐变高,比如有的项目有几十万行代码,各个模块之间区别比较模糊,逻辑比较混乱,代码越多复杂性越高,越难解决遇到的问题。(肉铺急速扩展,猪肉,牛肉,狗肉,乱七八糟肉越来越难维护)
- 技术债务逐渐上升,公司的人员流动是再正常不过的事情,有的员工在离职之前,疏于代码质量的自我管束,导致留下来很多坑,由于单体项目代码量庞大的惊人,留下的坑很难被发觉,这就给新来的员工带来很大的烦恼,人员流动越大所留下的坑越多,也就是所谓的技术债务越来越多。(肉铺主管运输的小鹿子离职,整个肉类运输瘫痪)
- 部署速度逐渐变慢,这个就很好理解了,单体架构模块非常多,代码量非常庞大,导致部署项目所花费的时间越来越多,曾经有的项目启动就要一二十分钟,这是多么恐怖的事情啊,启动几次项目一天的时间就过去了,留给开发者开发的时间就非常少了。(每天菜谱营业前都要集合所有员工,分配任务,应对新的顾客需求场景)
- 阻碍技术创新,比如以前的某个项目使用struts2写的,由于各个模块之间有着千丝万缕的联系,代码量大,逻辑不够清楚,如果现在想用spring mvc来重构这个项目将是非常困难的,付出的成本将非常大,所以更多的时候公司不得不硬着头皮继续使用老的struts架构,这就阻碍了技术的创新。(以前用斧子切牛肉,现在想换菜刀,换了菜刀发现猪肉需要斧子)
- 无法按需伸缩,比如说电影模块是CPU密集型的模块,而订单模块是IO密集型的模块,假如我们要提升订单模块的性能,比如加大内存、增加硬盘,但是由于所有的模块都在一个架构下,因此我们在扩展订单模块的性能时不得不考虑其它模块的因素,因为我们不能因为扩展某个模块的性能而损害其它模块的性能,从而无法按需进行伸缩。(总共就那么点儿员工,加个销售,就少个运输)
到后来大老虎引入了SOA模式,这种模式解决了相当一部分问题,但随着规模的庞大,由于 SOA 早期均使用了总线模式,这种总线模式是与某种技术栈强绑定的,比如:J2EE。这导致很多企业的遗留系统很难对接,切换时间太长,成本太高,新系统稳定性的收敛也需要一些时间。这个时候就需要加点儿微服务啦。微服务相对于SOA架构的区别是:
- 不与某种技术栈强绑定,这是最大的区别(定价服务使用了野狗公司,这个就很恼火,完全可以用其它公司更便宜的。)
- 服务可以更加细化拆分和部署(有点儿像docker啊)(将运输服务拆成一个个小的独立服务,例如为了方便肉菜蛋奶的新鲜,拆分了一个宅急送服务,对于不着急的水果,零食等拆分了一个普通运输服务,这些微小的服务不依赖于一个应用,但能保证提供更好的更有针对性的服务。)
微服务的特性
- 每个微服务可独立运行在自己的进程里,一系列独立运行的微服务共同构建起了整个系统
- 每个服务为独立的业务开发,一个微服务一般完成某个特定的功能,比如:订单管理,用户管理等(我用于图书管理系统和工单中心)
- 微服务之间通过一些轻量级的通信机制进行通信,例如通过REST API或者RPC的方式进行调用**(这就是Rest标签的由来吧,是一种通信机制)。**
微服务的特点
- 易于开发和维护。由于微服务单个模块就相当于一个项目,开发这个模块我们就只需关心这个模块的逻辑即可,代码量和逻辑复杂度都会降低,从而易于开发和维护。(部署独立mrest站点,启动迅速,代码量小)
- 启动较快,这是相对单个微服务来讲的,相比于启动单体架构的整个项目,启动某个模块的服务速度明显是要快很多的。(回收应用程序池即可,不到1分钟搞定)
- 局部修改容易部署,在开发中发现了一个问题,如果是单体架构的话,就需要重新发布并启动整个项目,非常耗时间,但是微服务则不同,哪个模块出现了bug只需要解决那个模块的bug就可以了,解决完bug之后,只需要重启这个模块的服务即可,部署相对简单,不必重启整个项目从而大大节约时间。(有了bug直接hotfix这部分的ESB的interface)
- 技术栈不受限,比如订单微服务和电影微服务原来都是用java写的,现在我们想把电影微服务改成nodeJs技术,这是完全可以的,而且由于所关注的只是电影的逻辑而已,因此技术更换的成本也就会少很多。(虽然目前还没有接触到多语言技术扩展,但感觉这个很强)
- 按需伸缩,单体架构在想扩展某个模块的性能时不得不考虑到其它模块的性能会不会受影响,对于微服务来讲,完全不是问题,电影模块通过什么方式来提升性能不必考虑其它模块的情况。
今天这篇就大概聊聊微服务是干嘛的,以及软件开发如何由IT独立单体架构到SOA架构再到微服务架构,之后实践多了,继续这个系列的跟进吧,希望能在更多业务场景里使用到微服务,对它的部署、调用,编写,维护等有更深刻的理解。PS:最近博客产出量较少,是得继续多学学啦。