从一次 RPC 请求,探索 MOSN 的工作流程

蚂蚁金服开源 MOSN 核心概念解析 前言 MOSN 是一款使用 Go 语言开发的 Service Mesh 数据平面代理,2018 年 7 月由蚂蚁金服开源,开源地址 ,MOSN 旨在为服务提供分布式、模块化、可观察和智能化的代理能力。MOSN 是 Modular Observable Smart Network 的简称。MOSN 可以与任何支持 xDS API 的 Service Mesh 集成,亦可以作为独立的四、七层负载均衡使... 阅读详情

589492c7a2e334cafda9cd3b4408165a.gif

王程铭(呈铭)

蚂蚁集团技术工程师,Apache Committer

专注 RPC、Service Mesh 和云原生等领域。

本文  7368  字,预计阅读  15  分钟

前言

MOSN(Modular Open Smart Network)是一款主要使用 Go 语言开发的云原生网络代理平台,由蚂蚁集团开源并经过了双十一大促几十万容器的生产级验证。

MOSN 为服务提供多协议、模块化、智能化、安全的代理能力,融合了大量云原生通用组件,同时也可以集成 Envoy 作为网络库,具备高性能、易扩展的特点。MOSN 可以和 Istio 集成构建 Service Mesh,也可以作为独立的四、七层负载均衡,API Gateway、云原生 Ingress 等使用。

MOSN 作为数据面,整体由 NET/IO、Protocol、Stream、Proxy 四个层次组成,其中:

  • NET/IO 用于底层的字节流传输

  • Protocol 用于协议的 decode/encode

  • Stream 用于封装请求和响应,在一个 conn 上做连接复用

  • Proxy 做 downstream 和 upstream 之间 stream 的转发

那么 MOSN 是如何工作的呢?下图展示的是使用 Sidecar 方式部署运行 MOSN 的示意图,服务和 MOSN 分别部署在同机部署的 Pod 上, 您可以在配置文件中设置 MOSN 的上游和下游协议,协议可以在 HTTP、HTTP2.0 以及 SOFARPC 等中选择。

84b5d708858154b33caff68a61c4da4d.jpeg

以上内容来自官网 https://mosn.io

RPC 场景下 MOSN 的工作机制

RPC 场景下,MOSN 的工作机制示意图如下:

6bd8e2578ca772f43bb356bd27320891.png

我们简单理解一下上面这张图的意义:

1. Server 端 MOSN 会将自身 ingress 的协议端口写入到注册中心;

2. Client 端 MOSN 会从注册中心订阅地址列表,第一次订阅也会返回全量地址列表,端口号是 Server 端 ingress 绑定的端口号;

3. 注册中心会实时推送地址列表变更到 Client 端(全量);

4. Client 端发起 rpc 调用时,请求会被 SDK 打到本地 Client 端 MOSN 的 egress 端口上;

5. Client 端 MOSN 将 RPC 请求通过网络转发,将流量通过负载均衡转发到某一台 Server 端 MOSN 的 ingress 端口处理;

6. 最终到了 Server 端 ingress listener,会转发给本地 Server 应用;

7. 最终会根据原来的 TCP 链路返回。

全局视野下的 MOSN 工作流程

现在我们已经了解了 MOSN 的工作机制,那么 MOSN 作为 MESH 的数据面,是怎么进行流量拦截并且将响应原路返回的呢?

outside_default.png

为了方便大家理解,我将以上时序图内容进行拆分,我们一一攻破。

3.1 建立连接

MOSN 在启动期间,会暴露本地 egress 端口接收 Client 的请求。MOSN 会开启 2 个协程,分别死循环去对 TCP 进行读取和写处理。MOSN 会通过读协程获取到请求字节流,进入 MOSN 的协议层处理。

// 代码路径 mosn.io/mosn/pkg/network/connection.go
func (c *connection) Start(lctx context.Context) {
  // udp downstream connection do not use read/write loop
  if c.network == "udp" && c.rawConnection.RemoteAddr() == nil {
    return
  }
  c.startOnce.Do(func() {
    // UseNetpollMode = false
    if UseNetpollMode {
      c.attachEventLoop(lctx)
    } else {
      // 启动读/写循环
      c.startRWLoop(lctx)
    }
  })
}


