微服务实践分享

微服务实践分享

微服务简介

微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在所有情况下,每个任务代表着一个小的业务能力。

从实践中分析

为了更加深入地讨论微服务为我们带来的优势与不足,首先我们需要明确我们使用微服务来解决的问题,随后将根据实践——分析这些问题:

  1. 随着需求的不断增加,系统的不断复杂,系统的更新和修复会变得越来越困难
  2. 兼容多种不同前端设备
  3. 适应快速变化的需求
  4. 灵活的部署及维护
  5. 针对不同问题,整合多种技术栈

问题1:复杂度递增

复杂度分为:次要复杂度、必要复杂度。次要复杂度是指由人们本身处理问题的方法所产生的,而这类型的问题是可以被解决的,比如:面对同样的问题,用C来解决往往比用JS来解决要复杂很多。必要复杂度则是从软件本身要解决的问题衍生而来,并且无法被移除,也就是说需求本来就很复杂的情况下,无法通过软件开发模式或架构来将其完全简化。

从实践经验中来看,微服务架构能解决的其实也是次要复杂度,面对必要复杂度它并不能起到银弹的作用。

面对次要复杂度,相对于整体式架构,微服务的优势在于,新增或修改功能,微服务只需要重新部署与这些功能相关的服务即可,而整体式架构则需要停掉整个系统来进行更新。

而必要复杂度,往往是如下三种情况:

  1. 需求的复杂往往是由于其本身会牵连到系统的各个部分
  2. 需求之间也并不是独立的,而是相互牵连的
  3. 需求的难度会随着时间呈非线性增长,因为后来的需求往往要与之前的需求相互兼容,因此单纯的需求叠加必然要适配更多限制条件

面对必要复杂度,微服务并没有表现得更为简单易用。无论是微服务还是整体式架构,只要需求之间的逻辑与限制条件没有理清楚,没有处理好,都会导致系统存在大大小小的缺陷。因此解决必要复杂度的决定性因素在于项目组成员对业务的理解程度及其个人经验高低

问题2:兼容多种前端

兼容多种前端的本质其实在于前后分离,后端专注于业务逻辑及数据管理,前端专注于UI显示及页面跳转,它们之间通过JSON RPC通信。在这个问题上是否使用微服务并不是问题的关键点

问题3:适应快速变化的需求

  • 与我们开发软件的速度相比,需求、用户以及硬件变得更快。
  • 要把决策视为是写在沙滩上的,而不要把它们刻在石头上,大浪随时可能到来,把它们抹去。
  • —— 程序员修炼之道:从小工到专家

在本文所提及的问题中,这个问题应该说是最难的一个。业务需求变动几乎是每个项目必然存在的,小到细节,大到方向都可能发生改变。不变的需求应该只会出现在两种情况下:(1)这个项目的产品已经没人用了,也没人理了(2)这是个外包项目,任何细节变动都要另收费用

在处理快速变化的需求时,按理来说是微服务稍微更具优势,因为每次需求更改或叠加,微服务都可以通过调整对应部分来适应。不过这种优势也仅在于次要复杂度层面,但其并不能在必要复杂度层面起决定性作用,因为在既有的微服务系统和整体式架构系统中要修改一个冲击很大的需求所需的成本几乎是差不多的

问题4:灵活的部署及维护

在部署与维护方面,微服务的门槛相对更高,因为过去的系统一般只需要搭建其程序运行时环境即可,而微服务更多在于服务集成管理这套环境的搭建,而两者最终都可以向着自动化运维发展。因此该问题重点在于运维人员的能力

问题5:针对不同问题,整合多种技术栈

随着现在IT系统的复杂化及业务类型的多样化,很多问题的解决方案都不一定落在一种技术栈或是一种编程语言,如:在系统IO密集的地方使用事件驱动的语言开发(nodejs),而在CPU密集的地方使用编译型语言(C++、Go),或是某种功能已有很好的开源实现只需要集成进系统即可。而微服务刚好就能满足这类需求。相对于整体式架构,微服务在这方面具有天然的优势。但这种优势并不是完全没有缺点,稍后会在下边讨论这个问题

最终可能的解决方案

在给出最终解决方案前,我们还需要分析微服务本身所带来的问题,这样给出来的方案才具有针对性:

  1. 微服务在数据层的拆分,导致针对业务的事务操作更加复杂,关联查询也变得更有难度
  2. 在没有仔细深入思考的拆分下,很可能无法顾及项目的整体情况,导致项目七零八散的
  3. 微服务的拆分如果与业务需求产生了冲突,要解决这类问题往往要付出很大的代价
  4. 服务间的通信会增加更多系统开销以及系统复杂度
  5. 天然支持多种技术栈是优势,也是问题——在团队成员变动不大的情况下,这种模式会使项目进度高速发展。而在团队成员经常变动的情况下,这种模式反而会起副作用,因为技术栈不统一,很难随时召集各技术栈的精英

