1. Spring版本说明
本文档对工业界常用的服务治理框架、及其对应的技术栈进行预研。相关技术栈均基于JDK + Spring生态,因此在探索具体的服务治理框架之前,我们需要先对jdk、spring、springBoot、springCloud的相关版本进行相关梳理及选定:
Spring Framework | springBoot | springCloud | JDK |
---|---|---|---|
Spring Framework 4.3.7.RELEASE | 1.5.2.RELEASE | Dalston.RC1 | JDK6-8 |
Spring Framework 4.3.13.RELEASE | 1.5.9.RELEASE | Edgware.RELEASE | JDK6-8 |
Spring Framework 5.0.6.RELEASE | 2.0.2.RELEASE | Finchley.BUILD-SNAPSHOT | JDK8-10 |
Spring Framework 5.0.7.RELEASE | 2.0.3.RELEASE | Finchley.RELEASE | JDK8-10 |
Spring Framework 5.1.2.RELEASE | 2.1.x.RELEASE** | Greenwich | JDK8-12 |
Spring Framework 5.* | 2.2.x.RELEASE | Hoxton | JDK8-12 |
根据spring官方说明,Spring Framework 5.1.*为目前的推荐版本
,对该版本的官方支持将持续到2019年底,而后将由5.2.版本取代,而就springCloud的生态演进而言,Finchley版本相较于Dalston,有了极大的丰富与优化。
因此,本文档相关技术栈均基于*SpringCloud Finchley**版本
关于SpringBoot的版本时间线如下:
- 2014年04月01号,Spring Boot 发布 v1.0.0.RELEASE,Spring Boot 正式商用
- 2014年06月11号,Spring Boot 发布 v1.1.0.RELEASE,主要修复了若干 Bug
- 2014年12月11号,Spring Boot 发布 v1.2.0.RELEASE,此版本更新的特性比较多,主要集成了 Servlet 3.1,支持 JTA、J2EE 等。
- 2015年11月16号,Spring Boot 发布 v1.3.0.RELEASE,增加了新 spring-boot-devtools 模块,缓存自动配置、颜色 banners 等新特性。
- 2016年07月29号,Spring Boot 发布 v1.4.0.RELEASE,以 Spring 4.3 为基础进行的构建,更新了很多第三方库的支持,重点增加了 Neo4J, Couchbase、 Redis 等 Nosql 的支持。
- 2017年01月30号,Spring Boot 发布 v1.5.0.RELEASE,更新了动态日志修改,增加 Apache Kafka、LDAP、事物管理等特性的支持。
- 2018年03月01号,Spring Boot 发布 v2.0.0.RELEASE
- 2018年10月30号,Spring Boot 发布 v2.1.0.RELEASE
2. CAP原则
CAP原则又称CAP定理(1998年由加州大学的计算机科学家 Eric Brewer 提出),指的是在一个分布式系统中有三个指标:一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)
CAP 原则指的是,这三个指标最多只能同时实现两点,不可能三者兼顾
- 一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
- 可用性(A):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
- 分区容忍性(P):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择【分区由网络故障、机器故障导致,具有外部不可抗力性,无法控制,是必选项】。
即:设计分布式数据系统,就是在一致性和可用性之间取一个平衡
组件名 | CAP | 一致性算法 |
---|---|---|
Eureka | AP | 无 |
Consul | CP | Raft |
Zookeeper | CP | Paxos |
etcd | CP | Raft |
nacos | AP | Raft |
二.常用服务治理框架
1. Eureka(*)
Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。其也是目前使用最广泛的服务发现框架。
Eureka包含两个组件:Eureka Server(即服务端,注册中心
)和Eureka Client(即客户端,服务提供者/消费者
)
- 服务提供者在启动时,向注册中心注册自己提供的服务。
- 服务消费者在启动时,向注册中心订阅自己所需的服务。
- 注册中心返回服务提供者地址给消费者。
- 服务消费者从提供者地址中调用消费者
2. Consul
Spring Cloud Consul项目是针对Consul的服务治理实现。Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置,它包含多个组件,但是作为一个整体,在微服务架构中为我们的基础设施提供服务发现和服务配置的工具。
- 使用Go语言编写,支持win、linux、mac全平台
- Consul和Eureka不同,Eureka只需要在项目中加入服务端依赖,就可以作为服务端使用;Consul需要从官网下载,并单独安装
- Consul服务器使用 Raft 协议(
要求必须过半数的节点都写入成功才认为注册成功 Leader 挂掉时,重新选举期间整个 Consul 不可用
)复制状态,保证了强一致性。相较于Eurake,高可用及效率均有损失。
3. Dubbo+Zookeeper
Dubbo是一个由阿里巴巴开源的分布式服务框架,提供面向接口的远程方法调用(RPC),智能容错和负载均衡,以及服务自动注册和发现等功能,其直接使用socket通信。传输效率高。Dubbo主要作用是提供服务治理
ZooKeeper是一个开源的分布式协调服务,为分布式应用提供配置维护、域名服务、分布式同步、组服务等功能。ZooKeeper是Dubbo的推荐注册中心,提供服务注册功能(Dubbo也还可以搭配其他注册中心:Multicast注册中、Redis注册中心、Simple注册中心
)
PS:最新Spring社区孵化的Spring Cloud Alibaba,默认选用了Nacos作为注册中心,可以更加便捷地使用Ribbon或Feign来实现服务消费
4. Nacos
Nacos是由阿里巴巴开源的动态服务发现、配置管理和服务管理平台。Nacos提供了如下关键特性:服务发现和服务健康监测、动态配置服务、动态 DNS 服务、服务及其元数据管理。
和Consul一样,Nacos也需要从官网下载服务,进行单独启动下图为Nacos官网提供的架构图:
5. etcd
etcd是一个采用http协议的分布式键值对存储系统,因其易用,简单。很多系统都采用或支持etcd作为服务发现的一部分,比如kubernetes。但其只是一个存储系统,如果想要提供完整的服务发现功能,必须搭配一些第三方的工具,搭建操作相对麻烦。
6. SpringCloud Alibaba
SpringCloud Alibaba作为一款旨在打造更符合中国国情的微服务体系
的开源组件,目前主要提供了服务发现、配置管理、高可用防护、基于RocketMQ的消息中间件等功能。其既提供了基于Nacos+Ribbon/Feign的服务治理方案,又支持基于Nacos+Dubbo的rpc服务治理方案。下图nacas启动后的管理界面:
三. Eureka项目实践
1. Eureka注册中心搭建(单机)
1). pom依赖
1 | <!--eureka依赖【Springboot1.x中 artifactId 为 spring-cloud-starter-netflix-eureka-server,注意区分】--> |
2). 启动类注解
通过在启动类上添加注解@EnableEurekaServer
,为该应用开启注册中心功能
3). application.properties配置
1 | # 服务名称 |
2. Eureka注册中心实现高可用
运行多个Eureka server实例,并进行互相注册即可实现注册中心的高可用
Eureka不允许在单台主机(即同一个ip)上搭建高可用服务,可以利用本机hosts文件构造本地域名来模拟多机,下述过程即是采用该方式进行搭建
1). hosts文件配置
1 | 127.0.0.1 eureka1 |
2). 搭建多个Eureka server
将上文”1. Eureka注册中心搭建(单机)
“中搭建的项目,复制多个即可
3). 修改Eureka server服务的application.properties配置
- 节点1配置
1 | # 服务名称 |
- 节点2配置
1 | # 服务名称 |
- 节点3配置
1 | # 服务名称 |
3. 注册服务至Eureka【构建生产者】
此步骤,即将现有的快融服务注册到Eureka注册中心
1). pom依赖
1 | <!-- eureka client 适配springboot1.*--> |
2). 启动类注解
通过在启动类上添加注解`@EnableDiscoveryClient,激活Eureka中的DiscoveryClient实现,这样才能实现Controller中对服务信息的输出
1 |
|
3). application.properties配置
1 | # 服务名称 |
- 进阶配置
1 | #状态页面的URL,相对路径,默认值是/info【https需要使用绝对路径配置eureka.instance.status-page-url】 |
4. 基于Ribbon实现服务间调用【构建消费者】
Spring Cloud Ribbon是基于基于HTTP和TCP的客户端负载均衡的工具(基于Netflix Ribbon实现
),它被集成在springCloud的基础设施中,并不需要独立部署(简而言之,引入依赖开启配置即可使用)
客户端负载均衡:区别于基于F5(硬件)、nginx(软件)等实现的服务端负载均衡,是将服务清单维护在服务端,按照算法进行请求分发;
客户端负载均衡,是由客户端(即服务消费者)自行维护服务节点清单【从Eureka server获取】,由客户端自行选择请求节点
Ribbon实现客户端负载均衡的方式,是通过在客户端中配置ribbonServerList来设置服务端列表去轮询访问以达到均衡负载的作用。Ribbon与Eureka联合使用时,ribbonServerList会被DiscoveryEnabledNIWSServerList重写,扩展成从Eureka注册中心中获取服务实例列表。同时它也会用NIWSDiscoveryPing来取代IPing,它将职责委托给Eureka来确定服务端是否已经启动。(相应的,当Ribbon与Consul联合使用时,ribbonServerList会被ConsulServerList来扩展成从Consul获取服务实例列表。同时由ConsulPing来作为IPing接口的实现)
1). pom依赖
1 | <dependency> |
2). 声明RestTemplate
通过显示地声明一个RestTemplate对象,并添加注解@LoadBalanced
,开启客户端负载均衡
1 |
|
3). 利用RestTemplate发起请求
RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法。相较于我们目前使用的HTTPClient,大大提高客户端的编写效率。
关于httpClient、OkHttpClient、RestTemplate三者的比较,可以参见
HttpUrlConnection VS RestTemplate
RestTemplate常用API:
- getForEntity(String url, Class
responseType, Object… uriVariables) - getForEntity(URI url, Class
responseType) - getForObject(String url, Class
responseType, Object… uriVariables) - getForObject(URI url, Class
responseType) - postForObject(URI url, @Nullable Object request, Class
responseType) - postForObject(String url, @Nullable Object request, Class
responseType, Object… uriVariables) - postForObject(String url, @Nullable Object request, Class
responseType,Map<String, ?> uriVariables)
- GET请求样例【手动获取实例地址】
1 | // 获取restTemplate对象 |
- POST请求样例【自动获取实例地址】
1 |
|
- POST请求样例 【上面是理想转态,下面才是现实】
1 |
|
- POST请求样例【带参数】
1 |
|
5. 基于Feign实现服务间调用(*)
Spring Cloud Feign是一套基于Netflix Feign实现的声明式服务调用客户端,只需要通过创建接口并用注解来配置它既可完成对Web服务接口的绑定。同时还整合了Ribbon和Eureka来提供均衡负载的HTTP客户端实现
另外,Feign同时整合了Hystrix功能,支持服务容错保护
1). pom依赖
1 | <dependency> |
2). 启动类注解
通过在启动类上添加注解@EnableFeignClients
,开启扫描Spring Cloud Feign客户端的功能
1 |
|
3). 创建Feign的客户端接口定义
Feign提供的是声明式的服务绑定功能,即使用@FeignClient
注解即可实现对服务的绑定
- 构造Feign客户端
1 | // 通过注解将该接口与门户后端服务进行绑定【服务名不区分大小写】 |
- 调用Feign客户端
1 | // 注入Feign客户端 |