微服务架构设计及解答

转发说明

本文转发自开源中国的一次高手问答,解答来自于@cloudskyme 张锋,在此文里看到了许多没有注意到的技术栈,以及设计过程中的思考过程,在这里整理了部分解答用作备用,在此表示感谢

Q:你好,想请教一下,关于微服务架构service mesh,它比起传统的微服务架构有那些优势的地方?

Service mesh被用来处理服务间通讯的专用基础设施层,通过复杂的拓扑结构让请求传递的过程变得更可靠。
Service mesh通常作为一组轻量级高性能网络代理,这些代理和程序代码部署在一起,但是应用程序不需要对代理有任何动作。
Service mesh是一个网络模型,它是位于TCP/IP之上的抽象层。它假定底层的L3/L4网络是真实存在的,并且能够点对点地传递字节。
但与TCP不同的是,Service mesh具有更高的性能。
Service mesh最终并不是引入一项新功能,而是功能定位的转变。Web应用程序总是必须管理服务间通信的复杂性。
你可以思考下2000年的中型web应用程序的典型架构: 三层应用程序。 在这个模型中,应用程序逻辑、web服务逻辑和存储逻辑都是单独的一层。 层之间的通信虽然复杂,但这种复杂性是限定在一定范围内,因为毕竟只有两个跳转。这里没有“网格”,但是在每个层的代码中处理的跳转之间有通信逻辑。
当这种架构方式在面对应用程序内部逻辑越来越复杂化的情形时,它就开始崩溃了。 像Google、Netflix和Twitter这样的公司无时无刻都面临着巨大的流量需求,它们实现了云原生方案的前身: 应用层被分解成许多服务(有时称为“微服务”),层级间则形成了一个拓扑结构。 在这些系统中,广义的通讯层突然变得相关起来, 但通常以“胖客户端”的库集(library)形式出现, 比如twitter的Finagle,Netflix的Hystrix,以及Google的Stubby就是这样的例子。
从很多方面上来讲,像Finagle, Stubby和Hystrix这些库集其实是Service mesh的雏形。虽然它们受其周围环境的细节影响,并且需要使用特定的语言和框架,但是它们是用于管理服务到服务间通信的专用基础设施,并且(在开源Finagle和 Hystrix库集的情形下)可以在其公司之外使用。
到了云原生应用时期, 云原生模型本身结合了许多小型服务的微服务方法和两个额外的因素:容器(例如Docker),它提供了资源隔离和依赖关系管理,以及一个编排层(例如Kubernetes),它将底层硬件抽象出了一个同质池。
这三个组件支持应用程序在负载下可弹性伸缩的自然机制, 并能够处理云平台环境中存在的部分故障。
但面对数百个服务或数千个实例,和随时在重新安排实例的编排层,单个请求经由服务拓扑的路径可能非常复杂, 而由于容器使每个服务用不同的语言写入处理变得更容易了,库集方法也就不再可行了。
这种复杂性和关键性的结合,激发了对服务到服务间通信的专用基础层的需求,这个专用层与应用程序代码分离出来,并能够捕捉底层环境的高度动态特性。就是这一专用层我们称之为Service mesh。

Q:您好,诚然,微服务给我们带来了诸多好处,但是微服务应用是分布式系统,由此必然会带来固有的复杂性,与单体应用比微服务技术显得更复杂一些。测试一个基于微服务架构的应用也是很复杂的任务。采用Spring Boot架构,对一个单体式web应用,测试它的REST API,是很容易的事情。反过来,同样的服务测试需要启动和它有关的所有服务(至少需要这些服务的stubs)。所以不能低估了采用微服务架构带来的复杂性。有什么好的有效的方式减少这些复杂性呢?另外,使用docker和k8s等容器技术是不是微服务架构体系的标配?一个成熟稳定的微服务架构体系是不是不能不使用docker和k8s?谢谢!

