ServiceMesh的关键:边车模式(sidecar);又要开车了
记性好的同学,一定记得我们那辆敞快明亮的JMC 。拥有一辆JMC,任嘶吼的狂风穿过车窗打在脸上,是一件无比畅快的事情。
这次的车不一样。有点高级。开的猛的时候,狂风能够掀掉头盔。
仔细观察上面的这辆车,它有三个轮子。其中左边多出来的轮子和座位,就叫做边车。它是可拆卸的,加上之后,就可以带人兜风了。
边车模式(sidecar),就像是梅超风对于陈玄风,莫邪对于干将。由于和比较前沿的ServiceMesh
概念息息相关,所以很容易让人望而却步。你到网上去随便一搜,都是晦涩难懂的概念。要了解下一代微服务,提前布局,需要啃一些枯燥的知识。
随着我的介绍,你会发现sidecar
模式,是一个高度抽象的模式。但是不要着急,这辆车形状怪异的交通工具,我们依然能够驾驭。它的概念很简单,只不过有很多使用限制。
一步步升级
注意:下面都是边车模式,只不过有的边车实在是简陋。
<1>
大家都知道,微服务是复杂的,引入了一系列的问题,服务治理显得尤关重要。比如日志收集、服务监控、服务治理等。
比如上面这张图,我们在一个Linux服务器上,部署了四个进程。其中,web服务是最主要的进程,其他进程只是作为一些附加功能部署上去的。
其实,这三个圆圈,就是边车的功能。只要把它给挂载上,上面的服务就拥有了这些功能。
但对于这三个组件的配置,是相当复杂的。我们需要很多重复的工作。
<2>
上面这张图,通过将Web应用与我们的辅助应用打包在一块,进一步增强了 不可变性。拥有了容器的加持,我们就能够靠约定来简化打包和发布操作。比如,上面的各个组件就可以通过localhost直接通信。
但可惜的是,我们的这些辅助程序,都是作为docker容器里的进程
去启动的,这种 富容器模式 有诸多缺陷,不符合不可变基础设施的理念,所以并不值得推荐。
<3>
k8s
的Pod
,在容器的基础上,进一步抽象。一个Pod中可以包含多个容器。如下图,基础服务和Web服务可以分别独自构建,最后以Pod作为载体,搭上便车就可以了。
为了更加显著的看到这个过程,下面这张图以日志收集为例,介绍了两个pod,相同日志收集docker容器的拓扑图。
从上面的演进过程我们可以看到。边车,就是辅助或者基础程序而已。但如何方便的管理这些附加的程序,我们有不同的组织方式。只有高度的抽象层次,才能进行方便的组装与设计。
<4>
到此为止,我们可以看一下ServiceMesh
经典的两张图了。
我们把Web应用(业务服务),抽象成绿色的方块
。然后把辅助组件(sidecar),抽象成蓝色方块
。在一个相对简单的环境中,我们的部署方式如下所示。
由于辅助组件并不能单独存在,所以它们都依附在绿色的服务上面。
我们抽调服务集群的血肉(Web服务),只留下它的筋骨(sidecar),就可以获得下面这张图,这就是ServiceMesh
。可以看到里面的连接线条是非常复杂的,人工不可能完成,只能依靠平台去管理。
任何东西只要一上规模了,就体现了它的复杂度。这还仅仅是只有36个服务节点的拓扑图。
不要小看这一个小小的蓝色方块。它不仅仅可以是一个辅助程序,而且可以成为基础设施。现在典型的service mesh,分为`数据平面`和`控制平面`,大多数落地的企业使用proxy方式实现了数据平面,对控制平面的实现有限。
像比较流行的Istio
,通过负载均衡、服务间的身份验证、监控等方法,它可以轻松地创建一个已经部署了服务的网络,而服务的代码只需很少更改甚至无需更改。通过在整个环境中部署一个特殊的 sidecar代理
,为服务添加 Istio 的支持,而代理会拦截微服务之间的所有网络通信,然后使用其控制平面的功能来配置和管理 Istio。
我们看下它官方的功能描述:
- 为 HTTP、gRPC、WebSocket 和 TCP 流量自动负载均衡。
- 通过丰富的路由规则、重试、故障转移和故障注入对流量行为进行细粒度控制。
- 可插拔的策略层和配置 API,支持访问控制、速率限制和配额。
- 集群内(包括集群的入口和出口)所有流量的自动化度量、日志记录和追踪。
- 在具有强大的基于身份验证和授权的集群中实现安全的服务间通信。
可以说,ServiceMesh将业务属性剥离了出去,只剩下一张大网,涵盖了所有运维和基础服务的工作。
要用它,不能说是没有代价的。其中有两点比较重要:
- 网络包通过层层的代理和转发(Ambassador模式),效率会降低,排错会变困难。
- 需要按照这个网格的规范进行改造,也就是写一堆适配器(Adapter模式)。
SpringCloud的Sidecar
说到适配器,就不禁想起了SpringCloud的Sidecar。
Java里要说玩新概念,怎么能少的了Spring家族?SpringCloud同样有一个sidecar的组件,它的maven
坐标如下。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-sidecar</artifactId>
</dependency>
它做的事情,更加像一个适配器。它能把一个普通的php或者nodejs服务,伪装成一个正常的SpringCloud服务。
通过简单的配置,我们就可以让一些其他语言开发的Web应用,加入到SpringCloud体系中来。
它的使用比较简单,在此不过多介绍。
End
- 一条update语句的优化探索(r9笔记第80天)
- OpenCV角点检测源代码分析(Harris和ShiTomasi角点)
- Java基础-day03-代码题
- mongodb11天之屠龙宝刀(九)js函数入门:MongoDB基于js的数据类型修改
- Go语言社区 APP --问答模块数据存储流程及代码
- Java基础-day09-重构随机点名器
- OpenCV3.4两种立体匹配算法效果对比
- 文件操作常用函数
- Java基础-day09-对象;类;封装 学生管理系统
- two Pass方法连通域检测
- 【Java入门提高篇】Day14 Java中的泛型初探
- 使用shell脚本快速得到主备关系(r9笔记第93天)
- 【Java入门提高篇】Day13 Java中的反射机制
- 仿腾讯课堂固定滚动列表ReactNative组件
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- arm(3)| 点亮led灯
- 根据 PID 获取容器所在的 Pod 名称
- Python 爬虫进阶必备 | 关于某服务平台数据解密流程分析
- batch-compute & GPU分布式机器学习
- 数据源管理 | 搜索引擎框架,ElasticSearch集群模式
- PHP的CLI命令行运行模式浅析
- 基于Pytorch构建三值化网络TWN
- 从零学Paddle系列-1 Paddle框架CNN相关API详解
- 智能搜索模型预估框架的建设与实践
- 1,Jupyter NoteBook 常用魔法命令
- 60行代码徒手实现深度神经网络
- 30行代码徒手实现logistic回归
- 8,模型的训练
- 在腾讯云上部署科学计算软件Amber
- 手把手教你搭建一个灰度发布环境