目录

一, 服务架构的演变

1.1 单体架构

1.2 分布式架构

1.3 微服务

1.4 SpringCloud

二, 服务拆分和远程调用

2,1 服务拆分原则

2.2 服务拆分示例

2.3 创建相应数据库

2.4 实现远程调用示例

1, 更改需求

2, 注册RestTemplate实现远程调用

2.5 服务消费者和提供者


一, 服务架构的演变

1.1 单体架构

将业务的所有功能集中在一个项目中开发,打成一个包进行部署项目称为单体架构.

假设有一个商城项目,该项目包含订单模块,用户功能,商品功能以及支付功能,将该项目进行部署时,只需要将该项目的所有功能打包成一个包部署在Tomcat上即可,该项目所有业务功能都只访问一个数据库,如图所示:

单体架构的优点:结构简单,部署成本低(只需要将整个项目打包放在一个Tomcat下即可);

单体架构的缺点:耦合度高(因为一个项目中包含了所有业务功能,不同业务之间的数据都密切耦合).

1.2 分布式架构

根据业务功能对系统进行拆分,每个业务模块作为独立项目开发,称为一个服务,多个这样的服务的组合称为分布式.

还是商城项目,项目包含4个业务功能,每个业务功能只需要开发和自己业务相关的代码即可,用户需要获取数据时只需要调用相应的模块即可,但是这几个模块使用的还是同一个数据库,如图所示:

分布式架构的优点:降低服务耦合(业务和业务之间相互独立),有利于服务的升级和拓展(需要其他业务模块时只需要单独开发该模块的代码即可);

分布式架构的缺点:服务调用关系错综复杂(假设某一个业务模块需要其他业务模块时就需要调用其他模块进行数据的获取).

1.3 微服务

分布式架构相对于单体架构一定程度上降低了业务模块之间的耦合性,但是正因为业务模块之间的耦合,不同业务模块想要进行交互时就会变的更加困难,还有我们定义的不同业务的粒度是多大,如何做到业务模块拆分的比较合理等等都是需要进一步解决的,所以引出了微服务的概念,微服务需要解决的问题如下:

  • 服务粒度的拆分;
  • 服务集群地址的维护;
  • 服务之间的远程调用;
  • 服务健康状态的感知.

微服务的架构特征

  • 单一职责:微服务拆分粒度很小,每一个服务对应唯一的业务能力,做到单一职责;
  • 自治:团队独立,技术独立,数据独立,独立部署和交付;
  • 面向服务:服务提供统一标准接口,与语言技术无关;
  • 隔离性强:服务调用做好隔离,容错,降级,避免出现级联问题.

用户进行服务访问时,会先经过服务网关,网关进行请求的过滤和路由,路由到相应的服务上,在相应的服务上进行数据库的访问等操作.

微服务的上述特性其实是在给分布式架构制定一个标准,进一步降低服务之间的耦合度,提供服务的独立性和灵活性,做到高内聚低耦合.

1.4 SpringCloud

从上述微服务的特征来看,可以认为微服务是一种经过良好架构设计的分布式架构方案,但是方案该怎么落地” />Spring CloudSpring Cloud

SpringCloud集成了各种微服务功能组件,并基于SpringBoot实现了这些组件的自动装配,从而提供了良好的开箱即用体验,其中常见的组件包括:

二, 服务拆分和远程调用

任何分布式架构都离不开服务的拆分,微服务也是一样.

2,1 服务拆分原则

微服务拆分一般有以下几个原则:

  • 不同微服务,不要重复开发相同业务;
  • 微服务数据独立,不要访问其他微服务的数据库;
  • 微服务可以将自己的业务暴露为接口,供其他微服务调用.

2.2 服务拆分示例

假设有一个微服务名为cloud-demo,其结构如下:

cloud-demo:父工程,管理依赖

  • order-service:订单微服务,负责订单相关业务
  • user-service:用户微服务,负责用户相关业务

要求:

  • 订单微服务和用户微服务都必须有各自的数据库,相互独立
  • 订单微服务和用户服务都对外暴露Restful的接口(供其他微服务进行调用)
  • 订单服务如果需要查询用户信息,只能调用用户服务的Restful接口,不能查询用户数据库

2.3 创建相应数据库

因为不同微服务所使用的数据库不一样,所以这里为了演示效果分别给order-service和user-service项目在一个机器上创建两个不同的数据库作为区分

order-service项目的tb_order表:

user-service项目的tb_user表:

2.4 实现远程调用示例

在order-service服务中,有一个根据id查询订单的接口:

根据查询结果可以看到,返回的Order对象中的user属性为null;

在user-service中有一个根据id查询用户的接口:

1, 更改需求

order-service和user-service都可以根据id查询到相应的订单和用户信息,假设现在有一个需求是在查询到订单的同时返回相应的用户信息.

因为不同业务模块之间是相互独立的,在order-service中查询相应订单的用户信息就需要在order-service模块下向user-service模块下发送一次http请求调用http://localhost:8081/user/{userId}这个接口获取到用户信息后再进行封装返回.

大概得步骤是这样的:

  1. 注册一个RestTemplate的实例到Spring容器
  2. 修改order-service服务中的OrderService类中的queryOrderById方法,根据Order对象中的userId查询User
  3. 将查询的User填充到Order对象中一起返回

2, 注册RestTemplate实现远程调用

1.我们在order-service服务中的OrderApplication启动类中,注册RestTemplate实例:

2.修改OrderService类中的queryOrderById方法实现远程调用

3.重启服务器查看结果

2.5 服务消费者和提供者

在服务调用关系中,会有两个不同的角色:

  • 服务提供者:一次业务中,被其他微服务调用的服务(提供接口给其他微服务)
  • 服务消费者:一次业务中,调用其他微服务的服务(调用其他微服务提供的接口)

但是,服务提供者与服务消费者的角色并不是绝对的,而是相对于业务而言,如果服务A调用了服务B,而服务B又调用了服务A,服务B既是服务提供者也是服务消费者.