如何用AIO技术提高程序性能

article/2025/9/13 20:16:43

写在前面

这是一篇关于 AIO 的文章。本篇文章详细对比了几个常见的I/O模型,并且介绍了AIO相关的一些API。

我把英文原文翻译过来整理成这篇文章。目的一个是自己学习,一个是方便不习惯看英文资料的同学进行学习。

英文原文地址:

https://developer.ibm.com/articles/l-async/

英文题目是:
Boost application performance using asynchronous I/O


正文开始

AIO介绍

Linux 异步 I/O 是最近 Linux 内核新增功能。 这是 2.6 内核的标准功能,在 2.4 版本是作为补丁出现的。 AIO 背后的基本思想是允许进程启动许多 I/O 操作,而不必阻塞或等待任何操作完成。 然后可以在后面收到 I/O 完成通知后,进程进一步查询 I/O 的结果。

I/O 模型

在深入研究 AIO API 之前,让我们先梳理一下 Linux 下不同 I/O 模型。这里只是简述这些不同的模型,目的是对这些模型做一些比较让你明白他们之间的区别。图 1 显示了同步和异步模型,以及阻塞和非阻塞模型。

在这里插入图片描述

从图中我们可以看到AIO所处的位置。

同步阻塞I/O

最常见的模型之一是同步阻塞I/O模型。在此模型中,用户空间应用程序执行系统调用,这个调用会导致阻塞。 这意味着应用程序会阻塞,直到系统调用完成(数据传输完成或错误)。调用方应用程序处于等待响应的状态,但是不消耗 CPU,从这个角度来看它还算高效。

图 2 展示了传统的阻塞 I/O 模型,这也是应用程序中最常用的模型。它的行为很好理解,并且它的使用对于典型的应用程序是有效的。 当调用 read 系统调用时,应用程序阻塞并且上下文切换到内核。然后开始读取,当响应返回时(从正在读取的设备),数据被移动到用户空间缓冲区。 然后应用程序被解除阻塞(并且读取调用返回)。

在这里插入图片描述

从应用程序的角度来看,读操作的持续时间很长。但是实际上只是在内核被阻塞了。

同步非阻塞I/O

同步阻塞的一个效率较低的变体是同步非阻塞 I/O。 在此模型中,设备以非阻塞方式打开。 这意味着读操作可能不会立即完成 I/O,而是返回一个错误代码表示无法立即满足命令(EAGAIN 或 EWOULDBLOCK),如图 3 所示。

在这里插入图片描述

非阻塞的含义是 I/O 命令可能不会立即得到满足,需要应用程序进行多次调用以等待完成。这可能导致效率极低,因为在许多情况下,应用程序必须一直在等待数据可用,或者在内核中执行命令时尝试执行其他工作。 如图 3 所示,此方法会在 I/O 中引入延迟,因为数据在内核中变得可用与用户调用 read 以返回数据之间的任何间隙都会降低整体数据吞吐量。

异步阻塞I/O

另一个阻塞范例是带有阻塞通知的非阻塞 I/O。 在此模型中,配置了非阻塞 I/O,然后使用阻塞 select 系统调用来确定 I/O 描述符何时有任何的变化。 select 调用的有趣之处在于,它不仅可以为一个描述符提供通知,还可以为多个描述符提供通知。对于每个描述符,可以请求接受的通知包括:描述符写入数据、读取数据以及是否发生错误。

在这里插入图片描述

select 调用的主要问题是效率不高。 虽然它是异步通知的模型,但不建议将其用于高性能 I/O。

异步非阻塞I/O

最后,异步非阻塞 I/O 模型是一种I/O重叠处理的模型。读取请求立即返回,表示读取成功启动。然后应用程序可以在后台读取操作完成时执行其他处理。当读取响应到达时,可以生成信号或基于线程的回调来完成 I/O 操作。

在这里插入图片描述