func (c *connection) startRWLoop(lctx context.Context) {
  // 标记读循环已经启动
  c.internalLoopStarted = true


  utils.GoWithRecover(func() {
    // 开始读操作
    c.startReadLoop()
  }, func(r interface{}) {
    c.Close(api.NoFlush, api.LocalClose)
  })
  // 省略。。。
}

3.2  Protocol 处理

Protocol 作为多协议引擎层,对数据包进行检测,并使用对应协议做 decode/encode 处理。MOSN 会循环解码,一旦收到完整的报文就会创建与其关联的 xstream,用于保持 tcp 连接用于后续响应。

// 代码路径 mosn.io/mosn/pkg/stream/xprotocol/conn.go
func (sc *streamConn) Dispatch(buf types.IoBuffer) {
  // decode frames
  for {
    // 协议 decode,比如 dubbo、bolt 协议等
    frame, err := sc.protocol.Decode(streamCtx, buf)


    if frame != nil {
      // 创建和请求 frame 关联的 xstream,用于保持 tcp 连接用于后续响应
      sc.handleFrame(streamCtx, xframe)
    }
  }
}


func (sc *streamConn) handleFrame(ctx context.Context, frame api.XFrame) {
  switch frame.GetStreamType() {
  case api.Request:
    // 创建和请求 frame 关联的 xstream,用于保持 tcp 连接用于后续响应,之后进入 proxy 层
    sc.handleRequest(ctx, frame, false)
  }
}


func (sc *streamConn) handleRequest(ctx context.Context, frame api.XFrame, oneway bool) {
  // 创建和请求 frame 关联的 xstream
  serverStream := sc.newServerStream(ctx, frame)
  // 进入 proxy 层并创建 downstream
  serverStream.receiver = sc.serverCallbacks.NewStreamDetect(serverStream.ctx, sender, span)
  serverStream.receiver.OnReceive(serverStream.ctx, frame.GetHeader(), frame.GetData(), nil)
}

3.3  Proxy 层处理

proxy 层负责 filter 请求/响应链、路由匹配、负载均衡最终将请求转发到集群的某台机器上。

  downstream 部分  

// 代码路径 mosn.io/mosn/pkg/proxy/downstream.go
func (s *downStream) OnReceive(ctx context.Context, headers types.HeaderMap, data types.IoBuffer, trailers types.HeaderMap) {
  s.downstreamReqHeaders = headers
  // filter 请求/响应链、路由匹配、负载均衡
  phase = s.receive(s.context, id, phase)
}


func (s *downStream) receive(ctx context.Context, id uint32, phase types.Phase) types.Phase {
  for i := 0; i <= int(types.End-types.InitPhase); i++ {
    s.phase = phase


    switch phase {


    // downstream filter 相关逻辑
    case types.DownFilter:
      s.printPhaseInfo(phase, id)
      s.tracks.StartTrack(track.StreamFilterBeforeRoute)


      s.streamFilterChain.RunReceiverFilter(s.context, api.BeforeRoute,
        s.downstreamReqHeaders, s.downstreamReqDataBuf, s.downstreamReqTrailers, s.receiverFilterStatusHandler)
      s.tracks.EndTrack(track.StreamFilterBeforeRoute)


      if p, err := s.processError(id); err != nil {
        return p
      }
      phase++


    // route 相关逻辑
    case types.MatchRoute:
      s.printPhaseInfo(phase, id)


      s.tracks.StartTrack(track.MatchRoute)
      s.matchRoute()
      s.tracks.EndTrack(track.MatchRoute)


      if p, err := s.processError(id); err != nil {
        return p
      }
      phase++
      
    // 在集群中选择一个机器、包含cluster和loadblance
    case types.ChooseHost:
      s.printPhaseInfo(phase, id)


      s.tracks.StartTrack(track.LoadBalanceChooseHost)
      // 这里很重要,在选中一个机器之后,这里upstreamRequest对象有两个作用
      // 1. 这里通过持有downstream保持着对客户端app的tcp引用,用来接收请求
      // 2. 转发服务端tcp引用,转发客户端app请求以及响应服务端response时的通知
      s.chooseHost(s.downstreamReqDataBuf == nil && s.downstreamReqTrailers == nil)
      s.tracks.EndTrack(track.LoadBalanceChooseHost)


      if p, err := s.processError(id); err != nil {
        return p
      }
      phase++
    }
  }
}

  upstream 部分  

