本文转载自关于Sidecar Pattern

导语

Sidecar 是一个很纠结的名字,我们在翻译技术雷达时采用了一个比较通俗的翻译,即边车,而这个词随着微服务的火热与 Service Mesh 的逐渐成熟而进入人们的视野。虽然很多企业在自己的后台应用中已经大量的使用了 Sidecar,但是也是没有意识到这是一个极为有用的 pattern,今天我们就来聊一聊。

什么是 Sidecar 与 Sidecar pattern?

Sidecar 直接表示就是挎斗摩托车,也就是常说的“三蹦子”,如果你经常玩吃鸡,你一定不陌生。在“三蹦子”中,往往有个挎子,它不提供动力,但是也是这个机动装置的一个重要的组成部分,如果坐着一个妹子就可以给开车的你喂水果。

sidecar

我们目前很多程序都是奔着 Cloud Native 的目标去的,我们的代码注定是要跑在云上的,当有人问我如果我要做到 Cloud Native 时,有没有合适的学习资料之类的时,我会考虑如果你是有一定经验的开发者,并且对 Design Pattern 有一些了解,那么你非常适合这本来自微软 P & P Group 的书 Cloud Design Patterns,虽然这本书很简单,实例也不多,但是更多的是启发性。我也是在 Cloud Design Pattern 这本书中学到了很多,sidecar 也是其中之一,并且我们写了很多很多 Sidecar 用于管理自己的 Service Mesh 。

[Pattern is] a solution to a problem in a context.

为什么你需要 Sidecar?

非常简单,想象一下你要编写一堆 Web Service API,使用 JSON 作为数据格式暴露给前端,这个应用程序是用最常见的 Spring Boot 编写的,然后你要把他丢在你的虚拟机或者 k8s 上,你除了写代码,还需要考虑什么?

  • DNS
  • 反向代理
  • 服务发现
  • 服务注册
  • 负载均衡
  • HTTPS
  • 弹性
  • 日志
  • 性能监控 APM
  • 警报
  • 终端安全
  • 获取配置
  • 等等

很多同事都对这些事情嗤之以鼻,毕竟大多数人的核心工作还是写代码,把应用做起来,至于这些事情是 ops 做的事儿,或者工程师可以做一部分,比如配置日志、给端点加个证书配置等等。于是我问一个朋友,Spring Boot 自带的 server 你知道怎么配证书和日志,那么 node express 呢?那么 on rails 呢?那么 play framework 呢?特别是当你决心要实现微服务架构的时候,这些看起来比较麻烦又很简单的事儿,反倒最消耗人,我们不希望给每个服务都做一遍,但是又不得不做一遍。所以,sidecar 的出现可以让我们以更优雅的方式解决这个事情,刚才我们提到的大量的功能都可以用 out-of-process 的方式实现,比如说反向代理。

Ruby 的 Unicorn Server 是一个很好的 Rack 容器,但是它对慢连接很敏感,而且不是很好处理 access log,熟悉 NGINX 的你一定想到了,如果我在虚拟机上开启一个 NGINX 进程,并且将 443 端口暴露出去,然后在这个 NGINX 中配置好 access log 与证书,并且将收到的请求使用 linux socket 的方式转发给 unicorn(或者直接走 docker network),这样我的 unicorn server 不就很简单了,我甚至都不需要配置。这样的一个 NGINX 就是一个 sidecar,它实现了访问记录、端点安全、进程隔离、并且轻量。你的应用程序不用再在乎这些,大约长得像这样:

