传统方式 VS 微服务
传统开发方式遇到的问题:
- 开发效率低:所有的开发在一个项目改代码,递交代码相互等待,代码冲突不断。
- 代码部署难:代码功能耦合在一起,新人不知道如何下手。
- 部署不灵活:构建时间长,任何小的修改必须重新构建整个项目。
- 稳定性不高:一个问题往往导致整个应用挂掉。
- 扩展性差:无法满足高并发情况下业务需求。
简单说:
微服务的目的是有效的拆分应用,实现敏捷开发部署。
官方对于微服务的定义:
- 一系列独立服务共同组成系统;
- 单独部署,跑在自己的进程中;
- 每个服务为独立业务开发;
- 分布式管理;
微服务标准:
- 分布式服务组成系统;
- 按照业务而不是技术划分组织;
- 做有生命的产品而不是项目;
- 自动化运维;
- 容错;
- 快速演化;
使用微服务的问题:
- 客户端如何访问微服务;
- 服务之间如何通信;
- 服务多了怎么找?
- 服务挂了怎么办?
客户端访问微服务
之前的UI和服务都是本地的,UI可以直接调用,现在按功能拆分成独立的服务,每个服务都跑着独立的虚拟机上的JAVA进程中。后台有N个服务,客户端就需要记住N个服务,一个服务下线/更新/升级,前台都需要重新部署。N个服务的调用也是不小的网络开销,用户授权管理需要统一。
所以一般在客户端和N个服务之间,建立代理或者API Gateway:
- 提供统一服务入口,让服务对客户端透明;
- 聚合后台服务,节省流量,提升性能;
- 提供安全,过滤,控流等API管理功能;
服务之间如何通信
所有服务都是独立的JAVA进程跑在独立的虚拟机上,所以服务间的通信是IPC,有很多成熟的解决方案,通用的有两种方式:
- 同步调用:
- REST (JAX-RS,Spring Boot)
- RPC (Thrift,Dubbo)
- 异步消息调用(Kafka,Notify,MetaQ)
同步调用:
简单,一致性强,容易出调用问题,性能体验会差一些,调用层次多的时候可能耗时。 REST基于HTTP,更易实现,更易接受,服务端实现更加灵活,各个语言都能支持,同时能跨客户端,对客户端没有特殊要求,使用更广。 RPC有自己的优点,传输协议更高效,安全性更可控。
异步调用:
降低系统服务之间耦合,为调用之间建立缓冲,确保消息积压不会冲垮被调用方; 需要付出一致性代价,后台服务一般需要实现幂等性,因为消息发送出于性能考量一般会重复; 需要引入独立的broker,对broker分布式管理也是一个挑战;
服务多了怎么找?
一般一个服务有多份拷贝,做负载均衡。一个服务随时可能下线,也可能面临访问压力时增加新服务节点。 服务之间如何感知?服务如何管理?
- 基于zookeeper框架实现服务注册分布式管理。
- 客户端做:优点是架构简单,扩展灵活,只对服务注册器依赖。缺点是客户端需要维护所有调用服务地址,有技术难度,可使用Dubbo。
- 服务端做:优点是简单,所有服务对前台调用透明,一般在小公司云服务上部署采用较多。
服务多了挂了怎么办?
单体应用风险是鸡蛋放在一个篮子中,分布式的特征是网络不可靠。所以当系统由一些列服务调用链组成的时候,必须确保任何环节不出问题而影响整个链路。手段如下:
- 重试机制;
- 限流;
- 熔断;
- 负载均衡;
- 降级(本地缓存);
最后提到微服务离不开DevOps和Docker,理解微服务架构是核心,devops和docker是工具,是手段。