技术

并发的成本 基础设施优化 hashicorp raft源码学习 docker 架构 mosn细节 与微服务框架整合 Java动态代理 编程范式 并发通信模型 《网络是怎样连接的》笔记 go细节 codereview mat使用 jvm 线程实现 go打包机制 go interface及反射 如何学习Kubernetes 《编译原理之美》笔记——后端部分 《编译原理之美》笔记——前端部分 Pilot MCP协议分析 go gc 内存管理玩法汇总 软件机制 istio流量管理 Pilot源码分析 golang io 学习Spring mosn源码浅析 MOSN简介 《datacenter as a computer》笔记 学习JVM Tomcat源码分析 Linux可观测性 MVCC 学习存储 学计算 Gotty源码分析 kubernetes operator kaggle泰坦尼克问题实践 kubernetes自动扩容缩容 神经网络模型优化 直觉上理解机器学习 knative入门 如何学习机器学习 神经网络系列笔记 TIDB源码分析 《阿里巴巴云原生实践15讲》笔记 Alibaba Java诊断工具Arthas TIDB存储——TIKV 《Apache Kafka源码分析》——简介 netty中的线程池 guava cache 源码分析 Springboot 启动过程分析 Spring 创建Bean的年代变迁 Linux内存管理 自定义CNI IPAM 扩展Kubernetes 副本一致性 spring redis 源码分析 kafka实践 spring kafka 源码分析 Linux进程调度 让kafka支持优先级队列 Codis源码分析 Redis源码分析 C语言学习 《趣谈Linux操作系统》笔记 docker和k8s安全机制 jvm crash分析 Prometheus 学习 Kubernetes监控 Kubernetes 控制器模型 容器日志采集 容器狂占cpu怎么办? 容器狂打日志怎么办? Kubernetes资源调度——scheduler 时序性数据库介绍及对比 influxdb入门 maven的基本概念 《Apache Kafka源码分析》——server Kubernetes objects之编排对象 源码分析体会 自动化mock AIOps说的啥 《数据结构与算法之美》——算法新解 Kubernetes源码分析——controller mananger Kubernetes源码分析——apiserver Kubernetes源码分析——kubelet Kubernetes介绍 ansible学习 Kubernetes源码分析——从kubectl开始 jib源码分析之Step实现 kubernetes实践 jib源码分析之细节 线程排队 跨主机容器通信 jib源码分析及应用 为容器选择一个合适的entrypoint kubernetes yaml配置 marathon-client 源码分析 《持续交付36讲》笔记 mybatis学习 程序猿应该知道的 无锁数据结构和算法 CNI 为什么很多业务程序猿觉得数据结构和算法没用? 串一串一致性协议 当我在说PaaS时,我在说什么 《数据结构与算法之美》——数据结构笔记 swagger PouchContainer技术分享体会 harbor学习 用groovy 来动态化你的代码 《深入剖析kubernetes》笔记 精简代码的利器——lombok 学习 编程语言的动态性 rxjava3——背压 rxjava2——线程切换 spring cloud 初识 《深入拆解java 虚拟机》笔记 《how tomcat works》笔记 hystrix 学习 rxjava1——概念 Redis 学习 TIDB 学习 分布式计算系统的那些套路 Storm 学习 AQS1——论文学习 Unsafe Spark Stream 学习 linux vfs轮廓 mysql 批量操作优化 《自己动手写docker》笔记 java8 实践 中本聪比特币白皮书 细读 区块链泛谈 比特币 大杂烩 总纲——如何学习分布式系统 hbase 泛谈 forkjoin 泛谈 看不见摸不着的cdn是啥 《jdk8 in action》笔记 程序猿视角看网络 bgp初识 mesos 的一些tips mesos 集成 calico calico学习 AQS2——粗略的代码分析 我们能用反射做什么 web 跨域问题 《clean code》笔记 硬件对软件设计的影响 《Elasticsearch权威指南》笔记 mockito简介及源码分析 2017软件开发小结—— 从做功能到做系统 《Apache Kafka源码分析》——clients dns隐藏的一个坑 《mysql技术内幕》笔记2 《mysql技术内幕》笔记1 log4j学习 为什么netty比较难懂? 回溯法 apollo client源码分析及看待面向对象设计 学习并发 从一个marathon的问题开始的 docker 环境(主要运行java项目)常见问题 Scala的一些梗 OpenTSDB 入门 spring事务小结 事务一致性 javascript应用在哪里 《netty in action》读书笔记 netty对http2协议的解析 ssl证书是什么东西 http那些事 苹果APNs推送框架pushy apple 推送那些事儿 编写java框架的几大利器 java内存模型 java exception Linux IO学习 network channel network byte buffer 测试环境docker化实践 netty(七)netty在框架中的使用套路 Nginx简单使用 《Linux内核设计的艺术》小结 Go并发机制及语言层工具 mesos深入 Macvlan Linux网络源代码学习——数据包的发送与接收 《docker源码分析》小结 docker中涉及到的一些linux知识 hystrix学习 Linux网络源代码学习——整体介绍 zookeeper三重奏 数据库的一些知识 Spark 泛谈 链式处理的那些套路 netty(六)netty回顾 Thrift基本原理与实践(二) Thrift基本原理与实践(一) 回调 异步执行抽象——Executor与Future Docker0.1.0源码分析 java gc Jedis源码分析 Redis概述 机器学习泛谈 Linux网络命令操作 JTA与TCC 换个角度看待设计模式 Scala初识 向Hadoop学习NIO的使用 以新的角度看数据结构 并发控制相关的硬件与内核支持 systemd 简介 那些有用的sql语句 异构数据库表在线同步 quartz 源码分析 基于docker搭建测试环境(二) spring aop 实现原理简述 自己动手写spring(八) 支持AOP 自己动手写spring(七) 类结构设计调整 分析log日志 自己动手写spring(六) 支持FactoryBean 自己动手写spring(九) 总结 自己动手写spring(五) bean的生命周期管理 自己动手写spring(四) 整合xml与注解方式 自己动手写spring(三) 支持注解方式 自己动手写spring(二) 创建一个bean工厂 自己动手写spring(一) 使用digester varnish 简单使用 关于docker image的那点事儿 基于docker搭建测试环境 分布式配置系统 JVM内存与执行 git spring rmi和thrift maven/ant/gradle使用 再看tcp mesos简介 缓存系统 java nio的多线程扩展 《Concurrency Models》笔记 回头看Spring IOC IntelliJ IDEA使用 Java泛型 vagrant 使用 Go常用的一些库 Python初学 Goroutine 调度模型 虚拟网络 《程序员的自我修养》小结 VPN(Virtual Private Network) Kubernetes存储 Kubernetes 其它特性 访问Kubernetes上的Service Kubernetes副本管理 Kubernetes pod 组件 使用etcd + confd + nginx做动态负载均衡 如何通过fleet unit files 来构建灵活的服务 CoreOS 安装 CoreOS 使用 Go学习 JVM类加载 硬币和扑克牌问题 LRU实现 virtualbox 使用 ThreadLocal小结 docker快速入门

