
微服务的简单介绍和示例
架构方式以及服务拆分
单体架构
单体架构:将业务的所有功能集中在一个项目中开发,打成一个包部署。
如图:
优点:架构简单,部署成本低
缺点:耦合度高(因为代码都在一个项目中,一个地方发生变动,有关的包中的代码都要变动,所以维护困难、升级困难)
分布式架构
分布式架构:根据业务功能对系统做拆分,每个业务功能模块作为独立项目开发,称为一个服务。
如图:
优点:降低服务耦合,有利于服务升级和拓展
缺点:服务调用关系错综复杂
分布式架构虽然降低了服务耦合,但是服务拆分时也有很多问题需要思考:
- 服务拆分的粒度如何界定?
- 服务之间如何调用?
- 服务的调用关系如何管理?
人们需要制定一套行之有效的标准来约束分布式架构。
SpringCloud
SpringCloud是目前国内使用最广泛的微服务框架。官网地址:https://spring.io/projects/spring-cloud。
SpringCloud集成了各种微服务功能组件,并基于SpringBoot实现了这些组件的自动装配,从而提供了良好的开箱即用体验。
其中常见的组件包括:
其中的常用的一些组件将会在后续介绍。
另外,SpringCloud底层是依赖于SpringBoot的,并且有版本的兼容关系,如下:
服务拆分和远程调用
任何分布式架构都离不开服务的拆分,微服务也是一样。
案例源码:https://github.com/VioletEvGaden/cloudstudy
服务拆分原则
这里我总结了微服务拆分时的几个原则:
- 不同微服务,不要重复开发相同业务
- 微服务数据独立,不要访问其它微服务的数据库
- 微服务可以将自己的业务暴露为接口,供其它微服务调用
服务拆分示例
以案例源码中cloud-demo结构如下:
cloud-demo:父工程,管理依赖
- order-service:订单微服务,负责订单相关业务
- user-service:用户微服务,负责用户相关业务
要求:
- 订单微服务和用户微服务都必须有各自的数据库,相互独立
- 订单服务和用户服务都对外暴露Restful的接口
- 订单服务如果需要查询用户信息,只能调用用户服务的Restful接口,不能查询用户数据库
打开后idea右下角有一个弹窗
点击显示运行配置后
这样就可以很方便的启动和停止多个服务
远程调用
在order-service服务中,有一个根据id查询订单的接口:
根据id查询订单,返回值是Order对象,如图:
其中的user为null
在user-service中有一个根据id查询用户的接口:
查询的结果如图:
远程调用案例:
修改order-service中的根据id查询订单业务,要求在查询订单的同时,根据订单中包含的userId查询出用户信息,一起返回。
因此,我们需要在order-service中 向user-service发起一个http的请求,调用http://localhost:8081/user/{userId}这个接口。
这样就能查到user信息,并放到order对象中返回
因此我们需要知道 controller层如何去发送 http 请求,Spring 提供了一个 RestTemplate 工具,只需要把它创建出来即可。
1 |
|
修改order-service服务中的cn.zh.order.service包下的OrderService类中的queryOrderById方法:
启动完成后,访问:http://localhost:8080/order/101即可看到返回的order对象中包含了user
提供者与消费者
在服务调用关系中,会有两个不同的角色:
服务提供者:一次业务中,被其它微服务调用的服务。(提供接口给其它微服务)
服务消费者:一次业务中,调用其它微服务的服务。(调用其它微服务提供的接口)
但是,服务提供者与服务消费者的角色并不是绝对的,而是相对于业务而言。
如果服务A调用了服务B,而服务B又调用了服务C,服务B的角色是什么?
- 对于A调用B的业务而言:A是服务消费者,B是服务提供者
- 对于B调用C的业务而言:B是服务消费者,C是服务提供者
因此,服务B既可以是服务提供者,也可以是服务消费者。