server {
listen 80;
...
location / {
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Request-Start "t=\${msec}";
proxy_set_header Host \$http_host;
proxy_redirect off;
proxy_pass http://backend;
...

再举一个例子,我们每个应用程序都会记录日志,而我们并不希望日志保存在每台机器上或者容器中,我们希望每个应用是不产生任何状态的。但是这很难,我们必须开发所谓的日志收集系统,并且相关的日志组件,往往我们只能兼顾一两个流行语言或平台,例如 Java 与 JavaScript,而且我们还得维护这些东西,直到公司倒闭。有没有更优雅的解决办法呢?答案是有,在 12 factor app: logs 中,我们希望以事件流的方式去处理日志,如果我的应用把日志丢到 stdout 与 stderr 中,然后有人来自动收集,归档并发送到日志中心呢?这就是日志收集器,这也是一个 sidecar。

Sidecar 核心思想

Sidecar 不是应用程序的必要组成部分,当你使用 docker-compose 在本地启动一个小服务做开发测试的时候,Sidecar 并不会起作用,所以它不影响你的核心功能。但是,Sidecar 在真正的生产环境中,是和你的应用程序绑定在一起的,应用在哪里启动,它就出现在哪里。我们的应用不论是在虚拟机或者是在容器中,每一个应用的实体,都有大量的 sidecar 来做这种与核心功能无关的活儿。

每个“三蹦子”都有自己的 sidecar,每个 sidecar 都是紧紧的 attach 到它的“三蹦子”上的。

没有上容器云之前的 Sidecar 例子

那么,引用并修改一下 sidecar 的特性

  • Sidecar 是独立于其应用程序之外的,不使用应用程序的运行环境与编程语言。比如你可以使用 JavaScript 去做日志收集器,而不用关心应用程序用的什么语言,你们使用进程通信的方式或者更粗暴的流
  • Sidecar 是可以访问一些相同的系统资源的,和应用程序一样。这样你才能进行系统监控与收集程序的健康数据。但是也有一些数据是在应用程序内打桩,然后暴露出去的比如 transaction
  • Sidecar 实际上对性能的损失非常小,特别是使用了容器化技术后,本来启动容器就是很廉价的事情,而且使用 docker image 发布 sidecar 让这个事情成本更低
  • Sidecar 同样可以进行应用程序扩展,比如说,我们可以将 circuit breaker 实现在 sidecar 中,这样就可以避免代码中使用各种 circuit breaker 的实现,你的代码依旧可以简单的 RestTemplate 去做你想做的事儿,也不用担心下游服务的实效,导致串联失效的问题

Sidecar 的适合场景

如果你们公司已经开始使用微服务架构,践行了小组自治,那么大量的应用程序会用各种流行语言编写,并且使用了各种不同的框架,那么 Sidecar 就是你一定要考虑的。使用 out-of-process 的方式封装共有的一些功能,让应用程序变得简单,而这些共有的功能,最理想的情况下就是部署脚本中的一些配置。

Sidecar 在微服务领域是服务治理的重要工具,也是实现 Service Mesh 的必备工具,在 Service Mesh 的概念下,我们希望提供一层额外的抽象来保证服务的简单、可以相互调用,并且帮助我们轻松的解决服务发现、服务调用、服务监控、服务注册等等功能,这额外的一层可以通过 sidecar 来实现。不论是 Istio 还是 conduit 很多关键功能就是这么实现的。当然,很多情况下我们还是会自己去写适合自己组织架构的 sidecar,之前我们提到的 NGINX 与日志收集器就是一些很好的例子。而之前我们列举出一个 Web Service 可能会需要的功能,也有一部分是根据你的云平台进行裁剪的,比如负载均衡和弹性,完全可以使用 AWS 的 ELB 与 AutoScaling 来解决。

那么什么时候不适用呢?

  • 应用程序过小,或者成本问题:如果没有使用微服务架构或者你的程序就一个 MVC App 就解决了,那就不需要使用 sidecar,毕竟开发成本很高
  • 对性能要求极高:进程间通信还是有成本的,有时也是会有显著的延迟或者被阻塞;docker network 的性能也是赶不上进程间通信的,所以如果你的应用有小于毫秒级别的性能要求的话,这个 sidecar 不适合你

Sidecar 与 DevOps

我在与别人聊 Sidecar 时,很多朋友觉得这个东西的难点不在于创建一个又一个的 sidecar,而是在于如何在部署时,按照应用程序的要求将 sidecar 与应用程序紧紧的组合在一起。这是非常难的,首先每个企业使用的平台并不相同,每个企业的部署方式也不一样,这是没有通用解的问题,只能按照现有情况。在之前我们使用 aws ec2 + docker 时,我们会在 ec2 的 launch config 中去启动不同的 docker image 并且配置其 docker network,但这是一种比较低效的做法,因为只是使用 docker image 来封装你的产出物,而不是使用其作为秒级开启的容器。但是如果在 k8s 上做这件事儿,我们更倾向于在一个容器中把应用的事情做好,很难做到每个应用所运行的容器上都有 attached sidecars。所以这个话题没有好的回答,只能说是 It depends。

Reference

关于Sidecar Pattern的更多相关文章

  1. image management in kubernet

    Image How can I edit an existing docker image metadata? docker-copyedit Registry Disk kubevirtis a g ...

  2. Kubernetes与容器设计模式

    目录贴:Kubernetes学习系列 在程序设计领域,面向对象设计和面向对象语言是大家最为熟悉和强大的工具,而面向对象除了其强大的核心特性之外,还有人们通过实践总结出来的一系列设计模式,可以用来解决实 ...

  3. 《Kubernetes与云原生应用》系列之容器设计模式

    http://www.infoq.com/cn/articles/kubernetes-and-cloud-native-app-container-design-pattern <Kubern ...

  4. k8s管理pod资源对象(上)

    一.容器于pod资源对象 现代的容器技术被设计用来运行单个进程时,该进程在容器中pid名称空间中的进程号为1,可直接接收并处理信号,于是,在此进程终止时,容器即终止退出.若要在一个容器中运行多个进程, ...

  5. docker,容器,编排,和基于容器的系统设计模式

    目录 从容器说起 背景 docker实现原理 编排之争 基于容器的分布式系统设计之道 单节点协作模式 Sidecar pattern(边车模式) Ambassador pattern(外交官模式) A ...

  6. 浅析 Dapr 里的云计算设计模式

    Dapr 实际上是把分布式系统 与微服务架构实践的挑战以及k8s 这三个主题的全方位的设计组合,特别是Kubernetes设计模式 一书作者Bilgin Ibryam 提出的Multi-Runtime ...

  7. k8s sidecar, Ambassador, Adapter containers

    When you start thinking in terms of Pods, there are naturally some general patterns of modular appli ...

  8. K8S 使用 SideCar 模式部署 Filebeat 收集容器日志

    对于 K8S 内的容器日志收集,业内一般有两种常用的方式: 使用 DaemonSet 在每台 Node 上部署一个日志收集容器,用于收集当前 Node 上所有容器挂载到宿主机目录下的日志 使用 Sid ...

  9. 按照Enterprise Integration Pattern搭建服务系统

    在前一篇文章中,我们已经对Enterprise Integration Pattern中所包含的各个组成进行了简单地介绍.限于篇幅(20页Word以内),我并没有深入地讨论各个组成.但是如果要真正地按 ...

随机推荐

  1. SealClient

    import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import ja ...

  2. Flink-v1.12官方网站翻译-P017-Execution Mode (Batch/Streaming)

    执行模式(批处理/流处理) DataStream API 支持不同的运行时执行模式,您可以根据用例的要求和作业的特点从中选择.DataStream API 有一种 "经典 "的执行 ...

  3. 牛客小白月赛30 J.小游戏 (DP)

    题意:给你一组数,每次可以选择拿走第\(i\)个数,得到\(a[i]\)的分数,然后对于分数值为\(a[i]-1\)和\(a[i]+1\)的值就会变得不可取,问能得到的最大分数是多少. 题解:\(a[ ...

  4. JavaScript——匿名函数和闭包

    匿名函数就是没有名字的函数 闭包就是一个函数中的另一个函数 函数可以不加分号,但是语句要加!! 可以把匿名函数的返回值赋值给变量!! box()时返回里面的函数,再加一个()就会返回里面那函数的值(浅 ...

  5. Python+Appium实现自动抢微信红包

    前言 过年的时候总是少不了红包,不知从何时开始微信红包横空出世,对于网速和手速慢的人只能在一旁观望,做为python的学习者就是要运用编程解决生活和工作上的事情. 于是我用python解决我们的手速问 ...

  6. [Golang]-3 函数、多返回值、变参、闭包、递归

    // test01 project main.go package main import ( "fmt" ) // 单返回值的函数 func plus(a int, b int) ...

  7. 3.安装可视化工具kibana

    作者 微信:tangy8080 电子邮箱:914661180@qq.com 更新时间:2019-06-19 10:10:42 星期三 欢迎您订阅和分享我的订阅号,订阅号内会不定期分享一些我自己学习过程 ...

  8. Qt开发Activex笔记(一):环境搭建、基础开发流程和演示Demo

    前言   使用C#开发动画,绘图性能跟不上,更换方案使用Qt开发Qt的控件制作成OCX以供C#调用,而activex则是ocx的更高级形式.  QtCreator是没有Active控件项目的,所有需要 ...

  9. codeforces 1009D Relatively Prime Graph【欧拉函数】

    题目:戳这里 题意:要求构成有n个点,m条边的无向图,满足每条边上的两点互质. 解题思路: 显然1~n这n个点能构成边的条数,就是2~n欧拉函数之和(x的欧拉函数值代表小于x且与x互质的数的个数. 因 ...

  10. mysql 索引类型以及创建

    明天就去面浦发了,感觉对数据库有些忘了,时间紧迫,就直接把链接贴这了,有空再整理. 参考: 1. https://www.cnblogs.com/crazylqy/p/7615388.html