gavin_zhang
作者gavin_zhang·2019-07-04 10:08
系统架构师·某股份制银行

微服务系统设计之微服务拆分问题总结

字数 7298阅读 4640评论 0赞 1

随着移动互联网的发展和应用云化的普及,微服务已经成为企业应用服务化架构最流行的设计理念。随着银行 Fintech 的推广,越来越多的银行应用系统已采用或是计划采用微服务架构进行应用设计。以微服务、容器、 DevOps 等为支撑的云原生设计理念,缓解了随着新需求的不断增加的大型单体式应用变更越来越困难与移动互联网时代要求企业能实现应用功能的持续上线的矛盾。

微服务架构是一项在云中部署应用和服务的新技术。在企业内部推行微服务的实践过程中,会遇到各种各样的方案和策略的选择。在设计微服务系统的时候,如何拆分微服务是每个微服务系统设计的时候都需要面临的问题。微服务拆分是否合理,不仅影响到应用系统的效率,有时还会影响系统的成败。

日前,社区邀约了来自某股份银行的专家撰写了实践经验文章《微服务系统设计的 5 大挑战》,文中提出了进行微服务系统设计时会面临的 5 大挑战,同时讲解了如何解决这 5 大挑战,其中包含了微服务拆分这部分内容,因为篇幅原因,没有展开讲,所以本次活动将展开和深入微服务拆分这一方向,帮助大家更好的了解有关微服务拆分的内容。

活动中,各个领域的工程师和架构师,针对微服务拆分和建设进行探讨。活动结束后,我将活动中的问题和讨论进行了梳理,供大家参考。

1.关于微服务业务粒度拆分思路问题?

回答 1:

微服务粒度通常看业务情况,数据事务之间的关联,比如银行客户,可能有机构客户 ( 对公 ) ,个人客户 ( 对私 ) ,他们之间的数据差别其实还是挺大的,所以建议分为两个微服务,是否需要再细分,要看客户数据模型,比如客户有基本信息,扩展信息,关联信息等等,是否需要细分可以根据业务需求决定

回答 2:

微服务的拆分的原则就是业务对象,业务对象,业务对象(重要的事情说三遍),为什么是业务对象,其中包含两层含义,一个是业务,一个是对象。业务要求拆分的服务应该能完成一个相对完整的业务功能,而不是一个业务的一个步骤;对象要求服务有相对较好的封装,能够有一定的独立性。至于服务的粒度,没有一个标准,实际生产中不需要太过于纠结,个人偏向一开始时按照比较大的粒度,在随着需求不断迭代中,根据需求的变更成都和耦合性进行分拆,简单说,就是经常一起变更的,相关性比较大的功能,可以拆解成新的服务。

2.保险行业如果走微服务的路线,是先往容器云转还是直接用微服务来替换现有的系统?

回答 1:

是否可以考虑第三种路径,现有的微服务改造是一个渐进的过程,建议采用演进式的开发方式,通过 API 网关,将程序入口与主程序分离,在通过部分功能的微服务改造,结构整个系统,解耦出来的微服务就运行在容器云上。这个过程中,容器化和微服务是同时进行的。

回答 2:

步子千万别迈的太大,这样的话可能由于需要还很多技术债导致影响业务

正确打开方式应该像共产党学习,采取农村包围城市,先把简单的功能进行微服务改造,并验证效果

最好一步一个脚印来,如果直接大刀阔斧的改造,那就是刀刃上舔血,且收入产出比极低、风险极大

微服务改造并不是一蹴而就的,要循序渐进,施主莫急

回答 3:

容器和微服务不矛盾,也不是不可分离,不管容器或者微服务,建议能够自主可控!

做不到自主可控,可以先一步步来,一点点尝试,容器实现平台化,微服务构建业务,业务部署于平台,怎么走看项目优先级和需求,投入等,没有绝对的最佳实践

回答 4:

两者不是一会事情,只不过容器的管理运行模式和微服务化相辅相称,容器提倡一个进程运行模型, 微服务化和容器均可以逐步替换的形式

3.银行容器是直接运行在物理机的 linux 上,还是运行在云平台的虚拟机上,这两种方式哪种好?

回答 1:

各有优缺点,要看实际的需求和业务,以及机器配置 虚拟机相对容易管理,快速部署,回收,可以可以超分资源,隔离安全性更好,但会有性能损失 物理机则相反

回答 2:

都行啊,挺稳定的

回答 3:

物理机的 linux 上应该多些吧。

回答 4:

目前我了解,有很大一部分是运行在虚拟机上,最大的好处就是可以沿用虚拟化层对物理机的管理能力,不需要一套新的物理机调度系统。劣势就是,多引入了一层 Hypervisor ,不仅有性能的损耗,还可能多了一层故障点,如果是商用的 VM ,还是一大笔成本。 直接运行在物理机上,没有上述的问题,后续物理机上运行容器,可能会成为主流

