优化二三章结构

This commit is contained in:
2026-05-20 14:33:40 +08:00
parent deb07aeb3e
commit 49761cf843
8 changed files with 50 additions and 14 deletions

Binary file not shown.

View File

@@ -2,7 +2,10 @@
\chapter{背景介绍与研究动机} \chapter{背景介绍与研究动机}
本章首先在\ref{sec:背景介绍}节中介绍云网络、覆盖网络和网络编码的基本信息,介绍在维持高质量服务前提下进行成本优化这一核心问题。之后在\ref{sec:实验观察与已有工作不足}节介绍一些本文作者对云网络的观察发现及已有工作在这些新观察下暴露出的不足。最后,在\ref{sec:basic idea}节介绍本文提出的通过对云网络公网进行分段质量修复的基本思路及面临的挑战。
\section{背景介绍} \section{背景介绍}
\label{sec:背景介绍}
\subsection{云网络与覆盖网络} \subsection{云网络与覆盖网络}
@@ -21,7 +24,7 @@
在跨地域云网络场景中,不同节点之间通常存在多条物理连接路径,这些物理链路具有不同的链路质量和不同的链路价格及计费方式。例如,许多云服务商同时提供公网链路互联与专线链路互联\cite{azure_bandwidthcost,gcp_bandwidthcost}。其中,专线链路通常具有更稳定的传输性能、更低的丢包率与时延,但部署成本与使用成本较高;而公网链路虽然成本较低,却容易受到网络拥塞、跨域路由波动等因素影响,出现高丢包、时延抖动等问题\cite{kataria2024titan}。与此同时,链路质量与网络负载往往还会随着时间动态变化,使得不同链路在不同时间段内呈现出不同的性能特征。随着云计算与实时互联网应用的发展,现代云网络中的跨域流量规模持续增长,用户对于传输质量与服务稳定性的要求也不断提高。传统的覆盖网络服务商为了为用户提供高质量的传输服务,确保能为用户持续稳定提供低延迟、高带宽、低丢包的转发路径,选择尽可能多地使用专线链路构建覆盖网络,而这对运营成本带来了较大的压力。如何在维持网络服务质量保持高带宽、低丢包、低延迟的前提下,尽可能减少构建和运营云网络所需的成本,是各服务商关注的重点。 在跨地域云网络场景中,不同节点之间通常存在多条物理连接路径,这些物理链路具有不同的链路质量和不同的链路价格及计费方式。例如,许多云服务商同时提供公网链路互联与专线链路互联\cite{azure_bandwidthcost,gcp_bandwidthcost}。其中,专线链路通常具有更稳定的传输性能、更低的丢包率与时延,但部署成本与使用成本较高;而公网链路虽然成本较低,却容易受到网络拥塞、跨域路由波动等因素影响,出现高丢包、时延抖动等问题\cite{kataria2024titan}。与此同时,链路质量与网络负载往往还会随着时间动态变化,使得不同链路在不同时间段内呈现出不同的性能特征。随着云计算与实时互联网应用的发展,现代云网络中的跨域流量规模持续增长,用户对于传输质量与服务稳定性的要求也不断提高。传统的覆盖网络服务商为了为用户提供高质量的传输服务,确保能为用户持续稳定提供低延迟、高带宽、低丢包的转发路径,选择尽可能多地使用专线链路构建覆盖网络,而这对运营成本带来了较大的压力。如何在维持网络服务质量保持高带宽、低丢包、低延迟的前提下,尽可能减少构建和运营云网络所需的成本,是各服务商关注的重点。
一些工作意识到了公网链路与专线链路在经常存在定价差异,因而尝试在维持覆盖网络服务质量的前提下,利用覆盖网络易于实时配置的特性,将部分流量转移至质量优秀的公网链路上,以减少专线链路的压力\cite{kataria2024titan,wu2023xron}。这些工作利用低价的公网链路为部分用户提供服务,从而降低部分高价专线的流量,从而在服务流量总量不变的情况下,降低了价流量的占比,进而降低了链路部署的总成本。 一些工作意识到了公网链路与专线链路在经常存在定价差异,因而尝试在维持覆盖网络服务质量的前提下,利用覆盖网络易于实时配置的特性,将部分流量转移至质量优秀的公网链路上,以减少专线链路的压力\cite{kataria2024titan,wu2023xron}。这些工作在公网链路质量较好时,利用低价的公网链路为部分用户提供服务,降低了高价专线需要承载的流量,从而在服务流量总量不变的情况下,降低了价流量的占比,进而降低了链路部署的总成本。
\subsection{网络编码} \subsection{网络编码}
@@ -34,11 +37,13 @@
% 不过在传统应用场景中FEC往往被部署在端到端发送端和接收端之间将整条网络路径视为一条整体链路并根据端到端丢包情况决定冗余强度。这种方式虽然对中间网络透明但没有利用云网络和覆盖网络中间节点可控、路径可分段的特点。在跨域覆盖网络中一条端到端路径通常由多个链路片段接力组成不同片段的质量可能存在显著差异。如果仍然对整条路径统一添加冗余质量良好的片段也需要承载额外冗余流量而真正发生丢包的低质量片段也无法得到更精细的针对性修复。因此本文关注的核心问题并不是重新设计一种完全端到端的编码机制而是如何结合覆盖网络的分段转发能力将FEC用于低质量公网链路片段的定向修复从而在控制带宽开销的同时提升端到端服务质量。 % 不过在传统应用场景中FEC往往被部署在端到端发送端和接收端之间将整条网络路径视为一条整体链路并根据端到端丢包情况决定冗余强度。这种方式虽然对中间网络透明但没有利用云网络和覆盖网络中间节点可控、路径可分段的特点。在跨域覆盖网络中一条端到端路径通常由多个链路片段接力组成不同片段的质量可能存在显著差异。如果仍然对整条路径统一添加冗余质量良好的片段也需要承载额外冗余流量而真正发生丢包的低质量片段也无法得到更精细的针对性修复。因此本文关注的核心问题并不是重新设计一种完全端到端的编码机制而是如何结合覆盖网络的分段转发能力将FEC用于低质量公网链路片段的定向修复从而在控制带宽开销的同时提升端到端服务质量。
\section{观察与已有工作不足} \section{观察与已有工作不足}
\label{sec:实验观察与已有工作不足}
\begin{enumerate} \begin{enumerate}
\item \textbf{公网链路质量下降与用户流量高峰重合,基于公网分流的调度方法难以削减专线峰值成本。} \item \textbf{公网链路质量下降与用户流量高峰重合,基于公网分流的调度方法难以削减专线峰值成本。}
\end{enumerate} \end{enumerate}
公网链路质量下降的时间段与用户流量高峰有明显的相关性,公网链路分流能力有限。如图\ref{fig:用户高峰与公网劣化重合}在某企业的某条公网连接中用户流量带宽提升的时段与丢包率提升、延迟波动的时段有较强的相关性只在公网丢包低、延迟稳定的时段使用公网链路只能削减专线上承载的一小部分流量。进一步地由于用户流量带宽较大的时段公网持续恶化这些方法也不能利用公网链路削减专线需要承载的峰值带宽使得专线链路仍然在传输流量时起主导作用链路使用成本的削减程度有限。另外专线链路的价格通常以峰值带宽定价而不能以传输数据量计费当前公网分流策略不能降低专线链路的使用成本。这是因为与公网链路通常可以灵活选用按量付费与按峰值带宽付费不同专线链路通常只能按一段时间内的峰值带宽或95分位带宽付费\cite{aliyun_bandwidthcost,tencent_bandwidthcost},这些方法不能有效地削减专线上承载的峰值带宽就意味着专线的使用成本不会由于公网的部分分流而显著降低。因此,这些工作对链路使用成本的削减十分有限,甚至可能由于额外使用公网链路而导致链路使用成本增加。
已有的链路调度类工作没有考虑到公网链路质量下降的时间段与用户流量高峰有明显的相关性,公网链路的实际分流能力有限。如图\ref{fig:用户高峰与公网劣化重合}在某企业的某条公网连接中用户流量带宽提升的时段与丢包率提升、延迟波动的时段有较强的相关性只在公网丢包低、延迟稳定的时段使用公网链路只能削减专线上承载的一小部分流量。进一步地由于用户流量带宽较大的时段公网持续恶化这些方法也不能利用公网链路削减专线需要承载的峰值带宽使得专线链路仍然在传输流量时起主导作用链路使用成本的削减程度有限。另外专线链路的价格通常以峰值带宽定价而不能以传输数据量计费当前公网分流策略不能降低专线链路的使用成本。这是因为与公网链路通常可以灵活选用按量付费与按峰值带宽付费不同专线链路通常只能按一段时间内的峰值带宽或95分位带宽付费\cite{aliyun_bandwidthcost,tencent_bandwidthcost},这些方法不能有效地削减专线上承载的峰值带宽就意味着专线的使用成本不会由于公网的部分分流而显著降低。因此,这些工作对链路使用成本的削减十分有限,甚至可能由于专线链路成本没有明显下降,反而由于额外使用公网链路而导致链路使用成本增加。
\begin{figure}[H] \begin{figure}[H]
\centering \centering
\includegraphics[width=\linewidth]{hongkong-jinan-withbd.pdf} \includegraphics[width=\linewidth]{hongkong-jinan-withbd.pdf}
@@ -47,17 +52,19 @@
\end{figure} \end{figure}
\begin{enumerate}[resume] \begin{enumerate}[resume]
\item \textbf{公网链路不同分段质量差异显著} \item \textbf{公网链路不同分段质量差异显著,端到端进行网络编码带宽浪费严重。}
\end{enumerate} \end{enumerate}
云服务商只对专线链路的质量提供服务质量保证Service level agreement, SLA而对公网的具体性能没有任何形式的保证。尽管服务商不对公网的性能做出任何保证但这不意味着所有的公网链路质量都远远不如专线。如图\ref{fig:公网片段热力图}所示,部分公网链路有着较低的平均丢包率,质量几乎与专线相当,而只有部分链路,特别是跨域链路的丢包率较高,链路质量较差,与低丢包的专线有较大差距。覆盖网络对用户流量进行转发时,通常将多个不同的网络片段相连组成连接两侧接入网关的路径。由于覆盖网络的内部转发机制通常对端到端的传输透明,两端的客户端只能感知到由多个链路的丢包级联而成的最终丢包率,只要组成转发路径的链路中有至少一条是丢包率较高的跨域公网链路,端到端感知到的丢包率就会明显上升。这导致在跨域连接的场景下,网络编码类工作只能以感知到的高丢包率对在整个路径上转发的包加入大量的冗余,造成了较大的带宽浪费。
云服务商只对专线链路的质量提供服务质量保证Service level agreement, SLA而对公网的具体性能没有任何形式的保证。尽管服务商不对公网的性能做出任何保证所有的公网链路在所有的时间段质量都劣于专线链路。如图\ref{fig:公网片段热力图}所示,部分公网链路有着较低的平均丢包率,质量几乎与专线相当,而只有部分链路,特别是跨域链路的丢包率较高,链路质量较差,与低丢包的专线有较大差距。覆盖网络对用户流量进行转发时,通常将多个不同的网络片段相连组成连接两侧接入网关的路径。由于覆盖网络的内部转发机制通常对端到端的传输透明,两端的客户端只能感知到由多个链路的丢包级联而成的最终丢包率,只要组成转发路径的链路中包含了至少一条丢包率较高的跨域公网链路,端到端感知到的丢包率就会明显上升。这导致在跨域连接的场景下,网络编码类工作只能以感知到的高丢包率对在整个路径上转发的包加入大量的冗余,造成了较大的带宽浪费,造成链路使用成本上升。
\begin{figure}[H] \begin{figure}[H]
\centering \centering
\includegraphics[width=.8\linewidth]{loss_avg_heatmap.pdf} \includegraphics[width=\linewidth]{loss_avg_heatmap.pdf}
\caption{不同公网链路连续七天内平均丢包率热力图} \caption{不同公网链路连续七天内平均丢包率热力图}
\label{fig:公网片段热力图} \label{fig:公网片段热力图}
\end{figure} \end{figure}
\section{研究动机} \section{研究动机}
\label{sec:basic idea}
前文的观察表明,现有方法在跨域云网络场景下仍然存在局限。一方面,链路调度类方法主要利用公网质量较好时的机会窗口,将部分流量从专线迁移到公网;但当用户流量进入高峰期时,公网链路也更容易出现丢包和抖动,系统仍然需要依赖专线承载主要流量,因而难以真正降低按峰值带宽计费的专线成本。另一方面,网络编码类方法虽然能够修复丢包,但通常将端到端路径视为一条整体链路,在整条路径上统一添加冗余,没有区分不同链路片段之间的质量差异,容易在质量良好的片段上引入不必要的带宽开销。 前文的观察表明,现有方法在跨域云网络场景下仍然存在局限。一方面,链路调度类方法主要利用公网质量较好时的机会窗口,将部分流量从专线迁移到公网;但当用户流量进入高峰期时,公网链路也更容易出现丢包和抖动,系统仍然需要依赖专线承载主要流量,因而难以真正降低按峰值带宽计费的专线成本。另一方面,网络编码类方法虽然能够修复丢包,但通常将端到端路径视为一条整体链路,在整条路径上统一添加冗余,没有区分不同链路片段之间的质量差异,容易在质量良好的片段上引入不必要的带宽开销。

