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

Java面试准备-(09)微服务与dubbo

Java面试准备之微服务与dubbo


微服务

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

每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于 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

REST是一种架构风格,其核心是面向资源;而webService底层SOAP协议,主要核心是面向活动;
RestFul利用HTTP请求方式进行HTTP方法(GET,POST,PUT,DELETE)的直接应用。
RestFul是一种约定,以资源为中心进行CRUD操作,它把网络上任何东西都看做是资源。
RestFul能通过HTTP形式直接调用,也可以基于JSON,SOAP通过XML传输。

REST 架构该怎么生动地理解?
https://www.zhihu.com/question/27785028

restful安全验证

对于基于WSDL和SOAP的Web Service,我们有WS-Security这样的安全规范来指导实现认证、授权、身份管理等安全需求。那么,RESTful API有无成熟可用规范或实现框架呢?如何保证RESTful API的安全性呢?

HTTP Basic(base64编码)

REST由于是无状态的传输,所以每一次请求都得带上身份认证信息,身份认证的方式,身份认证的方式有很多种,第一种便是http basic,这种方式在客户端要求简单,在服务端实现也非常简单,只需简单配置apache等web服务器即可实现,所以对于简单的服务来说还是挺方便的。但是这种方式安全性较低,就是简单的将用户名和密码base64编码放到header中。
正是因为是简单的base64编码存储,切记切记在这种方式下一定得注意使用ssl,不然就是裸奔了。

Http Basic 是一种比较简单的身份认证方式。 在 Http header 中添加键值对 Authorization: Basic xxx (xxx 是 username:passowrd base64 值)。
例如 username 为 zmk ,password 为 123456,请求则如下
GET /auth/basic/ HTTP/1.1
Host: xxxxx
Authorization: Basic em1rOjEyMzQ1Ng==
而Base64 的解码是非常方便的,如果不使用 Https ,相当于是帐号密码直接暴露在请求中。
危险性高,实际开发者使用的应该几乎为0。

HTTP Digest

顺便提下 DIGEST 认证,和 BASIC 认证相差无几,而且不适合 api 设计,实际又需要两次请求,首次请求,服务器端返回401,并且带上 nonce 值,然后客户端再利用 username + password + nonce 默认MD5之后再请求。对 http 请求的作用是仅仅防止二次请求,对身份认证并没有什么提升。

API KEY

API Key就是经过用户身份认证之后服务端给客户端分配一个API Key

client端向服务端注册,服务端给客户端发送响应的api_key以及security_key,注意保存不要泄露,然后客户端根据api_key,secrity_key,timestrap,rest_uri采用hmacsha256算法得到一个hash值sign,构造途中的url发送给服务端。

服务端收到该请求后,首先验证api_key,是否存在,存在则获取该api_key的security_key,接着验证timestrap是否超过时间限制,可依据系统成而定,这样就防止了部分重放攻击,途中的rest_api是从url获取的为/rest/v1/interface/eth0,最后计算sign值,完之后和url中的sign值做校验。这样的设计就防止了数据被篡改。

通过这种API Key的设计方式加了时间戳防止了部分重放,加了校验,防止了数据被篡改,同时避免了传输用户名和密码,当然了也会有一定的开销。

Oauth

OAuth协议适用于为外部应用授权访问本站资源的情况。其中的加密机制与HTTP Digest身份认证相比,安全性更高。使用和配置都比较复杂

JWT(Json Web Token)

JWT 是JSON Web Token,用于发送可通过数字签名和认证的东西,它包含一个紧凑的,URL安全的JSON对象,服务端可通过解析该值来验证是否有操作权限,是否过期等安全性检查。由于其紧凑的特点,可放在url中或者 HTTP Authorization头中

RESTFUL API 安全设计
https://blog.csdn.net/degwei/article/details/51489391

RESTful Api 身份认证安全性设计
http://www.phpabc.cn/restful-api-shen-fen-ren-zheng-an-quan-xing-she-ji.html

如何设计好的RESTful API之安全性
https://blog.csdn.net/ywk253100/article/details/25654101

webservice与rest对比

何时使用REST:
若本身只是简单的CRUD业务操作,那么抽象资源就比较容易。
而对于复杂的业务活动抽象资源并不是一个简单的事情,比如校验用户等级,转账,事务处理等。
何时使用SOAP:
若有严格的规范和标准定义要求,且前期需要指导多个业务系统集成和开发的时,
因SOAP风格有清晰的规范标准定义,SOAP更适合。
我们可以在开始和实现之前就严格定义相关的接口方法和接口传输数据。

SOAP 不仅像 REST 一样支持 SSL,而且还支持增加了很多企业级安全特性的 WS-Security

REST对于资源型服务接口来说很合适,同时特别适合对于效率要求很高,但是对于安全要求不高的场景。而SOAP的成熟性可以给需要提供给多开发语言的,对于安全性要求较高的接口设计带来便利。所以我觉得纯粹说什么设计模式将会占据主导地位没有什么意义,关键还是看应用场景。

一句话:简单数据操作,无事务处理,开发和调用简单使用REST架构风格较好。

【接口开发】浅谈 SOAP Webserver 与 Restful Webserver 区别
https://www.cnblogs.com/hyhnet/archive/2016/06/28/5624422.html

REST Vs SOAP,Soap 和 Rest 的区别
http://blog.csdn.net/defonds/article/details/49000993


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


上一篇 Java面试准备-(10)JMS和MQ

下一篇 Java面试准备-(08)Web架构

阅读
6,465
阅读预计24分钟
创建日期 2018-05-12
修改日期 2018-12-13
类别
百度推荐