当前位置:首页 > 公众号精选 > 架构师社区
[导读]有幸参加了 Flomesh[1] 组织的workshop,了解了他们的Pipy网络代理,以及围绕Pipy构建起来的生态。Pipy在生态中,不止是代理的角色,还是Flomesh服务网格中的数据平面。整理一下,做个记录,顺便瞄一下Pipy的部分源码。介绍下面是摘自Github上关于P...

有幸参加了 Flomesh[1] 组织的workshop,了解了他们的 Pipy 网络代理,以及围绕 Pipy 构建起来的生态。Pipy 在生态中,不止是代理的角色,还是 Flomesh 服务网格中的数据平面。

整理一下,做个记录,顺便瞄一下 Pipy 的部分源码。

介绍

下面是摘自 Github 上关于 Pipy 的介绍:

Pipy 是一个轻量级、高性能、高稳定、可编程的网络代理。Pipy 核心框架使用 C 开发,网络 IO 采用 ASIO 库。Pipy 的可执行文件仅有 5M 左右,运行期的内存占用 10M 左右,因此 Pipy 非常适合做 Sidecar proxy。

Pipy 内置了自研的 pjs 作为脚本扩展,使得Pipy 可以用 JS 脚本根据特定需求快速定制逻辑与功能。

Pipy 采用了模块化、链式的处理架构,用顺序执行的模块来对网络数据块进行处理。这种简单的架构使得 Pipy 底层简单可靠,同时具备了动态编排流量的能力,兼顾了简单和灵活。通过使用 REUSE_PORT 的机制(主流 Linux 和 BSD 版本都支持该功能),Pipy 可以以多进程模式运行,使得 Pipy 不仅适用于 Sidecar 模式,也适用于大规模的流量处理场景。在实践中,Pipy 独立部署的时候用作“软负载”,可以在低延迟的情况下,实现媲美硬件的负载均衡吞吐能力,同时具有灵活的扩展性。

Pipy 的核心是消息流处理器:

Pipy 流量处理的流程:

核心概念

流(Stream)管道(Pipeline)模块(Module)会话(Session)上下文(Context)

以下是个人浅见

Pipy 使用 pjs 引擎将 JavaScript格式的配置,解析成其抽象的 Configuration 对象。每个 Configuration 中包含了多个 Pipeline,每个 Configuration 中又会用到多个 Filter。这些都属于 Pipy 的静态配置部分。(后面会提到 Pipeline 的三种不同类型)

而属于运行时的就是流、会话和上下文了,在 Pipy 中,数据流是由对象(Pipy 的抽象)组成的。而这些对象抵达 Pipy,被抽象成不同的事件。而事件触发不同的过滤器的执行。

我个人更喜欢将其核心理解为:对数据流的事件处理引擎。

理解归理解,实践出真知。“大胆假设,小心求证!”

本地编译

从编译 Pipy 开始。

环境准备

#安装 nodejs$ nvm install lts/erbium #安装 cmake$ brew install cmake

编译 Pipy

从 https://github.com/flomesh-io/pipy.git 克隆代码。

Pipy 的编译包括了两个部分,GUI 和 Pipy 本体。

GUI 是 Pipy 提供的一个用于开发模式下进行配置的界面,首先编译Pipy GUI。

# pipy root folder$ cd gui$ npm install$ npm run build接着编译 Pipy 的本体

# pipy root folder$ mkdir build$ cd build$ cmake -DCMAKE_BUILD_TYPE=Release -DPIPY_GUI=ON ..$ make完成后检查根目录下的 bin 目录,可以看到 pipy 的可执行文件,大小只有 11M。

$ bin/pipy --helpUsage: pipy [options] <script filename>Options: -h, -help, --help Show help information -v, -version, --version Show version information --list-filters List all filters --help-filters Show detailed usage information for all filters --log-level=<debug|info|warn|error> Set the level of log output --verify Verify configuration only --reuse-port Enable kernel load balancing for all listening ports --gui-port=<port> Enable web GUI on the specified port

Demo:Hello Pipy

开发模式下可以让 Pipy 携带 GUI 启动,通过 GUI 进行配置。

#指定 gui 的端口为 6060,从 test 目录中加载配置$ bin/pipy --gui-port=6060 test/2021-05-30 22:48:41 [info] [gui] Starting GUI service...2021-05-30 22:48:41 [info] [listener] Listening on 0.0.0.0:6060浏览器中打开

配置界面

展开 002-hello 子目录点选 pipy 并点击运行按钮:

$ curl -i localhost:6080HTTP/1.1 200 OKConnection: keep-aliveContent-Length: 7Hello!

Pipy 过滤器

通过 pipe 的命令可以输出其支持的过滤器列表,一共 31 个。通过将一系列过滤器进行组装,可以实现复杂的流处理。

比如 007-logging 的配置实现了日志的功能:记录请求和响应的数据,并批量发送到 ElasticSearch。这里就用到了 forkconnectonSessionStartencodeHttpRequestdecodeHttpRequestonMessageStartonMessagedecodeHttpResponsereplaceMessagelinkmuxtask 等十多种过滤器。