复杂性是必然的,不能随便切分服务,因为每增加一层,就增加一层复杂度
docker的话应该说是标配,k8s现在是docker官方的标配,使用不使用这个需要看团队的熟悉及掌握情况
docker是提高了资源的利用率,降低了部署的复杂性,使开发 测试 线上环境能够保持一致

Q:您好,我是来自于一家中小企业的运维和开发人员,一直很微服务很感兴趣,如果我们企业将来打算采用微服务的架构,我们将面临着哪些挑战?给不能给我们一些建议?

面临着哪些挑战?
1、思想的转变。首先要理解什么是微服务。
2、新技术以及新框架的学习。比如spring boot、docker等。
给不能给我们一些建议?
1、本书的第一章讲解了传统的架构和微服务架构的区别以及演变流程,可以首先有一个概念性的了解。
2、可以先让一部分人使用并且深入,然后在整体推广

Q:我想请问一下,微服务的粒度到底怎么划分,有什么经验吗

这个也是个设计问题,首先是业务必须熟悉,然后可以根据领域模型进行领域划分,拆分可以根据AKF扩展立方体(Scalability Cube),
这个立方体有三个轴线,每个轴线描述扩展性的一个维度,他们分别是产品、流程和团队:
X轴 —— 代表无差别的克隆服务和数据,工作可以很均匀的分散在不同的服务实例上;
Y轴 —— 关注应用中职责的划分,比如数据类型,交易执行类型的划分;
Z轴 —— 关注服务和数据的优先级划分,如分地域划分。
三个维度扩展的对比

通过这三个维度上的扩展,可以快速提高产品的扩展能力,适应不同场景下产品的快速增长。不同维度上的扩展,有着不同的优缺点:
1.X轴扩展
优点:成本最低,实施简单;
缺点:受指令集多少和数据集大小的约束。当单个产品或应用过大时,服务响应变慢,无法通过X轴的水平扩展提高速度;
场景:发展初期,业务复杂度低,需要增加系统容量。
2.Y轴扩展
优点:可以解决指令集和数据集的约束,解决代码复杂度问题,可以实现隔离故障,可以提高响应时间,可以使团队聚焦更利于团队成长;
缺点:成本相对较高;
场景:业务复杂,数据量大,代码耦合度高,团队规模大。
3.Z轴扩展
优点:能解决数据集的约束,降低故障风险,实现渐进交付,可以带来最大的扩展性。
缺点:成本最昂贵,且不一定能解决指令集的问题;
场景:用户指数级快速增长。
如何将理论付诸实践?

1.为扩展分割应用
X轴:从单体系统或服务,水平克隆出许多系统,通过负载均衡平均分配请求;
Y轴 :面向服务分割,基于功能或者服务分割,例如电商网站可以将登陆、搜索、下单等服务进行Y轴的拆分,每一组服务再进行X轴的扩展;
Z轴 :面向查找分割,基于用户、请求或者数据分割,例如可以将不同产品的SKU分到不同的搜索服务,可以将用户哈希到不同的服务等。
2.为扩展分割数据库
X轴:从单库,水平克隆为多个库上读,一个库写,通过数据库的自我复制实现,要允许一定的读写时延;
Y轴 :根据不同的信息类型,分割为不同的数据库,即分库,例如产品库,用户库等;
Z轴 :按照一定算法,进行分片,例如将搜索按照MapReduce的原理进行分片,把SKU的数据按照不同的哈希值进行分片存储,每个分片再进行X轴冗余。
3.为扩展而缓存
在理想情况下,处理大流量最好的方法是通过高速缓存来避免处理它。从架构层面看,我们能控制的主要有以下三个层次的缓存:
对象缓存:对象缓存用来存储应用的对象以供重复使用,一般在系统内部,通过使用应用缓存可以帮助数据库和应用层卸载负载。
应用缓存:应用缓存包括代理缓存和反向代理缓存,一个在用户端,一个在服务端,目标是提高性能或减少资源的使用量。
内容交付网络缓存:CDN的总原则是将内容推送到尽可能接近用户终端的地方,通过不同地区使用不同ISP的网关缓存,达到更快的响应时间和对源服务的更少请求。
4.为扩展而异步
同步改异步:同步调用,由于调用间的同步依赖关系,有可能会导致雪崩效应,出现一系列的连锁故障,进而导致整个系统出现问题,所以在进行系统设计时,要尽可能的考虑异步调用方式,邮件系统就是一个非常好的异步调用例子。
应用无状态:当进行AKF扩展立方体的任何一个轴上的扩展时,都要首先解决应用的状态问题,即会话的管理,可以通过避免、集中和分散的方式进行解决。

