微服务的服务间通讯与服务治理是微服务架构的实现层面的两大核心问题。html
本文但愿经过结合扇贝生产环境中的实践(百万日活场景),给你们分享相关的经验心得。node
从通讯类型的角度看,大概有三种类型:同步调用,异步调用,广播。python
在微服务的设计之初要想清楚调用关系以及调用方式,哪些须要同步,哪些能够异步,哪些须要广播,最好团队内部要有统一的认识。git
而后就是要肯定好调用协议了,例如常见的选择有:github
对于如何选择,咱们须要从不少角度去思考。网上有大量的 "X vs Y"的文章或问答。其实无非就是从几个角度:性能,成熟度,易用性,生态,技术团队。咱们的建议是:优先选择社区活跃,以及和本身团队技术栈相融的。社区活跃的技术每每表明了趋势和生态,而团队技术栈的相容性则是可否落地成功的保证。网络
好比当时扇贝选择gRPC
做为同步调用的接口协议。主要考虑的就是两点:1. 社区活跃,发展很是迅速;2.基于 HTTP/2,与咱们的技术栈相容。架构
除了选择协议,更加剧要的应该就是接口文档的管理了。最好接口文档和代码是强相关的,就像 gRPC 的 proto 和生成出来的代码那样。不然人每每是有惰性的,颇有可能代码改了文档没改。负载均衡
总之,关于服务间通讯,咱们须要作好:框架
服务治理是个很是大的话题,真的要铺开来说,可能几篇文章的篇幅都讲不完。这里咱们想先简单地看一下服务治理要解决的问题,以及如今的一些解决方案,发展趋势。
最后以扇贝为例,简单介绍下在一个真实的百万日活的生产环境中,服务治理是如何作的。异步
什么是服务治理
微服务化带来了不少好处,例如:经过将复杂系统切分为若干个微服务来分解和下降复杂度,使得这些微服务易于被小型的开发团队所理解和维护。然而也带来了不少挑战,例如:微服务的链接、服务注册、服务发现、负载均衡、监控、AB测试,金丝雀发布、限流、访问控制,等等。
这些挑战便是服务治理的内容。
现有方案
服务治理的问题由来已久,微服务化盛行以后尤其突出。主流的方案有:基于Spring Cloud或者Dubbo等框架。可是这些方案的问题是:1.对代码有侵入,也就意味着,若是想换框架,得改不少东西。2.语言特异性(Java),若是咱们用的是 Go/Python,或者咱们的微服务不全是 Java,就搞不定了。
Service Mesh
2017 Service Mesh 横空出世,让咱们眼前一亮。网上有不少关于 Service Mesh 的介绍,你们能够去网上搜一搜。个人理解,Service Mesh 的核心思想就是“代理流量”。Service Mesh经过一个个"代理" 来为微服务转发/接收全部流量,经过控制这些代理,就能够实现服务链接,注册,发现,负载均衡,熔断,监控等等一系列服务治理相关功能,从而微服务的代码再也不须要服务治理的实现,换句话说,也就是服务治理对于微服务开发者而言是透明的。以下图所示:绿色方块为微服务,蓝色方块为 service mesh 的代理,蓝色线条为服务间通信。能够看到蓝色的方块和线条组成了整个网格。这个网络就是 Service Mesh。
目前广泛认为 Service Mesh 有两代:第一代的 Linkerd/Envoy 和第二代的 Istio/Conduit。第一代相对比较成熟稳定,能够直接用于生产环境,第二代目前(2018年初)都不完善,严重不推荐用于生产。
扇贝的 Service Mesh 是基于 Envoy 配合 Kubernetes 实现的。
这一节以扇贝为例,简单介绍下咱们是如何作服务治理的。
首先介绍一些前提:扇贝的微服务所有容器化,编排系统基于 kubernetes
,同步调用基于 gRPC
,异步基于 celery[rabbitmq]
。开发语言以 python3
, nodejs
, go
为主。 Service Mesh 基于 Envoy
整体的方案是:Envoy
以 DaemonSet
的形式部署到 kubernetes
的每一个 Node
上,采用 Host
网络模式。 全部的微服务的 Pod
都将 gRPC
的请求发送到所在 Node
的 Envoy
,由 Envoy
来作负载均衡。以下图所示:
这里作一些详细的解释。
Envoy
中的Route
相似于 Nginx
的 Location
, Cluster
相似于 Nginx
的 upstream
,Endpoint
对应于 Nginx
的 upstream
中的条目。Envoy
而没有用 Linkerd
,是由于当时 Envoy
是对 HTTP/2
支持最好的。且资源消耗更少。Host
网络模式是为了最大化提升性能。Enovy
而言,服务发现就是告诉 Envoy
,每一个 Cluster
背后提供服务的实例的IP(对应于 Kubernetes
也就是 Pod
的IP)是什么。Kubernetes
的 DNS
,所以,在建立Service
的时候,要使用 ClusterIP: None
。Kubernetes
的 Endpoint
API 实现了 Enovy
的 EDS
(这个项目咱们往后会开源到 GitHub 上)。Envoy
而言,实现熔断,只要实现 rate limit service 就好了。咱们基于Lyft/ratelimit 实现的 rate limit service。Envoy
的 statistic API反映出来,因此咱们针对 statistic API作服务调用的监控报警。Envoy
的 Access Log 来实现。关于服务治理,咱们接下来的文章还会跟你们分享关于DevOps的实践, 监控报警系统,日志系统的构建等等内容。最后,若是你也对微服务,k8s, service mesh, devops 感兴趣,欢迎加入!
---
欢迎关注咱们的 知乎专栏:扇贝技术架构小组