容器七层负载均衡解决方案——IngressNGINX

一、概述

当我们使用 K8S 对容器进行编排时,基于负载均衡和高可用方面考虑,且设计上 Pod 易失态,不能直接使用 PodIP 作为外部访问的方式。因此,K8S 官方提供了一些负载均衡的解决方案。这其中有四层和七层两种,本文主要介绍 K8S 内的七层负载均衡实现方案 Ingress,它是主流的 K8S 南北向七层负载均衡实现。

二、功能介绍

 1. 功能入口   

项目 -> 应用列表 -> 流量接入 -> Ingress

9a53b9b9df8cd0aa25f9f27d09217d84.png

2. 创建 Ingress 规则

首先需要确定的是暴露到内网还是外网,选择要发布的地域和集群。

3a27f12753d1cb0d65e60514859d1852.png

然后最核心的是 ingress 规则,需要填写域名和路径匹配的方式,以及最终处理流量的 backend service。

7411b2ab06c98f9e92708f6f87f46d01.png

如果用户有高级需求,可以使用注释进行实现。

3. HTTPS TLS 证书配置

Ingress 默认提供 HTTP 的流量处理,如果需要可以把 ingress 配置为支持 HTTPS 的类型,其中 tls 证书则由 secret 提供。

6a064901c087e6be41308eff5fb379ff.png

需要注意的是,创建的 Secret 类型必须为 kubernetes.io/tls,然后添入 cert 和 key 即可。

865cba763037c5d7b5bc70d6364c04f8.png


4. 验证

创建完 ingress,可以在 ingress 的详细页面看到可以访问的 IP 地址。我们把刚刚配置的域名DNS解析到这个 IP,然后就可以进行访问了。

d912a68acf4659c71be1a01f34038739.png

三、技术选型

1. 常见的三种负载均衡方案


20372a5e04615fb2b850d976411d6973.png

(1)NodePort

NodePort 如其名,直接使用宿主机的 Port 进行暴露。缺点是 端口随机(通常30000+)且有限,使用不便利,维护成本高。唯一的优点是 原生支持,不需要引入额外的组件。但如果想实现高可用和负载均衡,也需要在上层再挂一个四层反向代理。

(2)LoadBalancer

LB 与 服务 一对一 创建,这种模式 最灵活、性能最高、安全性最好。但是对 IP 资源消耗较大,每个云厂商实现不同。适合做四层负载

(3)Ingress

一个流量入口对应多个 SVC,类似 Nginx,拥有处理七层流量的能力,一般可根据域名和路径等策略进行路由和相关处理。支持限流、TLS、黑名单等诸多功能,用户体验与 网关 相似,适合做七层负载

2. Ingress 资源配置

让我们看看创建一个 Ingress,通常会填写的一些基本参数有哪些:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: ingress-wildcard-host
spec:rules:- host: "foo.bar.com"http:paths:- pathType: Prefixpath: "/bar"backend:service:name: service1port:number: 80

可以看到,通常我们会通过使用基于不用的域名和路径的策略,来访问不同的后端服务。所以配置文件中我们填写了 host、path 用来进行规则匹配,backend.service 则是指明了转发给哪个K8S服务。

所以,我们可以把 Ingress 理解成集成在 K8S 中的七层网关,每当我们 创建/修改 Ingress 资源时,就是对网关的配置进行修改。

3. IngressController 选型方案对比

2cb6a3369ea3f0a4a2023f9108b46d72.png

图中 Kubernetes Ingress 即为 IngressNginx,为K8S官方开发支持。而与之相邻的 NginxIngress 则是 NGINX 官方所开发支持。

如无特殊说明,本文中所提及的 IngressNginx 均指 Kubernetes Ingress。

最终,我们选择了 IngressNGINX 方案。

IngressNginx 优点:

➡️基本等同于传统 Nginx 的方案,优势是性能、简单、稳定可靠 和 低成本。

➡️社区默认支持的 IngressController。

IngressNginx 缺点:

➡️由于Nginx的模式是 Watch K8S 集群的相关资源事件,当发现有更新时,会重新生成配置文件,并进行 Reload。然而 Reload 的成本会随着配置文件的大小增长,当配置文件过大,热更新配置可能会有几秒的延迟,这期间可能会有问题(当然,也有方案进行解决,例如在集群中部署多个 IngressNginx 分摊压力,但会增加维护成本)。