Q:您好,请教一下,在基于Spring Cloud的微服务架构中,使用docker和k8s这些容器化技术能带来哪些方面的好处?对于中小规模的微服务架构中,是否有使用docker和k8s的必要性呢?谢谢。

容器技术不是模仿硬件层次,而是 在Linux内核里使用cgroup和namespaces来打造轻便的、将近裸机速度的虚拟技术操作系统环境。因为不是虚拟化存储,所以容器技术不会管 底层存储或者文件系统,而是你放哪里,它操作哪里。
也就是说,它能更细粒度的控制linux,能够做到按需分配,我们企业级开发种经常面临的一个问题就是资源不足,而使用docker可以更加有效的利用资源。这个跟企业的规模个人感觉不是很大。

Q:您好,我想问下在您10多年的职业生涯中,您对自己最满意的项目是哪个,它给你带来了哪些收获呢?

其实是接触服务化之后,涉及到微服务改造的项目,说收获吧,有效的提升了自己的架构能力,开阔了视野,从一个简单的CRUD码农晋升为架构级别,面对高并发以及大数据的挑战,有了应对的心得和体会。

Q:微服务怎么实现事务管理的?

其实微服务的事务就是分布式事务,刚性事务和柔性事务。
刚性事务是指严格遵循ACID原则的事务, 例如单机环境下的数据库事务。
柔性事务是指遵循BASE理论的事务, 通常用在分布式环境中, 常见的实现方式有: 两阶段提交(2PC), TCC补偿型提交, 基于消息的异步确保型, 最大努力通知型.。
分布式事务的各种实现方式:
如果业务场景需要强一致性, 那么尽量避免将它们放在不同服务中, 也就是尽量使用本地事务, 避免使用强一致性的分布式事务.
如果业务场景能够接受最终一致性, 那么最好是使用基于消息的最终一致性的方案(异步确保型)来解决.
如果业务场景需要强一致性, 并且只能够进行分布式服务部署, 那么最好是使用TCC方案而不是2PC方案来解决.

Q:微服务架构和传统的SOA架构有什么区别?仅仅只是微服务系统更小吗?

面向服务的架构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种各样系统中的服务可以以一种统一和通用的方式进行交互。
都是做服务化,那么微服务与SOA的异同有哪些呢?
相同点
需要Registry,实现动态的服务注册发现机制。
Ÿ需要考虑分布式下面的事务一致性,CAP原则下,两段式提交不能保证性能,事务补偿机制需要考虑。
Ÿ同步调用还是异步消息传递,如何保证消息可靠性?SOA由ESB来集成所有的消息。
Ÿ都需要统一的Gateway来汇聚、编排接口,实现统一认证机制,对外提供APP使用的RESTful接口。
Ÿ 同样要关注如何再分布式下定位系统问题,如何做日志跟踪?就像电信领域做了十几年的信令跟踪的功能。
差异点
Ÿ是持续集成、持续部署?对于CI、CD(持续集成、持续部署),这本身和敏捷、DevOps是交织在一起的,所以更倾向于软件工程的领域而不是微服务技术本身。
Ÿ使用不同的通信协议是不是区别?微服务的标杆通信协议是RESTful,而传统的SOA一般是SOAP,不过目前来说采用轻量级的RPC框架(Dubbo、Thrift、gRPC)非常多,在Spring Cloud中也有Feign框架将标准RESTful转为代码的API这种仿RPC的行为,这些通信协议不应该是区分微服务架构和SOA的核心差别。
Ÿ 是流行的基于容器的框架还是虚拟机为主?Docker虚拟机和物理机都是架构实现的一种方式,不是核心区别。
SOA和微服务的一个主要不同点就是自动化程度上的不同。大部分的SOA实现只达到服务级别的抽象,而微服务达到了对实现和运行环境的抽象级别。
在一个规范的微服务中,每个微服务应该被构建成胖JAR(fat JAR),其中内置了所有的依赖,然后作为一个单独的Java进程存在。