标签


下一代微服务Service Mesh

2019年12月04日

简介

Service Mesh技术社区的官方网站

Service Mesh 的概念最早是由 Buoyant 公司的 CEO William Morgan What’s a service mesh? And why do I need one? 提到的

什么是 Service Mesh

为什么说 Service Mesh 是微服务发展到今天的必然产物?

著名软件大师Chris Richardson 曾一针见血地指出:“微服务应用是分布式系统,由此会带来固有的复杂性。开发者需要在 RPC 或者消息传递之间选择并完成进程间通讯机制。此外,他们必须写代码来处理消息传递中速度过慢或者不可用等局部失效问题。”种种复杂局面便催生了服务间通信层的出现,这个层既不会与应用程序的代码耦合,又能捕捉到底层环境高度动态的特点,让业务开发者只关注自己的业务代码,并将应用云化后带来的诸多问题以不侵入业务代码的方式提供给开发者。这个服务间通信层就是 Service Mesh

普元微服务专家宋潇男:让我们回忆一下单机程序的运作方式,源代码被编译器编译为一系列目标文件,然后交由链接器将这些目标文件组装成一个可执行文件,链接过程就是将各个目标文件之间对符号(方法、变量、函数、接口等)的引用转化为对内存地址的引用,由于这个过程在生成可执行文件时就完成了,所以被称为静态链接。后来为了程序的模块化和功能上的解耦与共用,开始把一些常见的公共程序剥离出来,制作成库文件供其他程序使用,在引用这些库文件的程序运行时,操作系统上的动态链接器会在库文件中查询到被引用的符号,然后将这些符号的内存地址映射到该程序的虚拟内存空间之中,由于这个过程是在程序运行时完成的,所以被称为动态链接。