➡️另一个缺点就是可扩展性,当我们想对它进行功能扩展时,只能使用 Lua 的方式,这个成本也是很高的。当然,原生支持的功能基本足够使用。

四、IngressNGINX 技术原理

1. IngressNGINX 架构

Ingress 一般由 Ingress资源对象、IngressController 和 GW 三部分组成(对于 IngressNGINX来说 GW 就是 NGINX)。

7b387ac0c9c8f70d018f1e4295c13ad4.png

IngressController 实际上就是一种适配器模式,把原本毫无关系的 Ingress 和 NGINX 集成起来。IC 作为适配器,使 NGINX 拥有了感知 K8S 集群资源变化的能力。

01acf0fb4311b9adf44bd213b72899ab.png

2. IngressNGINX 模型原理

IN 的 POD 由一个容器组成,该容器又包括以下内容:

  • IC进程,它根据 Ingress 和集群中创建的其他资源配置 NGINX。

  • NGINX Master进程,它是负责控制NGINX的管理进程。

  • NGINX Worker进程,它负责处理客户端通信,并对后端应用程序的流量进行负载均衡。

下面是一个模块图,它展示了这些流程如何在一起交互,以及如何与一些外部流程/实体交互:

4c895404054f59713f91fb63e073e583.png

下面的编号列表用花括号描述了每个连接的类型:

1. (HTTP)Prometheus通过IC公开的HTTP端点获取IC和NGINX指标。默认值为:9113/metrics。注意:Prometheus不是IC所需要的,端点可以关闭。

2. (HTTPS)IC读取Kubernetes API以获取集群中资源的最新版本,并写入API以更新已处理资源的状态并发出事件。

3. (HTTP)Kubelet探测IC就绪探针(默认值为:8081/nginx-ready),以考虑IC-Pod就绪。

4.(文件I/O)当IC启动时,它从文件系统中读取配置生成所需的配置模板。模板位于容器的 /etc/nginxtemplate/ 目录中,扩展名为 .tmpl。

5. (文件I/O)IC将日志写入容器运行时收集的stdout和stderr。

6. (文件I/O)IC根据集群中创建的资源生成NGINX配置,并将其写入文件系统的 /etc/nginx 目录中。配置文件的扩展名为 .conf。

7.(文件I/O)IC将TLS证书和密钥从入口和其他资源中引用的任何TLS机密写入文件系统。

8.(HTTP)IC通过UNIX:/var/lib/NGINX/nginx-status.sock UNIX套接字获取NGINX指标,并将其转换为#1中使用的普罗米修斯格式。

9.(HTTP)为考虑配置重新加载成功,IC确保至少有一个NGINX Worker具有新配置。为此,IC通过UNIX:/var/lib/nginx/nginx-config-version.sock UNIX套接字检查特定端点。

10.(N/A)为了启动NGINX,IC运行NGINX命令,该命令启动NGINX主机。

11.(信号)为了重新加载NGINX,IC 运行 nginx-s reload 命令,该命令验证配置并将重新加载信号发送给NGINX主机。

12.(信号)为了关闭NGINX,IC执行nginx-s quit命令,该命令将优美的关闭信号发送给NGINX主机。

13.(文件I/O)NGINX主服务器将日志发送到它的stdout和stderr,这两个日志由容器运行时收集。

14.(文件I/O)NGINX主机在启动或重新加载时读取配置中引用的TLS证书和密钥。

15.(文件I/O)NGINX主机在启动时或重新加载期间读取配置文件。

16.(信号)NGINX主程序控制NGINX Worker的生命周期,它使用新配置创建 Worker,并使用旧配置关闭Worker。

17.(文件I/O)NGINX工作人员将日志写入容器运行时收集的stdout和stderr。

18.(UDP)NGINX Worker通过UNIX套接字/var/lib/NGINX/nginx-syslog.sock通过Syslog协议将HTTP上游服务器响应延迟日志发送到IC。反过来,IC分析并将日志转换为普罗米修斯度量。

