前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >人人视频基于K8s的微服务实践:TKE + Spring Cloud

人人视频基于K8s的微服务实践:TKE + Spring Cloud

作者头像
CNCF
发布2019-12-04 10:58:38
1.6K0
发布2019-12-04 10:58:38
举报
文章被收录于专栏:CNCFCNCF

以下文章来源于腾讯云容器团队,作者陈勇

导读:本文主要介绍了人人视频在微服务化和云原生领域的一些自己的探索,我们的内部技术栈也在朝着这些主流的方向发展演进,不至于在这波潮流中落后,当然任何技术的使用最后都是为业务服务的,所以我们在关注使用最新技术的过程中也会考虑自身现有系统的现状以及技术储备的情况。实践微服务和云原生的方式有多种,这里介绍的只是一种方式,希望可以给大家一个参考。

背景

目前,完成微服务化改造的应用系统数量已有50+,微服务化的强大功能正在被越来越多的人所认可,市面上也已存在多种微服务架构可供选择。一个微服务架构的核心功能,往往都包含服务注册/发现,配置中心,负载均衡,API 网关,熔断限流,链路跟踪等几个部分,但是不同的微服务架构各有优劣,到底哪种更适合我们?微服务实践落地过程中,我们又应该如何选择呢?

本文接下来将主要讲述我们在微服务实践方面的经验和心得体会。由于我们的系统主要是 Java 语言开发,所以采用了 Spring Cloud。本次分享将重点介绍 Spring Cloud 的大致架构与 K8s 的互补关系,以及我们在腾讯云 TKE 上的部署实践。

Spring Cloud 微服务框架图

- Consul 或者 Eureka

主要用于服务注册和服务发现。每个微服务启动时会向服务注册中心注册自己,该注册中心存储所有服务的信息。并且,服务会周期性地向注册中心发送心跳,注册中心会检查超过一定时间没有 renew 的服务并且注销该服务。因此,某个服务要访问其他服务时,可以先到服务注册中心查询被调用者的地址是否存在。

目前,Consul 已经取代 Eureka 成为 Spring Cloud 的缺省服务注册发现组件。Consul 内置注册发现框架、一致性协议、健康检查、KV 存储,虽然仍像 Eureka 不依赖 Zookeeper,但是也能够使其使用起来更加方便。

- 服务网关的功能包括

• 认证、鉴权

• 安全

• 金丝雀测试(灰度)

• 动态路由

• 限流

• 聚合

Spring Cloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Netflix Zuul,其不仅提供统一的路由方式,还以基于 Filer 链的方式提供安全、监控/埋点、限流功能。

- 熔断器- Hystrix

在分布式架构中,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝)向调用方返回一个错误响应,而不是长时间的等待。这样就不会使得线程因调用故障服务而被长时间占用得不到释放,能够避免故障在分布式系统中的蔓延。

Hystrix 负责监控服务之间的调用情况,连续多次失败进行熔断保护。其主要工作流程:

• 检查缓存

• 检查 circuit breaker 状态

• 执行相应指令

• 记录数据,计算失败比率

Spring Cloud Hystrix 在我们的微服务治理中扮演着重要角色,我们对它做了二次开发,使其能够提供更加灵活的故障隔离、降级和熔断策略,满足 API 网关等服务的特殊业务需求。进程内的故障隔离仅是服务治理的一方面,另一方面,在一个应用混部的主机上,应用间应该互相隔离,避免进程间互抢资源,影响业务 SLA。比如绝对要避免一个离线应用失控占用了大量 CPU,使得同主机的在线应用受影响。我们通过 K8s 限制了容器运行时的资源配额(以 CPU 和内存限制为主),实现了进程间的故障和异常隔离。 K8s 提供的集群容错、高可用、进程隔离,配合 Spring Cloud Hystrix 提供的故障隔离和熔断,能够很好地实践 “Design for Failure” 设计哲学。

- 负载均衡 - Ribbon

