2014年能够认为是微服务1.0的元年,当年有几个标志性事件,一是Martin Fowler在其博客上发表了“Microservices”一文,正式提出微服务架构风格;二是Netflix微服务架构通过多年大规模生产验证,最终抽象落地造成一整套开源的微服务基础组件,统称NetflixOSS,Netflix的成功经验开始被业界承认并推崇;三是Pivotal将NetflixOSS开源微服务组件集成到其Spring体系,推出Spring Cloud微服务开发技术栈。ios
一晃三四年过去,微服务技术生态又发生了巨大变化,容器,PaaS,Cloud Native,gRPC,ServiceMesh,Serverless等新技术新理念你方唱罢我登场,不知不觉咱们又来到了微服务2.0时代。基于近年在微服务基础架构方面的实战经验和平时的学习积累,我想总结并提出一些构建微服务2.0技术栈的选型思路,供各位在一线实战的架构师、工程师参考借鉴。对于一些暂时尚未成熟开源产品的微服务支撑模块,我也会给出一些定制自研的设计思路。nginx
对于技术选型,我我的有不少标准,其中下面三项是最重要的:git
咱们选择的技术栈是要解决实际业务问题和上生产抗流量的(选择不慎可能形成生产级事故),而不是简单作个POC或者Demo展现,因此生产级(Production Ready),可运维(Ops Ready),可治理,成熟稳定的技术才是咱们的首选;程序员
咱们会尽可能采用在一线互联网公司落地而且开源的,且在社区内造成良好口碑的产品,它们已经在这些公司通过流量冲击,坑已经基本被填平,且被社区接受造成一个良好的社区生态(本文附录部分会给出全部推荐使用或参考的开源项目的github连接。)。github
Github上的stars的数量是一个重要指标,同时会参考其代码和文档更新频率(尤为是近年),这些指标直接反应开源产品的社区活跃度或者说生命力。算法
另外,对于不一样业务体量和团队规模的公司,技术选型标准每每是不一样的,创业公司的技术选型和BAT级别公司的技术选型标准可能彻底不一样。本文主要针对日流量千万以上,研发团队规模很多于50人的公司,若是小于这个规模我建议认真评估是否真的须要采用微服务架构。考虑到Java语言在国内的流行度和我我的的背景经验,本文主要针对采用Java技术栈的企业。本文也假定自建微服务基础架构,有些产品其实有对应的云服务能够直接使用,自建和采用云服务各有利弊,架构师须要根据场景上下文综合权衡。spring
下面脑图中芒果色标注的七个模块,我认为是构建微服务2.0技术栈的核心模块,本文后面的选型会分别基于这些模块展开。对于每一个模块我也列出一些核心架构关注点,在选择具体产品时,须要尽量覆盖到这些关注点。docker
下图是在参考过华为技术专家王磊的《微服务的设计与生态系统》的基础上,结合做者自身的实践调整而来,其中粉红色标注的模块是和微服务关系最密切的模块,你们在作技术选型时,能够同时对照这个体系。数据库
服务框架是一个比较成熟的领域,有太多可选项。 Spring Boot/Cloud [附录12.1]因为Spring社区的影响力和Netflix的背书,目前能够认为是构建Java微服务的一个社区标准,Spring Boot目前在github上有超过20k星。基于Spring的框架本质上能够认为是一种RESTful框架(不是RPC框架),序列化协议主要采用基于文本的JSON,通信协议通常基于HTTP。RESTful框架自然支持跨语言,任何语言只要有HTTP客户端均可以接入调用,可是客户端通常须要本身解析payload。目前Spring框架也支持Swagger契约编程模型,可以基于契约生成各类语言的强类型客户端,极大方便不一样语言栈的应用接入,可是由于RESTful框架和Swagger规范的弱契约特性,生成的各类语言客户端的互操做性仍是有很多坑的。apache
Dubbo[附录12.2]是阿里多年构建生产级分布式微服务的技术结晶,服务治理能力很是丰富,在国内技术社区具备很大影响力,目前github上有超过16k星。Dubbo本质上是一套基于Java的RPC框架,当当Dubbox扩展了Dubbo支持RESTful接口暴露能力。Dubbo主要面向Java 技术栈,跨语言支持不足是它的一个弱项,另外由于治理能力太丰富,以致于这个框架比较重,彻底用好这个框架的门槛比较高,可是若是你的企业基本上投资在Java技术栈上,选Dubbo可让你在服务框架一块站在较高的起点上,无论是性能仍是企业级的服务治理能力,Dubbo都作的很出色。新浪微博开源的Motan(github 4k stars)也不错,功能和Dubbo相似,能够认为是一个轻量裁剪版的Dubbo。
gRPC[附录12.3]是谷歌近年新推的一套RPC框架,基于protobuf的强契约编程模型,能自动生成各类语言客户端,且保证互操做。支持HTTP2是gRPC的一大亮点,通信层性能比HTTP有很大改进。Protobuf是在社区具备悠久历史和良好口碑的高性能序列化协议,加上Google公司的背书和社区影响力,目前gRPC也比较火,github上有超过13.4k星。目前看gRPC更适合内部服务相互调用场景,对外暴露HTTP RESTful接口能够实现,可是比较麻烦(须要gRPC Gateway配合),因此对于对外暴露API场景可能还须要引入第二套HTTP RESTful框架做为补充。整体上gRPC这个东西还比较新,社区对于HTTP2带来的好处还未造成一致认同,建议谨慎投入,能够作一些试点。
运行时支撑服务主要包括服务注册中心,服务路由网关和集中式配置中心三个产品。
服务注册中心,若是采用Spring Cloud体系,则选择 Eureka [附录12.4]是最佳搭配,Eureka在Netflix通过大规模生产验证,支持跨数据中心,客户端配合Ribbon能够实现灵活的客户端软负载,Eureka目前在github上有超过4.7k星; Consul [附录12.5]也是不错选择,自然支持跨数据中心,还支持KV模型存储和灵活健康检查能力,目前在github上有超过11k星。
服务网关也是一个比较成熟的领域,有不少可选项。若是采用Spring Cloud体系,则选择 Zuul[附录12.6]是最佳搭配,Zuul在Netflix通过大规模生产验证,支持灵活的动态过滤器脚本机制,异步性能不足(基于Netty的异步Zuul迟迟未能推出正式版)。Zuul网关目前在github上有超过3.7k星。基于Nginx/OpenResty的API网关 Kong [附录12.7]目前在github上比较火,有超过14.1k星。由于采用Nginx内核,Kong的异步性能较强,另外基于lua的插件机制比较灵活,社区插件也比较丰富,从安全到限流熔断都有,还有很多开源的管理界面,可以集中管理Kong集群。
配置中心,Spring Cloud自带 Spring Cloud Config [附录12.8](github 0.75k stars),我的认为算不上生产级,不少治理能力缺失,小规模场景能够试用。我的比较推荐携程的 Apollo [附录12.9]配置中心,在携程通过生产级验证,具有高可用,配置实时生效(推拉结合),配置审计和版本化,多环境多集群支持等生产级特性,建议中大规模须要对配置集中进行治理的企业采用。Apollo目前在github上有超过3.4k星。
主要包括日志监控,调用链监控,Metrics监控,健康检查和告警通知等产品。
ELK目前能够认为是日志监控的标配,功能完善开箱即用, Elasticsearch [附录12.10]目前在github上有超过28.4k星。 Elastalert [附录12.11] (github 4k stars)是Yelp开源的针对ELK的告警通知模块。
调用链监控目前社区主流是点评 CAT [附录12.12](github 4.3k stars),Twitter以前开源如今由OpenZipkin社区维护的 Zipkin [附录12.13](github 7.5k stars)和Naver开源的 Pinpoint [附录12.14](github 5.3k stars)。我的比较推荐点评开源的CAT,在点评和国内多家互联网公司有落地案例,生产级特性和治理能力较完善,另外CAT自带告警模块。下面是我以前对三款产品的评估表,供参考。
Metrics监控主要依赖于时间序列数据库(TSDB),目前较成熟的产品是StumbleUpon公司开源的基于HBase的 OpenTSDB [附录12.15](基于Cassandra的 KariosDB [附录12.16]也是一个选择,github 1.1k stars,它基本上是OpenTSDB针对Cassandra的一个改造版),OpenTSDB具备分布式能力能够横向扩展,可是相对较重,适用于中大规模企业,OpenTSDB目前在github上有近2.9k星。OpenTSDB 自己不提供告警模块, Argus [附录12.17](github 0.29k星)是Salesforce开源的基于OpenTSDB的统一监控告警平台,支持丰富的告警函数和灵活的告警配置,能够做为OpenTSDB的告警补充。近年也出现一些轻量级的TSDB,如 InfluxDB [附录12.18](github 12.4k stars)和 Prometheus [附录12.19](github 14.3k stars),这些产品函数报表能力丰富,自带告警模块,可是分布式能力不足,适用于中小规模企业。 Grafana [附录12.20](github 19.9k stars)是Metrics报表展现的社区标配。
社区还有一些通用的健康检查和告警产品,例如 Sensu [附录12.21](github 2.7k stars),可以对各类服务(例如spring boot暴露的健康检查端点,时间序列数据库中的metrics,ELK中的错误日志等)定制灵活的健康检查(check),而后用户能够针对check结果设置灵活的告警通知策略。Sensu在Yelp等公司有落地案例。其它相似产品还有Esty开源的 411 [附录12.22](github 0.74k星)和Zalando的 ZMon [附录12.23] (github 0.15k星),它们是分别在Esty和Zalando落地的产品,可是定制check和告警配置的使用门槛比较高,社区不热,建议有定制自研能力的团队试用。ZMon后台采用KairosDB存储,若是企业已经采用KariosDB做为时间序列数据库,则能够考虑ZMon做为告警通知模块。
针对Java技术栈,Netflix的 Hystrix [附录12.24](github 12.4k stars)把熔断、隔离、限流和降级等能力封装成组件,任何依赖调用(数据库,服务,缓存)均可以封装在Hystrix Command以内,封装后自动具有容错能力。Hystrix起源于Netflix的弹性工程项目,通过Netflix大规模生产验证,目前是容错组件的社区标准,github上有超12k星。其它语言栈也有相似Hystrix的简化版本组件。
Hystrix通常须要在应用端或者框架内埋点,有必定的使用门槛。对于采用集中式反向代理(边界和内部)作服务路由的公司,则能够集中在反向代理上作熔断限流,例如采用 nginx [附录12.25](github 5.1k stars)或者 Kong [附录12.7](github 11.4k stars)这类反向代理,它们都有插件支持灵活的限流容错配置。Zuul网关也能够集成Hystrix实现网关层集中式限流容错。集中式反向代理须要有必定的研发和运维能力,可是能够对限流容错进行集中治理,能够简化客户端。
后台服务主要包括消息系统,分布式缓存,分布式数据访问层和任务调度系统。后台服务是一个相对比较成熟的领域,不少开源产品基本能够开箱即用。
消息系统,对于日志等可靠性要求不高的场景,则Apache顶级项目 Kafka [附录12.26](github 7.2k stars)是社区标配。对于可靠性要求较高的业务场景,kafka其实也是能够胜任,但企业须要根据具体场景,对 Kafka的监控和治理能力进行适当定制完善,Allegro公司开源的 hermes [附录12.27](github 0.3k stars)是一个可参考项目,它在Kafka基础上封装了适合业务场景的企业级治理能力。阿里开源的 RocketMQ [附录12.28](github 3.5k星)也是一个不错选择,具有更多适用于业务场景的特性,目前也是Apache顶级项目。 RabbitMQ [附录12.29](github 3.6k星)是老牌经典的MQ,队列特性和文档都很丰富,性能和分布式能力稍弱,中小规模场景可选。
对于 缓存治理 ,若是倾向于采用客户端直连模式(我的认为缓存直连更简单轻量),则SohuTv开源的 cachecloud [附录12.30](github 2.5k stars)是一款不错的Redis缓存治理平台,提供诸如监控统计,一键开启,自动故障转移,在线伸缩,自动化运维等生产级治理能力,另外其文档也比较丰富。若是倾向采用中间层Proxy模式,则Twitter开源的 twemproxy [附录12.31](github 7.5k stars)和CodisLab开源的 codis [附录12.32](github 6.9k stars)是社区比较热的选项。
对于 分布式数据访问层 ,若是采用Java技术栈,则当当开源的 shardingjdbc [附录12.33](github 3.5k stars)是一个不错的选项,分库分表逻辑作在客户端jdbc driver中,客户端直连数据库比较简单轻量,建议中小规模场景采用。若是倾向采用数据库访问中间层proxy模式,则从阿里Cobar演化出来的社区开源分库分表中间件 MyCAT [附录12.34](github 3.6k stars)是一个不错选择 。proxy模式运维成本较高,建议中大规模场景,有必定框架自研和运维能力的团队采用。
任务调度系统,我的推荐徐雪里开源的 xxl-job [附录12.35](github 3.4k stars),部署简单轻量,大部分场景够用。当当开源的 elastic-job [附录12.36](github 3.2k stars)也是一个不错选择,相比xxl-job功能更强一些也更复杂。
对于微服务安全认证受权机制一块,目前业界虽然有OAuth和OpenID connect等标准协议,可是各家具体实现的作法都不太同样,企业通常有不少特殊的定制需求,整个社区尚未造成通用生产级开箱即用的产品。有一些开源受权服务器产品,比较知名的如 Apereo CAS [附录12.37](github 3.6k stars),JBoss开源的 keycloak [附录12.38](github 1.9 stars), spring cloud security [附录12.39]等,大都是opinionated(一家观点和作法)的产品,同时因支持太多协议形成产品复杂,也缺少足够灵活性。我的建议基于OAuth和OpenID connect标准,在参考一些开源产品的基础上(例如Mitre开源的 OpenID-Connect-Java-Spring-Server [附录12.40],github 0.62k stars),定制自研轻量级受权服务器。Wso2提出了一种微服务安全的参考方案[附录12.45],建议参考,该方案的关键步骤以下:
使用支持OAuth 2.0和OpenID Connect标准协议的受权服务器(我的建议定制自研);
使用API网关做为单一访问入口,统一实现安全治理;
客户在访问微服务以前,先经过受权服务器登陆获取access token,而后将access token和请求一块儿发送到网关;
网关获取access token,经过受权服务器校验token,同时作token转换获取JWT token。
网关将JWT Token和请求一块儿转发到后台微服务;
JWT中能够存储用户会话信息,该信息能够传递给后台的微服务,也能够在微服务之间传递,用做认证受权等用途;
每一个微服务包含JWT客户端,可以解密JWT并获取其中的用户会话信息。
整个方案中,access token是一种by reference token,不包含用户信息能够直接暴露在公网上;JWT token是一种by value token,能够包含用户信息但不暴露在公网上。
10、技术详解
微服务技术是程序员绕不开的话题,在这里给你们推荐一个架构交流学习群:650385180,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多,以上的知识体系图也是在群里获取。相信对于已经工做和遇到技术瓶颈的码友,在这个群里会有有你须要的内容。
为解决单体架构下的各类问题,微服务架构应运而生。与其构建一个臃肿庞大、难以驯服的怪兽,还不如及早将服务拆分。微服务的核心思想即是服务拆分与解耦,下降复杂性。微服务强调将功能合理拆解,尽量保证每一个服务的功能单一,按照单一责任原则(Single Responsibility Principle)明确角色。 将各个服务作轻,从而作到灵活、可复用,亦可根据各个服务自身资源需求,单独布署,单独做横向扩展。
容器已经被社区接受为交付微服务的一种理想手段,能够实现不可变(immutable)发布模式。一个轻量级的基于容器的服务部署平台主要包括容器资源调度,发布系统,镜像治理,资源治理和IAM等模块。
集群资源调度系统:屏蔽容器细节,将整个集群抽象成容器资源池,支持按需申请和释放容器资源,物理机发生故障时可以实现自动故障迁移(fail over)。目前Google开源的 kubernetes [附录12.41],在Google背书和社区的强力推进下,基本已经造成市场领导者地位,github上有31.8k星,社区的活跃度已经远远超过了 mesos [附录12.42](github 3.5k stars)和swarm等竞争产品,因此容器资源调度建议首选k8s。固然若是你的团队有足够定制自研能力,想深度把控底层调度算法,也能够基于mesos作定制自研。
镜像治理:基于docker registry,封装一些轻量级的治理功能。vmware开源的harbor[附录12.43] (github 3.5k stars)是目前社区比较成熟的企业级产品,在docker registry基础上扩展了权限控制,审计,镜像同步,管理界面等治理能力,能够考虑采用。
资源治理:相似于CMDB思路,在容器云环境中,企业仍然须要对应用app,组织org,容器配额和数量等相关信息进行轻量级的治理。目前这块尚未生产级的开源产品,通常企业须要根据本身的场景定制自研。
发布平台:面向用户的发布管理控制台,支持发布流程编排。它和其它子系统对接交互,实现基本的应用发布能力,也实现如蓝绿,金丝雀和灰度等高级发布机制。目前这块生产级的开源产品不多,Netflix开源的 spinnaker [附录12.44](github 4.2k stars)是一个,可是这个产品比较复杂重量(由于它既要支持适配对接各类CI系统,同时还要适配对接各类公有云和容器云,使得整个系统异常复杂),通常企业建议根据本身的场景定制自研轻量级的解决方案。
IAM:是identity & access management的简称,对发布平台各个组件进行身份认证和安全访问控制。社区有很多开源的IAM产品,比较知名的有 Apereo CAS (github 3.6k stars),JBoss开源的 keycloak(github 1.9 stars) 等。可是这些产品通常都比较复杂重量,不少企业考虑到内部各类系统灵活对接的需求,都会考虑定制自研轻量级的解决方案。
考虑到服务部署平台目前尚未端到端生产级解决方案,企业通常须要定制集成,下面给出一个能够参考的具有轻量级治理能努力的发布体系:
简化发布流程以下:
应用经过CI集成后生成镜像,用户将镜像推到镜像治理中心;
用户在资产治理中心申请发布,填报应用,发布和配额相关信息,而后等待审批经过;
发布审批经过,开发人员经过发布控制台发布应用;
发布系统经过查询资产治理中心获取发布规格信息;
发布系统向容器云发出启动容器实例指令;
容器云从镜像治理中心拉取镜像并启动容器;
容器内服务启动后自注册到服务注册中心,并保持按期心跳;
用户经过发布系统调用服务注册中心调拨流量,实现蓝绿,金丝雀或灰度发布等机制;
网关和内部微服务客户端按期同步服务注册中心上的服务路由表,将流量按负载均衡策略分发到新的服务实例上。
另外,持续交付流水线(CD Pipeline)也是微服务发布重要环节,这块主要和研发流程相关,通常须要企业定制,下面是一个可供参考的流水线模型,在镜像治理中心上封装一些轻量级的治理流程,例如只有经过测试环境测试的镜像才能升级发布到UAT环境,只有经过UAT环境测试的镜像才能升级发布到生产环境,经过在流水线上设置一些质量门,保障应用高质量交付到生产。
注意,本文限于篇幅,对测试和CI等环节没有涉及,但它们一样是构建微服务架构的重要环节,也有众多成熟的开源成熟产品可选。
技术选型虽然重要,但还只是微服务建设的一小部分工做,选型后的产品要在企业内部真正落地,造成完整的微服务技术栈体系,则后续还有大量集成、定制、治理、运维和推广等工做。
本文仅限我的经验视角,选型思路仅供参考借鉴。每一个企业的具体上下文(业务场景,团队组织,技术架构等)各不相同,每一个架构师的背景经验也各不相同,你们要结合实际本身作出选型,没有最好的技术栈,只有相对较合适的技术栈。另外,好的技术选型是相互借鉴甚至PK出来的,欢迎你们讨论,给出本身的微服务2.0技术栈选型意见。
Spring Boot
https://github.com/spring-projects/spring-boot
Alibaba Dubbo
https://github.com/alibaba/dubbo
Google gRPC
https://github.com/grpc/grpc
NetflixOSS Eureka
https://github.com/Netflix/eureka
Hashicorp Consul
https://github.com/hashicorp/consul
NetflixOSS Zuul
https://github.com/Netflix/zuul
Kong
https://github.com/Kong/kong
Spring Cloud Config
https://github.com/spring-cloud/spring-cloud-config
CTrip Apollo
https://github.com/ctripcorp/apollo
ElasticSearch
https://github.com/elastic/elasticsearch
Yelp Elastalert
https://github.com/Yelp/elastalert
Dianping CAT
https://github.com/dianping/cat
Zipkin
https://github.com/openzipkin/zipkin
Naver Pinpoint
https://github.com/naver/pinpoint
OpenTSDB
https://github.com/OpenTSDB/opentsdb
KairosDB
https://github.com/kairosdb/kairosdb
Argus
https://github.com/salesforce/Argus
InfluxDB
https://github.com/influxdata/influxdb
Prometheus
https://github.com/prometheus/prometheus
Grafana
https://github.com/grafana/grafana
Sensu
https://github.com/sensu/sensu
Esty 411
https://github.com/etsy/411
Zalando ZMon
https://github.com/zalando/zmon
NetflixOSS Hystrix
https://github.com/Netflix/Hystrix
Nginx
https://github.com/nginx/nginx
Apache Kafka
https://github.com/apache/kafka
Allegro Hermes
https://github.com/allegro/hermes
Apache Rocketmq
https://github.com/apache/rocketmq
Rabbitmq
https://github.com/rabbitmq/rabbitmq-server
Sohutv CacheCloud
https://github.com/sohutv/cachecloud
Twitter twemproxy
https://github.com/twitter/twemproxy
CodisLab codis
https://github.com/CodisLabs/codis
Dangdang Sharding-jdbc
https://github.com/shardingjdbc/sharding-jdbc
MyCAT
https://github.com/MyCATApache/Mycat-Server
Xxl-job
https://github.com/xuxueli/xxl-job
Dangdang elastic-job
https://github.com/elasticjob/elastic-job-lite
Apereo CAS
https://github.com/apereo/cas
JBoss keycloak
https://github.com/keycloak/keycloak
Spring cloud security
https://github.com/spring-cloud/spring-cloud-security
OpenID-Connect-Java-Spring-Server
https://github.com/mitreid-connect/OpenID-Connect-Java-Spring-Server
Google Kubernetes
https://github.com/kubernetes/kubernetes
Apache Mesos
https://github.com/apache/mesos
Vmware Harbor
https://github.com/vmware/harbor
Netflix Spinnaker
https://github.com/spinnaker/spinnaker
Microservices in Practice – Key Architecture Concepts of an MSA
https://wso2.com/whitepapers/microservices-in-practice-key-architectural-concepts-of-an-msa/