简介
所有的功能打包在一个war包里,基本没有外部依赖(除了容器),部署在一个JEE容器(Tomcat,JBoss,WebLogic)里,包含了DO/DAO,Service,UI等逻辑;
特点
- 开发简单直接,集中式管理;
- 基本不会重复开发;
- 功能都在本地,没有分布式的管理开销和调用开销;
目的是有效的拆分应用,实现敏捷开发和部署;
定义
- 一系列的独立的服务共同组成系统;
- 单独部署,跑在自己的进程中;
- 每个服务为独立的业务开发;
- 分布式管理;
- 分布式服务组成的系统;
- 按照业务而不是技术来划分组织;
- 做有生命的产品而不是项目;
- 强服务个体,弱通信;
- 自动运维;
- 容错;
- 快速进化;
落地问题
- 客户端如何访问这些服务?
- 服务之间如何通信?
- 服务这么多,怎么找?
- 服务挂了怎么办?
客户端如何访问
现在拆分成独立的服务,跑在独立的虚拟机上的java进程,后台N个服务和UI之间会有一个代理或者API GateWay,作用包括:
- 统一服务入口,让服务队前台透明;
- 聚合后台服务,节省流量,提升性能;
- 提供安全,过滤,流控等API管理功能;
API GateWay可以有很广义的实现方法,可以是一个软硬一体的盒子,可以是一个简单的MVC框架,甚至是一个Node.js的服务端。作用是为前台(通常移动应用)提供后台服务的聚合,提供一个统一的服务出口,解除他们之间的耦合,不过API GateWay也有可能成为单点故障点或者性能的瓶颈。
服务之间如何通信
因为所有的微服务都是独立的JAVA进程,跑在独立的虚拟机上,所以服务之间的通信就是IPC(interprocess communication),已经有很多成熟的方案。
同步调用:
- REST(JAX-RS,Spring Boot)
- RPC(Thrift,Dubbo)
异步消息:
- kafka,Notify,MetaQ
一般来说同步调用比较简单,一致性强,但是容易出调用错误问题,性能体验上也会差,特别是调用层次多的时候。restful和rpc的比较是有意思的话题。
一般rest基于http,更容易实现,容易被接受,服务端实现技术比较灵活,各个语言都支持,同时跨客户端,对客户端没有特殊要求,只要封装了HTTP的SDK都能调用。
RPC传输更高效,安全更可控,特别是公司内部,如果同意一个的开发规范和同意的服务框架,开发效率更高。
异步方式在分布式系统中使用比较广泛,既能降低服务之间耦合,又能成为调用之间的缓冲,去报消息积压不会冲垮调用方,付出的代价就是一致性问题,需要接受最终一致性。
服务这么多,怎么找?
微服务架构中,一般没一个服务都是有多个拷贝,来做负载。一个服务随时可能下线,也可能面临访问压力增加新的服务点。服务之间如何感知?服务如何管理?
一般两类作法,基本是通过zookeeper类似技术做服务注册信息的分布式管理。当服务上线时,服务的提供者将自己的服务信息注册到ZK,通过心跳维持长连接,试试更新链接信息。服务调用者通过ZK寻址,根据指定算法找到服务,可以将服务缓存在本地提高性能。当服务下线时,ZK会发通知给服务客户端。
- 客户端:优点是框架简单,扩展灵活,只对服务注册器依赖。缺点是客户端要维护所有的调用服务的地址,有技术难度,一般大公司有成熟的内部框架支持,Dubbo;
- 服务端:优点简单,所有服务队前台调用同名,一般在小公司在云服务上部署的应用采用的比较多。
这么多服务,服务挂了怎么办?
微服务风险是把所有的鸡蛋放在一个篮子里面,而分布式最大的特点就是网络不可靠,通过微服务拆分能降低这个风险,所以当系统由一系列调用链组成的时候,必须保证任一环节出现问题不至于影响整体链路。
- 重用机制
- 限流
- 熔断机制
- 负载均衡
- 降级(本地缓存)
微服务的应用
一个微服务架构基本包括:
- api gateway;
- 服务间调用;
- 服务发现;
- 服务容错;
- 服务部署;
- 数据调用;
优点:
- 开发简单;
- 技术栈灵活;
- 服务独立无依赖;
- 独立按需扩展;
- 可用性高;
缺点:
- 多服务运维难度;
- 系统部署依赖;
- 服务间通信成本;
- 数据一致性;
- 系统集成测试;
- 重复工作;
- 性能监控;
技术上不是问题,意识比工具重要。
最后,一般提到微服务都离不开DevOps和Docker,理解微服务架构的核心,DevOps和Docker是工具,是手段。