2017年微服务在国内火的一塌糊涂,无论是BAT企业还是初创型公司,无不在践行着微服务,就好像如果系统不是采用微服务架构就不是搞开发一样,那么到底什么样的公司和系统适合实施微服务架构,微服务架构的整体体系是什么,如何实施微服务架构,本文作为微服务系列的第一篇文章,把在项目中的一些使用的一些心得和坑整理成文分享出来。
一、微服务适合的场景
我们先来了解一下什么是微服务,微服务在《Spring Cloud微服务实战》书中有如下一段定义:
微服务是将一个原本独立的系统拆分成多个微小型服务,这些小型服务都在各自独立的进程中运行,服务之间通过基于HTTP的RESTful API进行协作。被拆分成的每一个小型服务都围绕着系统中的某一项或一些耦合度较高的业务功能进行构建,并且每个服务都维护着自身的数据存储、业务开发、自动化测试案例以及独立部署机制。由于有了轻量级的通信协作基础。
在日常项目中,我们常常会碰到项目越做越大,越做越臃肿,当项目大到一定程度就会出现以下问题:
1、有些业务模块是非常重要且常用的,有些是不常用的,但在整个系统中一旦其中一个不常用模块出现问题可能会导致整个系统不可用。
2、所有业务都在一个项目里面,不同客户对不同业务模块的需求和取舍都不同,每个业务模块也不能独立出来复用,这样就导致一个项目改来改去N多个版本,版本管理起来非常麻烦。
3、所有的业务在一个项目里面,团队所有的人在同一个项目中修改,哪怕一个小小的修改,都需要进行全量的测试,测试苦不堪然,工作效率极其低下,版本迭代越来越慢。
4、所有的业务打包在一个应用容器下运行,无法针对使用量大的业务进行合理的扩容,只能一股脑的全部扩容,极大的浪费了系统资源,一个业务挂了,所有的业务都无法继续进行。
5、多个系统面临使用同一个数据时候,由于系统的边界划分不明确,各个团队间独立作战,缺少沟通,往往会出现一份各种同步来同步去,又没有有效的机制去保证同步数据的及时性和准确性,造成了各个系统的数据不一致,其影响性是灾难性的。
当你所在的项目出现以上问题,并呈现越发放大,一发不可收拾的地步的时候,微服务架构如同病中的一剂良药,可以有效了帮助你解决和规避上述问题。
微服务把原本独立的系统按照业务进行拆分,每个业务独立成为一个个微小的服务,服务之间通过契约协议进行协作,服务与服务约定接口协议及通信方式,如果采用微服务架构,那么就可以按照业务独立安排开发团队,各开发团队互相不受影响,各服务拥有自身独立的数据库、应用、接口及运行环境,可有针对性的根据不同服务的用途、性质进行有效的扩容及容灾策略。
二、微服务整体体系
一个完整的微服务体系,个人认为需要包含以上部分,这张图来自于极客时间,拿来用用,归纳的很完整的,
服务框架:微服务发展到今天,用于选型的服务框架太多太多,在这里就不一一列出,国内目前比较常用的有spring boot/Cloud和Dubbo,spring cloud 有spring在背书,整合了一些netflix项目,成熟度就不用说了,社区也比较活跃,更新比较及时,dubbo的话在服务治理这一块比spring cloud 做的要深入,文档比较健全,并且有完整的中文版文档,在国内用的也比较广泛,尤其是在2017 阿里重启了dubbo开源项目,在 这一年更新也很迅速。
运行时支撑服务:由于微服务是把一个系统拆分成N多的微小的服务,那么如何把这些服务整合在一起,就需要一些运行时支撑的一些服务,主要包含注册中心,配置中心、服务网关
注册中心:在spring cloud 体系中,注册中心选用eureka是最佳搭配了,eureka经过Netflix大规模的生产验证,已经相对成熟和完善了,当然spring 本身也提供了一个Consul也是不错的选择。
配置中心:spring cloud 自带的spring cloud config 个人认为算不上生产级,只是提供了一个简单的集中式的配置管理,很多治理的能力都是需要后续自行扩展的,在小型的微服务场景下可以试用,国内在这一块开源比较好的是携程的Apollo,它在携程的项目中经过了生产的验证,具备高可用、配置准实时生效(无需重启服务)配置审计、版本化管理,以及多环境多集群多机房支持,最重要的是它和spring boot、cloud结合的非常好。
服务网关:服务网关在微服务中是不可或缺的一块,在spring cloud 体系一般选用zuul,zuul 也是netflix开源出来的,也是经过生产级的验证,在稳定性和性能方面还是有所保障的,而是我们这篇接下来说的重点。
服务安全:对于微服务安全,在微服务体系中通常会在网关层面作为统一的安全认证,国际通用的做法采用的是auth2.0的授权机制,由于微服务是典型的无状态的服务架构,因此不会采用session有状态的会话的机制去存储相应的安全信息,通常会采用token的作为安全的一种授信机制
后台服务:在微服务体系中,为了避免各项目针对一些技术组件重复造轮子,减少技术对各项目压力,通常我们会对各项目进行技术屏蔽,减少技术壁垒对项目时间进行干扰,我们会对一些公用技术组件进行封装,如缓存、分布式存储、MQ消息、任务调度等进行封装,以微服务的形式提供给各项目使用
服务容错:针对java 技术栈,我们通常会采用Hystrix把熔断、隔离、限流和降级等能力封装成组件,任何依赖调用(数据库,服务,缓存)都可以封装在 Hystrix Command 之内,封装后自动具备容错能力。
服务监控:微服务也是不银弹,我们在享受着微服务的好处的同时,我们也必须忍受着微服务自身带来的一些麻烦,由于微服务架构把一个完整的业务系统拆分成N个服务,那么微服务监控这一块就是至关重要的,微服务监控主要包含日志的监控、调用链的监控、微服务应用自身健康状况的监控以及一些告警通知。
服务部署平台:服务部署平台对于微服务来说也是至关重要的,微服务的部署不同于传统的单体架构应用,在实施微服务之前,我们必须针对微服务搭建一套持续部署平台,可做到事半功倍的效果,微服务部署平台是一个行业级的课题,目前能使用的技术栈非常之多,也非常之杂,后续会细讲。
三、网关应具备的功能
随着微服务的兴起,API网关也成为微服务的标配,API Gateway(APIGW / API 网关),顾名思义,是出现在系统边界上的一个面向API的、串行集中式的强管控服务,这里的边界是企业IT系统的边界,主要解决统一认证、报文转换、访问统计等问题,那么一个网关到底应该具备哪些功能呢?
更细的来说,一个网关要具备以下功能特性
* 性能:API高可用,负载均衡,容错机制。
* 安全:权限身份认证、脱敏,流量清洗,后端签名(保证全链路可信调用),黑名单(非法调用的限制)。
* 日志:日志记录(spainid,traceid)一旦涉及分布式,全链路跟踪必不可少。
* 缓存:数据缓存。
* 监控:记录请求响应数据,api耗时分析,性能监控。
* 限流:流量控制,错峰流控,目前有漏桶算法、令牌桶算法也可以定制限流规则。
* 灰度:线上灰度部署,可以减小风险。
* 路由:动态路由规则。
* 静态:静态资源代理
* 协议:多协议支持,不同协议的数据进行转换
四、微服务网关的选型
目前做网关主流的有反向代理Nginx,这个用于做微服务网关不合适,具体怎么不合适大家可以脑补以下。另外还有一个Kong它是基于Nginx基础开发了的,有开源版本和商用版本,有非常多的插件,在性能和功能也都还可以,可惜不是用java开发的,用Lua语言这方面的程序员应该在市面上还是比较少的把。
在java领域和spring cloud 整合的比较好的就两个 ,netflix的zuul 和spring 官方的gateway,zuul已经经过netflix的生产验证,在性能方面是没有特别突出,但是也能凑合着用,spring 官网的gateway 2017年才刚出来,目前应该还没有几家公司真正用在生产中把。所以如果你的微服务技术栈是spring cloud的话 ,用zuul其实是不二之选,用zuul 建议使用2.0版本,因为2.0版本支持异步调用,这样可以提高网关的吞吐量,记住是吞吐量不是响应时长。