19.(HTTP、HTTPS、TCP、UDP)客户端向端口80和443以及GlobalConfiguration资源公开的任何其他端口上的任何NGINX工作端口发送通信量,并从其接收通信量。

20.(HTTP、HTTPS、TCP、UDP)NGINX工作器向后端发送通信量,并从后端接收通信量。

21.(HTTP)Admin 可以通过NGINX工作器使用端口8080连接到NGINX stub_status。注意:默认情况下,NGINX只允许来自本地主机的连接。

3. 创建一个 Ingress 的处理流程

f899139e25391ace982fa88b605deaff.png

核心步骤如下:

1.  用户 创建 Ingress。

2. IC 感知到 Ingress 资源发生变化。

6. IC 重新生成配置文件。

7. IC 触发 NGINX Reload。

7.2 NGINX 读取配置文件。

4.  何时进行 NGINX Reload


3b535e0afcbfecd383282cdb682340c9.png

通常,Kubernetes 控制器使用SyncLoop模式来检查控制器中所需的状态是否更新或需要更改。为此,我们需要使用集群中的不同对象来构建模型,特别是 Ingress、Service、Endpoint、Secret 以及 Configmap 来生成一个反映集群状态的时间点配置文件。

为了从集群中获得这个对象,我们使用了 Kubernetes Informer。当添加、修改或删除一个新对象时,该informer允许对使用回调对单个更改的更改作出反应。不幸的是,没有办法知道某个特定的更改是否会影响最终的配置文件。因此,对于每一个变化,必须根据集群的状态从零开始重建一个新的模型,并与当前的模型进行比较。

如果新模型等于当前模型,那么我们就避免生成新的 NGINX 配置并触发重新加载。否则,将检查差异是否仅限于 Endpoints。如果是这样,那么就使用 HTTP POST 请求将 Endpoints 的新列表发送给在 NGINX 中运行的 Lua 处理程序,同样避免生成新的 NGINX 配置并触发重新加载。如果运行和新模型之间的差异不仅仅是 Endpoints,那么将基于新模型创建一个新的 NGINX 配置,替换当前模型并触发Reload。

该模型的一个用途是避免不必要的重载,当状态没有变化时,并检测定义中的冲突。NGINX 配置的最终表示是从一个 Go 模板生成的,该模板使用新模型作为模板所需变量的输入。

一些需要 Reload 的场景(括号中表示 NGINX配置文件对应需要做出的改动):

➡️创建新的 Ingress 资源(添加 server)。

➡️TLS 部分添加到现有的 Ingress(增加 tls 配置)。

➡️从 Ingress 添加/删除路径(增加/删除 location)。

➡️删除 Ingress、Svc、Secret 等(需要删除  server 等)。

需要注意的是,NGINX 使用 balancer_by_lua_block 模块进行负载均衡,这个lua模块可以在不 Reload 的情况下,动态更新upstream上游节点。换句话说,如果只是 Endpoint 有更新,则无需进行 Reload

下面是 NGINX 的配置文件 nginx.conf 简略:     