至此已经选中一台服务端的机器,开始准备转发。

// 代码路径 mosn.io/mosn/pkg/proxy/upstream.go
func (r *upstreamRequest) appendHeaders(endStream bool) {


  if r.downStream.oneway {
    _, streamSender, failReason = r.connPool.NewStream(r.downStream.context, nil)
  } else {
    // 会使用 ChooseHost 中选中的机器 host 创建 sender,xstream 是客户端的流对象
    _, streamSender, failReason = r.connPool.NewStream(r.downStream.context, r)
  }
}

接下来会到达 conn.go 的 handleFrame 的 handleResponse 方法,此时 handleResponse 方法继续调用 downStream 的 receiveData 方法接收数据。

//代码路径 mosn.io/mosn/pkg/stream/xprotocol/conn.go
func (sc *streamConn) handleFrame(ctx context.Context, frame api.XFrame) {
  switch frame.GetStreamType() {
  case api.Response:
    // 调用 downStream 的 receiveData 方法接收数据
    // 因为 mosn 在转发之前修改了请求id,因此会重新 encode 请求
    sc.handleResponse(ctx, frame)
  }
}

一旦准备好转发就会通过 upstreamRequest 选择的下游主机直接发送 write 请求,请求的协程此时会被阻塞。

// 代码路径 mosn.io/mosn/pkg/stream/xprotocol/stream.go
func (s *xStream) endStream() {
  defer func() {
    if s.direction == stream.ServerStream {
      s.DestroyStream()
    }
  }()


  if log.Proxy.GetLogLevel() >= log.DEBUG {
    log.Proxy.Debugf(s.ctx, "[stream] [xprotocol] connection %d endStream, direction = %d, requestId = %v", s.sc.netConn.ID(), s.direction, s.id)
  }


  if s.frame != nil {
    // replace requestID
    s.frame.SetRequestId(s.id)
    // 因为 mosn 在转发之前修改了请求 id,因此会重新 encode 请求
    buf, err := s.sc.protocol.Encode(s.ctx, s.frame)
    if err != nil {
      log.Proxy.Errorf(s.ctx, "[stream] [xprotocol] encode error:%s, requestId = %v", err.Error(), s.id)
      s.ResetStream(types.StreamLocalReset)
      return
    }


    tracks := track.TrackBufferByContext(s.ctx).Tracks


    tracks.StartTrack(track.NetworkDataWrite)
    // 一旦准备好转发就会通过upstreamRequest选择的下游主机直接发送 write 请求,请求的协程此时会被阻塞
    err = s.sc.netConn.Write(buf)
    tracks.EndTrack(track.NetworkDataWrite)
    }
  }
}

3.4  准备将响应写回客户端

接下来客户端 xstream 将通过读协程接收响应的字节流,proxy.go 的 OnData 方法作为 proxy 层的数据接收点。

// 代码位置 mosn.io/mosn/pkg/proxy/proxy.go
func (p *proxy) OnData(buf buffer.IoBuffer) api.FilterStatus {
  // 这里会做两件事
  // 1. 调用 protocol 层进行decode
  // 2. 完成后通知upstreamRequest对象,唤醒downstream阻塞的协程
  p.serverStreamConn.Dispatch(buf)


  return api.Stop
}


// 代码位置 mosn.io/mosn/pkg/proxy/upstream.go
func (r *upstreamRequest) OnReceive(ctx context.Context, headers types.HeaderMap, data types.IoBuffer, trailers types.HeaderMap) {
  // 结束当前stream
  r.endStream()


  // 唤醒
  r.downStream.sendNotify()
}

downstream 被唤醒处理收到的响应,重新替换回正确的请求 ID,并调用 protocol 层重新编码成字节流写回客户端,最后销毁请求相关的资源,流程执行完毕。

