SpringCloud微服务框架复习笔记
什么是微服务架构?
微服务是一种软件开发技术,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于HTTP的RESTful API)。每个服务都围绕着具体业务进行构建,并且能够独立地部署到生产环境、类生产环境等。——Wikipedia
我们将在开发中将业务的所有功能都集中在一个项目开发,打成一个包部署的架构方式成为单体架构,架构简单,部署成本低是它的优点。单体架构是一些简单的演示练习项目或低并发需求的个人项目中最常采用的架构方式。但其缺点是耦合度高,不便于大型项目的维护。
分布式架构:根据业务功能进行拆分,每个业务模块作为独立项目开发,称为一个服务;优点:降低耦合,有利于服务升级扩展;缺点:架构复杂,难度大。
微服务是一种良好的分布式架构方案,它有以下特征:
- 单一职责:微服务拆分粒度更小,每一个服务都对应唯一的业务能力,做到单一职责,避免重复业务开发
- 面向服务:微服务对外暴露业务接口
- 自治:团队独立、技术独立、数据独立、部署独立
- 隔离性强:服务调用做好隔离、容错、降级,避免出现级联问题
认识微服务架构
一个成熟的微服务架构解决方案将包含以下相关技术栈:
-
注册中心:
微服务架构把单一应用程序划分成一组小的服务,每个服务运行在自己的进程中,服务之间通过网络调用进行通信。注册中心是微服务架构中的一个核心组件,它负责维护服务实例的注册和发现。
微服务架构中的服务实例是动态的,服务实例可能会经常添加、删除和修改。注册中心能够帮助服务消费者快速发现服务提供者,并且还能够监控服务提供者的健康状态。 -
配置中心:
每个服务都有自己的配置文件,而一个上线的项目可能会有成百上千的服务,这些配置文件,我们不可能一个一个去修改,这个时候需要一个配置中心,它主要用来统一管理整个服务集群成千上百的配置,我们要变更某些配置,只要找到配置中心就可以了,它就会去找到对应的配置,实现配置的热更新。 -
网关:
所有的请求进来,并不能直接就去访问对应的服务,而是要通过一个网关服务,由它来路由到对应的服务。 -
分布式缓存:
数据库层,由于数据库即使是集群部署,也很难抗住高并发,往往还需要一个缓存集群,把数据库的数据搬到内存中以提高访问效率。请求先查询缓存,缓存未命中的时候再去查询数据库。 -
分布式搜索:
对于一些复杂的数据的搜索、统计、分析,我们还需要使用搜索集群。 -
消息队列:
在分布式架构中,还需要消息队列,因为一个业务往往会调用多个服务,但我们不能等到所有的服务都执行完成再返回响应数据,因为这样操作就类似串行执行,响应速度有所下降。这个时候可以使用消息队列,让服务发送消息通知其他服务去执行指定的任务,而自己则可以结束运行,提高响应速度。 -
分布式日志服务:
主要用来统计成百上千的服务的运行日志,方便系统出问题时的定位。 -
系统监控链路追踪:
可以实时监控整个服务集群的所有节点的运行状态。
目前主流的微服务开发框架中,Dubbo、SpringCloud、SpringCloudAlibaba 在国内外市场拥有较高的占有率。下方是框架技术的对比图:
其中 SpringCloud 是国内使用最广泛的微服务框架技术。其官网为:https://spring.io/projects/spring-cloud。 SpringCloud 集成了各种微服务功能组件,并基于 SpringBoot 实现了这些组件的自动装配。
一、微服务的注册中心
微服务技术依据各个服务功能分成不同的模块,而一项业务需要多个服务模块共同完成,这便少不了各模块接口间的互相调用。下面是不同微服务模块远程调用的一个实例:
首先浏览器发送请求到订单模块,订单模块在到数据库查询信息;这时候订单模块再发送请求到用户模块,用户模块在到数据库查询信息。
基于 RestTemplate 实现的服务器远程调用:
- 在配置类(也可直接再启动类注入)中注册 RestTemplate。
/**
* 注入RestTemplate发送http请求获取数据
*
* @return new RestTemplate()
*/
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
- RestTemplate 服务远程调用
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private RestTemplate restTemplate;
/**
* 通过id查询订单
*
* @param orderId 订单编号
* @return json
*/
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
// 2.使用 RestTemplate 远程调用服务器接口
String url = "http://localhost:8081/user/" + order.getUserId();
User user = restTemplate.getForObject(url, User.class);
// 3.封装数据
order.setUser(user);
// 4.返回 order 对象
return order;
}
}
考虑上述案例,我们将远程调用过程中的双方分别成为服务提供者和服务消费者。
- 服务提供者:一次业务中被其它微服务调用的。(提供接口给其它微服务使用)
- 服务消费者:一次业务中调用其他微服务。(调用其他微服务的接口)
- 提供者与消费者角色其实是相对的,一个服务可以同时是服务提供者和服务消费者。
Ⅰ、Eureka 注册中心
上述服务远程调用存在一些问题:
- 服务消费者该如何获取服务提供者的地址信息?
- 如果有多个服务提供者,消费者该如何选择?
- 消费者如何得知服务提供者的健康状态?
为了解决这些问题,SpringCloud 为我们提供了一个注册中心技术——Eureka。
Eureka 是 SpringCloud 框架中的一个核心组件,它负责维护服务实例的注册和发现。服务提供者启动时会向 eureka 注册自己的信息,随后消费者则根据服务名称向 eureka 拉取提供者信息。若服务提供者存在多个,服务消费者将利用负载均衡算法,从服务列表中挑选一个。
动手实践
步骤一:搭建 Eureka 服务器
- 为项目新建一个模块,引入 eureka-server 依赖:
<!-- eureka服务器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
- 编写启动类,添加
@EnableEure