解决问题

针对问题1、2,要明白一点——做微服务不是为了拆而拆,而是应该拆才拆。至于怎样才是应该拆会在下边的方案中讨论

针对问题3,除了明白应不应该拆,掌握针对业务的正确拆法之外,还需要做好吐血的觉悟,因为在第一步拆法正确的情况下还出现这个问题,那大概率就是因为该项目的核心业务已经发生了较大的变化,那么就需要重新来审视整个项目,做一个合适的调整

针对问题4,系统之间的相互调用越多越是体现了耦合太紧,虽然拆是拆了但是很可能是这种拆法有问题,或是并不该拆的东西被拆掉了

针对问题5,该问题很重要,团队中一定要有一个主要技术,比如Golang,随后如果要为了某个功能引入另外的技术栈时要考虑清楚是否必需得用这种技术,如果不是绝对的必要,则最好用现有的技术栈来解决

最终方案

这里给出的方案应该是不限于微服务的,不过由于会使用微服务的分治思想,因此建议在一套微服务环境中运行(如:k8s)

三步主要思路:

  1. 设计以自己业务为中心的数据结构:首先必需根据整个业务设计好数据结构,整个系统中数据本身就应该是自我完善的一个整体,也就说就算没有后边的系统,数据结构本身针对业务逻辑就应该是合理的,对于分库分表除非已经是非常明确的情况下才做这部分设计,否则则不需要先考虑这个问题
  2. 设计以自己业务为中心的程序:根据整个业务设计好程序的各个模块,在需要拆分的地方做拆分,如:已经能够很明显看出是多个子系统。拆分原则,保证服务之间几乎没有耦合调用,只有业务调用
  3. 设计易变的服务:如第三方功能调用、业务中很可能发生经常变动又不该做成配置的功能,这部分服务也可以有它自己的数据库
思路1:整体业务数据结构设计

数据结构设计要仔细说恐怕一篇文章都是不够的,不过这里专门讨论一下运用冗余数据的技巧。在DB这层,如果完全不存冗余数据,则面对某些需求会出现很多复杂的关联查询等操作,如果针对查询主体保存一些冗余数据则可以减少关联查询。但是,冗余数据带来的弊端就是,当你要修改冗余数据时,你会发现你需要改的地方不止一处,最终反而会导致事倍功半。而在微服务中如果一开始只注重拆,很可能就会导致系统中会存在这些不该冗余的数据,而更吐血的是这些数据还在不同的服务中。因此在设计数据结构这个层面,一定要保证其对整体业务逻辑是兼容的。而冗余数据最好是那些存了就不会变的数据,可变数据还是使用关联查询更好

思路2:整体业务程序设计

一般web网站的业务程序设计还是比较容易掌握的,只要数据结构正确了,业务程序再烂也会有个底。如果非要说点什么,还是一些老话,做好模块解偶,做好工具封装,做好分层设计即可,剩下的难点就是根据个人经验去处理那些必要复杂度问题,以及纯算法问题

思路3:易变服务设计

易变服务设计最主要的地方还是在服务发现,比如你要针对某个订单做某个特定处理,而该处理又是另一个服务实现的功能,那么就得有个东西告诉你它在哪,你才能找到它并获取处理结果。另外,按理说这些服务也可以有自己的状态(DB),只是这些DB是不可能与第一步中的业务数据库有任何强关联,如果这些DB的数据对业务数据产生了不良影响,那么就说明这种拆分方式或数据结构设计很可能有问题。

系统整体结构图

avatar

总结

在软件工程中,没有银弹是不争的事实。但是,我们在不断的实践中,总能总结出许多可靠且实用的原则,以及针对不同情况采用不同处理方法的规律。微服务虽然上手门槛比较高,并且存在诸多问题需要驾驭,但是它本身为我们带来的思想和实现上的革新就值得让我们在其上狠下功夫。它给出的分治思想只要运用得当,就能够让我们避免遭遇项目庞大到无法维护的地步

一个项目只要它的必要复杂度达到一个量级,无论是采用何种架构都会面临很多棘手的问题,而最终是否能够很好的处理这些问题关键还是在于参与该项目的人。因此,架构的优劣并不是最关键的问题,最关键的是人在很多项目中磨练之后不断提升的经验与思想,只有人的经历、总结、提升,才是做好一个项目、做好一件事的关键所在

转载于:https://my.oschina.net/lovelyBoy/blog/1809143

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值