Q:您好,想请教下微服务模式下数据库的管理,多个服务之间的数据聚合怎么做才能避免数据过于分散导致查询实现困难?感觉 k8s 可以代替 spring cloud 的一些组件(比如均衡负载,配置服务,服务发现),如何才能分清它们之间的关系?

数据聚合
这个其实设计到微服务的一种设计模型,微服务的设计模式主要有以下几种:链式设计模式、聚合器设计模式、数据共享设计模式和异步消息控制模式。
聚合器设计模式是将请求统一由网关路由到聚合器,聚合器向下路由到指定的微服务中获取结果,并且完成聚合,如图2-5所示。首页展现、分类搜索和个人中心等通常都使用这种设计。

数据共享模式也是微服务设计模式的一种。应用通过网关调用多个微服务,微服务之间的数据共享通过同一个数据库,这样能够有效地减少请求次数,并且对于某些数据量小的情况非常适合,如图2-6所示。

也就是说,服务需要经过一定的设计处理。可以再网关部分实现数据查询的路由。

两个平台在核心领域都很强,并且在其他领域改进。Spring Cloud可以快速使用、对开发者友好的平台,然而Kubernetes对DevOps友好,艰难的学习曲线,但是覆盖更广泛的微服务障碍。以下是这些点的总结。
优点和缺点
两种架构处理了不同范围的MSA障碍,并且它们从根本上用了不同的方法。Spring Cloud方法是试图解决在JVM中每个MSA挑战,然而Kubernetes方法是试图让问题消失,为开发者在平台层解决。Spring Cloud在JVM中非常强大,Kubernetes管理那些JVM很强大。同样的,它就像一个自然发展,结合两种工具并且从两个项目中最好的部分受益。

Q:对于 #Jboot# 你怎么看?

从个人爱国的角度,我是非常支持Jboot这种开源项目的。而且它加入了很多符合中国企业级服务的东西在里边。
我觉得选择框架要基于两点:
1、开源项目更新的频率,如果更新的比较快,那么说明可维护性比较高,可以尝试使用。
2、使用群体,如果使用群体比较小众,那么很多坑就很难被发现,一旦在线上环境遇到,就会很难处理。还有就是如果使用的群体较小的话,遇到问题的时候解决的周期会较耗时。

Q:老师您好微服务之间通讯方式除了 RPC 还有哪些?

通常建议微服务之间使用RPC 的方式进行通信。但是像百度、google内部都使用brpc grpc进行通信。
蚂蚁金服使用的框架是SOFARPC,所以,如果公司内部能够统一,可以选择一套成型的rpc框架。

Q:您好,目前DUBBO重新启动后支持了更多语言,但是我们之前体验基于DUBBO的微服务时感觉不舒服,因为要设计出一个聚合层接收HTTP请求。对这部分内容您怎么看?之前试图增加一个BFF层,但是发现如果前端/移动端人员没有能力维护这一层,或者这一层耦合了业务的话,对后端人员是增加了工作量,最后放弃了。您这方面有什么经验么?目前微服务框架特别多,GOA等等都发了新版本,您对他们和SPRING CLOUD之间的取舍有什么意见么?最后就是现在有很多PAAS平台帮助实施微服务,甚至提供了Service mesh,您觉得这会是未来的趋势么?毕竟源生K8S还是比较有难度的。