View File

@@ -2,7 +2,10 @@
\chapter{相关工作} \chapter{相关工作}
\section{覆盖网络隧道技术} 本章主要介绍一些与本文工作相关的已有工作。\ref{sec:隧道技术介绍}节主要介绍了当前在工业界得到较为广泛使用的用于构建覆盖网络的几种隧道技术\ref{sec:链路质量优化相关工作}节介绍了多种常用于进行网络编码的前项纠错编码技术,并比较了他们的异同。最后,\ref{sec:SDN相关工作}介绍了与覆盖网络紧密联系的软件定义网络Software defined network, SDN的概念以及与其相关的一些工作。
\section{覆盖网络与隧道技术}
\label{sec:隧道技术介绍}
覆盖网络的实现依赖于隧道封装技术其基本原理是将原始的二层或三层报文封装在另一种网络协议中进行传输从而在底层的IP网络上构建虚拟的二层网络。当前主流的Overlay隧道技术主要包括VXLAN\cite{rfc7348vxlan}、NVGRE\cite{rfc7637nvgre}和Geneve\cite{rfc8926geneve}等,它们在封装格式、协议机制和适用场景上各有特点。 覆盖网络的实现依赖于隧道封装技术其基本原理是将原始的二层或三层报文封装在另一种网络协议中进行传输从而在底层的IP网络上构建虚拟的二层网络。当前主流的Overlay隧道技术主要包括VXLAN\cite{rfc7348vxlan}、NVGRE\cite{rfc7637nvgre}和Geneve\cite{rfc8926geneve}等,它们在封装格式、协议机制和适用场景上各有特点。
@@ -13,6 +16,7 @@ NVGRENetwork Virtualization using Generic Routing Encapsulation基于路
GeneveGeneric Network Virtualization Encapsulation通用虚拟化网络封装技术\cite{rfc8926geneve}是IETF新提出的通用网络虚拟化封装协议旨在以单一、可扩展的封装格式取代碎片化的VXLAN、NVGRE等多种隧道协议以维持生态统一。Geneve也采用MAC over UDP的封装通过灵活配置的元数据传递机制满足多种网络虚拟化需求。Geneve也使用24比特的虚拟网络标识Virtual Network Identifier, VNI来区分不同的虚拟网络支持的网络数量与VXLAN、NVGRE等协议相当。与VXLAN等协议不同Geneve允许在头部后添加可变长度和数量的控制位和控制信息可以有效满足不同虚拟网络的需求增强了可扩展性。Geneve协议通过设计可选的元数据空间允许在不修改协议的前提下引入新功能自推出以来已经逐步得到各类虚拟网络平台的支持\cite{ovn_geneve,vmware_nsxt_geneve},但是协议较为复杂,适配难度较大。 GeneveGeneric Network Virtualization Encapsulation通用虚拟化网络封装技术\cite{rfc8926geneve}是IETF新提出的通用网络虚拟化封装协议旨在以单一、可扩展的封装格式取代碎片化的VXLAN、NVGRE等多种隧道协议以维持生态统一。Geneve也采用MAC over UDP的封装通过灵活配置的元数据传递机制满足多种网络虚拟化需求。Geneve也使用24比特的虚拟网络标识Virtual Network Identifier, VNI来区分不同的虚拟网络支持的网络数量与VXLAN、NVGRE等协议相当。与VXLAN等协议不同Geneve允许在头部后添加可变长度和数量的控制位和控制信息可以有效满足不同虚拟网络的需求增强了可扩展性。Geneve协议通过设计可选的元数据空间允许在不修改协议的前提下引入新功能自推出以来已经逐步得到各类虚拟网络平台的支持\cite{ovn_geneve,vmware_nsxt_geneve},但是协议较为复杂,适配难度较大。
\section{链路质量优化} \section{链路质量优化}
\label{sec:链路质量优化相关工作}
低质量的互联网链路由于负载较大出现拥塞或部分设备运行故障容易出现丢包或者延迟波动。在这些低质量的链路上进行传输时即使链路还有可用的传输带宽也会出现丢包或是延迟波动。即使TCP\cite{rfc9293tcp}等可靠传输协议通过重传确保了所有数据都能可到送达但性能较差。这是因为TCP协议依靠超时重传来在确保所有数据都最终送达至接收端即使使用了基于重复ACK的快速重传机制如图\ref{fig:TCP丢包恢复缓慢}恢复单个丢失的包也至少要经历接收端检测丢包——请求发送端重传——发送端重传包送达恢复的过程至少需要一个往返时延Round Trip Time, RTT才能恢复。对于一条在云网络中的跨域链路往返时延可能达到\SI{300}{ms}或更长,如此缓慢的丢包恢复不仅会阻塞后续数据包的发送,也会极大地影响实时媒体服务如影视直播、视频通话等应用的用户体验。 低质量的互联网链路由于负载较大出现拥塞或部分设备运行故障容易出现丢包或者延迟波动。在这些低质量的链路上进行传输时即使链路还有可用的传输带宽也会出现丢包或是延迟波动。即使TCP\cite{rfc9293tcp}等可靠传输协议通过重传确保了所有数据都能可到送达但性能较差。这是因为TCP协议依靠超时重传来在确保所有数据都最终送达至接收端即使使用了基于重复ACK的快速重传机制如图\ref{fig:TCP丢包恢复缓慢}恢复单个丢失的包也至少要经历接收端检测丢包——请求发送端重传——发送端重传包送达恢复的过程至少需要一个往返时延Round Trip Time, RTT才能恢复。对于一条在云网络中的跨域链路往返时延可能达到\SI{300}{ms}或更长,如此缓慢的丢包恢复不仅会阻塞后续数据包的发送,也会极大地影响实时媒体服务如影视直播、视频通话等应用的用户体验。
@@ -84,6 +88,7 @@ XOR、R-S等分组码结合交织已经能较好地应对网络中的丢包问
尽管现有FEC技术已经能够有效提升低质量网络环境中的数据恢复能力但大多数研究主要关注编码结构本身的恢复性能、冗余效率以及恢复时延等问题通常默认数据传输路径已经固定而较少进一步考虑不同网络链路之间的质量差异与成本差异。在跨域云网络场景下不同链路可能同时具有显著不同的传输性能与租赁成本如何结合链路状态动态选择冗余保护策略并进一步联合流量调度共同优化整体传输性能与网络成本仍然是值得进一步研究的问题。 尽管现有FEC技术已经能够有效提升低质量网络环境中的数据恢复能力但大多数研究主要关注编码结构本身的恢复性能、冗余效率以及恢复时延等问题通常默认数据传输路径已经固定而较少进一步考虑不同网络链路之间的质量差异与成本差异。在跨域云网络场景下不同链路可能同时具有显著不同的传输性能与租赁成本如何结合链路状态动态选择冗余保护策略并进一步联合流量调度共同优化整体传输性能与网络成本仍然是值得进一步研究的问题。
\section{软件定义网络与网络调度} \section{软件定义网络与网络调度}
\label{SDN相关工作}
软件定义网络Software defined networking, SDN指的是将网络中各个转发设备的数据平面与控制平面解耦集中进行控制的网络。SDN网络大大简化了网络的管理和控制流程。对于跨域云网络及其中部署的虚拟网络尽管有部分的网络设备由SDN统一控制但是各个设备间的跨域互联通常仍仍旧由传统的网络设备提供连接形成了混合形软件定义网络hybrid SDN network如图\ref{fig:混合SDN网络}\cite{amin2018hybridsdnsurvey} 软件定义网络Software defined networking, SDN指的是将网络中各个转发设备的数据平面与控制平面解耦集中进行控制的网络。SDN网络大大简化了网络的管理和控制流程。对于跨域云网络及其中部署的虚拟网络尽管有部分的网络设备由SDN统一控制但是各个设备间的跨域互联通常仍仍旧由传统的网络设备提供连接形成了混合形软件定义网络hybrid SDN network如图\ref{fig:混合SDN网络}\cite{amin2018hybridsdnsurvey}

