【SpringCloud】一、认识微服务

1、学习提纲

相比传统单体架构,微服务的整体架构如下图:

在这里插入图片描述

再引入日志、监控、持续集成、持续部署,就成了下面这个图:

在这里插入图片描述

对这里涉及到的技术,进行一个分类:

在这里插入图片描述

2、和单体架构的比较

单体架构

之前的单体架构,即将业务的所有功能集中在一个项目中开发,打成一个包进行部署。单体架构有优点:

  • 架构简单
  • 部署成本低

缺点则是:

  • 耦合度高

在这里插入图片描述

微服务架构

相比单体架构,分布式架构则是根据业务功能对系统进行拆分,每个业务模块做为独立项目开发,成为一个个服务。从而:

  • 降低服务的耦合
  • 有利于服务的升级拓展

在这里插入图片描述
但此时也产生了新的问题:

  • 系统怎么拆,即服务拆分粒度如何
  • 服务集群的地址怎么维护
  • 服务之间如何远程调用
  • 服务健康状态怎么感知
    在这里插入图片描述

3、认识微服务

微服务是一种经过良好架构设计的分布式架构方案,微服务架构特征:

  • 单一职责:微服务拆分粒度更小,每一个服务都对应唯一的业务能力

  • 面向服务:微服务对外暴露业务接口

  • 自治:团队独立、技术独立、数据独立、部署独立。即每个服务有一个小组负责,这个小组有自己的前后端、测试、运维。可以选择适合该服务的语言与技术。每个服务有自己的数据库。

  • 隔离性强:服务调用做好隔离、容错、降级,避免出现级联问题(一个服务挂了,向依赖的服务全挂了)

在这里插入图片描述

服务之间的调用关系错综复杂,需要进行维护,因此微服务中还有一个注册中心,去维护每个微服务的信息和监控服务的健康状态。

对于一些配置,每次去微服务代码中去修改不现实,因此,还有一个配置中心,去统一管理每个微服务的配置。

最后再加上一个网关做为访问的入口,就得到了这样的架构:

在这里插入图片描述

4、微服务技术常用框架

微服务这种技术需要技术框架来进行落地,最常用的是SpringCloud和阿里巴巴的Dubbo。下面做个对比:

在这里插入图片描述
企业中常用的一个情况是:

  • SpringCloud技术栈
  • 接口采用Restful风格
  • 服务调用采用Feign方式

5、SprigCloud

SpringCloud是目前国内使用最广泛的微服务框架。官网地址:https://spring.io/projects/spring-cloud

SpringCloud集成了下面的各种微服务功能组件,并基于SpringBoot实现了这些组件的自动装配。

在这里插入图片描述

SpringCloud和SpringBoot的版本适配情况:

在这里插入图片描述

6、服务拆分

微服务拆分的注意事项:

  • 单一职责:不同微服务,不要重复开发相同业务

  • 数据独立:不要访问其它微服务的数据库

  • 面向服务:将自己的业务暴露为接口,供其它微服务调用

在这里插入图片描述

案例:

在这里插入图片描述
在IDEA中导入Demo工程:

在这里插入图片描述
这里有两个模块:

在这里插入图片描述

调用一下两个模块的接口:

在这里插入图片描述

到此,可以看到拆分完成,不同的模块干不同的职责,order模块查订单,user模块查用户。并且数据库也做了分离。每个微服务有自己独立的数据库。

7、微服务远程调用

需求:根据订单id查询订单的同时,把订单所属的用户信息一起返回
# 两个信息在不同的数据库
# 查询这两个信息得用两个模块的接口(这里只是举例,当然你强行在其中一个模块创建mapper并指定数据库也能实现,但这首先不符合微服务规范,因为操作了其他微服务的数据库。其次当这里的接口实现很复杂,不再是一句SQL能完成的时候,这么操作就不现实了)

分析:

在这里插入图片描述

实现远程调用:

在这里插入图片描述
像在浏览器发送HTTP请求得到用户信息一样,在模块中发送HTTP请求也可以得到响应。那如何在Java代码中发起合HTTP请求呢?

实现微服务调用的步骤:

STEP1:在调用方的(配置类)启动类中注册RestTemplate

//Bean的注入只能放在配置类中,而@SpringBootApplication注解的启动类本身也是配置类
@Bean
public RestTemplate restTemplate(){
    
    
	return new RestTemplate();
}

在这里插入图片描述

STEP2:在需要远程调用其他服务的方法中,使用restTemplate对象,调用getForObject方法或者postForObjecct方法,传入调用的url,和需要的类型(就可以json反序列化出User.class类型的对象)

@Service
public class OrderService{
    
    

	@Autowired
	private RestTemplate restTemplate;
	public Order queryOrderById(Long orderId){
    
    
		//查询订单
		Order order = orderMapper.findById(orderId);
		//查询用户
		String url = "http://localhost:8081/user/" + order.getUserId();
		//这里的url参数,浏览器中是个啥,这里也就是个啥,一样的
		User user = restTemplate.getForObject(url,User.class);
		//封装user信息,order对象中有引用属性User类型
		order.setUser(user);
		return order;
		
	}
}

重启order服务:

在这里插入图片描述

到此,跨服务的调用实现。

猜你喜欢

转载自blog.csdn.net/llg___/article/details/129612372