// 比如我的 demo 是 dubbo 协议
func encodeFrame(ctx context.Context, frame *Frame) (types.IoBuffer, error) {


  // 1. fast-path, use existed raw data
  if frame.rawData != nil {
    // 1.1 replace requestId
    binary.BigEndian.PutUint64(frame.rawData[IdIdx:], frame.Id)


    // hack: increase the buffer count to avoid premature recycle
    frame.data.Count(1)
    return frame.data, nil
  }


  // alloc encode buffer
  frameLen := int(HeaderLen + frame.DataLen)
  buf := buffer.GetIoBuffer(frameLen)
  // encode header
  buf.WriteByte(frame.Magic[0])
  buf.WriteByte(frame.Magic[1])
  buf.WriteByte(frame.Flag)
  buf.WriteByte(frame.Status)
  buf.WriteUint64(frame.Id)
  buf.WriteUint32(frame.DataLen)
  // encode payload
  buf.Write(frame.payload)
  return buf, nil
}

总结

本文以工作中非常常见的一个思路为出发点,详细描述了 MOSN 内部网络转发的详细流程,希望可以帮助小伙伴加深对 MOSN 的理解。

MOSN 是一款非常优秀的开源产品。MOSN 支持多种网络协议(如HTTP/2, gRPC, Dubbo 等),并且能够很容易地增加对新协议的支持;MOSN 提供了丰富的流量治理功能,例如限流、熔断、重试、负载均衡等;MOSN 在性能方面进行了大量优化,比如内存零拷贝、自适应缓冲区、连接池、协程池等,这些都有助于提升其在高并发环境下的表现。此外在连接管理方面,MOSN 设计了多协议连接池;在内存管理方面,MOSN 在 sync.Pool 之上封装了一层资源对的注册管理模块,可以方便的扩展各种类型的对象进行复用和管理。总的来说,MOSN 的设计体现了可扩展性、高性能、安全性以及对现代云环境的适应性等多方面的考虑。

对于开发者来说,深入研究 MOSN 的代码和架构,无疑可以学到很多关于高性能网络编程和云原生技术的知识。MOSN 社区欢迎您的加入!

  • MOSN 官网:https://mosn.io/

  • MOSN Github:https://github.com/mosn/mosn

f953581bce51073cc9fb8ab2e55c74dc.png

MOSN:基于延迟负载均衡算法实现更快速、更稳定的分布式网络 总结起来,MOSN作为一个基于延迟负载均衡算法的分布式网络代理,通过优化请求分发和选择最佳服务器的过程,实现了更快速、更稳定的分布式网络服务。MOSN利用延迟负载均衡算法实现了更快速的请求分发,并且通过一系列的优化措施,保证了系统的稳定性和可靠性。连接池中保存着与后端服务器的连接,当有新的请求到达时,MOSN会从连接池中选择一个可用的连接,并将请求发送到对应的服务器。通过上述的延迟负载均衡算法的实现,MOSN能够快速、准确地选择最佳的服务器,并将请求发送到该服务器,从而提高了系统的处理速度和性能。 阅读详情

相关推荐

深入了解MOSN云原生网络数据平面源码 v0.21.0

本文还有配套的精品资源,点击获取 简介:MOSN(Mesh Over Service Network)是一个面向服务网格的数据平面,用于提供灵活的服务间通信解决方案。本源码解析文档详细介绍了v0.21.0版本的MOSN,它是一个高度可扩展、高性能的云原生网络代理。文档涵盖了MOSN的设计理念、核心架构、服务发现机制、负载均衡策略、安全特性,以及如何阅读源码和参与社区贡献。此...

weixin_42524864的博客 1293

MOSN 反向通道详解

目前例如 SuperEdge、Yurttunnel 等业界知名云边协同开源框架,对于云边通信的实现方案都是基于反向通道。本文将着重介绍 MOSN 之上的反向通道运作流程和原理。

金融级分布式架构 586

飞书多维表格+影刀RPA:我如何用3个指令搞定每周的销售数据自动汇总(附完整配置截图)

本文详细介绍了如何利用飞书多维表格和影刀RPA实现销售数据的自动化汇总,通过三个核心指令(建立链接、列出记录、更新记录)简化繁琐的手工操作。文章包含完整的配置截图和实战指南,帮助用户快速部署自动化流程,提升工作效率。

weixin_29273849的博客 285

MOSN 多协议扩展开发实践