View File

@@ -1,7 +1,7 @@
% !TEX root = ../bachelor-thesis.tex % !TEX root = ../bachelor-thesis.tex
\begin{denotation}[3cm] % \begin{denotation}[3cm]
\item[PI] 聚酰亚胺 % \item[PI] 聚酰亚胺
% \item[MPI] 聚酰亚胺模型化合物N-苯基邻苯酰亚胺 % \item[MPI] 聚酰亚胺模型化合物N-苯基邻苯酰亚胺
% \item[PBI] 聚苯并咪唑 % \item[PBI] 聚苯并咪唑
% \item[MPBI] 聚苯并咪唑模型化合物N-苯基苯并咪唑 % \item[MPBI] 聚苯并咪唑模型化合物N-苯基苯并咪唑
@@ -40,7 +40,7 @@
% \item[ONIOM] 分层算法Our own N-layered Integrated molecular Orbital and molecular Mechanics % \item[ONIOM] 分层算法Our own N-layered Integrated molecular Orbital and molecular Mechanics
% \item[SCF] 自洽场Self-Consistent Field % \item[SCF] 自洽场Self-Consistent Field
% \item[SCRF] 自洽反应场Self-Consistent Reaction Field % \item[SCRF] 自洽反应场Self-Consistent Reaction Field
\end{denotation} % \end{denotation}
@@ -49,7 +49,7 @@
% \makenomenclature % \makenomenclature
% 在这里输出符号说明 % 在这里输出符号说明
% \printnomenclature[3cm] \printnomenclature[3cm]
% 在正文中的任意为都可以标题 % 在正文中的任意为都可以标题
% \nomenclature{PI}{聚酰亚胺} % \nomenclature{PI}{聚酰亚胺}

