首页/新闻资讯/正文详情

Envoy 前端代理(Front Proxy)实战:基于 Docker Compose 的边缘反向代理与负载均衡指南

发布时间:2026/9/24 21:45:56 来源:云帆数科 栏目:资讯中心
Envoy 前端代理(Front Proxy)实战:基于 Docker Compose 的边缘反向代理与负载均衡指南
教程云原生容器编排【免费下载链接】kubernetes-handbookKubernetes 架构与生态从云原生到 AI 原生基础设施的构建指南项目地址https://gitcode.com/gh_mirrors/ku/kubernetes-handbook点击查看免费下载导读本文以 Kubernetes Handbook 仓库中 usecases/envoy-front-proxy.md 为核心完整讲解如何使用 Envoy 作为前端边缘反向代理通过 Docker 容器与 docker-compose 在单机环境编排front-envoy、service1、service2三个服务从底层理解 Envoy 的路由、负载均衡与 admin 管理端点。读完本文你将掌握 Envoy 的 YAML 静态配置listener / cluster / admin、进程外out-of-process与无侵入式架构原理并为后续将 Envoy 作为 Istio Service Mesh 数据平面data plane打下扎实基础。Envoy 与前端代理的定位Envoy 是 Lyft 开源、使用 C 编写的 L7 代理和通信总线是 CNCF 旗下的毕业项目也是 Istio 服务网格默认的数据平面。其关键特性包括进程外架构不侵入应用进程、L3/L4 与 HTTP L7 filter 架构、HTTP/2 支持、L7 路由、动态配置xDS、最佳可观测性、front/edge proxy 支持、高级负载均衡、健康检查与服务发现等。从 usecases/envoy.md 可知Envoy 本身无法构成完整的 Service Mesh但可以作为 service mesh 中应用间流量的代理负责数据层。而前端代理正是 Envoy 支持的一种部署角色Edge envoy即流量进出 mesh 时的入口代理相当于 Kubernetes 中的 Ingress。与之相对的是随每个服务实例一起运行的Service envoy在 Kubernetes 中作为 Sidecar 与应用容器共存于同一 Pod详见 usecases/envoy-terminology.md。本文的示例正对应边缘反向代理这一角色Envoy 类似于 Nginx但与之不同的是它还可以作为进程伴随每个服务运行在同一个容器/Pod 中Sidecar 模式这也是它无侵入、进程外架构的体现。快速开始克隆 Envoy 源码Envoy 中的所有规则配置与 Kubernetes 一样都是通过 YAML 文件完成的。在继续之前先克隆 Envoy 的 GitHub 仓库git clone https://github.com/envoyproxy/envoy.gitEnvoy 官方提供了多个可直接使用docker-compose运行的打包用例sandbox代码位于 Envoy 仓库的examples目录下Front Proxy前端代理Zipkin TracingJaeger TracinggRPC Bridge本文的核心示例即取自其中的Front proxy用例envoy/examples/front-proxy。Front Proxy 示例的整体架构本示例的部署结构如下图所示此时 Envoy 作为反向代理运行在 mesh 边缘承担边缘网关的角色。从图中可以看到三组角色的分工front-envoy边缘前端Envoy监听 80 端口接收外部流量根据 URL 前缀将请求反向代理到后端的 service1 / service2同时暴露 8001 端口提供 admin 管理接口service1 / service2两个后端业务服务每个服务都与一个 service-envoy 共同运行示例中通过SERVICE_NAME环境变量区分实例编号对外只暴露 80 端口envoymesh 网络三个容器共享的自定义 docker 网络front-envoy通过 DNS 名称service1、service2发现后端。这与 usecases/envoy-terminology.md 中描述的 mesh 概念一致一组互相协调以提供一致网络拓扑的主机其中 edge envoy 负责流量进出service envoy 与应用进程无感知地共存。编写 docker-compose.yml 编排文件在此示例中一共有 3 个服务首先为其创建容器编排的docker-compose.yml文件version: 2 services: front-envoy: build: context: . dockerfile: Dockerfile-frontenvoy volumes: - ./front-envoy.yaml:/etc/front-envoy.yaml networks: - envoymesh expose: - 80 - 8001 ports: - 8000:80 - 8001:8001 service1: build: context: . dockerfile: Dockerfile-service volumes: - ./service-envoy.yaml:/etc/service-envoy.yaml networks: envoymesh: aliases: - service1 environment: - SERVICE_NAME1 expose: - 80 service2: build: context: . dockerfile: Dockerfile-service volumes: - ./service-envoy.yaml:/etc/service-envoy.yaml networks: envoymesh: aliases: - service2 environment: - SERVICE_NAME2 expose: - 80 networks: envoymesh: {}该编排文件的关键设计点网络别名aliasesservice1、service2在网络envoymesh中注册了 DNS 别名这使得front-envoy的 cluster 配置可以直接用主机名service1、service2寻址后端端口映射front-envoy将容器内 80 端口映射到宿主机的8000端口对外流量入口将 8001 端口直接透出admin 管理接口两个后端服务仅通过expose声明端口不映射到宿主机只能在envoymesh网络内部被访问配置挂载./front-envoy.yaml挂载到容器内/etc/front-envoy.yaml./service-envoy.yaml挂载到/etc/service-envoy.yaml实现配置与镜像分离。使用docker-compose up --build启动后三个服务都会处于frontproxy_envoymesh这个网络中网络名前缀为项目目录名从而保证相互可达。front-envoy 镜像与启动方式front-envoy使用Dockerfile-frontenvoy文件构建镜像内容如下FROM envoyproxy/envoy:latest RUN apt-get update apt-get -q install -y \ curl CMD /usr/local/bin/envoy -c /etc/front-envoy.yaml --service-cluster front-proxy该 Dockerfile 有两个值得注意的地方基础镜像为官方envoyproxy/envoy:latest并额外安装了curl方便在容器内做连通性验证启动命令中-c /etc/front-envoy.yaml指定静态配置文件由宿主机./front-envoy.yaml挂载进来--service-cluster front-proxy设置 Envoy 实例所属的服务集群名该名称会出现在统计信息中便于多实例场景下区分。front-envoy.yaml 静态配置详解/etc/front-envoy.yaml是本次示例的核心配置文件完整内容如下static_resources: listeners: - address: socket_address: address: 0.0.0.0 port_value: 80 filter_chains: - filters: - name: envoy.http_connection_manager config: codec_type: auto stat_prefix: ingress_http route_config: name: local_route virtual_hosts: - name: backend domains: - * routes: - match: prefix: /service/1 route: cluster: service1 - match: prefix: /service/2 route: cluster: service2 http_filters: - name: envoy.router config: {} clusters: - name: service1 connect_timeout: 0.25s type: strict_dns lb_policy: round_robin http2_protocol_options: {} hosts: - socket_address: address: service1 port_value: 80 - name: service2 connect_timeout: 0.25s type: strict_dns lb_policy: round_robin http2_protocol_options: {} hosts: - socket_address: address: service2 port_value: 80 admin: access_log_path: /dev/null address: socket_address: address: 0.0.0.0 port_value: 8001配置整体包含三大顶级配置项static_resources静态资源定义包含 listener监听器与 cluster集群两部分clustersenvoymesh 中的服务注册信息此处为静态注册也可通过 SDS/xDS 动态发现admin管理接口监听 8001 端口可通过/stats获取当前 Envoy 的统计信息通过/server_info获取版本信息。ListenerHTTP 连接管理器listeners定义 Envoy 监听的网络位置与流量处理链。示例中监听0.0.0.0:80通过filter_chains挂载一个envoy.http_connection_managerHTTP 连接管理器过滤器其中codec_type: auto自动协商 HTTP/1.1 与 HTTP/2 编解码stat_prefix: ingress_http统计信息前缀用于区分不同 listener 的度量route_config.virtual_hosts虚拟主机配置domains: [*]匹配所有域名routes内通过prefixURL 路径前缀与cluster目标集群建立映射/service/1→service1/service/2→service2http_filters中最后挂载envoy.router过滤器负责真正的路由转发动作。结合 usecases/envoy-terminology.md 中的术语说明virtual_hosts必须包含name服务名称、domainsDNS 域名必须能跟 virtual host 的 URL 匹配、routes路由列表每个路由可包含prefixURL 路径前缀、cluster处理请求的 envoy cluster、timeout_ms超时时间。这里的内联路由配置即为静态 RDS若采用动态配置则可由 Route Discovery ServiceRDS下发。Cluster服务发现与负载均衡clusters定义了一组逻辑上相似的上游主机。示例中service1与service2两个 cluster 的关键参数namecluster 名称即服务名称与路由中引用的 cluster 一一对应connect_timeout: 0.25s与上游建立连接的超时时间type: strict_dns服务发现类型Envoy 持续监听 DNS每个匹配的 A 记录都认定为有效主机DNS 解析出的每个 IP 都会加入 clusterlb_policy: round_robin负载均衡策略轮询访问各上游主机http2_protocol_options: {}启用 HTTP/2 上游协议支持Envoy 对上游默认优先协商 HTTP/2hosts上游主机地址列表此处通过 socket_address 指定 DNS 名称service1:80、service2:80。关于type服务发现方式usecases/envoy-terminology.md 汇总了四种取值static静态配置监听 cluster 中列出的所有主机strict_dnsEnvoy 持续监听 DNS每个匹配的 A 记录都认定为有效logical_dnsEnvoy 使用 DNS 增加主机但即使 DNS 不再返回该主机也不会删除这些主机信息sdsService Discovery ServiceEnvoy 访问外部的 REST 接口获取 cluster 成员信息即 usecases/envoy-mesh-in-kubernetes-tutorial.md 中讨论的 SDS 方案用于发现服务的所有 endpoint 而非仅 ClusterIP。Admin管理接口admin块配置管理服务监听地址为0.0.0.0:8001access_log_path设为/dev/null关闭访问日志。启动后访问http://localhost:8001即可看到管理端点列表详见下文admin 端点一节。启动并验证环境在envoy/examples/front-proxy目录下执行$ pwd envoy/examples/front-proxy $ docker-compose up --build -d $ docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------------------------------- example_service1_1 /bin/sh -c /usr/local/bin/ ... Up 80/tcp example_service2_1 /bin/sh -c /usr/local/bin/ ... Up 80/tcp example_front-envoy_1 /bin/sh -c /usr/local/bin/ ... Up 0.0.0.0:8000-80/tcp, 0.0.0.0:8001-8001/tcp三个容器全部启动成功两个后端服务仅监听 80 端口front-envoy将宿主机的8000映射到容器 80流量入口、8001映射到容器 8001admin 接口。路由验证访问 service1http://localhost:8000/service/1$ curl -v localhost:8000/service/1 * Trying ::1... * TCP_NODELAY set * Connected to localhost (::1) port 8000 (#0) GET /service/1 HTTP/1.1 Host: localhost:8000 User-Agent: curl/7.54.0 Accept: */* HTTP/1.1 200 OK content-type: text/html; charsetutf-8 content-length: 89 server: envoy date: Fri, 20 Apr 2018 08:26:33 GMT x-envoy-upstream-service-time: 14 Hello from behind Envoy (service 1)! hostname: a3e4185a9a49 resolvedhostname: 172.18.0.4 * Connection #0 to host localhost left intact访问 service2http://localhost:8000/service/2时返回* Trying ::1... * TCP_NODELAY set * Connected to localhost (::1) port 8000 (#0) GET /service/2 HTTP/1.1 Host: localhost:8000 User-Agent: curl/7.54.0 Accept: */* HTTP/1.1 200 OK content-type: text/html; charsetutf-8 content-length: 89 server: envoy date: Fri, 20 Apr 2018 08:27:27 GMT x-envoy-upstream-service-time: 10 Hello from behind Envoy (service 2)! hostname: f6650e1911a0 resolvedhostname: 172.18.0.3 * Connection #0 to host localhost left intact响应特征印证了 Envoy 的路由与代理行为响应头中server: envoy表明流量确实经过 Envoy 转发x-envoy-upstream-service-time头记录了上游服务的处理耗时单位毫秒这是 Envoy 可观测性的一部分返回体中的hostname与resolvedhostname是后端示例应用打印的容器 ID 与解析到的 IP两者不同一个指向 service1一个指向 service2说明请求被正确路由到了对应的后端服务。负载均衡验证通过docker-compose scale将 service1 扩容到 3 个实例注意新版 docker-compose 中 scale 命令已废弃推荐使用up --scale参数$ docker-compose scale service13 WARNING: The scale command is deprecated. Use the up command with the --scale flag instead. Starting frontproxy_service1_1 ... done Creating frontproxy_service1_2 ... done Creating frontproxy_service1_3 ... done $ docker-compose ps Name Command State Ports --------------------------------------------------------------------------------------------------------------------------- frontproxy_front-envoy_1 /usr/bin/dumb-init -- /bin ... Up 10000/tcp, 0.0.0.0:8000-80/tcp, 0.0.0.0:8001-8001/tcp frontproxy_service1_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp frontproxy_service1_2 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp frontproxy_service1_3 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp frontproxy_service2_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp此时 service1 已有 3 个实例。循环访问 service1 观察负载均衡效果$ while true;do curl localhost:8000/service/1;sleep 1;done Hello from behind Envoy (service 1)! hostname: a3e4185a9a49 resolvedhostname: 172.18.0.4 Hello from behind Envoy (service 1)! hostname: fe44dba64122 resolvedhostname: 172.18.0.5 Hello from behind Envoy (service 1)! hostname: c5b9f1289e0f resolvedhostname: 172.18.0.6 Hello from behind Envoy (service 1)! hostname: a3e4185a9a49 resolvedhostname: 172.18.0.4 Hello from behind Envoy (service 1)! hostname: fe44dba64122 resolvedhostname: 172.18.0.5 Hello from behind Envoy (service 1)! hostname: c5b9f1289e0f resolvedhostname: 172.18.0.6三个不同 hostname对应三个容器实例循环出现说明round_robin轮询负载均衡已生效——这一策略正是在front-envoy.yaml的cluster配置项中通过lb_policy: round_robin声明的。值得注意的是这里的负载均衡发生在 Envoy 层由于strict_dns会持续解析service1的 DNS 记录Envoy 动态感知到了扩容后新增的容器地址并纳入轮询池。admin 端点与运维能力访问http://localhost:8001可以看到 Envoy admin 提供的管理 API 端点命令描述/Admin 主页/certs打印机器上的 certs/clustersupstream cluster 状态/config_dump输出当前的 Envoy 配置/cpuprofiler开启/关闭 CPU profiler/healthcheck/fail导致服务失败健康检查/healthcheck/ok导致服务通过健康检查/help打印管理命令的帮助信息/hot_restart_version打印热重启兼容版本/listeners打印 listener 地址/logging查询/更改日志级别/quitquitquit退出服务/reset_counters将计数器重置为 1/runtime打印运行时值/runtime_modify修改运行时值/server_info打印服务器版本/状态信息/stats打印服务器状态统计信息/stats/prometheus打印 prometheus 格式的服务器状态统计信息这些端点覆盖了日常运维的主要场景/stats与/stats/prometheus提供监控数据后者可直接被 Prometheus 抓取/config_dump可用于核对线上实际生效的配置/clusters查看上游集群健康与成员状态/logging动态调整日志级别/healthcheck/fail与/healthcheck/ok可人为触发健康检查失败/通过以测试故障转移逻辑。Enovy 通过这些管理 API 端点提供了运行时动态配置与观测能力。从前端代理到数据平面与 Istio 的衔接本示例的意义不止于单机实验。把 Envoy 部署在应用进程之外、与应用容器同 PodSidecar正是 Istio 数据平面的基本形态在 usecases/istio.md 的架构描述中数据平面由一组智能代理Envoy以 sidecar 模式部署协调和控制所有服务之间的网络通信控制平面负责管理和配置代理路由流量、执行策略仓库中的 manifests/istio/istio.yaml 展示了 Istio 的部署形态istio-ingress对应本示例中 front-envoy 的边缘入口角色、istio-manager负责 discovery即控制平面的配置下发、istio-mixer策略与遥测manifests/sofa-mesh/sofa-mesh-demo.yaml 中也可以看到istio-proxyenvoy容器的存在以及envoyfilters这类用于定制 Envoy 行为的 CRD 定义。在本示例中Envoy 的路由与 cluster 全部来自静态 YAML而在 Istio 中控制平面通过 xDSCDS/EDS/RDS/LDS 等发现服务将配置动态下发给 Envoy实现无重启的流量管理。理解了本示例中 listener 与 cluster 的静态配置逻辑再理解 Istio 的动态配置注入就水到渠成。小结通过 docker-compose 在单机运行 Envoy Front Proxy 示例我们可以得出以下与生产实践直接相关的结论进程外、无侵入Envoy 以独立进程运行在应用之外同一容器或同一 Pod应用代码无需任何改动即可获得代理、路由、负载均衡与可观测性能力YAML 驱动的声明式配置listener含 HTTP connection manager 与路由表、cluster服务发现 负载均衡策略、admin 三大配置块覆盖了边缘代理的核心能力边缘入口角色front-envoy 充当流量进出 mesh 的网关类似 Kubernetes Ingress支持基于 URL 前缀的路由与基于strict_dnsround_robin的动态负载均衡admin 端点提供运行时运维能力统计、配置导出、日志级别调整、健康检查开关等均可通过 8001 端口的 HTTP 端点完成为 Service Mesh 打基础本示例的静态配置模式正是 Istio 数据平面 Envoy 代理的雏形理解了它便能更快掌握 xDS 动态配置与 Sidecar 注入机制。如需继续深入建议阅读仓库中 usecases/envoy-terminology.mdEnvoy 架构与基本术语、xDS 概念、usecases/envoy-mesh-in-kubernetes-tutorial.mdEnvoy 在 Kubernetes 中做 mesh 的完整实战包括 edge envoy 与 SDS 服务发现以及 usecases/istio.mdIstio 数据平面与控制平面架构。赞分享教程云原生容器编排【免费下载链接】kubernetes-handbookKubernetes 架构与生态从云原生到 AI 原生基础设施的构建指南项目地址https://gitcode.com/gh_mirrors/ku/kubernetes-handbook点击查看免费下载相关推荐超实用PostgREST与Nginx反向代理负载均衡实战指南超实用PostgREST与Nginx反向代理负载均衡实战指南 PostgREST作为一款轻量级RESTful API服务器能快速将PostgreSQL数据后端API网关BilibiliDown3分钟学会下载B站视频支持高清画质与批量操作BilibiliDown3分钟学会下载B站视频支持高清画质与批量操作 想要轻松下载B站视频保存喜欢的UP主内容或者批量获取收藏夹里的视频吗Bilibi音视频桌面应用Kubernetes 集群中的 Envoy Mesh 实战从 edge envoy 反向代理到 SDS 服务发现与负载均衡Kubernetes 集群中的 Envoy Mesh 实战从 edge envoy 反向代理到 SDS 服务发现与负载均衡 本文以 kubernetes ha教程云原生容器编排上一篇揭秘gh_mirrors/box/boxes核心功能命令行参数与设计模板全解析下一篇图层导出效率提升指南Photoshop自动化工具的工作流优化方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