DUBBO的主要功能还是在服务治理。聚合层可以参考网关,比如zuul。
关于BFF,一般现在都是前后端分离,前端框架可以使用angularjs vue等。
GOA是go语言的吧,spring cloud是java语言的,微服务是语言无关的,也就是哪个实现更好就使用哪个。我们团队服务端java人员较多,所以选择的spring cloud。
可以参考阿里云的实现:
https://www.aliyun.com/product/edas?utm_medium=text&utm_source=baidu&utm_campaign=zhongjianjian&utm_content=se_1000125613

Q:老师 您好 我 对这两个问题比较感兴趣,您能简单说下吗 目前公司正在使用微服务,但是怎么控制质量,这点大家都没有什么好建议, 监听工具也集成了一个 zipkin 但是没有使用起来6.微服务如何做质量管理?7.常用的 APM 监控工具包括哪些?

微服务如何做质量管理?
其实可以做一些静态代码检查,比如使用checkstyle等。详细的书中有提到。
常用的 APM 监控工具包括哪些?
cat pinpoint zipkin也算一种,这些都是无侵入式的,基本不对现有工程做任何影响。详细的书中也有提到

Q:我想问下,对于一个工作五年的java工程师,也做过无数的项目,简单的分布式项目也搭建过,但我一直想向架构方面靠拢,如何才能在这条路上入门呢?根据您的架构经验来看,平常有什么是值得注意的,技术转型最重要的是什么呢?

首先5年已经算是高级工程师了,但是无数的项目不太理解是什么意思,如果项目多,说明参与的项目规模比较小,如果想做架构的话,需要多关注底层的实现原理,多了解比如分布式的实现,以及如何应对高并发等。

Q:微服务现在的概念比较火,大家都使用什么框架来构建微服务?它跟软件工程的关系是怎么样的?

现在比较流行的是spring cloud体系,与docker结合,利用spring boot的简化开发来整体构建,关于完整的流程及示例可以参考我书中的内容。
我们知道,微服务就是把大的工程进行切分,能够独立测试和部署,总的来说就是分而治之的思想。

Q:实施微服务架构之后,系统就多了,测试就复杂了,尤其是异常场景的测试,这一块有什么好的解决方案

这个对测试的要求很高,而且部署也相对复杂,如果项目小的话可以少拆分。大项目需要开发团队和测试团队紧密配合,运用最为广泛的是基本路径测试法。
基本路径测试法是在程序控制流图的基础上,通过分析控制构造的环路复杂性,导出基本可执行路径集合,从而设计测试用例的方法。
设计出的测试用例要保证在测试中程序的语句覆盖100%,条件覆盖100%。

Q:您好,想请问一下关于微服务的问题定位。有什么经验吗?设计微服务,考虑粒度,这些有参考资料可以了解一下吗?

粒度业务不同拆分的服务就不同,通常可以根据系统访问的热度来进行拆分。

Q:你们线上使用的参数配置服务是?你们的微服务中怎么做服务灰度的?关于熔断、限流简单引入Hystrix 然后仿照网上的写法就可以了吗?你们的产品是什么类型,怎么拆分服务模块的?

配置服务apollo挺好的,基于sprng cloud config的封装。
灰度这个可以参考k8s的做法,做滚动升级。
熔断可以根据自身业务的特点进行设计,配置

Q:你好,微服务中,接口入参和返回类型,通常我们都是定义成了一个bean,那么调用方需要调用的时候,也需要这个bean,如何设计才能避免类的重复声明?提取一个api模块吗?

单独提出一个两个都依赖的工程也可以,一般使用dubbo做分布式都是这样实现

Q:你好,问一个和微服务无关的话题,希望能得到你的回答。假设现在我们的业务是面向3端的,app.h5.pc,你们会针对同一个接口写三套实现还是公用一套独立部署?如果,页面显示的字段值80%相同,20%不同?又如何弄

