什么是微服务
将一个单体应用拆分为多个部分,每个部分实现特定的业务,每一个部分称为服务,单个系统由多个这样的服务组成,每个服务有单独的进程和机制,并且可独立开发、运行、部署,从而实现“让我们的系统尽可能快地响应变化”的目的
-
Monolithic架构(单体架构)
概念:
一个项目就是一个整体,开发、部署、运行时均为一个项目
优点:
- 开发简单直接,集中式管理,基本不会重复开发
- 功能都在本地,没有分布式的管理开销和调用开销
缺点:
- 开发效率低:所有的开发在一个项目改代码,递交代码相互等待,代码冲突不断
- 代码维护难:代码功能耦合在一起,新人不知道何从下手
- 部署不灵活:构建时间长,任何小修改必须重新构建整个项目,这个过程往往很长
- 稳定性不高:一个微不足道的小问题,可以导致整个应用挂掉
- 扩展性不够:无法满足高并发情况下的业务需求
-
Microservices架构(微服务架构)
概念:
将一个项目拆分为多个部分,每个部分实现一个具体的业务,每一个部分为一个服务,每个服务都有自己的处理和轻量通讯机制,可以部署在单个或多个服务器上,系统由多个服务组成
微服务是指开发一个单个小型的但有业务功能的服务,每个服务都有自己的处理和轻量通讯机制,可以部署在单个或多个服务器上。微服务也指一种种松耦合的、有一定的有界上下文的面向服务架构。也就是说,如果每个服务都要同时修改,那么它们就不是微服务,因为它们紧耦合在一起;如果你需要掌握一个服务太多的上下文场景使用条件,那么它就是一个有上下文边界的服务,这个定义来自DDD领域驱动设计。
相对于单体架构和SOA,它的主要特点是组件化、松耦合、自治、去中心化,体现在以下几个方面:
- 一组小的服务
服务粒度要小,而每个服务是针对一个单一职责的业务能力的封装,专注做好一件事情。 - 独立部署运行和扩展
每个服务能够独立被部署并运行在一个进程内。这种运行和部署方式能够赋予系统灵活的代码组织方式和发布节奏,使得快速交付和应对变化成为可能。 - 独立开发和演化
技术选型灵活,不受遗留系统技术约束。合适的业务问题选择合适的技术可以独立演化。服务与服务之间采取与语言无关的API进行集成。相对单体架构,微服务架构是更面向业务创新的一种架构模式。 - 独立团队和自治
团队对服务的整个生命周期负责,工作在独立的上下文中,自己决策自己治理,而不需要统一的指挥中心。团队和团队之间通过松散的社区部落进行衔接。
- 一组小的服务
相关博客:
https://www.cnblogs.com/wintersun/p/6219259.html
https://blog.csdn.net/polo2044/article/details/95319059
https://www.cnblogs.com/lqcswy/p/11839112.html
微服务的优点
- 开发阶段
-
开发团队小
微服务能够被小团队单独开发,这个小团队是2到5人的开发人员组成
-
耦合程度低
微服务是松耦合的,是有功能意义的服务,无论是在开发阶段或部署阶段都是独立的
-
方便灵活
微服务能使用不同的语言开发,也可以使用不同的数据库保存数据
-
- 部署阶段
-
部署灵活
微服务允许容易且灵活的方式集成自动部署,通过持续集成工具,如Jenkins, bamboo
-
按需部署
允许根据需求,动态调整每种服务的数量、规模,达到服务器资源的最大化利用
当需求增加时,微服务能够即时被要求扩展
-
服务器要求低
每个服务都是微小的,其运行时对性能的要求较低,因此可以部署在配置较低的服务器上,同时不影响系统的整体性能
-
微服务的缺点
-
开发阶段
-
技术要求高
相较于单体应用,微服务应用更为复杂,因此对于技术人员的要求更高
-
技术要求广
因为微服务应用通常要求一个团队负责该服务的整个生命周期,因此对于开发团队来说,不仅需要其足够好的开发能力,还需要其掌握设计、部署、运维等各方面的能力
-
系统更复杂
相较于单体应用,微服务应用将一个应用拆分为多个服务,因此其规模更大、结构更复杂
-
管理难度高
相较于单体应用,微服务应用将一个应用拆分为多个服务,因此需要管理的项目和人员更多
-
增加重复代码
每个微服务都可以独立的运行和部署,为减少耦合,因此可能会存在同一功能重复开发的情况
-
-
部署阶段
-
部署数量多
因为微服务每个服务均可独立部署,因此在部署时,需要部署更多的部分
-
部署方案多
因为微服务每个服务均可独立部署,因此其部署的方案很多,需要实施和运维人员考虑的问题就更多
-
对实施、运维人员要求更高
因为微服务每个服务均可独立部署,对实施和运维人员的要求更高
-
-
使用阶段
-
网络影响大
每个服务直接通常采用网络进行通信,因此相较于单条应用,微服务对网络的要求更高,同时受网络的影响更大
-
微服务的技术选型
参考博客:https://www.infoq.cn/article/micro-service-technology-stack
服务框架
-
Spring Boot/Cloud
官网:https://spring.io/projects/spring-boot
官网:https://spring.io/projects/spring-cloud
Spring boot 是 Spring 的一套快速配置脚手架,可以基于spring boot 快速开发单个微服务,Spring Cloud是一个基于Spring Boot实现的云应用开发工具;Spring boot专注于快速、方便集成的单个个体,Spring Cloud是关注全局的服务治理框架;spring boot使用了默认大于配置的理念,很多集成方案已经帮你选择好了,能不配置就不配置,Spring Cloud很大的一部分是基于Spring boot来实现。
Spring boot可以离开Spring Cloud独立使用开发项目,但是Spring Cloud离不开Spring boot,属于依赖的关系。
spring -> spring boot > spring cloud 这样的关系。
相关博客:https://blog.csdn.net/qq_39335514/article/details/80352843
-
Dubbo
-
Dubbox
-
Service Mesh(服务网格)
2017 年底,非侵入式的 Service Mesh 技术从萌芽到走向了成熟。
Service Mesh 又译作“服务网格”,作为服务间通信的基础设施层。
如果用一句话来解释什么是 Service Mesh,可以将它比作是应用程序或者说微服务间的 TCP/IP,负责服务之间的网络调用、限流、熔断和监控。对于编写应用程序来说一般无须关心 TCP/IP 这一层(比如通过 HTTP 协议的 RESTful 应用),同样使用 Service Mesh 也就无须关系服务之间的那些原来是通过应用程序或者其他框架实现的事情,比如 Spring Cloud、OSS,现在只要交给 Service Mesh 就可以了。
关于 Service Mesh,因为是很新的概念(去年年底才火起来),相关的框架并未真正用于生产环境,所以这边就不考虑了,但以后可能会发展的非常好。
两个框架的对比
使用 Dubbo 构建的微服务架构就像组装电脑,各环节我们的选择自由度很高,但是最终结果很有可能因为一条内存质量不行就点不亮了,总是让人不怎么放心,但是如果你是一名高手,那这些都不是问题;
而 Spring Cloud 就像品牌机,在 Spring Source 的整合下,做了大量的兼容性测试,保证了机器拥有更高的稳定性,但是如果要在使用非原装组件外的东西,就需要对其基础有足够的了解。
Dubbo 专注 RPC 和服务治理,Spring Cloud 则是一个微服务架构生态。
参考博客:https://www.cnblogs.com/xishuai/p/dubbo-and-spring-cloud.html
运行支撑服务
注册中心
-
Eureka
项目地址:https://github.com/Netflix/eureka
Eureka 在 Netflix 经过大规模生产验证,支持跨数据中心,客户端配合 Ribbon 可以实现灵活的客户端软负载,Eureka 目前在 GitHub 上有超过 4.7k 星
-
Consul
项目地址:https://github.com/hashicorp/consul
天然支持跨数据中心,还支持 KV 模型存储和灵活健康检查能力,目前在 GitHub 上有超过 11k 星
服务路由网关
-
Zuul
项目地址:https://github.com/Netflix/zuul
Zuul 在 Netflix 经过大规模生产验证,支持灵活的动态过滤器脚本机制,异步性能不足(基于 Netty 的异步 Zuul 迟迟未能推出正式版),Zuul 网关目前在 github 上有超过 3.7k 星
-
Kong
项目地址:https://github.com/kong/kong
因为采用 Nginx 内核,Kong 的异步性能较强,另外基于 lua 的插件机制比较灵活,社区插件也比较丰富,从安全到限流熔断都有,还有不少开源的管理界面,能够集中管理 Kong 集群,目前在 github 上比较火,有超过 14.1k 星
集中式配置中心
-
Apollo
项目地址:https://github.com/ctripcorp/apollo
在携程经过生产级验证,具备高可用,配置实时生效(推拉结合),配置审计和版本化,多环境多集群支持等生产级特性,建议中大规模需要对配置集中进行治理的企业采用,Apollo 目前在 github 上有超过 3.4k 星
-
Spring Cloud Config
官网:https://spring.io/projects/spring-cloud-config
Spring Cloud 自带 Spring Cloud Config[附录 12.8](GitHub 0.75k stars),个人认为算不上生产级,很多治理能力缺失,小规模场景可以试用
服务监控
日志监控
-
ElasticSearch
ELK 目前可以认为是日志监控的标配,功能完善开箱即用,目前在 GitHub 上有超过 28.4k 星
-
Elastalert
项目地址:https://github.com/Yelp/elastalert
是 Yelp 开源的针对 ELK 的告警通知模块,目前在 GitHub 上有超过 4k 星
调用链监控
-
CAT
项目地址:https://github.com/dianping/cat
在点评和国内多家互联网公司有落地案例,生产级特性和治理能力较完善,另外 CAT 自带告警模块
-
Zipkin
-
Pinpoint
Metrics 监控
-
OpenTSDB
OpenTSDB 具有分布式能力可以横向扩展,但是相对较重,适用于中大规模企业,目前在 GitHub 上有近 2.9k 星
-
KariosDB
基本上是 OpenTSDB 针对 Cassandra 的一个改造版),目前在 GitHub 上有近 1.1k 星
健康检查和告警通知
-
Argus
项目地址:https://github.com/salesforce/Argus
OpenTSDB 本身不提供告警模块,Argus(GitHub 0.29k 星)是 Salesforce 开源的基于 OpenTSDB 的统一监控告警平台,支持丰富的告警函数和灵活的告警配置,可以作为 OpenTSDB 的告警补充
-
InfluxDB
项目地址:https://github.com/influxdata/influxdb
函数报表能力丰富,自带告警模块,但是分布式能力不足,适用于中小规模企业
-
Prometheus
项目地址:https://github.com/prometheus/prometheus
函数报表能力丰富,自带告警模块,但是分布式能力不足,适用于中小规模企业
-
Grafana
是 Metrics 报表展示的社区标配
-
Sensu
官网:https://www.ibm.com/developerworks/cn/cloud/library/1607-sensu-monitoring-platform/index.html
能够对各种服务(例如 Spring Boot 暴露的健康检查端点,时间序列数据库中的 metrics,ELK 中的错误日志等)定制灵活的健康检查 (check),然后用户可以针对 check 结果设置灵活的告警通知策略。Sensu 在 Yelp 等公司有落地案例
-
411
项目地址:https://github.com/etsy/411
在 Esty 落地的产品,但是定制 check 和告警配置的使用门槛比较高,社区不热,建议有定制自研能力的团队试用
-
ZMon
项目地址:https://github.com/zalando/zmon
在 Zalando 落地的产品,但是定制 check 和告警配置的使用门槛比较高,社区不热,建议有定制自研能力的团队试用,后台采用 KairosDB 存储,如果企业已经采用 KariosDB 作为时间序列数据库,则可以考虑 ZMon 作为告警通知模块
服务容错
-
Hystrix
项目地址:https://github.com/Netflix/Hystrix
把熔断、隔离、限流和降级等能力封装成组件,任何依赖调用(数据库,服务,缓存)都可以封装在 Hystrix Command 之内,封装后自动具备容错能力。Hystrix 起源于 Netflix 的弹性工程项目,经过 Netflix 大规模生产验证,目前是容错组件的社区标准,GitHub 上有超 12k 星。其它语言栈也有类似 Hystrix 的简化版本组件。
-
Nginx
Hystrix 一般需要在应用端或者框架内埋点,有一定的使用门槛。对于采用集中式反向代理(边界和内部)做服务路由的公司,则可以集中在反向代理上做熔断限流,例如采用 Nginx或者 Kong这类反向代理,它们都插件支持灵活的限流容错配置。
-
Kong
项目地址:https://github.com/kong/kong
Hystrix 一般需要在应用端或者框架内埋点,有一定的使用门槛。对于采用集中式反向代理(边界和内部)做服务路由的公司,则可以集中在反向代理上做熔断限流,例如采用 Nginx或者 Kong这类反向代理,它们都插件支持灵活的限流容错配置。
后台服务
消息系统
-
Kafka
Kafka是社区标配,对于可靠性要求较高的业务场景,Kafka 其实也是可以胜任,但企业需要根据具体场景,对 Kafka 的监控和治理能力进行适当定制完善
-
hermes
项目地址:https://github.com/allegro/hermes
它在 Kafka 基础上封装了适合业务场景的企业级治理能力
-
RocketMQ
官网:https://rocketmq.apache.org
阿里开源,是一个不错选择,具备更多适用于业务场景的特性,目前也是 Apache 顶级项目
-
RabbitMQ
是老牌经典的 MQ,队列特性和文档都很丰富,性能和分布式能力稍弱,中小规模场景可选
分布式缓存
-
cachecloud
项目地址:https://github.com/sohutv/cachecloud
采用客户端直连模式(个人认为缓存直连更简单轻量),cachecloud是一款不错的 Redis 缓存治理平台,提供诸如监控统计,一键开启,自动故障转移,在线伸缩,自动化运维等生产级治理能力,另外其文档也比较丰富
-
twemproxy
项目地址:https://github.com/twitter/twemproxy
如果倾向采用中间层 Proxy 模式,则 Twitter 开源的 twemproxy[附录 12.31](GitHub 7.5k stars)和 CodisLab 开源的 codis[附录 12.32](GitHub 6.9k stars)是社区比较热的选项
-
codis
项目地址:https://github.com/CodisLabs/codis
如果倾向采用中间层 Proxy 模式,则 Twitter 开源的 twemproxy[附录 12.31](GitHub 7.5k stars)和 CodisLab 开源的 codis[附录 12.32](GitHub 6.9k stars)是社区比较热的选项
分布式数据访问层
-
shardingjdbc
官网:https://shardingsphere.apache.org
当当开源,是一个不错的选项,分库分表逻辑做在客户端 jdbc driver 中,客户端直连数据库比较简单轻量,建议中小规模场景采用
-
MyCAT
如果倾向采用数据库访问中间层 proxy 模式,则从阿里 Cobar 演化出来的社区开源分库分表中间件 MyCAT是一个不错选择 。proxy 模式运维成本较高,建议中大规模场景,有一定框架自研和运维能力的团队采用
任务调度系统
-
xxl-job
官网:https://www.xuxueli.com/xxl-job/
项目地址:https://github.com/xuxueli/xxl-job
徐雪里开源,部署简单轻量,大部分场景够用
-
elastic-job
官网:https://shardingsphere.apache.org/elasticjob
项目地址:https://gitee.com/elasticjob/elastic-job
当当开源,是一个不错选择,相比 xxl-job 功能更强一些也更复杂
服务安全
-
定制
OpenID-Connect-Java-Spring-Server
现有开源产品大都是 opinionated(一家观点和做法)的产品,同时因支持太多协议造成产品复杂,也缺乏足够灵活性。
该博客作者建议基于 OAuth 和 OpenID connect 标准,在参考一些开源产品的基础上(例如 Mitre 开源的 OpenID-Connect-Java-Spring-Server,定制自研轻量级授权服务器。
Wso2 提出了一种微服务安全的参考方案,建议参考,该方案的关键步骤如下:
- 使用支持 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,可以包含用户信息但不暴露在公网上。
-
Apereo CAS
-
keycloak
-
spring cloud security
服务部署平台
轻量级的基于容器的服务部署平台
一个轻量级的基于容器的服务部署平台主要包括容器资源调度,发布系统,镜像治理,资源治理和 IAM 等模块
考虑到服务部署平台目前还没有端到端生产级解决方案,企业一般需要定制集成,下面给出一个可以参考的具备轻量级治理能力的发布体系:
简化发布流程如下:
- 应用通过 CI 集成后生成镜像,用户将镜像推到镜像治理中心;
- 用户在资产治理中心申请发布,填报应用,发布和配额相关信息,然后等待审批通过;
- 发布审批通过,开发人员通过发布控制台发布应用;
- 发布系统通过查询资产治理中心获取发布规格信息;
- 发布系统向容器云发出启动容器实例指令;
- 容器云从镜像治理中心拉取镜像并启动容器;
- 容器内服务启动后自注册到服务注册中心,并保持定期心跳;
- 用户通过发布系统调用服务注册中心调拨流量,实现蓝绿,金丝雀或灰度发布等机制;
- 网关和内部微服务客户端定期同步服务注册中心上的服务路由表,将流量按负载均衡策略分发到新的服务实例上。
集群资源调度系统
屏蔽容器细节,将整个集群抽象成容器资源池,支持按需申请和释放容器资源,物理机发生故障时能够实现自动故障迁移 (fail over)
-
Kubernetes
Google 开源,在 Google 背书和社区的强力推动下,基本已经形成市场领导者地位,GitHub 上有 31.8k 星,社区的活跃度已经远远超过了 mesos[附录 12.42](GitHub 3.5k stars)和 swarm 等竞争产品,所以容器资源调度建议首选 K8s。当然如果你的团队有足够定制自研能力,想深度把控底层调度算法,也可以基于 Mesos 做定制自研
-
Mesos
镜像治理
基于 Docker Registry,封装一些轻量级的治理功能
-
harbor
项目地址:https://github.com/goharbor/harbor
VMware 开源,是目前社区比较成熟的企业级产品,在 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)等。但是这些产品一般都比较复杂重量,很多企业考虑到内部各种系统灵活对接的需求,都会考虑定制自研轻量级的解决方案。
持续交付流水线
另外,持续交付流水线(CD Pipeline)也是微服务发布重要环节,这块主要和研发流程相关,一般需要企业定制,下面是一个可供参考的流水线模型,在镜像治理中心上封装一些轻量级的治理流程,例如只有通过测试环境测试的镜像才能升级发布到 UAT 环境,只有通过 UAT 环境测试的镜像才能升级发布到生产环境,通过在流水线上设置一些质量门,保障应用高质量交付到生产。