server {server_name test-msc.qihoo.net ;listen 80  ;listen 443  ssl http2 ;......location / {// 一些和 K8S 资源相关的标识set $namespace      "nlzx-chy";set $ingress_name   "qc-safety-brain-test-msc";set $service_name   "qc-safety-brain-test-frontend";set $service_port   "80";set $location_path  "/";set $global_rate_limit_exceeding n;// 最终转发到 upstream_balancer 上游proxy_pass http://upstream_balancer;......upstream upstream_balancer {// 使用 balancer_by_lua_block  lua模块进行负载均衡balancer_by_lua_block {tcp_udp_balancer.balance()}}

5. NGINX Reload 原理

我们在前面提了很多次 NGINX Reload,接下来讲一下 NGINX Reload 的原理。让我们看看 NG 是如何在不影响流量的情况下,进行配置重载。

首先我们看一下 NG 的进程模型,NG 是多进程模型。Master 作为父进程,负责管理所有子进程,不处理流量。Worker作为子进程,负责处理流量。

Master 和 Worker 之间主要通过 signal 进行通信。

进程模型抽象:

826bab6e436aa812c930966788f1cb6d.png

早期 MasterListen + WorkerAccept 模型:

b5b655d8235168ef99a0beb2371ebfc2.jpeg

现在的 Worker:ReusePort + Accept 模型:

be08c7ba0cb0c908ec80c81a23a9389a.jpeg

早期 NGINX 的模型是,Master 负责 Listen,然后在 fork 时把 socket 传递给子进程,每个子进程进行 Accept 取客户端链接。但多个进程 Accept 同一个 Socket 有惊群问题,需要使用互斥锁处理,会对性能有一定影响。

而现在的 ReusePort 模型,socket 的 listen 也交给子进程,这样每个子进程都持有自己独有的 socket,就可以不用使用互斥锁,直接交给内核进行负载均衡,性能更佳。

该模型的原理是通过内核提供的 ReusePort 功能实现,性能提升的数据如下:

b2fde4ff21810b57db9571ada22a315c.jpeg

通常我们需要使用 nginx -s reload 指令进行 Reload,在现在的模型下,这个指令原理如下:

789824058a988d6ca8e9f8a7717fc477.jpeg

使用nginx -s reload进行平滑重启。nginx启动时会通过参数 -s 发现目前要进行信号处理而不是启动nginx服务,然后他会查看nginx的pid文件,pid文件中保存有master的进程号,然后向master进行发送相应的信号,reload对应的是HUP信号,所以nginx –s reload 与 kill -1 <MasterPid> 一样。

Master收到HUP信号后的处理流程如下:

1. master解析新的配置文件。

2. master fork出新的worker进程,此时新的worker会和旧的worker共存。

3. master向旧的worker发送QUIT命令。

4. 旧的worker会关闭监听端口,不再接受新的网络请求,并等待所有正在处理的请求完成后,退出。

5. 此时只有新的worker存在,nginx完成了重启。

NGINX 是 IO 密集型系统,关于 IO 密集型系统的各种性能优化,这里就不展开讲了。

6. IngressController 高可用

至此,我们对 IngressController 的原理有了一定的了解。最后我们聊一下 IC 本身的高可用,即 IC 本身的多副本部署架构。

我们使用 DaemonSet + NodeSelector(ingress=on) 方式,只在 Master 节点上部署 IC。

在 IC 的上层使用了 LVS,把 IC 挂载到 lvs 后面,对多个 IC 进行负载均衡。

aebea9249038c07d8de2aaa20a7a53da.jpeg

优点:IC 和 Master 组件集成在一起,不需要额外的机器部署,运维成本低。

缺点:正因为 IC 和 Master 组件部署在同一节点上,当 IC 接入的流量压力过大时,可能会与 Master 组件争抢节点的资源。

五、配置定制化

IngressNGINX 提供的 ConfigMap + Annotation 的方式,基本就可以解决用户的高级需求。但在某些场景下,我们可能仍需要更进一步的定制 NGINX 本身。对于这种情况,我们可以修改 NGINX 的 模板文件 nginx.tmpl。这个模板文件提供了一些语法支持,最终通过模板来定制生成的 nginx 配置文件,以达成需求。

由于 nginx.tmpl 有近 2k 行,这里就不展开介绍该模板的详细内容。

需要注意的是,直接修改配置模板虽然可以深度定制 NGINX,但是需要自行适配后续的 IngressNGINX 升级带来的兼容性变动。

六、未来规划


1. IngressNGINX 自身

由于 IngressNginx 是比较成熟的软件,几乎不用担心他的稳定性、性能 和 功能完善度。所以可优化的层面主要是部署架构:

  • IN 和 Master 分离开,单独机器部署,避免影响到集群基础组件运行。

  • 在一个集群里部署多个IC,分担流量压力。

按照目前集群对 Ingress 的使用规模来看,还没有达到这个地步,可以持续观察着,在遇到瓶颈时再进行变动,以节省成本。

2. Gateway API

GatewayAPI 人如其名,设计上也是用来处理流量,在职责定义上囊括了 Ingress 的能力。而社区之所以在有 Ingress 的情况下,又重新定义一个 GatewayAPI 出来,其实是为了解决 Ingress 设计上的不足。但截止目前,其仍处于发展期,还需要一些时间。

更多产品和技术文章,敬请关注👆

360智汇云是以"汇聚数据价值,助力智能未来"为目标的企业应用开放服务平台,融合360丰富的产品、技术力量,为客户提供平台服务。

目前,智汇云提供数据库、中间件、存储、大数据、人工智能、计算、网络、视联物联与通信等多种产品服务以及一站式解决方案,助力客户降本增效,累计服务业务1000+。

智汇云致力于为各行各业的业务及应用提供强有力的产品、技术服务,帮助企业和业务实现更大的商业价值。

官网:https://zyun.360.cn

客服电话:4000052360

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/393867.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

养猫必看!热销猫罐头有哪些?2024年推荐这4款口碑很好的主食罐

开猫咖3年啦&#xff0c;店里有加菲&#xff0c;美短&#xff0c;布偶&#xff0c;暹罗&#xff0c;都是我一手带大的。店铺开在高校附近&#xff0c;顾客以学生为主&#xff0c;也有很多养猫人士会到店里来&#xff0c;和我交流选粮经验。很多养猫人都在喂主食罐头&#xff0c…

FreeRTOS基础入门——FreeRTOS的任务基础知识(四)

个人名片&#xff1a; &#x1f393;作者简介&#xff1a;嵌入式领域优质创作者&#x1f310;个人主页&#xff1a;妄北y &#x1f4de;个人QQ&#xff1a;2061314755 &#x1f48c;个人邮箱&#xff1a;[mailto:2061314755qq.com] &#x1f4f1;个人微信&#xff1a;Vir2025WB…

Leetcode每日刷题之字符串相加(C++)

在学习的同时也不要忘记适当练习&#xff0c;本题字符串相加主要在于字符串类型与整数类型的转化&#xff0c;要将字符串类型转化为整数类型计算后转化为字符串类型输出即可。 思路解析 根据题中给出的信息&#xff0c;我们不可以使用库函数计算大整数&#xff0c;也不能直接将…

做空日经指数的策略与时机

一、市场背景分析 在全球股市的剧烈波动中&#xff0c;日本股市的表现尤为引人关注。日经225指数在经历一轮暴跌后&#xff0c;又出现了大幅反弹&#xff0c;这种剧烈的波动为投资者提供了做空日经指数的机会。近期&#xff0c;日本股市受到日元汇率波动、日本央行货币政策以及…

C++中的string的介绍(从string到STL)

C中的string的介绍 文章目录 C中的string的介绍1. 从string到STL2. string 的构造函数3. string 的iterator&#xff08;迭代器&#xff09;4. string 中的元素访问5. string 中容量相关6. string 中的插入删除7. string 中的查找8. string 的剩余函数 1. 从string到STL 严格来…

【轻松拿捏】Java是如何实现跨平台性的?

Java是如何实现跨平台性的&#xff1f; 一、Java 的跨平台性主要通过以下几个核心机制实现&#xff1a; 二、具体实现 三、示例 四、JVM 工作示意图 五、总结 &#x1f388;边走、边悟&#x1f388;迟早会好 一、Java 的跨平台性主要通过以下几个核心机制实现&#xff…

CICD流水线

一、CICD流水线简介 CICD概念 CI/CD流水线是现代软件开发的一个核心概念&#xff0c;它涉及自动化和管理软件从开发到部署的整个生命周期 概念定义 具体有三点&#xff1a;持续集成、持续交付、持续部署 流水线组成为&#xff1a;代码提交、测试、构建、部署、结果通知 二…

PHP最新可用获取QQ昵称API接口源码_非第三方

PHP最新可用获取QQ昵称API接口源码&#xff0c;运行环境为php7-8都可以&#xff0c;内容为直接调用QQ空间接口 在需要展示QQ昵称处&#xff0c;直接调用以下函数就可以。 例如&#xff1a;get_qq_nick(123456)就会直接输出123456的qq号昵称。 API源码下载&#xff1a;QQ昵称AP…

第R2周:LSTM-火灾温度预测:一文搞懂LSTM(长短期记忆网络)

一文搞懂LSTM&#xff08;长短期记忆网络&#xff09; 一句话介绍LSTM&#xff0c;它是RNN的进阶版&#xff0c;如果说RNN的最大限度是理解一句话&#xff0c;那么LSTM的最大限度则是理解一段话&#xff0c;详细介绍如下&#xff1a; LSTM&#xff0c;全称为长短期记忆网络(Lo…

python-鼠标绘画线条程序

闲来无聊简单编写了一个绘图小程序。 主要思路 主要是基于Python中的内置模块turtle编写的&#xff0c;简单扩展了一下&#xff0c;通过绑定事件能够达到鼠标绘制、删除、存储已经绘制图案的线条这几个功能。 路径结构 -draw- define.py- main.py- myturtle.py使用 点住鼠…

Element学习(入门)(1)

1、Element官网&#xff1a;https://element.eleme.cn/#/zh-CN 2、来源与用处 3、Element的快速入门 &#xff08;1&#xff09; &#xff08;2&#xff09;在入口文件&#xff08;main.js&#xff09;中引入 &#xff08;3&#xff09; 4、快捷键ctrlc&#xff0c;在当前的项目…

zsh 配置 docker 自动补全

zsh 配置 docker 自动补全 在终端中使用 docker 的命令的时候必须要全部手敲&#xff0c;没有提示&#xff0c;于是就在找是否有自动补全的脚本&#xff0c;搜索了一圈踩了一些坑总结了一下具体的步骤。 首先执行如下命令&#xff1a; mkdir -p ~/.zsh/completion curl -L h…

JavaEE: 查看线程信息

示例用代码 public class Main {static class MyThread extends Thread {Overridepublic void run() {while (true) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}}public st…

Python 用户输入和while循环

1、input()函数的工作原理&#xff08;用户输入&#xff09; input()函数让程序暂停运行&#xff0c;等待用户输入一些文本。获取用户输入后&#xff0c;Python将其赋给变量&#xff0c;以其使用。 在input()函数接受一个参数&#xff0c;既要向用户显示的提示&#xff0c;为了…

Linux 利用 ftrace 分析内核调用

目录 一、概述二、ftrace 的使用1、常用信息2、指定 ftrace 跟踪器3、设置要跟踪的函数4、ftrace 的开关5、function 跟踪程序6、function_graph 跟踪程序7、函数过滤器8、跟踪事件 三、trace-cmd 的使用1、常见命令2、常用选项2.1 列出可用的追踪器2.2 跟踪特定进程的函数调用…

计算机毕业设计选题推荐-课程教学平台-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

ceph

ceph是一个开源的&#xff0c;用c语言编写的分布式的存储系统。存储文件数据。 /dev/sdb fdisk /dev/sdb gdisk /dev/sdb lvm 逻辑卷 可以扩容 raid 磁盘 高可用 基于物理意义上的单机的存储系统。 分布式由多台物理磁盘组成一个集群&#xff0c;在这个基础之上实现高可…

激光导航AGV叉车那么多,究竟该怎么选?一篇文章讲明白~

AGV叉车 随着经济的快速发展&#xff0c;大部分企业的物料搬运开始脱离人工劳作&#xff0c;取而代之的是以叉车为主的机械化搬运。AGV叉车是工业搬运车辆&#xff0c;是指对成件托盘货物进行装卸、堆垛和短距离运输作业的各种轮式搬运车辆&#xff0c;主要应用于货场、工厂车间…

HslCommunicationDemo各品牌Plc通信测试软件工具

目录 1、HslCommunicationDemo程序包 2、ModbusTCP举例说明 (0)概述 &#xff08;1&#xff09;线圈写操作 &#xff08;2&#xff09;寄存器写操作 3、C#工程中DLL库文件使用 &#xff08;1&#xff09;创建Winform程序工程 &#xff08;2&#xff09;写寄存器 1、HslC…

基于内地城市生活垃圾收运场景的路线规划算法

基于混合遗传算法和模拟退火算法的优化垃圾收集路线规划 摘要 本文提出了一种基于混合遗传算法&#xff08;GA&#xff09;和模拟退火算法&#xff08;SA&#xff09;的创新路线规划方法&#xff0c;旨在优化内地城市的生活垃圾收集效率。算法结合了遗传算法的全局搜索能力和…