Binary file not shown.

View File

@@ -7,9 +7,12 @@ from pathlib import Path
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np import numpy as np
from matplotlib import font_manager from matplotlib import font_manager
from matplotlib.lines import Line2D
OVERSEAS_CITIES = {"迪拜", "法兰克福", "雅加达", "开普敦"} OVERSEAS_CITIES = {"迪拜", "法兰克福", "雅加达", "开普敦"}
OVERSEAS_COLOR = "#4285F4"
DOMESTIC_COLOR = "#EA4335"
def leading_group_size(labels: list[str], group: set[str]) -> int: def leading_group_size(labels: list[str], group: set[str]) -> int:
@@ -94,8 +97,29 @@ def plot_heatmap(csv_path: Path, output_path: Path) -> None:
ax.set_xlabel("接收端") ax.set_xlabel("接收端")
ax.set_ylabel("发送端") ax.set_ylabel("发送端")
# ax.set_title("公网链路平均丢包率") # ax.set_title("公网链路平均丢包率")
ax.xaxis.tick_top()
ax.xaxis.set_label_position("top")
ax.tick_params(axis="x", top=True, labeltop=True, bottom=False, labelbottom=False, pad=6)
plt.setp(ax.get_xticklabels(), rotation=35, ha="right", rotation_mode="anchor") plt.setp(ax.get_xticklabels(), rotation=-35, ha="right", rotation_mode="anchor")
for label in ax.get_xticklabels():
label.set_color(OVERSEAS_COLOR if label.get_text() in OVERSEAS_CITIES else DOMESTIC_COLOR)
for label in ax.get_yticklabels():
label.set_color(OVERSEAS_COLOR if label.get_text() in OVERSEAS_CITIES else DOMESTIC_COLOR)
legend_handles = [
Line2D([0], [0], marker="s", color="none", markerfacecolor=OVERSEAS_COLOR, markeredgecolor=OVERSEAS_COLOR, markersize=9, label="海外"),
Line2D([0], [0], marker="s", color="none", markerfacecolor=DOMESTIC_COLOR, markeredgecolor=DOMESTIC_COLOR, markersize=9, label="国内"),
]
ax.legend(
handles=legend_handles,
loc="lower center",
bbox_to_anchor=(0.5, 1.15),
ncol=2,
frameon=False,
columnspacing=1.4,
handletextpad=0.4,
)
for row_index in range(len(senders)): for row_index in range(len(senders)):
for col_index in range(len(receivers)): for col_index in range(len(receivers)):
@@ -120,7 +144,7 @@ def plot_heatmap(csv_path: Path, output_path: Path) -> None:
ax.tick_params(which="minor", bottom=False, left=False) ax.tick_params(which="minor", bottom=False, left=False)
colorbar = fig.colorbar(image, ax=ax, shrink=0.88) colorbar = fig.colorbar(image, ax=ax, shrink=0.88)
colorbar.set_label("平均丢包率%", fontsize=14) colorbar.set_label("平均丢包率", fontsize=14)
colorbar.ax.tick_params(labelsize=12) colorbar.ax.tick_params(labelsize=12)
output_path.parent.mkdir(parents=True, exist_ok=True) output_path.parent.mkdir(parents=True, exist_ok=True)

View File

@@ -130,8 +130,8 @@
} }
% 可以使用 nomencl 生成符号和缩略语说明 % 可以使用 nomencl 生成符号和缩略语说明
% \usepackage{nomencl} \usepackage{nomencl}
% \makenomenclature \makenomenclature
% 表格加脚注 % 表格加脚注
\usepackage{threeparttable} \usepackage{threeparttable}