回答 5:

现在的银行,证券行业内的开发测试云环境,若是跑 docker 的话,基本还是虚拟机。 他们几乎都会进行压测,将 docker 和 vm 进行对比。

理想一点的话,大家都明白 docker 直接跑在物理机上效果是最好的,如果物理机上的 docker 和 vm 对比性能的话, docker 几乎没有性能损失, vm 性能损失大约两成(有数据支撑)

所以尽力而为吧,采用容器技术栈的原因并不仅仅是为了性能提升,更重要的是对计算资源更细颗粒度的管理和更高效率的使用,加速微服务转型等等原因

回答 6:

具体宿主机选择物理机还是虚拟机,由数据中心实际情况决定,以下建议物理机仅供参考 1 、节省资源角度:虚拟机是虚拟化的结果,其目的是会了资源隔离,但会造成性能损耗;而容器技术也是一种虚拟化的实现,其调度技术也可以实现资源隔离的需求,因此直接使用物理机可充分利用计算资源,发挥容器技术的优势。

2 、应用角度:由于应用系统种类不一,对基础设施的资源需求也不一样,比如偏计算型就需要更多 CPU ,虚拟机无法灵活提供定制化的资源配置,而物理机可通过沟通特定硬件模块组装特定资源配置,并灵活拆卸和升级维护。

3 、建立应用规范及应用配置规格,同时确定各种规格的服务器

回答 7:

根据实际情况来定,跟网络,隔离性,对物理机,虚拟机的管理能力来定

4.一般拆分是否遵照用户最终价值原则,每个微服务都是纵向划分,微服务是对可用户可以使用的软件功能?

回答:

理论上,能够实现用户最终价值原则的拆分,是一种很好的方式。但是实际情况是很多时候按照这种方式进行拆分后,服务的很多功能可能是重复的,如果将这些功能独立成服务,那有违背了这个原则,不独立后续变更又不好维护。所以在这个原则的基础上,还需要一些折衷,但是一个原则是分出来的服务是业务对象,而不是功能。

5.双数据中心间进行 K8S 集群的 POD 调度?

回答:

可以大家一起讨论,一种做法是通过上层的云管理平台,为每个集群分配实例数,同时结合数据中心间的负载均衡策略,实现双活应用。在一个数据中心不可用时,需要通过云管,将实例转移到另外的集群。

6.微服务设计时应如何规划和考虑对服务可用性和性能的监控?

回答:

以下几点可以参考:
1 分布式链路追踪是整个监控系统的基础,基于 Goodle dapper 日志追踪很好的记录了系统请求的响应情况,是性能监控的基础。在实现分布式链路追踪,需要规划好日志规范(也可以选择响应的开发框架,如 sleuth )
2 微服务的资源使用情况,能够对微服务系统资源进行实时监控,自动或半自动的进行扩容
3 API endpoint 级别的故障监控,记录每个 API endpoint 的调用性能统计,结合负载均衡,及时的剔除亚健康的服务
4 可视化的监控和告警平台

7.微服务框架下与传统服务框架下的运维管理体系有哪些不同之处 ?

回答:

很好的一个问题,传统服务框架我理解是 SOA 的架构, SOA 对于运维管理体系和传统运维方式没有本质的区别。
而微服务由于本身的特点,他影响了不仅仅是应用架构,还有运维交付的方式。我们都知道 DevOps ,容器,微服务架构共同构成了云原生的设计理念。自动化基础设施和 DevOps 是 Martin fowler 提出的微服务前提条件,微服务为 DevOps 和自动化运维提供了一个合理的场景:微服务运维人员需要面对海量的运行实例和服务,服务之间相互调用,而且服务还需要支持快速的部署。这些传统运维体系是支持不了的,或者说支持成本非常的高。

8.Istio落地的难点在哪里?应用场景是怎样的?

回答:

Istio 目前是 Service Mesh 最流行的实现,这是一个优势也不是,优点是不需要在考虑选型了,缺点是没有其他的技术选择,基本上是和 kubernetes 强绑定了。随着 Istio 的成熟,未来可以支持大部分的微服务系统,但是目前还有一些问题:
1 Istio 目前还不是很成熟,问题,特别是性能上的问题还比较多
2 Istio 的模式比较适合服务接口规范和标准的,对于非标准的协议, Istio 支持不好
3 Istio 多应用隔离实现不好

9.保险行业如果不走微服务,只走容器云路线,有什么建议?

回答 1:

容器云的特点是轻,通过故障转移来实现高可用,否则很多的容器云的优势发挥不出来,所以我们的建议是容器云上的应用,要求是轻量级,以无状态为主。