Service Mesh 是当今云原生的关键部分,蚂蚁已经在生产环境完成了大规模的落地,但是业界整体 Service Mesh 改造程度还不高。其中平稳的进行 Mesh 化改造是可以对已上...

金融级分布式架构 462

GlobalPlatform Technology Secure Channel Protocol ‘03‘ 标准 - 安全通道协议简介

按照GlobalPlatform Technology Secure Channel Protocol '03' (SCP03)标准,描述了如何利用S-MAC,S-RMAC,S-ENC进行安全通信的过程。

mmmx777的专栏 6091

ChatGPT设置密钥后Codex免手机验证:配置顺序与身份凭证复用机制

API Key 是一种用于身份识别的凭证,其核心原理是通过预配置的密钥替代交互式登录流程。在开发工具中,密钥认证优先级通常高于会话认证,当本地存在有效密钥时,工具会直接复用该凭证,从而减少重复验证环节。这种机制的技术价值在于提升开发效率与配置一致性,尤其适用于多设备切换、CI/CD 流水线及编程辅助工具等场景。以 Codex 为例,在 ChatGPT 界面提前配置 API 密钥后,Codex 启动时可读取持久化存储的密钥,避免触发手机号验证,实现身份凭证的跨入口复用。

weixin_33940469的博客 474

社区文章|MOSN 路由框架详解

文|曹先胜e签宝中间件开发负责 e签宝中间件开发和维护包括 MQ、网关、微服务、数据同步、全链路压测等本文4827字 阅读7分钟01贡献者前言MOSN「 开源就是在使用中,共同...

金融级分布式架构 1212

Python爬虫抓取学术期刊数据(Springer、Elsevier)

本文详细介绍了如何使用Python爬虫抓取学术期刊网站(如Springer、Elsevier)上的文章信息,并进行数据清洗和存储。我们使用了requestsSeleniumpandas等技术,通过模拟浏览器行为来绕过反爬虫机制,并将数据保存为Excel文件,方便后续分析。未来,我们可以通过加入更多的期刊网站数据源,扩展爬虫的功能,抓取更多的学术数据。同时,结合自然语言处理(NLP)技术,可以对抓取的文章进行自动化的摘要提取和主题分类,为学术研究提供更多的支持。

2201_76125261的博客 1487

SOFA Weekly | MOSN & SOFARPC 发布、MOSN 社区活动报名

SOFA WEEKLY | 每周精选,筛选每周精华问答同步开源进展,欢迎留言互动SOFAStack(ScalableOpenFinancialArchitecture Stack)...

金融级分布式架构 373

【数字IC验证进阶】正则表达式(Regular Expression)快速入门指南

在芯片开发过程中,正则表达式的使用非常常见。初次上手晦涩难懂,多用几次爱不释手!

悟已往之不谏 知来者之可追 1441

Labview界面多按钮控件的一种处理方法

当界面中存在多个按钮控件时候,此时如果逐个为每个控件添加事件条件则会显得较为麻烦,此处提供了一种对多控件进行批量处理的方法

miracleis的博客 2702

直播预告:MOSN 的多协议机制解析

作为云原生网络代理,Service Mesh 是 MOSN 的重要应用场景。随着 Service Mesh 概念的日益推广,大家对这套体系都已经不再陌生...

ServiceMesher 353

UG NX二次开发(C++)-NX2406系列二次开发编程模板配置

前面已经写了有关UG NX二次开发编程模板配置的文章,但是由于NX2406/2412系列的版本中,在UGOpen文件夹中没有了vs_files文件夹了,而是采用了VSIX Project的方式配置(其适用于VS2019),在VS2022中不能正确的配置。我结合以前配置模板的经验和现在的配置方式讲一下NX2406系列二次开发编程模板的配置。我把相应的编程模板放在资源文件UG NX二次开发编程模板(基于NX2406版本制作)中,方便大家下载使用。

GimiGimmy 2640

MOSN 1.0 发布,开启新架构演进

MOSN 是一款主要使用 Go 语言开发的云原生网络代理平台,由蚂蚁集团开源,经过双 11 大促几十万容器的生产级验证。 经过 4 年的蓬勃发展,在 11 位 commiter,100 多个 contributor 和整个社区的共同努力下,经历 27 个小版本的迭代,MOSN 1.0 版本正式发布了。