再后来出现了分布式系统,程序被散布在网络中的不同主机上,那么如何链接这些程序呢?业界走过了和链接单机程序类似,但是却艰难得多的一段历程。

  1. 最开始是把这些服务的网络地址写在配置文件中,这个方案显然问题太多、很不靠谱。
  2. 接下来自然而然地出现了服务注册中心来统一记录这些服务的网络地址并维护这些地址的变化,服务通过注册中心提供的客户端 SDK 与注册中心通信并获得它们所依赖的服务的网络地址。由于网络通信远没有内存通信稳定,为了保证可靠的服务调用,又出现了用于流量控制的 SDK,提供流量监控、限流、熔断等能力。被依赖的服务往往以多实例的方式运行在多个主机上,有多个网络地址,所以又出现了用于负载均衡的 SDK。
  3. 我们手里多了一堆 SDK,已有的(未接入微服务)应用,必须用这些 SDK 重新开发;而对于新开发的应用,我们又发现这些 SDK 体积过大。对比单机上动态链接过程的顺畅,这种基于 SDK 的微服务动态链接方案简直是难用的不得了。

在三到五年之后,Kubernetes 会成为服务器端的标准环境,就像现在的 Linux,而 Service Mesh 就是运行在 Kubernetes 上的分布式应用的动态链接器,届时开发一个分布式应用将会像开发单机程序一样简单,业界在分布式操作系统上长达三十多年的努力将以这种方式告一段落

浅谈Service Mesh体系中的Envoy:如果用一句话来解释什么是Service Mesh,可以将其比作微服务间的TCP/IP层,负责服务之间的调用、限流、熔断和监控等。PS:如果你熟悉linux内核,就不会把协程和线程认为是两个东西。类似的,如果你熟悉通信协议分层,就不会把Service Mesh 和TCP 认为是两个东西。

SideCar的一种实现MOSN 全称是 Modular Observable Smart Network——模块化的、可观测的智能网络。这也是Service Mesh是下一代SDN吗?将Service Mesh 称为更广泛意义上的SDN。

李云 Service Mesh 带来的变化与发展机遇:阿里巴巴在分布式应用的开发和治理的整体解决方案的探索有超过10年的历程,且探索过程持续的通过双11这样的严苛场景做检验和孵化,采用单一的Java语言打造了一整套技术。即便如此,应对分布式应用的规模问题依然不轻松,体现于因为缺乏顶层设计而面临体系性不足,加之对技术产品自身的用户体验缺乏重视,最终导致运维成本和技术门槛都偏高。

传统微服务架构

Service Mesh架构

通信能力的下沉

深入解读Service Mesh背后的技术细节Service Mesh是Kubernetes支撑微服务能力拼图的最后一块

要想业务中台建得快,最好用Service Mesh来带从架构上看,中台是一种基础设施的下沉,微服务框架则是一种不彻底的下沉,因为它还是在业务开发代码里面的。而这种对业务的侵入性,也造成了服务框架升级的困难。

整体架构

内容主要来自胡忠想在极客时间上的《从0开始学微服务》

SideCar

业务和sidecar如何交互?

Control Plane

传统IP网络 ==> SDN ==> Service Mesh/控制面+数据面

Service Mesh是下一代SDN吗?

传统的IP网络是一个分布式的无中心架构,各个网络设备包含完整的控制面和数据面,单个设备通过网络协议探测网络中其他设备的状态,自主决定如何对流量进行路由。该架构的好处是容错性强,即使网络局部出现故障,整个网络也可以自主恢复,不会影响整个网络的运行。这种去中心的架构在基于文本和图片的web浏览器应用时代运作良好,但随着互联网业务的爆炸式增长,各种各样的业务纷纷承载在了IP网络上,包括各种实时业务如语音视频通话,对网络提出了新的挑战。

  1. 缺少网络质量保证: 绝大多数IP网络都是基于无连接的,只有基于大带宽的粗放带宽保障措施,缺乏质量保证和监控,业务体验较差。
  2. 低效的业务部署: 网络配置是通过命令行或者网管、由管理员手工配置到网络设备上,并且各种网络设备之间的控制命令互不兼容,导致业务的部署非常低效。
  3. 缓慢的业务适应: 业务由硬件实现,导致新业务的开发周期过长。需要持续数年的特性和架构调整、引入新设备,才能推出新的业务,无法快速适应市场,满足用户的需求。