回答 2:

首先还是得看需求

为什么要上容器云?为什么要做微服务转型?
并不是为了容器化改造,才上容器云
容器化业务和微服务转型 与传统物理机以及虚拟机的优势在于

  1. 更加轻量化,相较于虚拟机更细颗粒度的使用计算资源
  2. 和操作系统解耦,不再强依赖具体的 os 版本,这种痛大家都知道
  3. 提高业务扩展性,基于容器和微服务的业务在业务峰值和低谷的时候,我们可以设置 HPA 来自动的弹性伸缩,不需要人为控制,且速度更快(和 vm 完全不在一个数量级)

微服务和容器 是两个相辅相成的东西,微服务和容器相结合,会将两者的特点放大,产生 1+1 > 2 的效果

10.K8s平台网络规划该考虑哪些问题,如何做网络规划?

回答 1:

能否明确一下问题,我按照我的理解是 k8s 的网络组件( Flannel , calico 等)选择? K8s 有多种网络组件,每种网络的组件都有各自的优劣。如果是云原生的应用,建议采用 SDN 的组件,方便故障迁移。如果是传统的应用,建议选择 IP 端口映射的网络方案,方便兼容传统的 tcp 应用。同时选择网络组件时,网络监控的链路最终的能力也是需要考虑的。

回答 2:

你是指类似于 openstack 的多网络平面吗?
其实也不是不能做

  • 存储还是比较好隔离的,后端分布式存储比如 ceph ,更简单 nfs 都可以当做存储网络
  • 业务和管理隔离比较难隔离,如果有开发能力的话,完全可以将对应的管理组件全部放入 kube-system 命名空间下,且让这一个命名空间使用的网络和其他 ns 下面的网络不一致即可

只是简单说了一下思路,我这边落地也是这样设计的

11.ServiceMesh的应用场景?

回答 1:

也有些例外,比如 ServiceMesh 更社会所有的远程调用都是规范化标准化的,对于非标准的调用, ServiceMesh 支持不是很好。其次对于性能要求很高的系统, ServiceMesh 目前也不是很合适。 Service Mesh 目前还不是太成熟,要真正大规模的应用,善待时间。

回答 2:

现在的 servicemesh 落地还是很难得,但如果将 istio 和 envoy 拿出来的话,现在也有很多企业在使用了

首先我们需要看一下背景
servicemesh 的使用背景是 serverless 已经普及,我们部署业务也不需要自己购买 vm ,只需要远程调用函数即可,即代码也像水电等资源一样,按需付费

其次我们看一下条件
使用 servicemesh 的条件需要完成微服务改造,合理化的业务拆分等等

现在来说的话,这些都为时尚早,如果单纯想体验故障注入,熔断等功能的话,其实 istio 就可以了

12.windows应用系统和 Linux 应用系统如何容器化,并在一个容器云平台实现多集群管理?

回答:

Linux 原生就可以支持容器化,容器化应该问题不大;目前微软也支持 docker ,所以 .Net 应用也可以支持容器化。建议 windows 的容器集群和 linux 的容器集群单独部署,通过顶层的运管平台进行纳管。

13.证券行业如何进行微服务拆分?

回答:

对于证券的业务不是很熟悉,但是原理应该是差不多的。我们都知道,微服务的划分强调按照业务领域进行划分,每个服务是个业务对象。可以将系统的业务对象(这里的业务对象是业务人员的视角,不是开发人员的)进行归纳,记录每个业务对象之间的交互,对每个交互进行标注,那些是强一致的,那些是最终一致的。切分是,尽量找交互少的,支持最终一致性的关联进行切分。得到一个比较顶层的服务划分,再根据服务对象之间的数据共享进行梳理,提取公用的数据服务。

14.如何处理服务状态( State )? Stateless or Statefule ?

回答 1:

尽量不用有状态服务
或者结合中间件等工具改为无状态服务

回答 2:

服务状态可以简单的理解为两次请求之间需要共享的信息,如果一个服务请求的处理,需要依赖于之前或之后的请求,那么我们可以认为他是有状态的( Stateful )
有状态应用大大限制了应用的可扩展性,而且会导致服务之前的负载很难均衡,如果系统的大部分服务是有状态的,我们的微服务系统很难运维。
一般在设计微服务是,我们采用 “ 上升 ” 和 “ 下沉 ” 的方式来处理状态,把状态交给客户端和数据库。

15.为什么要避免出现上帝服务( God Service ),如何避免?

回答 1:

上帝服务这个概念谁能解释下?
如果不是微服务啥都不懂的话,不会出现 god service ,否则还叫微服务吗?
好好学习理解微服务就行

回答 2:

