概述和需求背景
我们在2018年Q3的时候已经完成大部分服务容器化,此时我们的微服务数量已经超过400个了,在沟通和维护上的成本很高。因为我们后端服务是主要是基于Dubbo的,跟前端直接的交互还是通过http的方式,在没有上Service Mesh之前,http请求都是经过Nginx转发的。维护Nginx的配置文件是一个工作量大且重复性高的事情,运维团队和业务团队迫切的需要更高效的方案来解决配置管理和沟通成本的问题,构建房多多Service Mesh体系就显得尤为重要。Envoy是一个成熟稳定的项目,也能够满足近期的需求,在现阶段我们并没有人力去动Envoy,所以我们直接使用了Envoy做Service Mesh的数据平面,关于控制平面这块,在调研了一些方案之后,我们采用了自研的方案。
我们的业务主要工作在自建IDC机房,公有云只有少量的灾备服务。因为是自建机房,相比较公有云而言,自建机房使用Macvlan是一个比较好的方案。我们预先划分了几个20位地址的子网,每个子网内配置一些物理机,通过集中式的IP管理服务去管理物理机和容器的IP。相比较bridge网络,Macvlan网络有着非常接近物理网络的性能,尤其是在大流量场景下性能出色,下面一张图显示了性能对比:
我们把Envoy作为两个网络之间的连接桥,这么做的好处在于可以控制流量都经过负载均衡器,便于集中管理以及对流量做分析。看到这里,肯定有疑问是为什么不使用Sidecar的方式部署Envoy。关于Sidecar我的考虑是,在现有的业务场景下,集中部署的维护成本更低且性能满足需求,也相对来说比较简单。我们在2018年Q4已经完成主要业务http2接入,目前来看,我们的网站速度应该是同行业中最快的,大家可以体验一下,https://m.fangdd.com。
如何解决虚拟机业务和容器业务的并存问题
控制平面服务主要基于data-plane-api开发,功能上主要是给数据平面提供服务的集群配置、路由配置等信息,并且需要实现微服务架构中降级和限流的配置功能。容器内部的集群数据主要依赖DNSRR实现,而虚拟机上的服务,我们在CMDB上存有AppID和机器的对应关系,很容器生成集群配置数据。
由于历史原因,还有相当多的业务无法从VM迁移到容器,需要有一个同时兼容容器和VM的数据平面服务,目前XDS服务的支持的功能如下:
集群数据来源同时包括容器内部DNS和外部CMDB中的VM数据
支持多个vhost配置
支持路由配置
支持速率控制和网关错误重试
同时也降低了框架开发成本和业务改动的成本,每次推动业务升级框架都需要比较长的一段时间,业务无法及时用上新框架的功能,多种框架版本也加重运维负担,Service Mesh帮我们解决了很多痛点。同时再加上我们的网关层建设,我们上线一个新服务几乎是零配置成本的。
代理层实现服务发现,对于开发而言只需要开发一个单机的应用,降低框架开发成本
降级和限流都在代理层实现,规则灵活,方便修改策略
框架功能的升级无需依赖业务
SOA和Service Mesh的对比与取舍
在我们现有的业务场景下,Service Mesh主要还是解决前后端的微服务对接问题,当做前后端服务的连接桥梁。但不可否认的是,Service Mesh带来研发效率的提升,在现有的场景下的价值远大于性能上的损失。在大多数的场景下,维护业务框架需要比较大的人力成本,很多团队都没有全职的人去维护业务框架。此外,推动业务框架的更新和升级也相对来说成本较高,这也是我们考虑的一个重要方面。
Q&A
Q:软件实现 Service Mesh,Istio?A:我们目前只使用了Envoy,Istio也做过一些选型的调研,不是很符合我们现在的业务场景和业务需求,我们在之后的实践中会考虑使用一部分Istio的功能。
Q:实施过程当中有使用到Istio吗?有定制一些Mixer适配器吗?A:目前还没有用,之后会考虑是用Istio中的pilot,我们目前在流量的控制的精细程度上面还欠缺,粒度还很粗。
Q:请问,实现微服务过程中有没有考虑分布式跟踪和分布式?A:Service Mesh层可以做到简单的分布式追踪,比如可以做到基于请求的追踪,Envoy可以把trace数据接入Zipkin这样的trace系统,但是更细粒度的trace目前还做不到。
Q:不论是使用都会产生大量的配置(yaml),尤其是Envoy/Istio,系统中会有大量零散的配置文件,维护困难,还有版本管理,有什么很好的维护实践经验吗?谢谢。A:是的,据我所知有些团队会使用ConfigMap来管理配置,我们做了一个配置的集中管理服务,从CMDB和DNS定时的抓取数据,数据会存在数据库里面,也会存一定量的副本用于配置回退,这个地方还是要结合你们现在其他配套系统的建设来看看怎么做比较好的。
Q:有没有遇到过Envoy被oom kill的情况,你们是如何处理的?A:这个我有碰到过一次,之前我们在对Envoy做测试的时候,发现Envoy总会尽可能的占满CGroup的内存大小,这个之前在使用TLS的情况下碰到的比较多。但是目前我们内部服务间使用TLS的情况并不多,所以后续这个问题就没有继续跟进了。
Q:性化方案有哪些?A:上面文章中有提到过,对于http服务可以全量接入http2,http2的长连接和多路复用对于一般的业务来说升是很明显的,我们在全量接入http2之后,网站的响应时间几乎下降了50%。另外还可以在底层的依赖上面做一些优化,比如底层的libc库,以及尽可能的减少基础镜像的大小,我们基本上所有业务都使用了alpine,这样可以保证发布性能和速度在一个很好的水平上。
Q:还是有一个服务治理/配置管理的问题请教,比如CPU,内存,这种资源request,在dev,test,staging,prod环境均不同,那么我们在编写Kubernetes配置的时候不同环境会不同,比如测试环境的replics数跟CPU需求就很低,生产就很高,另外这个配置在不同环境是多个还是一个呢?谢谢。A:我们现在会在CMDB里面维护这些配置数据,一般来说在新建项目的时候,我们就会要求业务线评估一下这个业务需要的资源,比如你说到的test和staging环境这种,我们默认会给一个很低的需求,比如1c1g这样的,而且replication也会默认设置为1,除非业务有特殊的需求,然后我们去根据配置的数据去生成yaml格式为配置。配置在数据存储的形式上是多个,但是在对业务展示上,尽量让业务感觉到是一个数据,这样也能使每个环境都规范起来,跟生产环境尽可能保持一致,这个对测试的好处还是很大的。
Q:你们目前的项目中,大量的微服务,以及调度层,瓶颈和容灾是如何处理的?A:由于我们的业务类型还是B端业务为主,流量的峰值是可以预估的,很少会出现突发的大流量的情况,我们一般都预留了1倍的容量用于临时的扩容。容灾和调度的话我们主要还是尽可能的隔离工作节点和调度节点,以及大量使用物理机集群,从我们的使用体验上来看,物理机的稳定性还是很不错的。
Q:如何用Jenkins自动完成Kubernetes部署?A:自动部署这块我们有完善的发布系统,如果单纯只要实现Jenkins自动完成Kubernetes的话,Jenkins可以直接调用Kubernetes的API,这个网上有挺多资料的,你可以找找看。
Q:Service Mesh比传统的微服务治理好在哪里?A:降低框架开发成本、代理规则灵活,方便修改策略、框架功能的升级无需依赖业务,最大的好处我觉得就是可以降低框架开发成本。
Q:我理解房多多目前的Mesh方案没有给每个微服务配一个Envoy作为Sidecar,而是使用一组Enovy并自研了xDS的配置发布管理系统,对吗?我想请问backend微服务之间的请求现在是怎么走的呢?谢谢。A:是的,刚刚文章中说了,我们后端SOA服务还是基于Dubbo的,这块目前我们还没有做改动,之后的话我们的初步构想会通过Sidecar的方式把这些Dubbo服务都接入到Mesh里面来。我们目前的Envoy也是会充当网关的角色。
![640?wx_fmt=png](https://i-blog.csdnimg.cn/blog_migrate/a9484f92d181ccf5147145e72af025fb.jpeg)