为了应对这些问题,提出了SDN的解决方案

从图中可以看到,SDN从下至上划分为三层体系结构(PS:说白了就是网络设施API化):

  1. 基础设施层(Infrastructure Layer): 是网络的数据平面,由各种网络设备构成,根据控制层下发的路由规则对网络数据进行处理和转发。
  2. 控制层(Control Layer): 是一个逻辑上集中的控制平面,维护了整个网络的信息,如网络拓扑和状态信息等,控制层根据业务逻辑生成配置信息下发给基础设施层,以管理整个网络的运行。
  3. 应用层(Application Layer):通过控制层提供的编程接口,可以编写各种应用利用控制层的能力对网络进行灵活的配置。

Service Mesh是下一代SDN吗?答案是否定的,因为两者之间还是有显著的不同。SDN主要面对L1到L4层,即网络层的基本转发和控制功能;Service Mesh则主要面对L7层及以上,用于处理应用层的服务发现,服务路由等功能,但两者采用了相似的理念,我们可以把Service Mesh看作SDN的理念在应用层的扩展和实践。

在该架构中,数据面承担的是一个白盒交换机的角色,不管何种实现,其功能都是类似的,不存在太多争议,目前envoy已经成为数据面的标准实现,因此数据面和控制面之间也采用了Envoy的xDS v2作为标准的数据面协议。各个Service Mesh项目的创新和争夺的战场主要在控制面上

Service Mesh 所带来的变化

基本摘抄自Service Mesh 是新瓶装旧酒吗?

服务治理手段从过去的框架思维向平台思维转变

框架思维向平台思维转变在执行上集中体现于“轻量化”和“下沉”两个动作。

  1. 轻量化是指将那些易变的功能从框架的 SDK 中移出,结果是使用了 SDK 的应用变得更轻,免除了因易变功能持续升级所带来的低效;也彻底让应用的开发者无需关心这些功能,让他们能更好地聚焦于业务逻辑本身;
  2. 从框架中移出的功能放到了 Service Mesh 的 Sidecar 中实现了功能下沉。

Service Mesh 作为平台性技术,将由云厂商去运维和提供相应的产品,通过开源所构建的全球事实标准一旦被所有云厂商采纳并实现产品化输出,那时应用的可移植性问题就能水到渠成地解决。

阿里巴巴的电商核心应用基本上都是用 Java 构建的,在 Mesh 化之前,RPC 的服务发现与路由是在 SDK 中完成的,为了保证 双11 这样的流量洪峰场景下的消费者用户体验,会通过预案对服务地址的变更推送做降级,避免因为频繁推送而造成应用进程出现 Full GC。

Mesh 化之后,SDK 的那些功能被放到了 Sidecar(开发语言是 C++)这一独立进程中,这使得 Java 应用进程完全不会出现类似场景下的 Full GC 问题。

Service Mesh 使得应用与技术基础设施之间的关系变得更松且稳定,通过流量无损的热升级方案,使得应用与技术基础设施的演进变得独立,从而加速各自的演进效率。软件不成熟、不完善并不可怕,可怕的是演进起来太慢、包袱太重。当应用被 Mesh 化后,接下来的技术基础设施的升级对之就透明了,之前因为升级工作所需的人力配合问题可以通过技术产品化的手段完全释放。

另外,以往应用进程中包含了业务逻辑和基础技术的功能,不容易讲清楚各自对计算资源的消耗,Service Mesh 通过独立进程的方式让这一问题得以更好地隔离而实现量化,有了量化结果才能更好地对技术做优化。

技术平台的建设从面向单一编程语言向面向多编程语言转变

当企业的发展进入了多元化、跨领域、规模更大的更高阶段时,多编程语言的诉求就随之产生,对于阿里巴巴这样的云厂商来说更是如此。多编程语言诉求的背后是每种编程语言都有自己的优势和适用范围。从技术层面,这一转变意味着:

  1. 技术平台的能力需要尽可能地服务化,避免因为服务化不彻底而需要引入 SDK,进而带来多编程语言问题(即因为没有相应编程语言的 SDK 而无法使用该编程语言);
  2. 在无法规避 SDK 的情形下,让 SDK 变得足够的轻且功能稳定,降低平台化和多编程语言化的工程成本,支持多编程语言 SDK 最好的手段是采用 IDL。

