当前位置 : 首页 » 文章分类 :  开发  »  面试准备09-微服务与dubbo

面试准备09-微服务与dubbo

Java面试准备之微服务与dubbo


服务治理

服务注册与发现Eureka

客服端负载均衡Ribbon

声明式服务调用Feign

熔断降级Hystrix

调用链跟踪APM

pinpoint的实现原理

见笔记 Pinpoint


微服务

微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。

每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于 HTTP 的 RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立地部署到生产环境、类生产环境等。

放弃Dubbo,选择最流行的Spring Cloud微服务架构实践与经验总结
http://developer.51cto.com/art/201710/554633.htm

Spring cloud

spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等。它运行环境简单,可以在开发人员的电脑上跑。另外说明spring cloud是基于springboot的

史上最简单的 SpringCloud 教程 | 第一篇: 服务的注册与发现(Eureka)
http://blog.csdn.net/forezp/article/details/69696915

微服务架构Spring cloud与dubbo区别

从项目的背景来看,Dubbo 国内用的公司挺多,国内影响力大,Spring Cloud 自然在国外影响力较大,所以这个来看不分伯仲了,毕竟都有大公司在使用。

从社区的活跃度来看,可以看下各自的Github托管项目来区分,Dubbo · GitHub 与 Spring Cloud · GitHub ,从更新频率与更新时间来看 Spring Cloud 优于Dubbo,Dubbo基本不维护了。

从框架的完整度来看,Dubbo只是实现了服务治理(注册 发现等),而Spring Cloud下面有很多个子项目覆盖了微服务架构下的方方面面,服务治理只是其中的一个方面,一定程度来说,Dubbo只是Spring Cloud Netflix中的一个子集。如果选择Spring Cloud,基本上每个环节都已经有了对应的组件支持,可能有些也不一定能满足你所有的需求,但是其活跃的社区与快速的迭代更新也会让你没有后顾之忧。

放弃Dubbo,选择最流行的Spring Cloud微服务架构实践与经验总结
http://developer.51cto.com/art/201710/554633.htm

请问哪位大神比较过spring cloud和dubbo,各自的优缺点是什么?
https://www.zhihu.com/question/45413135


webservice(SOAP)

WebService是一种跨编程语言和跨操作系统平台的远程调用技术。
WSDL: 服务描述协议。用来描述如何访问具体的服务。包括方法,参数
SOAP: 基于HTTP协议,采用XML格式,用来传递信息的格式

Apache cxf原理

基于CXF可以非常简单地以WebService的方式来实现Java甚至是跨语言的远程调用

cxf的实现原理是代理:
在服务端,提供一个JaxWsProxyFactoryBean工厂类,内部采用java原生发布webservice的方式(定义接口、实现类、Endpoint发布)对服务进行包装并发布。此外还提供Interceptor拦截器对服务进行扩展,可以在服务被调用前或调用后增加一些额外的处理,比如安全验证等。
在客户端,提供一个JaxWsProxyFactoryBean工厂类,能够直接以接口的方式来调用远程的WebService,不需要手动通过wsimport工具生成客户端代码,简化了调用WebService调用的复杂性。

CXF的大体原理
http://blog.sina.com.cn/s/blog_4adc4b090102v2wy.html

hessian

Hessian是一个轻量级的RPC框架。它基于HTTP协议传输,使用Hessian二进制序列化,对于数据包比较大的情况比较友好。
Hessian是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能。 相比WebService,Hessian更简单、快捷。采用的是二进制RPC协议,因为采用的是二进制协议,所以它很适合于发送二进制数据。

Hessian序列化

Hessian原理分析
https://www.cnblogs.com/happyday56/p/4268249.html

hessian序列化区别
https://blog.csdn.net/bohu83/article/details/51210468

java RMI

只能基于JAVA语言,客户机与服务器紧耦合。


restful api

详见rest笔记


rpc框架

rpc原理

一次完整的RPC调用流程(同步调用,异步另说)如下:
1)服务消费方(client)调用以本地调用方式调用服务;
2)client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体;
3)client stub找到服务地址,并将消息发送到服务端;
4)server stub收到消息后进行解码;
5)server stub根据解码结果调用本地的服务;
6)本地服务执行并将结果返回给server stub;
7)server stub将返回结果打包成消息并发送至消费方;
8)client stub接收到消息,并进行解码;
9)服务消费方得到最终结果。
RPC框架的目标就是要2~8这些步骤都封装起来,让用户对这些细节透明。

服务注册和发现

服务提供者启动后主动向注册中心注册机器ip、port以及提供的服务列表;
服务消费者启动时向注册中心获取服务提供方地址列表,可实现软负载均衡和Failover;