重叠计算和在单个进程中为多个 I/O 请求的能力来自,利用了处理速度和 I/O 速度之间的差距。当一个或多个慢速I/O请求挂起时,CPU可以执行其他任务,或者更常见的是,在启动其他 I/O 时对已完成的 I/O 进行操作。

下一节将进一步剖析这个模型,看看他的API。

异步I/O出现的动机

从之前的 I/O 模型分类中,可以看出 AIO 存在的必要性。 阻塞模型要求启动应用程序在 I/O 启动时阻塞。 这意味着不可能同时重叠处理和 I/O。 同步非阻塞模型允许处理和 I/O 重叠,但它要求应用程序定期检查 I/O 的状态。 这留下了异步非阻塞 I/O,它允许处理和 I/O 重叠,包括 I/O 完成通知。

select 函数(异步阻塞 I/O)提供的功能类似于 AIO,只是它在获取结果时仍然是阻塞的。

linux中的异步I/O

本节探讨 Linux 的异步 I/O 模型,以帮助你了解如何在应用程序中应用它。

AIO 在 2.5 中首次进入 Linux 内核,现在是 2.6 生产内核的标准功能。

在传统的 I/O 模型中,有一个由唯一句柄标识的 I/O 通道。 在 UNIX® 中,这些叫做文件描述符(对于文件、管道、套接字等都是相同的)。在阻塞I/O模型中,你启动传输,系统调用在传输完成或发生错误时返回。

在异步非阻塞 I/O 模型中,可以同时启动多个传输。这需要每次传输都有一个唯一的上下文,以便可以在传输完成时识别它。 在 AIO中,一个叫aiocb(AIOI/O控制块)结构扮演这个角色。该结构包含有关传输的所有信息,包括数据的用户缓冲区。 当发生 I/O 通知(完成)时,将提供 aiocb 结构来唯一标识已完成的 I/O。 下一个章节的API部分展示了如何执行此操作。

AIO API 介绍

AIO 接口 API 非常简单,它通过几种不同的通知模型为数据传输提供了必要的功能。

这些 API 函数中的每一个都使用 aiocb 结构来启动或检查。这个结构体有许多成员变量,下面这个清单 1 只显示了必要的元素。

struct aiocb {int aio_fildes;               // 文件描述符int aio_lio_opcode;           // lio_listio (r/w/nop)使用volatile void ∗aio_buf;       // 数据缓冲区size_t aio_nbytes;            // 数据缓冲区的数据大小struct sigevent aio_sigevent; // 通知结构体/∗ Internal fields ∗/...};

sigevent 结构告诉 AIO 在 I/O 完成时要做什么。 后面还会讲到此结构。 现在我们来看看 AIO 的各个 API 函数如何工作以及如何使用它们。

aio_read

aio_read 函数请求对有效文件描述符的异步读取操作。文件描述符可以是一个文件、一个套接字,甚至是一个管道。 aio_read 函数具有以下原型:

int aio_read( struct aiocb ∗aiocbp );

aio_read 函数在请求排队后立即返回。 成功时返回值为零,错误时返回 -1,其中定义了 errno。

要执行读取,应用程序必须初始化 aiocb 结构。 以下示例说明了填充 aiocb 请求结构并使用 aio_read 执行异步读取请求(暂时忽略通知)。 它还显示了 aio_error 函数的使用,稍后会解释这个函数。

#include <aio.h>...#include <aio.h>...int fd, ret;struct aiocb my_aiocb;fd = open( "file.txt", O_RDONLY );if (fd < 0) perror("open");/∗ Zero out the aiocb structure (recommended) ∗/bzero( (char ∗)&my_aiocb, sizeof(struct aiocb) );/∗ Allocate a data buffer for the aiocb request ∗/my_aiocb.aio_buf = malloc(BUFSIZE+1);if (!my_aiocb.aio_buf) perror("malloc");/∗ Initialize the necessary fields in the aiocb ∗/my_aiocb.aio_fildes = fd;my_aiocb.aio_nbytes = BUFSIZE;my_aiocb.aio_offset = 0;ret = aio_read( &my_aiocb );if (ret < 0) perror("aio_read");while ( aio_error( &my_aiocb ) == EINPROGRESS ) ;if ((ret = aio_return( &my_iocb )) > 0) {/∗ got ret bytes on the read ∗/} else {/∗ read failed, consult errno ∗/}

打开要从中读取数据的文件后,将 aiocb 结构清零,然后分配一个数据缓冲区。

对数据缓冲区的引用放在 aio_buf 中。 随后将缓冲区的大小初始化为 aio_nbytes。 aio_offset 设置为零(文件中的第一个偏移量)。 您将要从中读取的文件描述符设置为 aio_fildes。 设置这些字段后,调用 aio_read 请求读取。 然后您可以调用 aio_error 来确定 aio_read 的状态。 只要状态是 EINPROGRESS,说明还没有完成。 否则的话请求要么成功,要么失败。

这里关注下与使用标准库函数从文件中读取的相似之处。除了aio_read的异步特性之外,另一个区别是设置读取的偏移量。 在典型的读取调用中,偏移量是在文件描述符上下文中维护的。对于每次读取,都会更新偏移量,以便后续读取处理下一个数据块。

这对于异步 I/O 是不可能的,因为您可以同时执行许多读取请求,因此你必须为每个特定的读取请求指定偏移量。

aio_error

aio_error 用来判断请求的状态。它的原型是:

int aio_error( struct aiocb ∗aiocbp );

函数可能返回如下几个状态:

  • EINPROGRESS, 请求还没有完成
  • ECANCELLED, 请求被取消
  • -1, 请求发生错误

aio_return

异步 I/O 和标准阻塞 I/O 之间的另一个区别是无法立即访问函数的返回状态,因为您没有阻塞 read 调用。 在标准读取调用中,返回状态在函数返回时提供。 对于异步 I/O则可以使用 aio_return 函数。 该函数原型:

ssize_t aio_return( struct aiocb ∗aiocbp );

只有在 aio_error 调用确定您的请求已完成(成功或错误)后,才会调用此函数。 aio_return 的返回值与同步上下文中的 read 或 write 系统调用的返回值相同(传输的字节数或 -1 表示错误)。

aio_write

aio_write 用来执行异步写入操作。 它的原型是:

int aio_write( struct aiocb ∗aiocbp );

aio_write 函数立即返回,表明请求已入队(成功时返回 0,失败时返回 -1,并正确设置了 errno)。

这类似于 read 系统调用,但有一个行为差异值得注意。 回想一下,偏移量对于 read 调用很重要。 但是,对于写入,偏移量只有在未设置 O_APPEND 选项的文件上下文中使用时才重要。 如果设置了 O_APPEND,则忽略偏移量并将数据附加到文件末尾。否则,aio_offset字段确定数据写入文件的偏移量。

aio_suspend

可以使用 aio_suspend 函数挂起(或阻塞)调用进程,直到异步 I/O 请求完成、发出信号或发生可选超时。 调用者提供了一个 aiocb 引用列表,其中至少一个的完成将导致 aio_suspend 返回。 aio_suspend 的函数原型是:

int aio_suspend( const struct aiocb ∗const cblist[],int n, const struct timespec ∗timeout );

aio_suspend 使用非常简单。 提供一个 aiocb 参考列表。 如果其中任何一个完成,则调用返回 0。否则,返回 -1,表示发生错误。 请参见下面的示例:

struct aioct ∗cblistMAX_LIST
/∗ Clear the list. ∗/
bzero( (char ∗)cblist, sizeof(cblist) );/∗ Load one or more references into the list ∗/
cblist[0] = &my_aiocb;ret = aio_read( &my_aiocb );ret = aio_suspend( cblist, MAX_LIST, NULL );

注意 aio_suspend 的第二个参数是 cblist 中元素的数量,而不是 aiocb 引用的数量。 aio_suspend 将忽略 cblist 中的任何 NULL 元素。

如果向 aio_suspend 提供超时并且发生超时,则返回 -1 并且 errno 包含 EAGAIN。

aio_cancel

aio_cancel 函数可以针对一个文件描述符取消一个或者所有的 I/O 请求。它的原型是:

int aio_cancel( int fd, struct aiocb ∗aiocbp );

要取消单个请求,需要提供文件描述符和 aiocb 引用。 如果请求成功取消,该函数返回 AIO_CANCELED。 如果请求完成,该函数返回 AIO_NOTCANCELED。

取消对给定文件描述符的所有请求,请提供该文件描述符和aiocbp的NULL引用。如果所有请求都被取消,该函数返回 AIO_CANCELED,如果至少有一个请求无法取消,则返回AIO_NOT_CANCELED,如果没有一个请求可以取消,则返回 AIO_ALLDONE。 然后,可以使用 aio_error 评估每个单独的 AIO 请求。 如果请求被取消,aio_error 返回 -1,并且 errno 设置为 ECANCELED。

lio_listio

最后,AIO 提供了一种使用lio_listioAPI函数同时启动多个传输的方法。这个函数很重要,因为它意味着可以在单个系统调用的上下文中启动大量I/O(内核上下文切换)。从性能的角度来看,这很棒,值得研究。 lio_listio API 函数具有以下原型:

int lio_listio( int mode, struct aiocb ∗list[], int nent,struct sigevent ∗sig );

mode参数可以是 LIO_WAIT 或 LIO_NOWAIT。 LIO_WAIT 会阻塞调用,直到所有 I/O 完成。 LIO_NOWAIT 在操作排队后返回。 list参数是 aiocb 引用的列表,元素的最大数量由 nent 定义。 请注意,list 的元素可能为 NULL,lio_listio 会忽略它。 sigevent 引用定义了所有 I/O 完成时的信号通知方法。

对 lio_listio 的请求与典型的读取或写入略有不同,因为必须指定操作。 下面这个示例对此进行了说明。

struct aiocb aiocb1, aiocb2;
struct aiocb ∗list[MAX_LIST];.../∗ Prepare the first aiocb ∗/
aiocb1.aio_fildes = fd;
aiocb1.aio_buf = malloc( BUFSIZE+1 );
aiocb1.aio_nbytes = BUFSIZE;
aiocb1.aio_offset = next_offset;
aiocb1.aio_lio_opcode = LIO_READ;...bzero( (char ∗)list, sizeof(list) );
list[0] = &aiocb1;
list[1] = &aiocb2;ret = lio_listio( LIO_WAIT, list, MAX_LIST, NULL );

读取操作在带有 LIO_READ 的 aio_lio_opcode 字段中注明。 对于写操作,使用 LIO_WRITE,但LIO_NOP 对于无操作也有效。

AIO通知

相信现在你已经了解了可用的AIO函数,本节将深入研究可用于异步通知的方法。我将通过信号和函数回调两个方面来说明异步通知。

使用signal做异步通知

使用信号进行进程间通信 (IPC)是UNIX中的传统机制,AIO也支持。在此范例中,应用程序定义了一个信号处理程序,当指定信号发生时调用该处理程序。

然后,应用程序指定异步请求将在请求完成时发出信号。 作为信号上下文的一部分,提供特定的 aiocb 请求以跟踪多个潜在未完成的请求。 下面这个示例演示了这种通知方法。

void setup_io( ... )
{int fd;struct sigaction sig_act;struct aiocb my_aiocb;.../∗ Set up the signal handler ∗/sigemptyset(&sig_act.sa_mask);sig_act.sa_flags = SA_SIGINFO;sig_act.sa_sigaction = aio_completion_handler;/∗ Set up the AIO request ∗/bzero( (char ∗)&my_aiocb, sizeof(struct aiocb) );my_aiocb.aio_fildes = fd;my_aiocb.aio_buf = malloc(BUF_SIZE+1);my_aiocb.aio_nbytes = BUF_SIZE;my_aiocb.aio_offset = next_offset;/∗ Link the AIO request with the Signal Handler ∗/my_aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;my_aiocb.aio_sigevent.sigev_signo = SIGIO;my_aiocb.aio_sigevent.sigev_value.sival_ptr = &my_aiocb;/∗ Map the Signal to the Signal Handler ∗/ret = sigaction( SIGIO, &sig_act, NULL );...ret = aio_read( &my_aiocb );}void aio_completion_handler( int signo, siginfo_t ∗info, void ∗context )
{struct aiocb ∗req;/∗ Ensure it's our signal ∗/if (info‑>si_signo == SIGIO) {req = (struct aiocb ∗)info‑>si_value.sival_ptr;/∗ Did the request complete? ∗/if (aio_error( req ) == 0) {/∗ Request completed successfully, get the return status ∗/ret = aio_return( req );}}return;
}

在这个示例中,设置了信号处理程序以在 aio_completion_handler 函数中捕获 SIGIO 信号。

然后初始化 aio_sigevent 结构以引发 SIGIO 通知(通过 sigev_notify 中的 SIGEV_SIGNAL 定义指定)。 当读取完成时,信号处理程序从信号的 si_value 结构中提取特定的 aiocb 并检查错误状态和返回状态以确定 I/O 完成。

就性能而言,完成处理程序是通过请求下一个异步传输来继续I/O的理想位置。这样,当一个传输完成后,立即开始下一个。

使用回调做异步通知

另一种通知机制是系统回调。 该机制不是发出通知信号,而是调用用户空间中的函数进行通知。 这个函数在 aiocb 引用初始化到 sigevent 结构中,以唯一标识正在完成的特定请求。下面是示例:

void setup_io( ... )
{int fd;struct aiocb my_aiocb;.../∗ Set up the AIO request ∗/bzero( (char ∗)&my_aiocb, sizeof(struct aiocb) );my_aiocb.aio_fildes = fd;my_aiocb.aio_buf = malloc(BUF_SIZE+1);my_aiocb.aio_nbytes = BUF_SIZE;my_aiocb.aio_offset = next_offset;/∗ Link the AIO request with a thread callback ∗/my_aiocb.aio_sigevent.sigev_notify = SIGEV_THREAD;my_aiocb.aio_sigevent.notify_function = aio_completion_handler;my_aiocb.aio_sigevent.notify_attributes = NULL;my_aiocb.aio_sigevent.sigev_value.sival_ptr = &my_aiocb;...ret = aio_read( &my_aiocb );}void aio_completion_handler( sigval_t sigval )
{struct aiocb ∗req;req = (struct aiocb ∗)sigval.sival_ptr;/∗ Did the request complete? ∗/if (aio_error( req ) == 0) {/∗ Request completed successfully, get the return status ∗/ret = aio_return( req );}return;
} 

在这个示例中,在创建 aiocb 请求之后,使用 SIGEV_THREAD 作为通知方法请求线程回调。

然后,指定特定的通知处理程序并加载要传递给处理程序的上下文(在本例中,是对 aiocb 请求本身的引用)。 在处理程序中,只需转换传入的 sigval 指针并使用 AIO 函数来验证请求的完成。

总结

使用异步 I/O 可以帮助你构建更快、更高效的 I/O 应用程序。 如果您的应用程序可以重叠处理 I/O,那么 AIO 可以帮助你构建更有效地使用可用 CPU 资源的应用程序。 虽然这种 I/O 模型与大多数 Linux 应用程序中的传统阻塞模式不同,但异步通知模型在概念上很简单,还可以简化你的设计。


http://chatgpt.dhexx.cn/article/DgkCbyV7.shtml

相关文章

08【AIO编程】

八、AIO编程 8.1 AIO编程简介 8.1.1 AIO编程概述 AIO也叫异步非阻塞&#xff0c;JDK1.7之后的新特性&#xff0c;AIO引入异步通道的概念&#xff0c;采用了 Proactor 模式&#xff0c;简化了程序编写&#xff0c;有效的请求才启动线程&#xff0c;它的特点是先由操作系统完成…

linux aio进程简介,Linux AIO机制

Linux的I/O机制经历了一下几个阶段的演进&#xff1a; 1. 同步阻塞I/O: 用户进程进行I/O操作&#xff0c;一直阻塞到I/O操作完成为止。 2. 同步非阻塞I/O: 用户程序可以通过设置文件描述符的属性O_NONBLOCK&#xff0c;I/O操作可以立即返回&#xff0c;但是并不保证I/O操作成功…

关于aio

AIO 是异步非阻塞 同步意味着&#xff0c;在进行读写操作时&#xff0c;线程需要等待结果&#xff0c;还是相当于闲置 异步意味着&#xff0c;在进行读写操作时&#xff0c;线程不必等待结果&#xff0c;而是将来由操作系统来通过回调方式由另外的线程来获得结果 AIO的read方…

linux AIO

AIO 是 Linux 下的异步读写模型&#xff0c;它是 2.6 内核提供的一个标准增强特性。对于文件的读写&#xff0c;即使以 O_NONBLOCK 方式来打开一个文件&#xff0c;也会处于 “阻塞” 状态&#xff0c;因为文件时时刻刻处于可读状态&#xff0c;而从磁盘到内存所等待的时间是惊…

AIO模型

目录 AIO模型介绍 AsynchronousServerSocketChannel&#xff1a;AIO中网络通信服务端的socket 1、future方法 2、callback回调方式 AIO 的回调方式编程 BIO、NIO、AIO的比较 1、释义 BIO&#xff1a;同步阻塞IO模型 NIO&#xff1a;同步非阻塞IO模型 AIO&#xff1a;…

java中IO模型-AIO模型

AIO模型介绍 AIO&#xff08;Asynchronous I/O&#xff09; 异步非阻塞模型&#xff0c; 在javajdk.17版本开始支持AIO&#xff0c;AIO模型需要操作系统的支持。 AIO最大的特性是异步能力&#xff0c;对socket和I/O起作用。 异步IO模型类似的 与NIO模型不同&#xff0c;读写操…

架构解密从分布式到微服务:深入理解网络,AIO

AIO AIO是I/O模型里一个很高的层次&#xff0c;体现了大道至简的软件美学理念。与NIO相比&#xff0c;AIO的框架和使用方法相对简单很多。 AIO包括两大部分:AIO Files解决了文件的异步处理问题&#xff0c;AIO Sockets解决了Socket的异步处理问题。AIO的核心概念为应用发起非…

BIO,NIO,AIO区别

BIO,NIO,AIO 总结 Java 中的 BIO、NIO和 AIO 理解为是 Java 语言对操作系统的各种 IO 模型的封装。程序员在使用这些 API 的时候&#xff0c;不需要关心操作系统层面的知识&#xff0c;也不需要根据不同操作系统编写不同的代码。只需要使用Java的API就可以了。 在讲 BIO,NIO,…

Apache CXF - 快速指南

Apache CXF - 简介 在当今的环境中&#xff0c;您可以使用多个选项来创建 Web 服务应用程序。您可以使用多种标准和广泛接受的协议中的一种或多种进行通信。例如SOAP、XML/HTTP、RESTful HTTP和CORBA&#xff08;通用对象请求代理架构&#xff0c;在过去非常流行&#xff0c;但…

java cxf 安全_CXF client在并发下的线程安全问题

这个是发生在上周周末的真实案例&#xff0c;因为cxf client 端线程安全导致的错误&#xff0c;总结出来希望其他使用cxf的兄弟注意。 首先描述一下背景&#xff0c;简单的说就是使用cxf作为web service的客户端&#xff0c;运行在weblogic上&#xff0c;连接外部的服务器。为了…

linux cxf服务端,Apache CXF 框架应用实战

一、概述 Apache CXF提供了用于方便地构建和开发WebService的可靠基础架构。它允许创建高性能和可扩展的服务&#xff0c;可以部署在Tomcat和基于Spring的轻量级容器中&#xff0c;也可以部署在更高级的服务器上&#xff0c;例如Jboss、WebSphere或WebLogic。 CXF提供了以下功能…

使用CXF调用WSDL

简介 时隔多年&#xff0c;再次遇到需要调用WebService的业务&#xff0c;对方给予的wsdl说明文档还是内网的链接&#xff0c;并且设有基础访问权限&#xff0c;即在浏览器打开wsdl链接时需要输入【用户名密码】登录后方可查看wsdl文档&#xff0c;这需要设置代理&#xff08;我…

spring5.x cxf3.4.x 服务端和客户端 非maven版本

文章目录 一、资料准备1. 官网链接2. 解压3. 依赖梳理 二、spring集成cxf2.1.创建spring项目2.2. 创建接口2.3. impl2.4. spring-cxf.xml2.5. 客户端2.6. 开源项目 一、资料准备 1. 官网链接 http://cxf.apache.org/download.html 下载apache-cxf-3.4.5.zip 2. 解压 3. 依赖…

CXF实现WebService

一、CXF简介 Apache CXF Celtix XFire&#xff0c;开始叫 Apache CeltiXfire&#xff0c;后来更名为 Apache CXF 了&#xff0c;以下简称为 CXF。CXF 继承了 Celtix 和 XFire 两大开源项目的精华&#xff0c;提供了对 JAX-WS 全面的支持&#xff0c;并且提供了多种 Binding …

SpringBoot2 整合 CXF 服务端和客户端

文章目录 一、CXF服务端1. 导入依赖2. 创建service接口3. 接口实现类4. cxf配置类5. 查看wsdl结果 二、CXF客户端2.1. 客户端2.2. 断点调试2.3. 发起调用服务开源源码. 一、CXF服务端 1. 导入依赖 <properties><cxf.version>3.3.1</cxf.version></proper…

CXF客户端乱码

CXF客户端乱码 解决办法一&#xff0c;设置服务端代码&#xff1a; 在使用CXF与其他系统对接时&#xff0c;发现对方系统响应的汉字乱码&#xff0c;使用soapui调用测试就没有问题&#xff0c;但是程序里面调用就乱码&#xff0c;很奇怪&#xff0c;乱码如下&#xff1a; 由…

SpringBoot集成CXF

CXF入门篇https://blog.csdn.net/tongxin_tongmeng/article/details/126482362Server端项目结构 Server端pom.xml <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation"…

走进cxf

一、什么是cxf 有很多人认为cxf就是webservice&#xff0c;其实cxf只是发布调用webservice的工具而已 Apache CXF Celtix Xfire&#xff0c;开始叫 Apache CeltiXfire&#xff0c;后来更名为 Apache CXF 了&#xff0c;以下简称为 CXF。Apache CXF 是一个开源的 web Service…

NewSQL ---- Mysql.8.0 与 MemSQL 7.0 大数据量查询性能对比

目录 1测试环境以及测试用例设计 1.1测试环境 1.2测试用例设计 2 千万级数据量性能测试对比 2.1 MemSQL时间范围分页查询 2.1.1 性能测试数据 2.2任务信息查询 2.2.1 性能测试数据 2.3 执行批次范围查询 2.3.1 性能测试数据 2.4 批次任务查询 2.4.1 性能测试数据 …

memsql架构2

接上次的MemSQL分布式架构介绍(一)&#xff0c;原文在这里&#xff1a;http://docs.memsql.com/latest/concepts/distributed_architecture/ 首先上张图&#xff0c;是我根据自己的理解画的&#xff0c;如有错误还请大家指出 几个概念 1、MemSQL有两种类型的表&#xff1a; ref…