不论是客户端实现还是服务器端的实现,都逃不开那些个负载均衡的常见算法。常见的服务端实现有:Nginx、HA Proxy 等。这里我们主要是客户端的实现,采用的是Netflix Ribbon,它的负载均衡策略比较丰富,包含以下几点:

1.随机选择(RandomRule)

2.线性轮询(RoundRobinRule)

3.重试机制(RetryRule)

4.加权响应(WeightedResponseTimeRule)

5.最小并发数(BestAvailableRule)

- 服务追踪- sleuth

微服务架构是一个分布式架构,它按业务划分服务单元,一个分布式系统往往有很多个服务单元。由于服务单元数量众多以及业务的复杂性,如果出现了错误和异常,很难去定位。主要体现在,一个请求可能需要调用很多个服务,而内部服务的调用复杂性,决定了问题难以定位。所以微服务架构中,必须实现分布式链路追踪,去跟进一个请求到底有哪些服务参与,参与的顺序又是怎样的,从而达到每个请求的步骤清晰可见,使得出了问题可以很快定位。

- 分布式配置中心

配置中心很重要,特别是业务调用错综复杂的情况下,不可能对单个应用使用单独配置文件的方式,Spring Cloud Config 就是用来解决微服务场景下的配置问题。关于分布式配置中心,在任何应用中都是需要的。一些敏感信息,配置在代码的配置文件中显然是不合适的,应当加密后存储在配置中心。

基于上面的介绍,我们可以看到基于 Spring Cloud 的微服务架构有很多好处:

• 服务简单,业务功能单一,易理解、开放、维护

• 每个微服务可由不同团队开发

• 微服务是松散耦合的

• 微服务持续集成、持续部署,服务独立部署、扩展

但是也有一些问题是它不能解决的,比如:

• 资源管理,应用编排、部署与调度

• 根据负载动态自动扩容缩容

• 服务间进程资源的隔离

SpringCloud 与 K8s 的优势互补

当前越来越多的应用走在了通往应用容器化的道路上,容器化会成为应用部署的标准形态,而 K8s 已经成为容器编排技术的代表,K8s 本身也支持上面提到的部分功能,下面我们看看在 K8s 上怎么解决上面的问题。

- 服务注册和发现

Kubernetes 系统之上用于名称解析和服务发现的 ClusterDNS 是集群的核心附件之一,集群中创建的每个 Service 对象,都会由其自动生成相关的资源记录。默认情况下,集群内各 Pod 资源会自动配置其作为名称解析服务器,并在其 dns 搜索列表中包含它所属名称空间的域名后缀。

无论使用 kubeDNS 还是 CoreDNS,它们提供的基于 DNS 的服务发现解决方案都会负责解析以下资源记录(Resource Record)类型以实现服务发现。

(1) 拥有 ClusterIP 的 Service 资源

(2) Headless 类型的 Service 资源

(3) ExternalName 类型的 Service 资源

名称解析和服务发现是 Kubernetes 系统许多功能得以实现的基础服务,它通常是集群安装完成后应该立即部署的附加组件。

创建 Service 资源对象时,ClusterDNS 会为它自动创建资源记录用于名称解析和服务注册。于是,Pod 资源可直接使用标准的 DNS 名称来访问这些 Service 资源。基于 DNS 的服务发现不受 Service 资源所在的名称空间和创建时间的限制。

- 负载均衡

每个节点都有一个组件 kube-proxy,实际上是为 Service 服务的。通过 kube-proxy,实现流量从 Service 到 Pod 的转发,kube-proxy 会监控集群中的 Service 和 Pod 的变化,及时更新 iptables 或者 ipvs 的规则,基于这些规则也就可以实现简单轮询的负载均衡功能。

- 配置中心

通过创建 ConfigMap,里面包含对应工作负载,Pod 的配置文件,环境变量信息,工作负载 Deployment/Daemonset 等引用并挂载 ConfigMap 到对应的容器中,通过这种方式可以提供类似配置中心的功能。

- 限流灰度发布