stub存根和动态代理

生成 client stub和server stub需要用到 Java 动态代理技术 ,我们可以使用JDK原生的动态代理机制,可以使用一些开源字节码工具框架 如:CgLib、Javassist等。

序列化

为了能在网络上传输和接收 Java对象,我们需要对它进行 序列化和反序列化操作。

序列化:将Java对象转换成byte[]的过程,也就是编码的过程;
反序列化:将byte[]转换成Java对象的过程;

可以使用Java原生的序列化机制,但是效率非常低,推荐使用一些开源的、成熟的序列化技术,例如:protobuf、Thrift、hessian、Kryo、Msgpack
关于序列化工具性能比较可以参考:jvm-serializers

NIO

当前很多RPC框架都直接基于netty这一IO通信框架,比如阿里巴巴的HSF、dubbo,Hadoop Avro,推荐使用Netty 作为底层通信框架。

服务注册中心

可选技术:
Redis
Zookeeper
Consul
Etcd

开源的优秀RPC框架

阿里巴巴 Dubbo:github.com/alibaba/dub…
新浪微博 Motan:github.com/weibocom/mo…
gRPC:github.com/grpc/grpc
rpcx :github.com/smallnest/r…
Apache Thrift :thrift.apache.org/


dubbo

阿里开源的一个分布式服务框架
Dubbo采用的是一种非常简单的模型,要么是提供方提供服务,要么是消费方消费服务,所以基于这一点可以抽象出服务提供方(Provider)和服务消费方(Consumer)两个角色。

Provider: 暴露服务的服务提供方。
Consumer: 调用远程服务的服务消费方。
Registry: 服务注册与发现的注册中心。
Monitor: 统计服务的调用次数和调用时间的监控中心。
Container: 服务运行容器。

调用关系说明:
0 服务容器负责启动,加载,运行服务提供者。

  1. 服务提供者在启动时,向注册中心注册自己提供的服务。
  2. 服务消费者在启动时,向注册中心订阅自己所需的服务。
  3. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
  4. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
  5. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

Dubbo入门—搭建一个最简单的Demo框架(Dubbo+Zookeeper+Spring)
http://blog.csdn.net/noaman_wgs/article/details/70214612

最近项目用到Dubbo框架,临时抱佛脚分享一下共探讨。
https://www.cnblogs.com/Javame/p/3632473.html

长连接和短连接

所谓长连接,指在一个TCP连接上可以连续发送多个数据包,在TCP连接保持期间,如果没有数据包发送,需要双方发检测包以维持此连接,一般需要自己做在线维持。

短连接是指通信双方有数据交互时,就建立一个TCP连接,数据发送完成后,则断开此TCP连接,一般银行都使用短连接。
比如http的,只是连接、请求、关闭,过程时间较短,服务器若是一段时间内没有收到请求即可关闭连接。

其实长连接是相对于通常的短连接而说的,也就是长时间保持客户端与服务端的连接状态。

长连接与短连接的操作过程:
通常的短连接操作步骤是:
连接→数据传输→关闭连接;

而长连接通常就是:
连接→数据传输→保持连接(心跳)→数据传输→保持连接(心跳)→……→关闭连接;

这就要求长连接在没有数据通信时,定时发送数据包(心跳),以维持连接状态,短连接在没有数据传输时直接关闭就行了.

什么时候用长连接,短连接
长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况,。每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不用建立TCP连接。例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。

dubbo相关知识(三)–socket长连接和短连接
https://blog.csdn.net/guchuanyun111/article/details/52047494

注册中心如何知道Provider挂掉了?(长连接心跳)

ConfigServer(zookeeper)
配置中心和每个Server/Client之间会作一个实时的心跳检测(因为它们都是建立的Socket长连接),比如几秒钟检测一次。收集每个Server提供的服务的信息,每个Client的信息,整理出一个服务列表,如:


当某个Server不可用,那么就更新受影响的服务对应的serverAddressList,即把这个Server从serverAddressList中踢出去(从地址列表中删除),同时将推送serverAddressList给这些受影响的服务的clientAddressList里面的所有Client。如:192.168.0.3挂了,那么UserService和ProductService的serverAddressList都要把192.168.0.3删除掉,同时把新的列表告诉对应的Client 172.16.0.1,172.16.0.2,172.16.0.3;
当某个Client挂了,那么更新受影响的服务对应的clientAddressList
ConfigServer根据服务列表,就能提供一个web管理界面,来查看管理服务的提供者和使用者。
新加一个Server时,由于它会主动与ConfigServer取得联系,而ConfigServer又会将这个信息主动发送给Client,所以新加一个Server时,只需要启动Server,然后几秒钟内,Client就会使用上它提供的服务

