SpringCloud与Dubbo
# Restful**、SOAP、RPC、SOA、微服务之间的 区别**
# 题⽬描述
Restful、SOAP、RPC、SOA、微服务之间的区别
# ⾯试题分析
根据题⽬要求我们可以知道:
什么是Restful
什么是SOAP
什么是RPC
4种典型RPC远程调⽤框架
什么是SOA
微服务和SOA的区别
为什么要使⽤微服务
分析需要全⾯并且有深度
容易被忽略的坑
分析⽚⾯
没有深⼊
# 什么是Restful
Restful是⼀种架构设计⻛格,提供了设计原则和约束条件,⽽不是架构,⽽满⾜这些约束条件和原则的应⽤程序或设计就是 Restful架构或服务。
主要的设计原则:
资源与URI
统⼀资源接⼝(HTTP⽅法如GET,PUT和POST)
资源的表述
资源的链接
状态的转移
总之,RESTful的核⼼就是后端将资源发布为URI,前端通过URI访问资源,并通过HTTP动词表示要对资源进⾏的操作。
# 什么是SOAP
简单对象访问协议是⼀种数据交换协议规范,是⼀种轻量的、简单的、基于XML的协议的规范。SOAP协议和HTTP协议⼀样,都是底层的通信协议,只是请求包的格式不同⽽已,SOAP包是XML格式的。
SOAP的消息是基于xml并封装成了符合http协议,因此,它符合任何路由器、 防⽕墙或代理服务器的要求。
SOAP可以使⽤任何语⾔来完成,只要发送正确的soap请求即可,基于soap的服务可以在任何平台⽆需修改即可正常使⽤。
# RPC
RPC就是从⼀台机器(客户端)上通过参数传递的⽅式调⽤另⼀台机器(服务器)上的⼀个函数或⽅法(可以统称为服务)并得到返回的结果。
RPC 会隐藏底层的通讯细节(不需要直接处理Socket通讯或Http通讯)
RPC 是⼀个请求响应模型。客户端发起请求,服务器返回响应(类似于Http的⼯作⽅式)
RPC 在使⽤形式上像调⽤本地函数(或⽅法)⼀样去调⽤远程的函数(或⽅法)。
# 4种典型RPC远程调⽤框架
(1)RMI实现,利⽤java.rmi包实现,基于Java远程⽅法协议(Java Remote Method Protocol)和java的原⽣序列化。
(2)Hessian,是⼀个轻量级的remoting onhttp⼯具,使⽤简单的⽅法提供了RMI的功能。 基于HTTP协议,采⽤⼆进制编解码。
(3)thrift是⼀种可伸缩的跨语⾔服务的软件框架。thrift允许你定义⼀个描述⽂件,描述数据类型和服务接⼝。依据该⽂件,编译器⽅便地⽣成RPC客户端和服务器通信代码。
(4)dubbo,阿⾥的RPC框架。
(5)还有SpringCloud框架,微服务全家桶。为开发⼈员提供了快速构建分布式系统的⼀些⼯具,包括配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等。
微服务在本质上,就是rpc。rpc有基于tcp的,http的,mq的等等。spring cloud是基于spring boot的,spring boot实现的是http协议的rpc,算是rpc的⼀个⼦集。
# 什么是SOA
SOA(Service-Oriented Architecture),中⽂全称:⾯向服务的架构。
通俗点来讲,SOA提倡将不同应⽤程序的业务功能封装成“服务”并宿主起来,通常以接⼝和契约的形式暴露并提供给外界应⽤访问(通过交换消息),达到不同系统可重⽤的⽬的。
SOA是⼀个组件模型,它能将不同的服务通过定义良好的接⼝和契约联系起来。服务是SOA的基⽯。
# 微服务和SOA的区别
微服务是SOA架构演进的结果。两者说到底都是对外提供接⼝的⼀种架构设计⽅式,随着互联⽹的发展,复杂的平台、业务的出现,导致SOA架构向更细粒度、更通过化程度发展,就成了所谓的微服务了。
总之,微服务是SOA发展出来的产物,它是⼀种⽐较现代化的细粒度的SOA实现⽅式。
SOA与微服务的区别在于如下⼏个⽅⾯:
微服务相⽐于SOA更加精细,微服务更多的以独⽴的进程的⽅式存在,互相之间并⽆影响;
微服务提供的接⼝⽅式更加通⽤化,例如HTTP RESTful⽅式,各种终端都可以调⽤,⽆关语⾔、平台限制;
微服务更倾向于分布式去中⼼化的部署⽅式,在互联⽹业务场景下更适合。
# 为什么要使⽤微服务?
技术为业务⽽⽣,架构也为业务⽽出现,当然SOA和微服务也是因为业务的发展⽽出现。出现SOA和微服务框架与业务的发展、平台的壮⼤密不可分,下⾯借⽤dubbo的⽹站架构发展图和说明:
单⼀应⽤架构
当⽹站流量很⼩时,只需⼀个应⽤,将所有功能都部署在⼀起,以减少部署节点和成本。
此时,⽤于简化增删改查⼯作量的 数据访问框架(ORM) 是关键。
垂直应⽤架构
当访问量逐渐增⼤,单⼀应⽤增加机器带来的加速度越来越⼩,将应⽤拆成互不相⼲的⼏个应⽤,以提升效率。
此时,⽤于加速前端⻚⾯开发的 Web框架(MVC) 是关键。
分布式服务架构
当垂直应⽤越来越多,应⽤之间交互不可避免,将核⼼业务抽取出来,作为独⽴的服务,逐渐形成稳定的服务中⼼,使前端应⽤能更快速的响应多变的市场需求。
此时,⽤于提⾼业务复⽤及整合的 分布式服务框架(RPC) 是关键。
流动计算架构
当服务越来越多,容量的评估,⼩服务资源的浪费等问题逐渐显现,此时需增加⼀个调度中⼼基于访问压⼒实时管理集群容量,提⾼集群利⽤率。
此时,⽤于提⾼机器利⽤率的 资源调度和治理中⼼(SOA) 是关键。
平台随着业务的发展从 All in One 环境就可以满⾜业务需求(以Java来说,可能只是⼀两个war包就解决了)。
发展到需要拆分多个应⽤,并且采⽤MVC的⽅式分离前后端,加快开发效率;在发展到服务越来越多,不得不将⼀些核⼼或共⽤的服务拆分出来,其实发展到此阶段,如果服务拆分的⾜够精细,并且独⽴运⾏,我觉得就可以将之理解为⼀个微服务了。
# Spring Cloud的核心成员、以及架构实现详 细介绍
# 题目描述
Spring Cloud的核心成员、以及架构实现详细介绍
# 面试题分析
根据题目要求我们可以知道:
1.什么是微服务
2.SOA和微服务的区别
3.微服务架构优势
4.什么是Spring Boot
5.什么是Spring Cloud
6.Spring Cloud的核心成员
7.Spring Cloud架构实现
8.微服务、Spring Cloud、Spring Boot三者关系
分析需要全面并且有深度
容易被忽略的坑
分析片面
没有深入
# 什么是微服务
微服务的概念源于Martin Fowler所写的一篇文章“Microservices”。
微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于HTTP的RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立地部署到生产环境、类生产环境等。另外,应尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。
微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在所有情况下,每个任务代表着一个小的业务能力。
# SOA和微服务的区别
Martin Fowler提出来这一概念可以说把SOA的理念继续升华,精进了一步。 微服务架构强调的第一个重点就是业务系统需要彻底的组件化和服务化,原有的单个业务系统会拆分为多个可以独立开发,设计,运行和运维的小应用。这些小应用之间通过服务完成交互和集成。
从服务粒度上,既然是微,必然微服务更倡导服务的细粒度,重用组合,甚至是每个操作(或方法)都是独立开发的服务,足够小到不能再进行拆分。而SOA没有这么极致的要求,只需要接口契约的规范化,内部实现可以更粗粒度,微服务更多为了可扩充性、负载均衡以及提高吞吐量而去分解应用,但同时也引发了打破数据模型以及维护一致性的问题。
从部署方式上,这个是最大的不同,对比以往的Java EE部署架构,通过展现层打包WARs,业务层划分到JARs最后部署为EAR一个大包,而微服务则把应用拆分成为一个一个的单个服务,应用Docker技术,不依赖任何服务器和数据模型,是一个全栈应用,可以通过自动化方式独立部署,每个服务运行在自己的进程。
如果一句话来谈SOA和微服务的区别,即微服务不再强调传统SOA架构里面比较重的ESB企业服务总
线,同时SOA的思想进入到单个业务系统内部实现真正的组件化。
# 微服务架构优势
1.粒度更细(可维护和效率)
在将应用分解,每一个微服务专注于单一功能,并通过定义良好的接口清晰表述服务边界。由于体积小、复杂度低,每个微服务可由一个小规模开发团队完全掌控,易于保持高可维护性和开发效率。
2.独立部署
由于微服务具备独立的运行进程,所以每个微服务也可以独立部署。
3.容错
在微服务架构下,故障会被隔离在单个服务中。若设计良好,其他服务可通过重试、平稳退化等机制实现应用层面的容错。
4.扩展
单块架构应用也可以实现横向扩展,就是将整个应用完整的复制到不同的节点。
# 什么是Spring Boot
Spring Boot 框架是由 Pivotal 团队提供的全新框架,其设计目的是用来简化基于 Spring
应用的初始搭建以及开发过程。SpringBoot框架使用了特定的方式来进行应用系统的配置,从而使开发人员不再需要耗费大量精力去定义模板化的配置文件。
# 什么是Spring Cloud
Spring Cloud 是一个基于 Spring Boot 实现的云应用开发工具,它为基于 JVM 的云应用开发中的配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等,是微服务的一种实现。
# Spring Cloud的核心成员
1.Spring Cloud Netflix
Spring Cloud Netflix 集成众多Netflix的开源软件:Eureka, Hystrix, Zuul, Archaius,组成了微服务的最重要的核心组件。
2.Netflix Eureka
服务中心,用于服务注册与发现,一个基于 REST 的服务,用于定位服务。
3.Netflix Hystrix
熔断器,容错管理工具,旨在通过熔断机制控制服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。
4.Netflix Zuul
Zuul 是在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架。
5.Netflix Archaius
配置管理API,包含一系列配置管理API,提供动态类型化属性、线程安全配置操作、轮询框架、回调机制等功能,可以实现动态获取配置。
6.Spring Cloud Config
配置中心,利用git集中管理程序的配置。
7.Spring Cloud Bus
事件、消息总线,用于在集群(例如,配置变化事件)中传播状态变化,可与Spring Cloud Config联合实现热部署。
8.Spring Cloud Ribbon
Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP的客户端的行为。为Ribbon配置服务提供者地址后,Ribbon就可基于某种负载均衡算法,自动地帮助服务消费者去请求。
# Spring Cloud架构实现
通过这张图,可以比较清楚的了解到各组件配置使用运行机制:
1、请求统一通过API网关(Zuul)来访问内部服务.
2、网关接收到请求后,从注册中心(Eureka)获取可用服务
3、由Ribbon进行均衡负载后,分发到后端具体实例
4、微服务之间通过Feign进行通信处理业务
5、Hystrix负责处理服务超时熔断
6、Turbine监控服务间的调用和熔断相关指标
# 微服务、Spring Cloud、Spring Boot三者关系
微服务是一种架构的理念,提出了微服务的设计原则,从理论为具体的技术落地提供了指导思想。
SpringBoot专注于快速方便的开发单个个体微服务。
SpringCloud是关注全局的微服务协调整理治理框架,它将SpringBoot开发的一个个单体微服务整合并管理起来,
为各个服务之间提供,配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、精选决策、分布式会话等集成服务。
SpringBoot可以离开SpringCloud独立开发项目,但是SpringCloud离不开SpringBoot,属于依赖关系。
SpringBoot专注于快速、方便的开发单个微服务个体,SpringCloud关注全局的服务治理框架。
# 扩展内容
Spring Cloud与Dubbo的详细比较
从单体架构、到SOA、再到微服务的架构设计详解
微服务Dubbo和SpringCloud架构设计、优劣势比较
Dubbo与SpringCloud的Ribbon、Hystrix、Feign的优劣势比较
# 定时任务与feign超时该咋优化?
# 题目描述
面试中的问题:定时任务和feign的超时如何优化呢?
# 案情回顾
业务定时器应用半夜经常会触发熔断异常的告警邮件
根据邮件提示的类找到归纳以下表格
以上AD都是在一个分布式定时器事件处理应用(pinka-mod-scheduler)中对外的feign微服务调用产生的,相当于4类任务,每类都会调1次或多次外部feign微服务接口,而其中的AD接口发生了问题
其中A和B都是如下形式的异常
com.netflix.hystrix.exception.HystrixTimeoutException
at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$1$1.run(AbstractCommand.java:1154)
at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$1.call(HystrixContextRunnable.java:45)
at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$1.call(HystrixContextRunnable.java:41)
...
而C和D都是如下形式的异常
feign.RetryableException: 10.13.32.111:56000 failed to respond executing POST http://pinka-mod-customer/vip/partner/wallet/handlePartnerWithdraw
at feign.FeignException.errorExecuting(FeignException.java:67)
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:104)
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76)
at feign.hystrix.HystrixInvocationHandler$1.run(HystrixInvocationHandler.java:114)
...
Caused by: org.apache.http.NoHttpResponseException: 10.13.32.111:56000 failed torespond
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:141)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259)
...
# 追查
# HystrixTimeoutException超时异常
A与B的异常几乎每天都发生,且提示很明显,是Hystrix中设置了超时时间(目前为10s),并且执行超时导致的。为何会超时?去接口实现发现是有for循环场景的耗时逻辑
通过Kibana日志系统查历史执行耗时,也可以发现都基本>13s,所以这类异常基本确因
# 解决与思考
这其实是一个很典型场景,定时器任务执行并且处理逻辑是在另外一个微服务中,而处理逻辑属于复杂耗时,怎么办?
A. 增加超时时间,这是个粗暴的思路,因为设长了可能导致更大的问题,因为超时本来就是为了fastfail,设20s那之后可能还会遇到要30s甚至更久的场景。所以这个方案不能用在所有调用的公共默认超时时间上;
但是可以考虑用在某些接口上,比如VipTradeReportFeignService#getShopTradeReportByDate接口
评估正常耗时就是要15s以上,那就单独为其设置。相关配置方式:
#默认公共超时
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000
#单独为某个feign接口设置超时
hystrix.command."FeignService#sayHello(String)".execution.isolation.thread.timeoutInMilliseconds=15000
B. 优化接口提供方的逻辑执行时间。比如上述
VipTradeReportFeignService#getShopTradeReportByDate中的for循环,能否移到接口调用方,相当于接口提供方每次只执行for循环的1次操作。说白了就是确保接口返回要在超时时间内,这也符合微服务接口的设计原则。
C. 还有种思路是接口处理异步化,即接口提供方立刻返回,自己再用异步线程去处理最终逻辑。但是单纯这样会导致任务执行不可靠,即接口返回成功不代表真实一定执行成功了,如果此时接口提供方重启或异常导致耗时的异步逻辑执行一半就中断了,反而无法利用分布式定时任务调度的机制去重试执行等。所以使用此思路时,接口立刻返回但不能立刻将任务也作为成功执行完毕,需要配合一些异步通知机制,即接口提供方真实成功结束耗时操作,通知给接口调用方,接口调用方再将任务作为成功返回上报。
# feign.RetryableException failed to respond executing异常
这是C和D的异常,是随机低频告警。看字面意思是接口请求无响应,再结合邮件中的“熔断”字眼就自然推测是接口提供应用的问题了(事后证明被“熔断”字眼坑了)。所以去追查接口所属应用pinka-mod-customer在告警前后的监控指标,发现tcp连接、CPU、内存、网络流量表现都没什么异常状况。另外如果是熔断,那此接口必然得是调用失败多次呀,而每次定时任务对该接口调用却只有一次。
这时候查看接口提供方Controller层日志,发现告警时刻确实提供方没进入controller处理。
由此推测,提供方应用本身并无问题。而查看调用方应用日志和性能指标,在那个时刻也无异常情况,还在不断向其他应用调用产生日志。再结合这个异常日志,推测原因是由于调用方与提供方某次调用的网络闪断导致的(所以是随机低频)。
但为何会开启“熔断”,这个还无法解释。此时去追查邮件告警的代码源头,告警本质是通过重写了openfeign官方的HystrixCommand创建逻辑中的getFallback方法实现的,即进入fallback逻辑就会发邮件
此时真相大白了,其实只是进了fallback降级,并不代表开启熔断,比如在HystrixCommand的run中抛出异常会进fallback,run执行超时会进fallback,熔断也会进fallback。即A~D这些异常,虽然邮件写的是熔断,但其实都没开启熔断,而只是进了fallback降级!
所以feign.RetryableException failed to respond executing这个其实只是一次偶然的调用失败进了fallback而已,并没之前猜想的那么复杂。
# 解决与思考
邮件告警逻辑自然是要修改,区分熔断和降级。如果要判断熔断,可以用如下方法
protected Object getFallback()
{
if(this.isCircuitBreakerOpen())
{
// 熔断告警方式
sendExceptionEmail(...);
}
else
{
// 非熔断降级告警,如果无需告警也可不写
sendExceptionEmail(...);
}
....
}
# 微服务Dubbo和SpringCloud架构设计、优劣 势比较
# 题⽬描述
微服务Dubbo和SpringCloud架构设计、优劣势⽐较
# ⾯试题分析
根据题⽬要求我们可以知道:
微服务主要的优势
通讯协议
服务依赖⽅式
组件运⾏流程
微服务架构组成及注意事项
分析需要全⾯并且有深度
容易被忽略的坑
分析⽚⾯
没有深⼊
本⽂主要围绕微服务的技术选型、通讯协议、服务依赖模式、开始模式、运⾏模式等⼏⽅⾯来综合⽐较Dubbo和Spring Cloud 这2种开发框架。架构师可以根据公司的技术实⼒并结合项⽬的特点来选择某个合适的微服务架构平台,以此稳妥地实施项⽬的微服务化改造或开发进程。
微服务架构是互联⽹很热⻔的话题,是互联⽹技术发展的必然结果。它提倡将单⼀应⽤程序划分成⼀组⼩的服务,服务之间互相协调、互相配合,为⽤户提供最终价值。虽然微服务架构没有公认的技术标准和规范或者草案,但业界已经有⼀些很有影响⼒的开源微服务架构框架提供了微服务的关键思路,例如Dubbo和Spring Cloud。各⼤互联⽹公司也有⾃研的微服务框架,但其模式都于这⼆者相差不⼤。
# 微服务主要的优势如下:
# 1、降低复杂度
将原来偶合在⼀起的复杂业务拆分为单个服务,规避了原本复杂度⽆⽌境的积累。每⼀个微服务专注于单⼀功能,并通过定义良好的接⼝清晰表述服务边界。每个服务开发者只专注服务本身,通过使⽤缓存、DAL等各种技术⼿段来提升系统的性能,⽽对于消费⽅来说完全透明。
# 2、可独⽴部署
由于微服务具备独⽴的运⾏进程,所以每个微服务可以独⽴部署。当业务迭代时只需要发布相关服务的迭代即可,降低了测试的⼯作量同时也降低了服务发布的⻛险。
# 3、容错
在微服务架构下,当某⼀组件发⽣故障时,故障会被隔离在单个服务中。 通过限流、熔断等⽅式降低错误导致的危害,保障核⼼业务正常运⾏。
# 4、扩展
单块架构应⽤也可以实现横向扩展,就是将整个应⽤完整的复制到不同的节点。当应⽤的不同组件在扩展需求上存在差异时,微服务架构便体现出其灵活性,因为每个服务可以根据实际需求独⽴进⾏扩展。
本⽂主要围绕微服务的技术选型、通讯协议、服务依赖模式、开始模式、运⾏模式等⼏⽅⾯来综合⽐较Dubbo和Spring Cloud 这2种开发框架。架构师可以根据公司的技术实⼒并结合项⽬的特点来选择某个合适的微服务架构平台,以此稳妥地实施项⽬的微服务化改造或开发进程。
# ⼀、核⼼部件
微服务的核⼼要素在于服务的发现、注册、路由、熔断、降级、分布式配置,基于上述⼏种必要条件对
Dubbo和Spring Cloud做出对⽐。
# 1、总体架构
Dubbo 核⼼部件(如下图):
Provider: 暴露服务的提供⽅,可以通过jar或者容器的⽅式启动服务
Consumer:调⽤远程服务的服务消费⽅。
Registry: 服务注册中⼼和发现中⼼。
Monitor: 统计服务和调⽤次数,调⽤时间监控中⼼。(dubbo的控制台⻚⾯中可以显示,⽬前只有⼀个简单版本)
Container:服务运⾏的容器。
Dubbo 总体架构
Spring Cloud总体架构如下图
Service Provider: 暴露服务的提供⽅。
Service Consumer:调⽤远程服务的服务消费⽅。
EureKa Server: 服务注册中⼼和服务发现中⼼。
Spring Cloud总体架构
点评:从整体架构上来看,⼆者模式接近,都需要需要服务提供⽅,注册中⼼,服务消费⽅。
# 2、微服务架构核⼼要素
Dubbo只是实现了服务治理,⽽Spring Cloud⼦项⽬分别覆盖了微服务架构下的众多部件,⽽服务治理只是其中的⼀个⽅⾯。Dubbo提供了各种Filter,对于上述中“⽆”的要素,可以通过扩展Filter来完善。
例如
1.分布式配置:可以使⽤淘宝的diamond、百度的disconf来实现分布式配置管理
2.服务跟踪:可以使⽤京东开源的Hydra,或者扩展Filter⽤Zippin来做服务跟踪
3.批量任务:可以使⽤当当开源的Elastic-Job、tbschedule
点评:从核⼼要素来看,Spring Cloud 更胜⼀筹,在开发过程中只要整合Spring Cloud的⼦项⽬就可
以顺利的完成各种组件的融合,⽽Dubbo缺需要通过实现各种Filter来做定制,开发成本以及技术难度略⾼。
# ⼆、通讯协议
基于通讯协议层⾯对2种框架⽀持的协议类型以及运⾏效率⽅⾯进⾏⽐较;
# (⼀)⽀持协议
1、Dubbo:dubbo使⽤RPC通讯协议,提供序列化⽅式如下:
dubbo:Dubbo缺省协议采⽤单⼀⻓连接和NIO异步通讯,适合于⼩数据量⼤并发的服务调⽤,以及服务消费者机器数远⼤于服务提供者机器数的情况
rmi:RMI协议采⽤JDK标准的java.rmi.*实现,采⽤阻塞式短连接和JDK标准序列化⽅式
Hessian:Hessian协议⽤于集成Hessian的服务,Hessian底层采⽤Http通讯,采⽤Servlet暴露服务,Dubbo缺省内嵌Jetty作为服务器实现
http:采⽤Spring的HttpInvoker实现
Webservice:基于CXF的frontend-simple和transports-http实现
2、Spring Cloud:Spring Cloud 使⽤HTTP协议的REST API
# (⼆)性能⽐较
使⽤⼀个Pojo对象包含10个属性,请求10万次,Dubbo和Spring Cloud在不同的线程数量下,每次请求耗时(ms)如下:
说明:客户端和服务端配置均采⽤阿⾥云的ECS服务器,4核8G配置,dubbo采⽤默认的dubbo协议
点评:dubbo⽀持各种通信协议,⽽且消费⽅和服务⽅使⽤⻓链接⽅式交互,通信速度上略胜Spring Cloud,如果对于系统的响应时间有严格要求,⻓链接更合适。
# 三、服务依赖⽅式
Dubbo:服务提供⽅与消费⽅通过接⼝的⽅式依赖,服务调⽤设计如下:
ninterface层:服务接⼝层,定义了服务对外提供的所有接⼝
Molel层:服务的DTO对象层,
business层:业务实现层,实现interface接⼝并且和DB交互
因此需要为每个微服务定义了各⾃的interface接⼝,并通过持续集成发布到私有仓库中,调⽤⽅应⽤对微服务提供的抽象接⼝存在强依赖关系,开发、测试、集成环境都需要严格的管理版本依赖。
通过maven的install & deploy命令把interface和Model层发布到仓库中,服务调⽤⽅只需要依赖interface和model层即可。在开发调试阶段只发布Snapshot版本。等到服务调试完成再发布Release版本,通过版本号来区分每次迭代的版本。通过xml配置⽅式即可⽅⾯接⼊dubbo,对程序⽆⼊侵。
Dubbo接⼝依赖⽅式
Spring Cloud:服务提供⽅和服务消费⽅通过json⽅式交互,因此只需要定义好相关json字段即可,消费⽅和提供⽅⽆接⼝依赖。通过注解⽅式来实现服务配置,对于程序有⼀定⼊侵。
点评:Dubbo服务依赖略重,需要有完善的版本管理机制,但是程序⼊侵少。⽽Spring Cloud通过Json交互,省略了版本管理的问题,但是具体字段含义需要统⼀管理,⾃身Rest API⽅式交互,为跨平台调⽤奠定了基础。
# 四、组件运⾏流程
下图中的每个组件都是需要部署在单独的服务器上,gateway⽤来接受前端请求、聚合服务,并批量调⽤后台原⼦服务。每个service层和单独的DB交互。
▲Dubbo组件运⾏流程
gateWay:前置⽹关,具体业务操作,gateWay通过dubbo提供的负载均衡机制⾃动完成
Service:原⼦服务,只提供该业务相关的原⼦服务
Zookeeper:原⼦服务注册到zk上
▲Spring Cloud 组件运⾏
Spring Cloud
所有请求都统⼀通过 API ⽹关(Zuul)来访问内部服务。
⽹关接收到请求后,从注册中⼼(Eureka)获取可⽤服务。
由 Ribbon 进⾏均衡负载后,分发到后端的具体实例。
微服务之间通过 Feign 进⾏通信处理业务。
点评:业务部署⽅式相同,都需要前置⼀个⽹关来隔绝外部直接调⽤原⼦服务的⻛险。Dubbo需要⾃⼰开发⼀套API⽹关,⽽Spring Cloud则可以通过Zuul配置即可完成⽹关定制。使⽤⽅式上Spring Cloud略胜⼀筹。
# 五、微服务架构组成以及注意事项
到底使⽤是dubbo还是Spring Cloud其实并不重要,重点在于如何合理的利⽤微服务。下⾯是⼀张互联⽹通⽤的架构图,其中每个环节都是微服务的核⼼部分。
# (⼀)架构分解
⽹关集群:数据的聚合、实现对接⼊客户端的身份认证、防报⽂重放与防数据篡改、功能调⽤的业务鉴权、响应数据的脱敏、流量与并发控制等
业务集群:⼀般情况下移动端访问和浏览器访问的⽹关需要隔离,防⽌业务耦合
Local Cache:由于客户端访问业务可能需要调⽤多个服务聚合,所以本地缓存有效的降低了服务调⽤的频次,同时也提示了访问速度。本地缓存⼀般使⽤⾃动过期⽅式,业务场景中允许有⼀定的数据延时。
服务层:原⼦服务层,实现基础的增删改查功能,如果需要依赖其他服务需要在Service层主动调⽤
Remote Cache:访问DB前置⼀层分布式缓存,减少DB交互次数,提升系统的TPS
DAL:数据访问层,如果单表数据量过⼤则需要通过DAL层做数据的分库分表处理。
MQ:消息队列⽤来解耦服务之间的依赖,异步调⽤可以通过MQ的⽅式来执⾏
数据库主从:服务化过程中毕竟的阶段,⽤来提升系统的TPS
# (⼆)注意事项
服务启动⽅式建议使⽤jar⽅式启动,启动速度快,更容易监控
缓存、缓存、缓存,系统中能使⽤缓存的地⽅尽量使⽤缓存,通过合理的使⽤缓存可以有效的提⾼系统的TPS
服务拆分要合理,尽量避免因服务拆分⽽导致的服务循环依赖
合理的设置线程池,避免设置过⼤或者过⼩导致系统异常
# 六、总结
Dubbo出⽣于阿⾥系,是阿⾥巴巴服务化治理的核⼼框架,并被⼴泛应⽤于中国各互联⽹公司;只需要通过spring配置的⽅式即可完成服务化,对于应⽤⽆⼊侵。设计的⽬的还是服务于⾃身的业务为主。虽然阿⾥内部原因dubbo曾经⼀度暂停维护版本,但是框架本身的成熟度以及⽂档的完善程度,完全能满⾜各⼤互联⽹公司的业务需求。如果我们需要使⽤配置中⼼、分布式跟踪这些内容都需要⾃⼰去集成,这样⽆形中增加了使⽤ Dubbo 的难度。
Spring Cloud 是⼤名鼎鼎的 Spring 家族的产品, 专注于企业级开源框架的研发。 Spring Cloud ⾃从发展到现在,仍然在不断的⾼速发展,⼏乎考虑了服务治理的⽅⽅⾯⾯,开发起来⾮常的便利和简单。
Dubbo于2017年开始⼜重启维护,发布了更新后的2.5.6版本,⽽Spring Cloud更新的⾮常快,⽬前已经更新到Finchley.M2。因此,企业需要根据⾃身的研发⽔平和所处阶段选择合适的架构来解决业务问题,不管是Dubbo还是Spring Cloud都是实现微服务有效的⼯具。
# Dubbo与SpringCloud的Ribbon**、Hystrix、** Feign的优劣势比较
在微服务架构中,分布式通信、分布式事务、分布式锁等问题是亟待解决的⼏个重要问题。
Spring Cloud是⼀套完整的微服务解决⽅案,基于 Spring Boot 框架。确切的说,Spring Cloud是⼀个⼤容器(⽽不是⼀个框架),它可以将通过集成⼀些好的微服务框架,从⽽简化开发者的代码量。
Dubbo 是阿⾥开源的分布式通信框架,专注于通信服务治理,类似于Spring Cloud中 Ribbon、Hystrix、 Feign等核⼼组件的功能。
下⾯,我们着重来聊下这两种处理⽅式有何不同。
# 01 协议处理
1)Spring Cloud更加优雅简单
Feign使⽤Http进⾏传输。
Feign 集成了Ribbon,并且嵌⼊了Spring cloud全家桶 ,通过简单配置 ,就能在分布式⾥⾯实现服务间的调⽤,类似于Bean 调⽤。
2)Dubbo⽅式更灵活
Dubbo协议可选,⼤部分情况使⽤Dubbo传输协议,也可以使⽤http协议。
从协议层选择看,Dubbo是配置化的,更加灵活。
Dubbo 协议更适合⼩数据⾼并发场景。
# 02 性能⽅⾯
1)Spring Cloud性能调优
Feign 在⾼并发场景下,通常需要进⾏如下性能优化,有明显瓶颈,需要改造。
调整服务容器到 UnderTow ,在负载⼤的情况下Undertow 的性能有提⾼;
曾有同学表示将HTTPURLConnection 改成 Httpclient /Okhttp,这样可以优化性能,其实单次调⽤性能Httpclient差很多,HttpClient 因为封装了很多⽅便开发者处理的⽅法,性能⽐HTTPURLConnection差,改进同时Httpclient 需要设置复⽤连接池,效果可⻅⼀般;
开启Gzip;
Feign中HttpMessageConverters 默认使⽤jackson2⽅式进⾏序列化和反序列化,可以将其改造为ProtoBuf,降低Cpu 损耗并且响应时间也降低。
2)Dubbo性能调优
主要是配置⽽⽆需改造。
# 03 负载均衡
1)Ribbon的负载均衡策略
随机;
规则轮询;
空闲策略;
响应时间策略。
Feign默认使⽤Ribbon作为负载均衡的组件,Ribbon需要进⾏全局配置,个性化配置⽐较麻烦。
2)Dubbo的负载均衡策略
随机;
权重轮询;
最少活跃调⽤数;
⼀致性Hash策略。
Dubbo 可以使⽤路由策略,然后再进⾏负载均衡。
# 04 容错机制
Spring cloud 的 Hystix 提供了服务降级,服务熔断,依赖隔离,监控(Hystrix Dashboard)等功能。
图⽚为引⽤,来源于官⽅图⽚
Dubbo 提供了⼀整套 FailOver、FailFast、Failsafe、FailBack、Aviailable、Broadcast、Forking 策略,以及Mock
图⽚为引⽤,来源于官⽅图⽚
# 05 路由、流量调度、ABtest
1)Ribbon需⾃⼰实现,应⽤不灵活
Ribbon主要通过扩展 AbstractLoadBalancerRule负载均衡的⽅法来实现,在负载均衡的部分还要进⾏改造升级。
2)Dubbo更加灵活⽅便
Dubbo通过界⾯化、校本化配置路由规则,可以实现灰度发布、动态流量调度、容量计算等,⽅案成熟。
另外,Dubbo 还⽀持多版本调⽤。
# 06 总结
正如Dubbo的介绍(如下图),业务发展影响着架构的选型,当服务数量不是很⼤时,使⽤普通的分布式RPC架构即可,当服务数量增⻓到⼀定数据,需要进⾏服务治理时,就需要考虑使⽤流式计算架构。
图⽚为引⽤,来源于官⽅图⽚
Dubbo可以⽅便的做更精细化的流量调度,服务结构治理的⽅案成熟,适合⽣产上使⽤,虽然Dubbo是尘封后重新开启,但这并不影响其技术价值。
Ribbon Hystrix Feign在服务治理中,配合Spring Cloud做微服务,使⽤上有很多优势,社区也⽐较活跃,看将来更新发展。
# nacos权限控制方案
# 方案背景
分布式系统中需要对未知的或者不受信任的请求或者服务的来源、请求进行识别和拒绝。权限控制一般分为两个阶段:身份识别(Authentication)和权限识别(Authorization)。身份认证主要确定访问者的身份,权限识别则判断这个访问者是否有对应资源的权限。
那么在分布式中如何在根本上控制身份和权限的识别尤为重要。
# 场景重现
在Nacos的场景中,配置管理的权限控制指的是设置某个配置能否被某个用户读写,这个比较好理解,没有权限的用户旧无法读取或者写入对应的配置。服务发现的权限控制指的是用户是否有权限进行某个服务的注册或者订阅,这里需要注意的是服务发现的权限控制只能够控制用户是否可以从Nacos获取到服务的地址或者在Nacos上修改服务的地址。但是如果已经获取到了服务的地址,Nacos无法在服务真正调用时进行权限控制,这个时候的权限控制需要由服务框架来完成。
正常应该如下图
# 常见实现方式
# 认证(Authentication)
用户名+密码
Cookie(只适用于浏览器)
Session
Token(JWT,Oauth,LDAP,SAML,OpenID)
AK/SK
# 鉴权(Authorization)
ACL: 规定资源可以被哪些主体进行哪些操作;
DAC: 规定资源可以被哪些主体进行哪些操作 同时,主体可以将资源的权限,授予其他主体;
MAC:a. 规定资源可以被哪些类别的主体进行哪些操作 b. 规定主体可以对哪些等级的资源进行哪些操作 当一个操作,同时满足a与b时,允许操作;
RBAC: a. 规定角色可以对哪些资源进行哪些操作 b. 规定主体拥有哪些角色当一个操作,同时满足a与b时,允许操作;
ABAC: 规定哪些属性的主体可以对哪些属性的资源在哪些属性的情况下进行哪些操作
# Nacos权限控制使用
# 安装Nacos 1.2.0
- 部署包准备。可以直接下载安装包:https://github.com/alibaba/nacos/releases/tag/1.2.0,也可以将Nacos master分支clone下来进行源码编译:
mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U
2.安装包解压,然后使用distribution/nacos-mysql.sql进行数据库初始化,主要是新增了users,roles, permissions三张表,standalone模式使用distribution/schema.sql进行初始化。
3.Server端打开权限控制开关。修改con/application.properties内容:
nacos.core.auth.enabled=true
这个开关采用了热加载模式,无需重启Server即可生效。因此当权限控制功能使用有异常时,可以直接回滚到不鉴权的模式。
注意: Nacos 1.2.0里登录和鉴权是绑定关系,而由于这个开关的默认值为false,因此默认启动时,是没有登录界面的,这点请读者注意。
# 使用权限控制
- 使用管理员账号登录Nacos控制台(如果页面提示错误,可以清空浏览器缓存刷新页面):
可以看到,左侧边栏增加了一个父菜单和三个子菜单,分别用于权限控制里的用户创建、角色创建以及权限管 理。这个菜单栏只会在管理员登录的时候显示,也就意味着只有管理员才能进行权限的管理和分配。
2.管理用户。点击“用户列表”,进入用户管理页面,可以进行用户的创建、修改和删除:
3.管理角色。因为Nacos的自带的权限是基于角色来进行分配的,因此需要给创建好的用户绑定一些角色:
4.管理权限。角色创建好以后,就可以给这个角色赋予特定的权限了:
在“添加资源”对话框里,可以选择绑定的角色,命名空间资源以及对应的动作类型,例如在上图中,我们给角色role1绑定命名空间test的读写权限。然后又因为刚刚我们是将user1绑定到了role1上,那么user1这个用户就可以对test这个命名空间的资源进行读写操作了。
5.使用user1登录控制台。点击控制台右上角,退出admin账号,然后用刚才创建的user1进行登录:
如上图所示,首先是左侧的权限管理菜单消失了,因为当前用户不是管理员。其次是会弹出一个鉴权失败的提示框。不用担心,这个提示框意思是user1没有public命名空间的读权限,所以会弹出,但是不影响我们将命名空间切换到test:
如上图所示,我们可以看到test命名空间的配置数据了,下面我们再来介绍客户端的使用。
6.首先依赖最新的nacos 1.2.0客户端,然后在初始化时添加如下代码:
Properties properties = new Properties();
properties.put(PropertyKeyConst.NAMESPACE, "99a791cf-41c4-4535-9e93-b0141652bad0");
properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:8848");
// 配置用户名:
properties.put(PropertyKeyConst.USERNAME, "user1");
// 配置密码:
properties.put(PropertyKeyConst.PASSWORD, "pwd1");
ConfigService iconfig = NacosFactory.createConfigService(properties);
7、使用客户端进行正常的读写配置操作。
# 注意事项
因为nacos的权限控制当前并不稳定,所以使用时需要注意,service版本也要使用1.2.0以及以上的。而
在springcloud中alibaba的版本也要使用最新的2.2.3的。不然会没有这个用户和密码属性。
# 资料
Nacos 权限控制介绍及实战 (opens new window)
# Spring Cloud与Dubbo的对比
# 题目描述
springcloud与dubbo的详细对比
# 面试题分
根据题目要求我们可以知道:
什么是Spring Cloud
为什么需要Spring Cloud
微服务架构使用场景
SpringCloud与同类Dubbo微服务比较
分析需要全面并且有深度
容易被忽略的坑
分析片面
没有深入
# 什么是Spring Cloud
Spring Cloud 是一套完整的微服务解决方案,基于 Spring Boot 框架,准确的说,它不是一个框架,而是一个大的容器,它将市面上较好的微服务框架集成进来,从而简化了开发者的代码量。
# 为什么需要Spring Cloud
Spring Cloud 是整个 Spring 家族中新的成员,要致力于分布式系统、云服务的框架。
Spring Cloud 为开发人员提供了快速构建分布式系统中一些常见模式的工具,例如:
- 配置管理
- 服务注册与发现
- 断路器
- 智能路由
- 服务间调用
- 负载均衡
- 微代理
- 控制总线
- 一次性令牌
- 全局锁
- 领导选举
- 分布式会话
- 集群状态
- 分布式消息
一句话概括:Spring Cloud是分布式微服务架构下的一站式解决方案,是各个微服务架构落地技术集合,俗称微服务全家桶。
# 微服务架构使用场景
首先,我们需要看看一般的微服务架构需要的功能或使用场景:
1、我们把整个系统根据业务拆分成几个子系统。
2、每个子系统可以部署多个应用,多个应用之间使用负载均衡。
3、需要一个服务注册中心,所有的服务都在注册中心注册,负载均衡也是通过在注册中心注册的服务来使用一定策略来实现。
4、所有的客户端都通过同一个网关地址访问后台的服务,通过路由配置,网关来判断一个URL请求由哪个服务处理。请求转发到服务上的时候也使用负载均衡。
5、服务之间有时候也需要相互访问。例如有一个用户模块,其他服务在处理一些业务的时候,要获取用户服务的用户数据。
6、需要一个断路器,及时处理服务调用时的超时和错误,防止由于其中一个服务的问题而导致整体系统的瘫痪。
7、还需要一个监控功能,监控每个服务调用花费的时间等。
总之,Spring Cloud只是微服务架构的一种解决方案,下面我们再看看微服务架构同类产品比较。
# SpringCloud与同类Dubbo微服务比较
目前市面上主要就是SpringCloud VS Dubbo。
# 1.Spring Cloud的优缺点
Spring Cloud主要优点:
集大成者,Spring Cloud 包含了微服务架构的方方面面。
约定优于配置,基于注解,没有配置文件。
轻量级组件,Spring Cloud 整合的组件大多比较轻量级,且都是各自领域的佼佼者。
开发简便,Spring Cloud 对各个组件进行了大量的封装,从而简化了开发。
开发灵活,Spring Cloud 的组件都是解耦的,开发人员可以灵活按需选择组件。
Spring Cloud的缺点:
项目结构复杂,每一个组件或者每一个服务都需要创建一个项目。
部署门槛高,项目部署需要配合 Docker 等容器技术进行集群部署,而要想深入了解 Docker,学习成本高。
# 2.Spring Cloud对比Dubbo
Dubbo,是阿里巴巴服务化治理的核心框架,并被广泛应用于阿里巴巴集团的各成员站点。
1)社区活跃度
在社区活跃度上,Spring Cloud毋庸置疑的优于Dubbo,这对于没有大量精力与财力维护这部分开源内容的团队来说,Spring Cloud会是更优的选择。
2)架构完整度
上图可以看出,Spring Cloud 比较全面,Spring Cloud下面有17个子项目(可能还会新增)分别覆盖了微服务架构下的方方面面,服务治理只是其中的一个方面。
而 Dubbo 由于只实现了服务治理,需要集成其他模块,需要单独引入,增加了学习成本和集成成本。一定程度来说,Dubbo只是Spring Cloud Netflix中的一个子集。
3)文档质量
Dubbo的 文档 可以说在国内开源框架中算是一流的,非常全,并且讲解的也非常深入,由于版本已经稳定不再更新,所以也不太会出现不一致的情况,另外提供了中文与英文两种版本,对于国内开发者来说,阅读起来更加容易上手,这也是dubbo在国内更火一些的原因吧。
Spring Cloud由于整合了大量组件,文档在体量上自然要比dubbo多很多,文档内容上还算简洁清楚,但是更多的是偏向整合,更深入的使用方法还是需要查看其整合组件的详细文档。另外由于Spring Cloud基于Spring Boot,很多例子相较于传统Spring应用要简单很多(因为自动化配置,很多内容都成了约定的默认配置),这对于刚接触的开发者可能会有些不适应,比较建议了解和学习Spring Boot之后再使用Spring Cloud,不然可能会出现很多一知半解的情况。
总之:虽然Spring Cloud的文档量大,但是如果使用Dubbo去整合其他第三方组件,实际也是要去阅读大量第三方组件文档的,所以在文档量上,我觉得区别不大。对于文档质量,由于Spring Cloud的迭代很快,难免会出现不一致的情况,所以在质量上我认为Dubbo更好一些。而对于文档语言上,Dubbo自然对国内开发团队来说更有优势。
# 3.对比总结
通过上面再几个环节上的分析,相信大家对Dubbo和Spring Cloud有了一个初步的了解。
就我个人对这两个框架的使用经验和理解,打个不恰当的比喻:
使用Dubbo构建的微服务架构就像组装电脑,各环节我们的选择自由度很高,但是最终结果很有可能因为一条内存质量不行就点不亮了,总是让人不怎么放心,但是如果你是一名高手,那这些都不是问题。
而Spring Cloud就像品牌机,在Spring Source的整合下,做了大量的兼容性测试,保证了机器拥有更高的稳定性,但是如果要在使用非原装组件外的东西,就需要对其基础有足够的了解。
# 扩展内容
幻影读+分段锁+死锁+Spring Cloud+秒杀
微服务技术架构、监控、Docker、服务治理等体系
Restful、SOAP、RPC、SOA、微服务之间的区别