Deployment 这种工作负载类型是支持多副本,以及滚动升级机制,借助 traefik 可以实现一些简单的灰度发布和流量控制功能,但是只能是 instance 副本级别的控制,粒度比较大。

下面是腾讯云网站上的一张图片,可以看到:

从应用的生命周期角度来看,K8s 覆盖了更广的范围,特别是资源管理,应用编排、部署与调度等,Spring Cloud 则对此无能为力。

从功能上看,虽然两者存在一定程度的重叠,比如服务发现、负载均衡、配置管理、集群容错等方面,但两者解决问题的思路完全不同。Spring Cloud 面向的纯粹是开发者,开发者需要从代码级别考虑微服务架构的方方面面;而 K8s 面向的是 DevOps 人员,提供的是通用解决方案,它试图将微服务相关的问题都在平台层解决,对开发者屏蔽复杂性。

举个简单的例子,关于服务发现,Spring Cloud 给出的是传统的带注册中心 Eureka 的解决方案,需要开发者维护 Eureka 服务器的同时,改造服务调用方与服务提供方代码以接入服务注册中心,开发者需关心基于 Eureka 实现服务发现的所有细节。虽然可以通过 Java 注解最大程度地降低代码量,但是本质上还是代码侵入方式。而 K8s 提供的是一种去中心化方案,抽象了服务 (Service),通过 DNS+ClusterIP+iptables 解决服务暴露和发现问题,对服务提供方和服务调用方而言完全没有侵入。

K8s 虽然可以实现部分微服务框架的功能,在限流,服务熔断,链路跟踪等功能支持就比较有限。考虑到上述问题以及我们业务系统的现状、技术积累,作为主要编程语言是 Java 的容器服务来说,选择 Spring Cloud 去搭配 K8s 是一件很自然的事情。因此,我们采用了 SpringCloud + K8s 组合的方式来解决微服务化改造。

业务部署模式

• 我们所有的生产环境都是部署在公有云环境上,以腾讯云为主,使用腾讯云 TKE 部署了多套 K8s 集群。

• 每套 TKE 集群里部署 Spring Cloud 相应的组件运行我们的业务 Pod。

• 外部访问流量首先到达 Nginx 集群,根据路由规则会被发送到相应的 TKE 集群的 API Gateway 服务,再转发到对应的服务后端。

• 公司自研的发布系统会根据业务需求相应更新集群以及 Nginx 集群路由配置。通过这种方式可以实现蓝绿发布,要发布新版本时先只更新预发布集群的业务版本,相应的更新 Nginx 路由规则。比如,把从公司内部 IP 地址或者 android 客户端过来的访问请求导入预发布集群,验证试运行几天没有问题后再全量发布。

未来规划

目前我们是在每个集群中部署一套 Spring Cloud 系统来实现的,后续也有计划考虑只部署一套系统来打通多套 TKE 集群,借助腾讯云强大的 VPC 网络功能,实现不同集群之间以及集群内部与集群外部的业务之间的无缝连接通信。

Spring Cloud 官方也推出了 spring-cloud-kubernetes 开源项目,用于将 Spring Cloud 和

Spring Boot 应用运行在 Kubernetes 环境,并且提供了通用的接口来调用 Kubernetes 服务,比如 spring-cloud-kubernetes 的 Discovery Client 服务将 Kubernetes 中的"service"资源与 Spring Cloud 中的服务对应起来了,在 Kubernetes 环境就不需要 eureka 来做服务注册发现了,利用 spring-cloud-kubernetes-config 可以借助 K8s 原生的 ConfigMap 配置服务可以避免部署 Spring Cloud config server,这些也是我们未来尝试的方向。

公司介绍:

人人视频是一家基于海外文化短视频平台。主要为用户提供影视花絮、教育、音乐以及纪录片等领域的短视频分享内容。用户观看后可在社区平台进行评论、交流、分享。通过字幕翻译打通国内外文化屏障,让国内的年轻人方便易懂的了解外国生活的真实情况以及老外生活中具有正能量的热门事件。

文章转载自腾讯云容器团队。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CNCF 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档