Client(Consumer)
调用服务的机器,每个Client启动时,主动与ConfigServer建立Socket长连接,并将自己的IP等相应信息发送给ConfigServer。
Client在使用服务的时候根据服务名称去ConfigServer中获取服务提供者信息(这样ConfigServer就知道某个服务是当前哪几个Client在使用),Client拿到这些服务提供者信息后,与它们都建立连接,后面就可以直接调用服务了,当有多个服务提供者的时候,Client根据一定的规则来进行负载均衡,如轮询,随机,按权重等。
一旦Client使用的服务它对应的服务提供者有变化(服务提供者有新增,删除的情况),ConfigServer就会把最新的服务提供者列表推送给Client,Client就会依据最新的服务提供者列表重新建立连接,新增的提供者建立连接,删除的提供者丢弃连接

Server(Provider)
真正提供服务的机器,每个Server启动时,主动与ConfigServer建立Scoket长连接,并将自己的IP,提供的服务名称,端口等信息直接发送给ConfigServer,ConfigServer就会收集到每个Server提供的服务的信息。

优点:
1,只要在Client和Server启动的时候,ConfigServer是好的,服务就可调用了,如果后面ConfigServer挂了,那只影响ConfigServer挂了以后服务提供者有变化,而Client还无法感知这一变化。
2,Client每次调用服务是不经过ConfigServer的,Client只是与它建立联系,从它那里获取提供服务者列表而已
3,调用服务-负载均衡:Client调用服务时,可以根据规则在多个服务提供者之间轮流调用服务。
4,服务提供者-容灾:某一个Server挂了,Client依然是可以正确的调用服务的,当前提是这个服务有至少2个服务提供者,Client能很快的感知到服务提供者的变化,并作出相应反应。
5,服务提供者-扩展:添加一个服务提供者很容易,而且Client会很快的感知到它的存在并使用它。

分布式服务框架dubbo原理解析
https://blog.csdn.net/zhongbaolin/article/details/50847951

zookeeper注册中心的作用?

Zookeeper到底在Dubbo服务框架体系中起到了一个什么作用?下面介绍一下:
Zookeeper是一个分布式服务框架的协调服务,意思就是说他服务于分布式的服务框架
Zookeeper可以做到集群服务统一管理
Zookeeper、Register、Consumer三者之间使用的都是长连接
如果Zookeeper感知一个Register挂掉了,会及时通知Consumer
如果Zookeeper挂掉了,Consumer会根据本地缓存的Register列表进行调用,不会影响服务间的调用
Dubbo可以完全脱离Zookeeper注册中心,Consumer和Register之间可以直连!

服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,服务消费者向注册中心获取服务提供者地址列表,并根据负载算法直接调用提供者,注册中心,服务提供者,服务消费者三者之间均为长连接,监控中心除外,注册中心通过长连接感知服务提供者的存在,服务提供者宕机,注册中心将立即推送事件通知消费者,注册中心和监控中心全部宕机,不影响已运行的提供者和消费者,消费者在本地缓存了提供者列表,注册中心和监控中心都是可选的,服务消费者可以直连服务提供者

Dubbo学习笔记(三)——Zookeeper注册中心
https://blog.csdn.net/keysilence1/article/details/54579914

Dubbo中的一些常见问题?
https://blog.csdn.net/qq_38765404/article/details/78617142

zk挂掉时服务还能调用吗?

Dubbo中zookeeper做注册中心,如果注册中心集群都挂掉,发布者和订阅者之间还能通信么?

可以
1.启动dubbo时,消费者会从zk拉取注册的生产者的地址接口等数据,缓存在本地。每次调用时,按照本地存储的地址进行调用。
2.注册中心对等集群,任意一台宕掉后,会自动切换到另一台 。
3.注册中心全部宕掉,服务提供者和消费者仍可以通过本地缓存通讯 。
4.服务提供者无状态,任一台 宕机后,不影响使用 。
5.服务提供者全部宕机,服务消费者会无法使用,并无限次重连等待服务者恢复 。

可以的,启动dubbo时,消费者会从zk拉取注册的生产者的地址接口等数据,缓存在本地。每次调用时,按照本地存储的地址进行调用

可以的,消费者本地有一个生产者的列表,他会按照列表继续工作,倒是无法从注册中心去同步最新的服务列表,短期的注册中心挂掉是不要紧的,但一定要尽快修复

挂掉是不要紧的,但前提是你没有增加新的服务,如果你要调用新的服务,则是不能办到的


面试题:Dubbo中zookeeper做注册中心,如果注册中心集群全都挂掉,发布者和订阅者之间还能通信么?
https://blog.csdn.net/zh521zh/article/details/77948208