这个典型的一个网关的应用场景啊
网关可以看作一个各种微服务的入口。通常一个系统可以有一个或者多个网关。
可以给不同的端设置不同的访问网关,这样当某个端出现问题时,不会导致整个系统瘫痪。网页端使用Web网关,手机端使用手机网关,但可以使用同一套服务。在服务中可以以报文的方式对各个端进行标识。

Q:你好!据我了解,Spring Boot(包含Cloud组件) + Docker + Jenkins 是一套非常不错解决方案,您觉得这套方案怎么样?另外,说到Docker就不得不说Swarm和K8s,您觉得容器群达到什么样的规模,您会考虑K8s?我个人觉得,如果只是七八台机器,二十多个容器,应该是没有必要上K8s的,Swarm完全没有问题。

对,Spring Boot(包含Cloud组件) + Docker + Jenkins 是一套非常不错解决方案
如果集群规模比较小,使用swarm比较灵活

Q:请问下 你们配置中心用哪个解决方案

apollo配置中心

Q:老师能不能谈谈你在微服务方面都掉进过哪些坑?又是怎么爬出来的?我想这些更有借鉴意义~~ 只是需要牺牲你一下,自爆家丑了~~

这么说吧,一个微服务的完整流程想弄清楚就需要一段时间,然后还涉及到团队的技术推广,团队成员本身技术参差不齐,我感觉沟通的问题甚至大于采坑

Q:什么才是微服务,公司使用springboot把不同的模块做成一个服务,多个服务之间用springcloud调用,当服务很多的时候,产品出现问题,排查的时候比较繁琐,有什么好的方式可以监控这些问题,能够让我们更好的快速的定位产品出现问题的位置,快速解决

这是一个典型的APM监控的问题,书中有一章专门介绍

Q:您好,微服务这块,拆分的点依赖什么? 拆分后事物是怎么保证的,

AKF拆分原则
数据一致性分为以下几种情况:
Ÿ 强一致性
当更新操作完成之后,任何多个后续进程或者线程的访问都会返回最新的更新过的值。这种是对用户最友好的,就是用户上一次写什么,下一次就保证能读到什么。根据CAP理论,这种实现需要牺牲可用性。
Ÿ 弱一致性
系统并不保证后续进程或者线程的访问都会返回最新的更新过的值。系统在数据写入成功之后,不承诺立即可以读到最新写入的值,也不会具体地承诺多久之后可以读到。
Ÿ 最终一致性
弱一致性的特定形式。系统保证在没有后续更新的前提下,系统最终返回上一次更新操作的值。在没有故障发生的前提下,不一致窗口的时间主要受通信延迟、系统负载和复制副本的个数影响。DNS是一个典型的最终一致性系统。

Q:在一些传统的应用场景(PV、UV较低),适合用oauth鉴定场景吗?

这个是安全那一块啊,跟pv uv的量关系不大吧

Q:我把一个数据库拆成20多个微服务 . 查用户数据文章资源的时候, 用户信息是一个微服务, 文章资源又是一个微服务. 拆的太细了, 调用接口都不方便

数据量不大的话不建议拆分,而且感觉拆的太细了,另外,如果同库的话为什么要拆分?

Q:微服务如何方便简单的调试比如spring cloud,服务之间互相有调用就需要在本地都起来才可以开始调试(需要eueka server,zull,需要调试的service,启动完这些才可以开始调试), 目前可以想到的就是在公司内部搭建一套开发环境的微服务。但是这样如果有多个人连接一套开发环境很容易就自动变成集群了。

如果用spring cloud技术栈可以以小组为单位,构建一套开发环境,或者如果资源足够的话,可以使用docker为每个人单独搭建自己的开发环境

Q:我像请教下,给予微服务 分布式 springcloud 分布式事务方面有没有什么好一点的 解决方案。