从组织层面,这一转变意味着平台技术团队的人员技能需要多编程语言化。一个只有单一编程语言的团队是很难做好面向多编程语言的技术平台的。

发展机遇

  1. 面向未来的分布式应用开发平台。在 Service Mesh 出现之前,各种分布式服务治理技术产品的发展,缺乏强有力的抓手去横向拉通做体系化设计和完成能力复用(比如springcloud与dubbo),因而难免出现概念抽象不一致和重新造轮子的局面,最终每个技术产品有自己的一套概念和独立的运维控制台。因为 Service Mesh 的出现,我们有机会就分布式应用的治理做一次全局的设计,也有机会将各种技术产品整合到一起而避免重复建设的问题。
  2. 给其他技术产品创造了重新思考云原生时代的发展机会。有了 Service Mesh 后,以前很多独立的技术产品(比如,服务注册中心、消息系统、配置中心)将变成 BaaS(Backend as a Service)服务,由 Service Mesh 的 Sidecar 负责与它们对接,应用对这些服务的访问通过 Sidecar 去完成,甚至有些 BaaS 服务被 Sidecar 终结而完全对应用无感
  3. 给技术基础设施如何与业务基础技术更好地协同提供了一次探索机会。每一种业务(比如电商)都会构建基于所在领域的基础技术,这类技术我们称之为业务基础技术。当阿里巴巴希望将某一业务的基础技术搬到外部去服务客户时,面临业务基础技术如何通过服务化去满足客户已选择的、与业务基础技术不同的编程语言的问题,否则会出现基于 Java 构建的业务基础技术很难与 Go 所编写的应用协同。在 Service Mesh 致力于解决服务化问题的过程中,能否通过一定的技术手段,让业务基础技术的能力通过插件的形式“长”在 Service Mesh 之上是一个很值得探索的点。当业务基础技术以插件的形式存在时,业务基础技术无需以独立的进程存在而取得更好的性能,且这一机制也能被不同的业务复用。业务的基础技术并非开发了一个独立的应用(进程)然后做发布和运维管理,而是针对 Service Mesh实现了业务技术插件,插件通过 Service Mesh 的运维平台进行管理,包含安装、灰度、升级、监控等能力。由于插件是“长”在 Service Mesh 之上的,插件化的过程就是业务技术服务化的过程。

  4. 给探索面向未来的异地多活、应用永远在线的整体技术解决方案打开了一扇大门。服务之间的互联互通,服务流量的控制、观测和安全加固是微服务软件架构下所要解决的关键问题,这些问题与规模化下的服务可用性和安全性紧密相关。

阿里巴巴 Service Mesh 落地的架构与挑战兑现 Service Mesh 的价值,让业务与技术设施能以更高的效率彼此独立演进

未来发展

胡忠想《从0开始学微服务》极客时间教程

  1. 业务中存在大量服务对缓存、数据库以及消息队列等资源的调用,如果把资源也看作是一种服务,那么 Service Mesh 不仅可以管理服务与服务之间的调用,还可以管理服务与资源之间的调用,这样的话 Service Mesh 强大的服务治理能力也能延伸到对资源的治理上,对业务来说又将解决资源治理这一大难题。
  2. 随着 Service Mesh 治理的服务越来越多,收集的数据也越来越多,利用这些数据可以挖掘一些更深层次的东西,也是 Service Mesh 未来的发展方向之一。比如,引入机器学习算法,对采集的数据进行分析,进行监控报警的优化等。

Service Mesh 发展趋势(续):棋到中盘路往何方

其它

软件设计的质量主要体现在“概念”和“关系”两个词上。同样功能的一个系统,不同的概念塑造与切分将产生完全不同的设计成果,甚至影响到最终软件产品的工程质量与效率。当概念确定后,关系也随之确立,而关系的质量水平体现在解耦的程度上

笔者的感觉:当docker 出现的时候,作为一个java开发,笔者的感觉是很弱的,认为更多是运维领域的一次变革。然后出来了Service Mesh,加上更激进的Serverless,这次开发真的摊上事儿了。“资源的按需使用、运行”从硬件打通到软件, 以前变革开发模式的,更多的是一个语言、框架,改造的是应用本身的开发效率。而现在是整个编程模式的革新,并且一开始就考虑了应用与应用之间的关系,应用的形态天生就是分布式的。cloud native