dubbo如何序列化?

使用默认dubbo协议的话,序列化使用的是修改过的hessian协议,这是一种高效的二进制与具体语言无关的协议。

Dubbo在安全机制方面是如何解决的?

Dubbo通过Token令牌防止用户绕过注册中心直连,然后在注册中心上管理授权。Dubbo还提供服务黑白名单,来控制服务所允许的调用方。

Dubbo中的一些常见问题?
https://blog.csdn.net/qq_38765404/article/details/78617142


dubbo集群容错

在集群调用失败时,Dubbo 提供了多种容错方案,缺省为 failover 重试。

Failover Cluster
失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。可通过 retries=”2” 来设置重试次数(不含第一次)。

Failfast Cluster
快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。

Failsafe Cluster
失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。

Failback Cluster
失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。

Forking Cluster
并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks=”2” 来设置最大并行数。

Broadcast Cluster
广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志等本地资源信息。

按照以下示例在服务提供方和消费方配置集群模式

<dubbo:service cluster="failsafe" />

<dubbo:reference cluster="failsafe" />

集群容错
http://dubbo.apache.org/books/dubbo-user-book/demos/fault-tolerent-strategy.html


dubbo服务降级

return null

mock=force:return+null 表示消费方对该服务的方法调用都直接返回 null 值,不发起远程调用。用来屏蔽不重要服务不可用时对调用方的影响。
mock=fail:return+null 表示消费方对该服务的方法调用在失败后,再返回 null 值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响。

在调用方配置:

<dubbo:reference id="iUser" interface="com.dubbosample.iface.IUser"  timeout="10000" check="false" mock="return null">
</dubbo:reference>

测试时,如果服务启动,则程序按照预期的运行正常;如果服务没启动,则此时运行程序,程序并未报错,输出数据为null。

自定义Mock类

配置mock=”true”,同时mock实现接口,接口名要注意命名规范:接口名+Mock后缀。此时如果调用失败会调用Mock实现。mock实现需要保证有无参的构造方法。

比如服务接口为IUser

public interface IUser {
    public void addUser(User u);
    public User getUserById(int id);
}

除了IUser的正常实现类外,在同一个包下添加IUserMock类

public class IUserMock implements IUser {
    @Override
    public void addUser(User u) {
        throw new RuntimeException("add user fail!");
    }

    @Override
    public User getUserById(int id) {
        return null;
    }
}

此时如果对应的方法调用失败,dubbo会自动调用Mock实现类中的方法。

dubbo服务降级
https://www.cnblogs.com/allenwas3/p/8427659.html

服务降级及dubbo中的实现示例
https://blog.csdn.net/whereismatrix/article/details/53354141


dubbo负载均衡

在集群负载均衡时,Dubbo 提供了多种均衡策略,缺省为 random 随机调用。

Random LoadBalance
随机,按权重设置随机概率。
在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。

RoundRobin LoadBalance
轮循,按公约后的权重设置轮循比率。
存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。

LeastActive LoadBalance
最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。

ConsistentHash LoadBalance
一致性 Hash,相同参数的请求总是发到同一提供者。
当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。
算法参见:http://en.wikipedia.org/wiki/Consistent_hashing
缺省只对第一个参数 Hash,如果要修改,请配置 <dubbo:parameter key="hash.arguments" value="0,1" />
缺省用 160 份虚拟节点,如果要修改,请配置 <dubbo:parameter key="hash.nodes" value="320" />

服务端和客户端配置示例:

<dubbo:service interface="..." loadbalance="roundrobin" />

<dubbo:reference interface="..." loadbalance="roundrobin" />

负载均衡
http://dubbo.apache.org/books/dubbo-user-book/demos/loadbalance.html


dubbo管理控制台

下载dubbo-admin-2.8.4.war,解压后放到Tomcat webapps中的ROOT中,也就是部署在根目录中。

zookeeper及账号密码配置:
/opt/app/tomcat/apache-tomcat-7.0.82/webapps/ROOT/WEB-INF/dubbo.properties

dubbo.registry.address=zookeeper://10.220.43.93:2181?backup=10.220.43.94:2181,10.220.43.95:2181
dubbo.admin.root.password=root
dubbo.admin.guest.password=guest

打开dubbo管理控制台
http://localhost:8080

dubbo管理控制台的安装部署
https://blog.csdn.net/u013144287/article/details/77921353


上一篇 面试准备10-消息中间件

下一篇 面试准备08-Web与系统架构

阅读
评论
5,682
阅读预计21分钟
创建日期 2018-05-12
修改日期 2020-04-28
类别

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论