这个之前回答了一下,可以参考一下。
其实微服务的事务就是分布式事务,刚性事务和柔性事务。
刚性事务是指严格遵循ACID原则的事务, 例如单机环境下的数据库事务。
柔性事务是指遵循BASE理论的事务, 通常用在分布式环境中, 常见的实现方式有: 两阶段提交(2PC), TCC补偿型提交, 基于消息的异步确保型, 最大努力通知型.。
分布式事务的各种实现方式:
如果业务场景需要强一致性, 那么尽量避免将它们放在不同服务中, 也就是尽量使用本地事务, 避免使用强一致性的分布式事务.
如果业务场景能够接受最终一致性, 那么最好是使用基于消息的最终一致性的方案(异步确保型)来解决.
如果业务场景需要强一致性, 并且只能够进行分布式服务部署, 那么最好是使用TCC方案而不是2PC方案来解决.

Q:项目微服务化后带来了一系列的问题。比如事务,请问作者在日常项目中所采用的解决方案是什么

我们一般是用
如果业务场景能够接受最终一致性, 那么最好是使用基于消息的最终一致性的方案(异步确保型)来解决.

Q:老师,您好。目前公司已微服务的理念用SpringCloud技术栈在开发,但是部署不能放在公网上,项目没有docker化,对于这种无法使用公网资源的情况,请问老师有没有好的解决思路或者是实践方法?

你们是互联网类的项目?这种一般都是暴露一部分服务给外部调用,可以选择nginx做反向代理,并且对于服务做高可用。
docker可以在内部项目中使用,如果这方面没经验,直接使用虚拟机也是可以的。

Q:微服务的运维和监控,是不是更麻烦了呢

现在一般都使用APM工具对总体做监控,比如pinpoint

Q:微服务之间,A服务要依赖B,C服务,怎么办,请求A服务时,怎么合并B,C服务返回的结果。注意什么,有哪些方式?谢谢〜〜

这个就跟正常的程序逻辑差不多,只是因为分布式的原因,需要加上熔断处理等,就是需要防止因为B、C服务不可用导致的雪崩效应。
这一部分在书中有讲到。

Q: 您好,我想咨询一下微服务业务层如何进行分层?业务系统如何定级,标准为什么?

设计原则之分层架构

同一公司使用统一应用分层,以减少开发维护学习成本。应用分层看起来很简单,但每个程序员都有自己的一套方法,哪怕是初学者,所以想实施起来并非那么容易。
最早接触的分层架构应该是我们最熟悉的MVC(Model-View-Controller)架构,其将应用分成了模型、视图和控制层,可以说引导了绝大多数开发者。而现在的应用(包括框架)中非常多架构设计都使用此模式。之后又演化出了MVP(Model-View-Presenter)和MVVM(Model-View-ViewModel)。这些可以说都是随着技术的不断发展,为了应对不同场景所演化出来的模型。而微服务的每个架构都可以再细分成领域模型,下面看一下经典的领域模型架构。
它包括了Domain、Service和Repositories。核心实体(Entity)和值对象(Value Object)应该在Domain层,定义的领域服务(Domain Service)在Service层,而针对实体和值对象的存储和查询逻辑都应该在Repositories层。值得注意的是,不要把Entity的属性和行为分离到Domain和Service两层中去实现,即所谓的贫血模型,事实证明这样的实现方式会造成很大的维护问题。基于这种设计,工程的结构可以构造为:

  • MicroService-Sample/src/
    domain
    gateways
    interface
    repositories
    services