$ bin/pipy --list-filtersconnect (target[, options]) Sends data to a remote endpoint and receives data from itdemux (target) Sends messages to a different pipline with each one in its own session and contextdecodeDubbo () Deframes a Dubbo messagedecodeHttpRequest () Deframes an HTTP request messagedecodeHttpResponse () Deframes an HTTP response messagedummy () Eats up all eventsdump ([tag]) Outputs events to the standard outputencodeDubbo ([head]) Frames a Dubbo messageencodeHttpRequest ([head]) Frames an HTTP request messageencodeHttpResponse ([head]) Frames an HTTP response messageexec (command) Spawns a child process and connects to its input/outputfork (target[, sessionData]) Sends copies of events to other pipeline sessionslink (target[, when[, target2[, when2, ...]]]) Sends events to a different pipelinemux (target[, selector]) Sends messages from different sessions to a shared pipeline sessiononSessionStart (callback) Handles the initial event in a sessiononData (callback) Handles a Data eventonMessageStart (callback) Handles a MessageStart eventonMessageEnd (callback) Handles a MessageEnd eventonSessionEnd (callback) Handles a SessionEnd eventonMessageBody (callback) Handles a complete message bodyonMessage (callback) Handles a complete message including the head and the bodyprint () Outputs raw data to the standard outputreplaceSessionStart (callback) Replaces the initial event in a sessionreplaceData ([replacement]) Replaces a Data eventreplaceMessageStart ([replacement]) Replaces a MessageStart eventreplaceMessageEnd ([replacement]) Replaces a MessageEnd eventreplaceSessionEnd ([replacement]) Replaces a SessionEnd eventreplaceMessageBody ([replacement]) Replaces an entire message bodyreplaceMessage ([replacement]) Replaces a complete message including the head and the bodytap (quota[, account]) Throttles message rate or data rateuse (module, pipeline[, argv...]) Sends events to a pipeline in a different modulewait (condition) Buffers up events until a condition is fulfilled

原理

“Talk is cheap, show me the code.”

配置加载

个人比较喜欢看源码来理解实现,即使是 C 。从浏览器请求入手发现运行时向/api/program 发送了 POST 请求,请求的内容是配置文件的地址。

检查源码后,找到逻辑的实现在 src/gui.cpp:189

1.创建新的 worker2.加载配置,将 JavaScrip 代码解析成 Configuration 对象3.启动 worker,执行Configuration::apply()4.卸载旧的 worker

从 src/api/configuration.cpp:267 处看:pipelinelisten 和 task 配置实际在 Pipy 的配置中都是被抽象为 Pipeline 对象,只是在类型上有差异分别为:NAMEDLISTEN 和 TASK。比如 listen 中可以通过 fork 过滤器将事件的副本发送到指定的 pipeline 中。

基于数据流事件的处理

src/inbound.cpp:171

结语

Pipy 虽小(只有 11M),但以其可编程的特性提供了灵活的配置能力,潜力无限。

Pipy 像处理 HTTP 一样处理任意的七层协议。内部版本支持Dubbo、Redis、Socks 等,目前正在迁移到开源版本。

期待即将开源的 Portal,以及服务网格 Flomesh。持续关注,后面考虑再写几篇。

“未来可期!”

引用链接

[1] Flomesh: https://flomesh.cn/

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

学好电子技术基础知识,如电路基础、模拟电路、数字电路和微机原理。这几门课程都是弱电类专业的必修课程,学会这些后能保证你看懂单片机电路、知道电路的设计思路和工作原理;

关键字: 单片机 编程 电路设计

单片机编程需要使用专门的软件工具,这些工具能够帮助程序员编写、调试和烧录程序到单片机中。以下是一些常用的单片机编程软件:

关键字: 单片机 编程 软件工具

Java语言和C语言是两种不同的编程语言,它们在语法、特性和应用领域上有许多差别。下面将详细介绍Java语言和C语言之间的差异以及它们各自的技术特点。

关键字: Java语言 C语言 编程

嵌入式系统是现代生活中无处不在的一部分。它们包括了我们的家电、汽车、智能手机、医疗设备等等。这些系统的工作必须高效、可靠,因为它们往往控制着生活中的关键方面。而C语言作为一种广泛用于嵌入式系统开发的编程语言,其质量和稳定...

关键字: 嵌入式系统 C语言 编程

在嵌入式系统开发领域中,C语言是使用最广泛的编程语言之一。它具有高效、灵活和可移植的特点,成为嵌入式系统设计师的首选语言。本文将介绍C语言编程的基本概念、特点以及在嵌入式系统开发中的应用。

关键字: 嵌入式系统 C语言 编程

在编程和计算中,运算符优先级是解释和计算表达式的一个关键因素。本文旨在阐述运算符优先级的概念、规则及其在表达式中的应用,以帮助读者更好地理解和运用运算符优先级。

关键字: 表达式 运算符 编程

泰克科技组合软件总经理Rick Khulman:“激发孩子们——尤其是女孩们对STEM的兴趣,对我本人乃至广大工程界都至关重要。”

关键字: 编程 机器人 示波器

PIC单片机采用精简指令集,例如对于PIC16F716单片机,只有35条单字节指令。要用这么少的指令实现复杂的控制或计算,显然要在程序设计上多做文章,以下就程序设计需要注意的问题谈一些看法。 美国微芯公司开发的CMOS工...

关键字: 单片机 控制 编程

PLC编程是一种数字运算操作的电子系统,专为在工业环境下应用而设计。它采用可编程序的存储器,用来在其内部存储执行逻辑运算、顺序控制、定时、计数和算术运算等操作的指令,并通过数字式、模拟式的输入和输出,控制各种类型的机械或...

关键字: plc 编程 plc编程

初学PLC梯形图编程,应要遵循一定的规则,并养成良好的习惯。下面以西门子PLC为例,简单介绍一下PLC梯形图编程时需要遵循的规则,希望对大家有所帮助。

关键字: 西门子 plc 编程
关闭
关闭