Blender建模模式详解:几何节点网格编辑与参数化实践
Blender建模模式详解:几何节点网格编辑与参数化实践

做Blender建模这么多年,我一直有个别扭的点:传统编辑模式里每一下操作都是破坏性的,CtrlZ能救一时,但关掉文件基本就回不去了;几何节点倒是强大,可默认逻辑是从零“生成”几何体,想直接把一块已… · 2026/9/24 21:45:56

C语言四大查找算法对比:顺序、二分、哈希与二叉搜索树
C语言四大查找算法对比:顺序、二分、哈希与二叉搜索树

别的不说,搞C语言开发的人,迟早会遇到一个场景:数据量一大,查个东西慢得让人抓狂。学生管理系统里按学号找人、嵌入式设备里查配置表、游戏服务端里查玩家状态,表面上看都是“找数据”,但用对查找算法和不讲… · 2026/9/24 21:45:56

Java工程管理系统从0到1:模块设计、权限模型与Spring Boot实战
Java工程管理系统从0到1:模块设计、权限模型与Spring Boot实战

前阵子一个做项目施工的朋友找我,说公司想上一套内部工程管理系统,市面上产品看了一圈,不是太贵就是接口封闭,想让我用 Java 帮他们搭一套。这类诉求我遇到过太多次了。工程管理系统这个名词听起来很垂直,但真正接触过… · 2026/9/24 21:45:50