当然,在微服务的架构中,每个微服务不必严格遵照这样的规定,切忌死搬硬套,最重要的是理解业务。在不同的业务场合,架构的设计可以适当地调整,毕竟适合的架构一定要具有灵活性。
分层的原则如下
Ÿ 文件夹分层法
应用分层采用文件夹方式的优点是可大可小、简单易用、统一规范,可以包括5个项目,也可以包括50个项目,以满足所有业务应用的多种不同场景。
Ÿ 调用规约
在开发过程中,需要遵循分层架构的约束,禁止跨层次的调用。
Ÿ 下层为上层服务
以用户为中心,以目标为导向。上层(业务逻辑层)需要什么,下层(数据访问层)就提供什么,而不是下层(数据访问层)有什么,就向上层(业务逻辑层)提供什么。
Ÿ 实体层规约
Entity是数据表对象,不是数据访问层对象;DTO是网络传输对象,不是表现层对象;BO是内存计算逻辑对象,不是业务逻辑层对象,不是只能给业务逻辑层使用。如果仅限定在本层访问,则导致单个应用内大量没有价值的对象转换。以用户为中心来设计实体类,可以减少无价值重复对象和无用转换。
Ÿ U型访问
下行时表现层是Input,业务逻辑层是Process,数据访问层是Output。上行时数据访问层是Input,业务逻辑层是Process,表现层是Output。

Q:我翻阅了好几本国内外各大高校广泛采用的软件工程、计算机专业的教材,都没有提到微服务这个概念。不过,书上倒是提到了一个相似的概念,那就是面向服务的架构(SOA)。所以说国内总是喜欢炒作一些概念,就好像不玩点新的就活不下去似的。微服务并不是技术标准,没有哪个标准化组织将其列为标准。我个人不推荐使用这个概念,因为不同的人对这个概念的理解是不一样的。我倒是提倡使用SOA,因为SOA是标准,Open Group就对其做了定义。并且SOA还有对应的建模语言,SoaML。

面向服务的架构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种各样系统中的服务可以以一种统一和通用的方式进行交互。
都是做服务化,那么微服务与SOA的异同有哪些呢?
相同点
Ÿ 需要Registry,实现动态的服务注册发现机制。
Ÿ 需要考虑分布式下面的事务一致性,CAP原则下,两段式提交不能保证性能,事务补偿机制需要考虑。
Ÿ 同步调用还是异步消息传递,如何保证消息可靠性?SOA由ESB来集成所有的消息。
Ÿ 都需要统一的Gateway来汇聚、编排接口,实现统一认证机制,对外提供APP使用的RESTful接口。
Ÿ 同样要关注如何再分布式下定位系统问题,如何做日志跟踪?就像电信领域做了十几年的信令跟踪的功能。
差异点
Ÿ 是持续集成、持续部署?对于CI、CD(持续集成、持续部署),这本身和敏捷、DevOps是交织在一起的,所以更倾向于软件工程的领域而不是微服务技术本身。
Ÿ 使用不同的通信协议是不是区别?微服务的标杆通信协议是RESTful,而传统的SOA一般是SOAP,不过目前来说采用轻量级的RPC框架(Dubbo、Thrift、gRPC)非常多,在Spring Cloud中也有Feign框架将标准RESTful转为代码的API这种仿RPC的行为,这些通信协议不应该是区分微服务架构和SOA的核心差别。
Ÿ 是流行的基于容器的框架还是虚拟机为主?Docker虚拟机和物理机都是架构实现的一种方式,不是核心区别。
SOA和微服务的一个主要不同点就是自动化程度上的不同。大部分的SOA实现只达到服务级别的抽象,而微服务达到了对实现和运行环境的抽象级别。
在一个规范的微服务中,每个微服务应该被构建成胖JAR(fat JAR),其中内置了所有的依赖,然后作为一个单独的Java进程存在。

Q:您好,对于企业软件:ERP、CRM、PDM、WMS、MES、HRMS、OA,各自都是独立的系统,适合改造成微服务吗?,适合,其实这是一个典型的微服务应用的场景,这些独立系统是市场上买回来的成熟产品,只是进行部分二次开发能实现微服务吗?国内有没有大企业把SAP、OracleEBS这样的ERP产品使用微服务改造?谢谢

如果不是自己开发的,购买的第三方的可能需要对原有系统进行改造,这种其实成本并不低。