1.认识微服务
- 单体架构: 将业务的所有功能集中在一个项目中开发,打成一个包部署
- 分布式架构: 根据业务功能对系统做拆分,每个业务功能模块作为独立项目开发,称为一个服务
架构 | 优点 | 缺点 |
---|---|---|
单体架构 | 架构简单,部署成本低, | 耦合度高(维护困难、升级困难) |
分布式架构 | 降低服务耦合,有利于服务升级和拓展 | 服务调用关系错综复杂 |
2.微服务架构的特征
- 单一职责: 微服务拆分粒度更小,每一个服务都对应唯一的业务能力,做到单一职责
- 自治: 团队独立、技术独立、数据独立,独立部署和交付
- 面向服务: 服务提供统一标准的接口,与语言和技术无关
- 隔离性强: 服务调用做好隔离、容错、降级,避免出现级联问题
3. SpringCloud
- SpringCloud是微服务架构的一站式解决方案,集成了各种优秀微服务功能组件
- Spring Cloud 为开发人员提供了在分布式系统中快速构建一些常见模式的工具(例如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性令牌、全局锁、领导选举、分布式会话、集群状态)。分布式系统的协调导致了样板模式,使用 Spring Cloud 开发人员可以快速建立实现这些模式的服务和应用程序。它们可以在任何分布式环境中很好地工作,包括开发人员自己的笔记本电脑、裸机数据中心和托管平台
4.服务拆分
-
原则
- 不同微服务,不要重复开发相同业务
- 微服务数据独立,不要访问其它微服务的数据库
- 微服务可以将自己的业务暴露为接口,供其它微服务调用
-
拆分时机
- 有快速迭代的需求
- 提交代码频繁出现大量冲突
- 小功能要积累到大版本才能上线
- 解决高并发横向扩展问题
-
拆分原则
- 单一职责原则: 每个微服务只需关心自己的业务规则,确保职责单一,避免职责交叉,耦合度过高将会造成代码修改重合,不利于后期维护。
- 服务自治原则: 每个微服务的开发,必须拥有开发、测试、运维、部署等整个过程,并且拥有自己独立的数据库等,可以完全把其当作一个单独的项目来做,而不牵扯到其他无关业务。
- 轻量级通信原则: 微服务间需通过轻量级通信机制进行交互。首先是体量较轻,其次是需要支持跨平台、跨语言的通信协议,再次是需要具备操作性强、易于测试等能力,如:REST通信协议。
- 接口明确原则: 明确接口要实现的内容,避免接口依赖,如A接口的改动会导致B接口的改动。
- 持续演进原则: 单体架构向微服务架构拆分过程中,无法做到一蹴而就,刚开始不建议拆分太小,过度拆分将会带来架构复杂度的急剧升高,开发、测试、运维等环节很难快速适应,将会导致故障率大幅增加,可用性降低,非必要情况,应逐步拆分细化,持续演进,避免微服务数量的瞬间爆炸性增长。
-
拆分方法
微服务的拆分应遵循上述拆分时机、拆分原则,并选择合适的拆分方法,逐步拆分,还要从实际业务领域出发,并结合考虑非业务的因素,比如需求变更的频率、高性能、安全性、团队规模以及技术异构等因素
- 业务领域拆分
- 需求变化频率
- 服务性能要求
- 组织架构和团队规模
- 安全边界
- 技术异构
5.远程调用
- 注册RestTemplate,在order-service服务中的OrderApplication启动类中,注册RestTemplate实例
@MapperScan("cn.pj.order.mapper")
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
/**
* 创建 RestTemplate 并注入 Spring 容器
* @return
*/
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
- 实现远程调用
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private RestTemplate restTemplate;
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
//2.利用 RestTemplate 发起 http 请求,查询用户
//2.1 url路径
String url ="http://localhost:8081/user/"+order.getUserId();
//2.2 发起 http 请求,实现远程调用
User user= restTemplate.getForObject(url, User.class);
//3. 封装 user 到 Order
order.setUser(user);
// 4.返回
return order;
}
}
6.提供者与消费者
-
服务提供者: 一次业务中,被其它微服务调用的服务。(提供接口给其它微服务)
-
服务消费者: 一次业务中,调用其它微服务的服务。(调用其它微服务提供的接口)
-
对于A调用B的业务而言:A是服务消费者,B是服务提供者
-
对于B调用C的业务而言:B是服务消费者,C是服务提供者
因此,服务B既可以是服务提供者,也可以是服务消费者