I2C总线1000KHz高速扫描测试实战:从USB转I2C到Excel报告
I2C总线1000KHz高速扫描测试实战:从USB转I2C到Excel报告

做嵌入式硬件调试这么多年,我越来越觉得,把I2C总线的测试做成一个可记录、可回看、可归档的流程,比单纯点亮一个设备重要得多。最近我手头正好需要验证一批从设备在1000KHz总线速率下能否被稳定扫描识别,测试项的名字就叫“USB TO… · 2026/9/24 22:20:39

基于CNN的人脸疲劳检测与预警系统设计与实现
基于CNN的人脸疲劳检测与预警系统设计与实现

简介:基于卷积神经网络的人脸识别驾驶员疲劳检测与预警系统,面向Python毕业设计、课程设计与期末大作业场景,适合需要综合运用深度学习、计算机视觉完成落地方案的学生。系统覆盖摄像头图像采集、图像预处理、卷积神经网络特征提取、疲劳状态… · 2026/9/24 22:20:39

智慧家庭聊天机器人毕设:BERT意图识别与规则回复实战指南
智慧家庭聊天机器人毕设:BERT意图识别与规则回复实战指南

简介:基于深度学习的智慧家庭聊天机器人,是一份可直接用于计算机毕业设计的完整项目方案,面向计算机相关专业本科生、研究生及正在准备毕设答辩的学生,尤其适合选择人工智能、自然语言处理或智能家居应用方向的学习者。资源包共27… · 2026/9/24 22:20:21

