目录
2.2、SpringBoot和SpringCloud,请你谈谈对他们的理解
2.4、Eureka和zookeeper都可以提供服务注册与发现的功能,请说区别
1、微服务基础概念
1.1、微服务架构特点
服务组件化:服务间利用远程调用RPC通信(尽可能采用RESTful的轻量级通信方式)、高内聚低耦合
按业务能力组织服务:开发团队分割,尽可能明确业务边界
去中心化:技术不同,构建不同,数据库不同
基础设施自动化:持续集成、持续交付
1.2、微服务架构基础组件
通信服务(RPC)、事件驱动(MQ)、负载均衡、服务路由、API网关、配置管理
1.3、微服务架构关键要素
服务治理、数据一致性、服务可靠性(容错、隔离、限流、降级)
1.4、注册中心选型
特性 | Zookeeper | ETCD | Consul | Euraka |
CAP | CP | CP | CP/AP | AP |
服务健康检查 | (弱)长连接、keepalive | 连接心跳 | 服务状态、内存、硬盘等 | 支持可配 |
kv存储服务 | 支持 | 支持 | 支持 | - |
多语言支持 | sdk | http/grpc | http&dnshtt | http(sidecar) |
watch | 支持 | 支持 | 支持 | long polling |
一致性协议 | ZAB(paxos) | raft | raft | 弱一致性 |
自身监控 | - | metrics | metrics | metrics |
多数据中心 | 无 | 无 | 支持 | 无 |
安全 | acl | https支持(弱) | acl/https | - |
社区支持 | 积极 | 积极 | 积极 | 暂停 |
1.5、Dubbo和SpringCloudhttps://blog.csdn.net/longgeqiaojie304/article/details/85259972
Dubbo | SpringCloud | |
---|---|---|
服务注册中心 | Zookeeper | SpringCloud Netflix Eureka |
服务调用方式 | RPC | RESTful API(Feign) |
API网关 | - | SpringCloud Netflix Zuul |
服务熔断器 | 不完善 | SpringCloud Netflix Hystrix |
分布式配置 | - | SpringCloud Config |
服务跟踪 | - | SpringCloud Sleuth |
消息总线 | - | SpringCloud Bus |
数据流 | - | SpringCloud Stream |
安全性 | - | SpringCloud Security |
负载均衡 | - | SpringCloud Ribbon |
2、微服务相关问题
2.1、SpringCloud和Dubbo有哪些区别
最大区别:SpringCloud抛弃了Dubbo的RPC通信,采用的是基于HTTP的REST方式。
总体来说,两者各有优势。虽说后者服务调用的功能,但也避免了上面提到的原生RPC带来的问题。而且REST相比RPC更为灵活,服务提供方和调用方的依赖只依靠一纸契约,不存在代码级别的依赖,这在强调快速演化的微服务环境下,显得更加合适。品牌机与组装机的区别:很明显SpringCloud比dubbo的功能更强大,覆盖面更广,而且能够与SpringFramework、SpringBoot、SpringData、SpringBatch等其他Spring项目完美融合,这些对于微服务至关重要。使用Dubbo构建的微服务架构就像组装电脑、各环节我们选择自由度高,但是最总可能会因为内存质量而影响整体,但对于高手这也就不是问题。而SpringCloud就像品牌机,在Spring Source的整合下,做了大量的兼容性测试,保证了机器拥有更高的稳定性。
2.2、SpringBoot和SpringCloud,请你谈谈对他们的理解
SpringBoot专注于快速方便的开发单个个体微服务
SpringCloud是关注全局的微服务协调、整理、治理的框架,它将SpringBoot开发的单体整合并管理起来
SpringBoot可以离开SpringCloud独立使用开发项目,但是SpringCloud离不开SpringBoot,属于依赖关系
2.3、什么是服务熔断?什么是服务降级?
熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务降级,进而熔断该节点微服务的调用,快速返回“错误”的响应信息。当检测到该节点微服务调用响应正常后恢复调用链路。在SpringCloud框架里熔断机制通过Hystrix实现,Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内调用20次,如果失败,就会启动熔断机制。熔断机制的注解是@HystrixCommand。
服务降级,一般是从整体负荷考虑。就是当某个服务熔断之后,服务器将不再被调用,此时客户端可以自己准备一个本地的fallback回调,返回一个缺省值。这样做,虽然水平下降,但好歹可用,比直接挂掉强。
2.4、Eureka和zookeeper都可以提供服务注册与发现的功能,请说区别
Zookeeper保证了CP(C:一致性,P:分区容错性),Eureka保证了AP(A:高可用)
当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的信息,但不能容忍直接down掉不可用。也就是说,服务注册功能对高可用性要求比较高,但zk会出现这样一种情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新选leader。问题在于,选取leader时间过长,30 ~ 120s,且选取期间zk集群都不可用,这样就会导致选取期间注册服务瘫痪。在云部署的环境下,因网络问题使得zk集群失去master节点是较大概率会发生的事,虽然服务能够恢复,但是漫长的选取时间导致的注册长期不可用是不能容忍的。
Eureka保证了可用性,Eureka各个节点是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点仍然可以提供注册和查询服务。而Eureka的客户端向某个Eureka注册或发现是发生连接失败,则会自动切换到其他节点,只要有一台Eureka还在,就能保证注册服务可用,只是查到的信息可能不是最新的。除此之外,Eureka还有自我保护机制,如果在15分钟内超过85%的节点没有正常的心跳,那么Eureka就认为客户端与注册中心发生了网络故障,此时会出现以下几种情况:
Eureka不在从注册列表中移除因为长时间没有收到心跳而应该过期的服务。Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其他节点上(即保证当前节点仍然可用),当网络稳定时,当前实例新的注册信息会被同步到其他节点。
因此,Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像Zookeeper那样使整个微服务瘫痪。
2.5、分布式事务
Zookeeper:Zookeeper的核心是原子广播(Zookeeper Atomic Broadcast),这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。
2.6、单片,SOA和微服务架构有什么区别
SOA | 微服务 |
---|---|
遵循“ 尽可能多的共享 ”架构方法 | 遵循“ 尽可能少分享 ”的架构方法 |
重要性在于 业务功能 重用 | 重要性在于“ 有界背景 ” 的概念 |
他们有 共同的 治理 和标准 | 他们专注于 人们的 合作 和其他选择的自由 |
使用 企业服务总线(ESB) 进行通信 | 简单的消息系统 |
它们支持 多种消息协议 | 他们使用 轻量级协议 ,如 HTTP / REST 等。 |
多线程, 有更多的开销来处理I / O. | 单线程 通常使用Event Loop功能进行非锁定I / O处理 |
最大化应用程序服务可重用性 | 专注于 解耦 |
传统的关系数据库 更常用 | 现代 关系数据库 更常用 |
系统的变化需要修改整体 | 系统的变化是创造一种新的服务 |
DevOps / Continuous Delivery正在变得流行,但还不是主流 | 专注于DevOps /持续交付 |
- 单片架构类似于大容器,其中应用程序的所有软件组件组装在一起并紧密封装。
- 一个面向服务的架构是一种相互通信服务的集合。通信可以涉及简单的数据传递,也可以涉及两个或多个协调某些活动的服务。
- 微服务架构是一种架构风格,它将应用程序构建为以业务域为模型的小型自治服务集合。
2.7、springboot 单例与多例注入
@Component
默认单例
如果想声明成多例用
@Component
@Scope("prototype")
2.8、限流算法
计数器、令牌桶、漏桶
漏铜算法:
不管服务调用方多么不稳定,通过漏桶算法进行限流,每10毫秒处理一次请求。因为处理的速度是固定的,请求进来的速度是未知的,可能突然进来很多请求,没来得及处理的请求就先放在桶里,既然是个桶,肯定是有容量上限,如果桶满了,那么新进来的请求就丢弃
令牌桶算法:
在令牌桶算法中,存在一个桶,用来存放固定数量的令牌。算法中存在一种机制,以一定的速率往桶中放令牌。每次请求调用需要先获取令牌,只有拿到令牌,才有机会继续执行,否则选择选择等待可用的令牌、或者直接拒绝。
2.9、服务拆分
拆分原则:
- 单一职责
- 服务粒度适中
- 考虑团队结构
- 以业务模型切入
- 演进式拆分
- 避免环形依赖和双向依赖
2.10、幂等操作
https://www.e-learn.cn/content/redis/2363823
3、微服务组件
3.1、Eureka()服务治理
Eureka包含两个组件:Eureka Server和Eureka Client。
Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。
Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也就是一个内置的、使用轮询(round-robin)负载算法的负载均衡器。
在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。
Eureka Server之间通过复制的方式完成数据的同步,Eureka还提供了客户端缓存机制,即使所有的Eureka Server都挂掉,客户端依然可以利用缓存中的信息消费其他服务的API。综上,Eureka通过心跳检查、客户端缓存等机制,确保了系统的高可用性、灵活性和可伸缩性。
3.2、Zuul(甲龙科)网关
Zuul的主要功能是路由转发、过滤器、限流。路由功能是微服务的一部分,比如/api/user转发到到user服务,/api/shop转发到到shop服务。zuul默认和Ribbon结合实现了负载均衡的功能。
zuul有以下功能:
- Authentication
- Insights
- Stress Testing
- Canary Testing
- Dynamic Routing
- Service Migration
- Load Shedding
- Security
- Static Response handling
- Active/Active traffic managemen
3.3、Hystrix(豪猪)熔断器
Netflix开源了Hystrix组件,实现了断路器模式,SpringCloud对这一组件进行了整合。 在微服务架构中,一个请求需要调用多个服务是非常常见的,如下图:
较底层的服务如果出现故障,会导致连锁故障。当对特定的服务的调用的不可用达到一个阀值(Hystric 是5秒20次) 断路器将会被打开。
Hystrix设计目标:
- 对来自依赖的延迟和故障进行防护和控制——这些依赖通常都是通过网络访问的
- 阻止故障的连锁反应
- 快速失败并迅速恢复
- 回退并优雅降级
- 提供近实时的监控与告警
Hystrix遵循的设计原则:
- 防止任何单独的依赖耗尽资源(线程)
- 过载立即切断并快速失败,防止排队
- 尽可能提供回退以保护用户免受故障
- 使用隔离技术(例如隔板,泳道和断路器模式)来限制任何一个依赖的影响,使用线程池来保证资源隔离
- 通过近实时的指标,监控和告警,确保故障被及时发现
- 通过动态修改配置属性,确保故障及时恢复
- 防止整个依赖客户端执行失败,而不仅仅是网络通信
3.4、Config()配置中心
在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件。在Spring Cloud中,有分布式配置中心组件spring cloud config ,它支持配置服务放在配置服务的内存中(即本地),也支持放在远程Git仓库中。在spring cloud config 组件中,分两个角色,一是config server,二是config client
- 提供服务端和客户端支持
- 集中管理各环境的配置文件
- 配置文件修改之后,可以快速的生效
- 可以进行版本管理
- 支持大的并发查询
- 支持各种语言
3.5、Security()安全器
OAuth2的原理
客户应用向授权服务器请求Sccess Token ---> 授权服务器向用户征询意见,是否将权限授予客户应用 ---> 用户同意 ---> 授权服务器生成颁发Access Token给客户应用 ---> 客户应用请求资源服务器 ---> 资源服务器验证客户应用的Access Token ---> 验证通过,返回数据.
涉及到三个角色:
- 客户应用(请求资源方)
- 授权服务器(生成Access Token并颁发Access Token)
- 资源服务器(验证Access Token,返回资源)
OAuth2的定义
OAuth2是用于REST/APIs的代理授权框架(delegated authorization framework)
是基于令牌Token的授权,在无需暴露用户密码的情况下,是应用能获取对用户数据有限访问权限
解耦认证和授权
标准安全框架,支持多种用例场景:服务器端WebApp、浏览器单页SAP、无线/原生App、服务器对服务器之间
3.6、Ribbon()负载均衡
ribbon是一个负载均衡客户端,可以很好的控制htt和tcp的一些行为。Feign默认集成了ribbon。
ribbon 已经默认实现了这些配置bean:
- IClientConfig ribbonClientConfig: DefaultClientConfigImpl
- IRule ribbonRule: ZoneAvoidanceRule
- IPing ribbonPing: NoOpPing
- ServerList ribbonServerList: ConfigurationBasedServerList
- ServerListFilter ribbonServerListFilter: ZonePreferenceServerListFilter
- ILoadBalancer ribbonLoadBalancer: ZoneAwareLoadBalancer
3.7、Bus()消息器
Spring Cloud Bus 将分布式的节点用轻量的消息代理连接起来。它可以用于广播配置文件的更改或者服务之间的通讯,也可以用于监控。目前只支持RabbitMQ和Kafka
3.8、Feign(假装)伪装器
Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。简而言之:
- Feign 采用的是基于接口的注解
- Feign 整合了ribbon
3.9、Stream
3.10、Sleuth
3.11、Apollo和Config
3.12、Redisson分布式锁
Redisson是架设在Redis基础上的一个Java驻内存数据网格(In-Memory Data Grid)。
Redisson在基于NIO的Netty框架上,充分的利用了Redis键值数据库提供的一系列优势,在Java实用工具包中常用接口的基础上,为使用者提供了一系列具有分布式特性的常用工具类。使得原本作为协调单机多线程并发程序的工具包获得了协调分布式多机多线程并发系统的能力,大大降低了设计和研发大规模分布式系统的难度。同时结合各富特色的分布式服务,更进一步简化了分布式环境中程序相互之间的协作。
在一些高并发的场景中,比如秒杀,抢票,抢购这些场景,都存在对核心资源,商品库存的争夺,控制不好,库存数量可能被减少到负数,出现超卖的情况,或者 产生唯一的一个递增ID,由于web应用部署在多个机器上,简单的同步加锁是无法实现的,给数据库加锁的话,对于高并发,1000/s的并发,数据库可能由行锁变成表锁,性能下降会厉害。那相对而言,redis的分布式锁,相对而言,是个很好的选择,redis官方推荐使用的Redisson就提供了分布式锁和相关服务。
4、其他相关框架介绍
4.1、iBatis和MyBatis
ibatis3.*版本以后正式改名为mybaits,它也从apache转到了google code下;也就是说ibatis2.*,mybatis3.*。
映射文件的不同
ibatis中根元素是sqlMap,mybatis中是mapper
在 iBatis 中,namespace 不是必需的,且它的存在没有实际的意义。在 MyBatis 中,namespace 终于派上用场了,它使得映射文件与接口绑定变得非常自然
ibatis中有resultMap和resultClass两种返回类型,resultMap是我们在ibatis的配置文件中定义的,也就是在配置文件中使用resultMap元素定义的;resultClass是指java语言中内置的类型,如:integer、java.util.HashMap等等
mybatis中将两者统一为resultType,这样挺好的,开发者不用再记两个属性了。
ibatis中有parameterClass,mybatis中有parameterType,两者区别不大。
参数的写法比较
Mybatis实现了接口绑定,使用更加方便,在ibatis2.x中我们需要在DAO的实现类中指定具体对应哪个xml映射文件, 而Mybatis实现了DAO接口与xml映射文件的绑定,自动为我们生成接口的具体实现,使用时不需要通过SqlMapClient去指定namespace 和 sql statement id,只需要在 sql map config 文件中指定接口的 namespace, 并且sql statement id 和 接口的名字意义对应,然后调用对一个接口即可
4.2、JPA和Hibernate
JPA本身是一种规范,它的本质是一种ORM规范(不是ORM框架,因为JPA并未提供ORM实现,只是制定了规范)因为JPA是一种规范,所以,只是提供了一些相关的接口,但是接口并不能直接使用,JPA底层需要某种JPA实现,JPA现在就是Hibernate功能的一个子集
Hibernate 从3.2开始,就开始兼容JPA。Hibernate3.2获得了Sun TCK的 JPA(Java Persistence API) 兼容认证。JPA和Hibernate之间的关系,可以简单的理解为JPA是标准接口,Hibernate是实现,并不是对标关系,借用下图可以看清楚他们之间的关系,Hibernate属于遵循JPA规范的一种实现,但是JPA是Hibernate遵循的规范之一,Hibernate还有其他实现的规范
4.3、MyBatis和Hibernate
Hibernate的优点:
- hibernate是全自动,hibernate完全可以通过对象关系模型实现对数据库的操作,拥有完整的JavaBean对象与数据库的映射结构来自动生成sql
- 功能强大,数据库无关性好,O/R映射能力强,需要写的代码很少,开发速度很快
- 有更好的二级缓存机制,可以使用第三方缓存
- 数据库移植性良好
- hibernate拥有完整的日志系统,hibernate日志系统非常健全,涉及广泛,包括sql记录、关系异常、优化警告、缓存提示、脏数据警告等
Hibernate的缺点:
- 学习门槛高,精通门槛更高,程序员如何设计O/R映射,在性能和对象模型之间如何取得平衡,以及怎样用好Hibernate方面需要的经验和能力都很强才行
- hibernate的sql很多都是自动生成的,无法直接维护sql;虽然有hql查询,但功能还是不及sql强大,见到报表等变态需求时,hql查询要虚,也就是说hql查询是有局限的;hibernate虽然也支持原生sql查询,但开发模式上却与orm不同,需要转换思维,因此使用上有些不方便。总之写sql的灵活度上hibernate不及mybatis
Mybatis的优点:
- 易于上手和掌握,提供了数据库查询的自动对象绑定功能,而且延续了很好的SQL使用经验,对于没有那么高的对象模型要求的项目来说,相当完美
- sql写在xml里,便于统一管理和优化, 解除sql与程序代码的耦合
- 提供映射标签,支持对象与数据库的orm字段关系映射
- 提供对象关系映射标签,支持对象关系组建维护
- 提供xml标签,支持编写动态sql
- 速度相对于Hibernate的速度较快
Mybatis的缺点:
- 关联表多时,字段多的时候,sql工作量很大
- sql依赖于数据库,导致数据库移植性差
- 由于xml里标签id必须唯一,导致DAO中方法不支持方法重载
- 对象关系映射标签和字段映射标签仅仅是对映射关系的描述,具体实现仍然依赖于sql
- DAO层过于简单,对象组装的工作量较大
- 不支持级联更新、级联删除
- Mybatis的日志除了基本记录功能外,其它功能薄弱很多
- 编写动态sql时,不方便调试,尤其逻辑复杂时
- 提供的写动态sql的xml标签功能简单,编写动态sql仍然受限,且可读性低