蚂蚁金服技术团队 590

Jenkins部署前后端分离项目最全图文教程(手把手教学)

最近Jenkins部署的热度比较高,于是就想出一篇关于我是如何使用Jenkins部署前后端分离项目的,本篇记录了我是如何一步一步去配置、搭建和部署的完整流程,每一行代码都进行了实测和讲解,通过图文的教学写成博客分享给大家!

黄团团的个人博客 4780

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

SOFA Weekly|MOSN、Layotto 社区会议通知、Seata 版本发布

SOFA WEEKLY | 每周精选筛选每周精华问答,同步开源进展欢迎留言互动~SOFAStack(ScalableOpenFinancialArchitecture Stack)是蚂蚁集团自主研发的金融级云原生架构,包含了构建金融级云原生架构所需的各个组件,包括微服务研发框架,RPC 框架,服务注册中心,分布式定时任务,限流/熔断框架,动态配置推送,分布式链路追踪,Metrics 监控...

金融级分布式架构 434

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

SOFA Weekly | MOSN、Seata 发布新版本、MOSN 相关阅读整理

SOFA WEEKLY | 每周精选,筛选每周精华问答同步开源进展,欢迎留言互动SOFAStack(ScalableOpenFinancialArchitecture Stack)...

金融级分布式架构 339

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

MOSN(Modular Open Smart Network)-00-聊一聊 MOSN

MOSN(Modular Open Smart Network)是由蚂蚁集团(原蚂蚁金服)于2018年7月开源的一款云原生网络代理平台,使用Go语言开发。其核心定位是为服务提供分布式、模块化、可观察且智能化的代理能力,主要应用于Service Mesh的数据平面(https://github.com/sofastack/sofa-mosn)(https://mosn.io/)。名称中的“Open”和“Smart”体现了其开放生态与智能化流量管理的特点。

1507

云原生网络代理 MOSN 多协议机制解析

本文根据 SOFAChannel#13 直播分享整理,主题:云原生网络代理 MOSN 多协议机制解析,查看视频回顾,https://tech.antfi...

ServiceMesher 605

记一次在 MOSN 对 Dubbo、Dubbo-go-hessian2 的性能优化

背景蚂蚁金服内部对 Service Mesh 的稳定性和性能要求是比较高的,内部 MOSN 广泛用于生产环境。在云上和开源社区,RPC 领域 Dubbo 和 Spring Cloud 同...

ServiceMesher 604

MOSN(Modular Open Smart Network)-02-核心概念

大家好,我是老马。sofastack 其实出来很久了,第一次应该是在 2022 年左右开始关注,但是一直没有深入研究。最近想学习一下 SOFA 对于生态的设计和思考。

793

曹大谈 dubbo mesh : 在 MOSN 中玩转 dubbo-go

service mesh 简介 service mesh 本身的理念并不复杂,就是将现代微服务应用的功能性与非功能性需求进行分离,并将非功能性需求下沉到应用的外部模块,从而使应用模块可以尽量聚焦于业务,不用关心诸如:服务发现、限流、熔断、tracing 这类非业务需求。下沉之后,相关的 service mesh 模块可以交由基础架构团队进行维护,使基础设施和业务能够完成解耦。 service mesh 设计一般划分为两个模块,控制面和数据面。可以通过下图来理解相应的职责: 对于应用来说,所有流量都会经过

joke59的博客 945

SOFA Weekly | QA 整理、Layotto 本周 Contributor、MOSN 本周发布

SOFA WEEKLY | 每周精选筛选每周精华问答,同步开源进展欢迎留言互动~SOFAStack(ScalableOpenFinancialArchitecture Stack...

金融级分布式架构 332

SOFA Weekly | MOSN 社区会议、本周 Contributor、QA 整理

SOFA WEEKLY | 每周精选筛选每周精华问答,同步开源进展欢迎留言互动~SOFAStack(ScalableOpenFinancialArchitecture Stack...

金融级分布式架构 1910
上一篇: SOFA Weekly|Koupleless 社区会议回顾、社区本周贡献、SOFA 聊天室、本周推荐阅读...
下一篇: 容器安全的贴身保镖:容器运行时(下)
SOFAStack
博客等级 码龄7年 747粉丝 389原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值