基于深度学习的智慧家庭聊天机器人:从意图识别到答辩落地全攻略
基于深度学习的智慧家庭聊天机器人:从意图识别到答辩落地全攻略

简介:一份面向计算机毕业设计的深度学习实战资源,以智慧家庭聊天机器人项目为核心,完整覆盖从对话数据训练到智能家居场景落地的主要环节,适合本科或高职学生用于毕业设计、课程项目及二次开发参考。资源包共27个文件,… · 2026/9/24 22:20:21

synchronized锁升级与优化实战:从偏向锁到重量级锁
synchronized锁升级与优化实战:从偏向锁到重量级锁

1. synchronized为什么值得反复聊:它到底在管什么做了几年Java开发,基本每次面试我都会被问到synchronized,而且问的深度一次比一次狠。从“你用过synchronized吗”到“它的锁升级过程是怎样的”,再到“偏向锁和轻量级锁的区别是什… · 2026/9/24 22:20:21

AI漫剧制作全流程教程:免费工具从0到1做出爆款短剧
AI漫剧制作全流程教程:免费工具从0到1做出爆款短剧

做AI漫剧这件事,我前后折腾了快两个月才跑通完整流程。最初看别人发出来的漫剧作品,觉得不就是“小说截图配音字幕”嘛,可真到自己上手才发现,从选剧本、定角色、生成画面到剪出有节奏的成片,每一步都有不少坑。这次我… · 2026/9/24 22:20:21

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13

1D-CNN时间序列建模实战:从Conv1d原理到工业落地
1D-CNN时间序列建模实战:从Conv1d原理到工业落地

简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26

柔软的L:汉语语流中被忽视的舌肌张力控制
柔软的L:汉语语流中被忽视的舌肌张力控制

1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码