God service 是一种类似与 SOA 总线的服务,这一个或少数几个服务可能实现了大部分业务逻辑,或者换句话说,叫做业务编排。一旦这个服务出现问题,整个系统就无法对外提供任何服务,成为系统的单点。而且这些服务会成为整个系统的性能瓶颈。微服务倡导的是 Event driven 的模式,而不是这种业务编排的方式。
说明一下, API gateway 和消息中间件,由于不包括业务逻辑,不属于 God Service 的范畴。

16.服务之间的数据一致性对服务拆分有什么影响?

回答 1:

数据一致性通常基于业务相关,需要考虑强一致性,弱一致性,弱一致性通常可以拆分为不同的服务,强一致性可以定义为一个微服务,但也要看业务的复杂性等因素

回答 2:

数据一致性是服务拆分的时候的一个重要依据,对于强一致的数据,属于强耦合,理论上应该是放在一个服务中,但是有时会因为各种原因需要进行拆分,那就需要有响应的机制进行保证。另外,微服务设计时,可以尽量使用命令模式之类的设计模式,尽量减少需要强一致的数据范围。可以为后续的开发节省很多精力

17.服务的数据库是否需要隔离,需要怎么样的隔离级别?

回答 1:

隔离指的具体是什么?微服务是否使用独立数据库?如果是这个意思的话,通常建议不同服务使用不同的数据库,至少 schema 要不同,这就对微服务划分要求相对较高,服务的数据模型定义很重要

回答 2:

统一 steven 的意见,微服务每一个服务需要独立的部署和升级,这就要求他的数据也是独立的。如果数据库没有独立的 schema ,会导致不同的服务相互数据耦合。数据库的隔离级别需要根据数据库的类型和应用要求的可用性来评估。如果是轻量级的数据库,建议还是单独实例,如果是 Oracle 这种重量级,可以考虑独立的 schema ,当然支持多租户的云数据库是个更好的选择。

18.保险行业微服务进行业务拆分需要注意哪些地方?

回答:

对于保险业的业务不是非常了解,但是应该和其他金融行业差不多。业务拆分需要注意的一个是数据的一致性问题,由于微服务一般都是采用远程调用,所以是个分布式系统,遵循 CAP 原则,在拆分是需要充分考虑那些数据需要强一致。第二就是服务的独立性问题,每个服务应该拆分后可以独立的部署和更新,不需要依赖其他的服务,实现故障隔离,以往 SOA 的拆分方式,容易出现 God Service ,所以的业务都要通过这个 God Service ,一旦这个业务出现问题,整个系统都不可用,这不符合微服务的设计理念。

19.如何拆分微服务,有没有拆分的方法?

回答 1 :

我们觉得微服务定义和拆分都要基于业务来考虑,因为微服务最终是为了实现业务需求,所以不同的业务需求,微服务定义和拆分可能会不一样,可以参考我们的微服务系列文章,也可以看主数据管理, ddd 的书籍,具体的微服务拆分最好能通过咨询项目来做,可以少走弯路

回答 2:

拆分的方法论还是有的,比如 DDD , EventStorming 等。方法是死的,人是活的,再好的方法也需要人来执行,这块对整个业务流程要求非常的熟悉,最好是架构师和业务人员一起做这块的划分。

对于不是太复杂的系统,可以参考一下的方法:

可以将系统的业务对象(这里的业务对象是业务人员的视角,不是开发人员的)进行归纳,记录每个业务对象之间的交互,对每个交互进行标注,那些是强一致的,那些是最终一致的。切分是,尽量找交互少的,支持最终一致性的关联进行切分。得到一个比较顶层的服务划分,再根据服务对象之间的数据共享进行梳理,提取公用的数据服务。

20.如何在同城双中心做容器化部署?

回答:

从架构上来说 , 同城双中心可以考虑主备方案
1.注册中心有多种实现方式,最简单的是用容器平台自身的注册机制,部署到两个中心的服务分别注册到两个中心的容器平台,彼此不影响。

如果采用 Eureka 、 consul 等,也需要考虑主备方式,可能两个中心都需要部署,不管容器化部署或非容器化部署。

2.配置中心、中间件服务也是一样。

如果异地双活架构,可以考虑多集群或多云管理方案,但备份机制可能是需要的,是生产就绪的一个必要条件

如果涉及多地都有数据汇集计算交互,架构会复杂很多,需要考虑微服务的定义合理拆分,消息事件机制等

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

1

添加新评论0 条评论

Ctrl+Enter 发表

本文隶属于专栏

活动总结
活动总结是社区交流活动内容的总结及延伸,为大家提供了社区专家们丰富且高水平的理论知识、实践经验以及常见问题的最佳解决方法,非常值得大家收藏学习。

作者其他文章

相关文章

相关问题

相关资料

X社区推广