Apache的winnt_accept: Asynchronous AcceptEx failed问题

Apache访问慢与404问题

现象:】


访问apache静态的http内容,有时候比较慢,有时候“找不到网页”404错误;另外在error.log里也报错:

[Mon May 26 10:11:47 2008] [warn] (OS 64)指定的网络名不再可用。 : winnt_accept: Asynchronous AcceptEx failed.

原因:】

winnt(MPM) - Apache 2.2 参考手册有下列描述

Apache MPM winnt

说明专门为Windows NT优化过的MPM
状态MPM
模块名mpm_winnt_module
源文件mpm_winnt.c

概述

该多路处理模块(MPM)是Windows NT上的默认值。它使用一个单独的父进程产生一个单独的子进程,在这个子进程中轮流产生多个线程来处理请求。

top

Win32DisableAcceptEx 指令

说明使用accept()代替AcceptEx()接受网络链接
语法Win32DisableAcceptEx
默认值AcceptEx()是默认的,使用这个指令将禁用它。
作用域server config
状态MPM
模块mpm_winnt
兼容性仅在 Apache 2.0.49 及以后的版本中可用

AcceptEx()是一个微软的WinSock2 API ,通过使用BSD风格的accept() API提供了性能改善。一些流行的Windows产品,比如防病毒软件或虚拟专用网络软件,会干扰AcceptEx()的正确操作。如果你遇到类似于如下的错误:

[error] (730038)An operation was attempted on something that is not a socket.: winnt_accept: AcceptEx failed. Attempting to recover.

你就需要使用这个指令来禁止使用AcceptEx()

 

【解决办法:】

在httpd.conf文件中添加 Win32DisableAcceptEx 标记,如下:

<IfModule mpm_winnt.c>

ThreadsPerChild 150

MaxRequestsPerChild 10000

Win32DisableAcceptEx

</IfModule>

这样可以允许并发连接更大一些。同时性能上也不会有明显的降低。

如果Apache的error.log还是出现大量的:Sat Dec 24 17:21:28 2006] [warn] (OS 64)指定的网络名不再可
用。 : winnt_accept: Asynchronous AcceptEx failed。可以参考下列配置:

1、网上邻居->本地连接->属性->internet协议(TCP/IP)->属性->高级->wins标签->去掉启用LMhosts查询前的
勾.

2、控制面版->windows防火墙->高级标签->本地连接设置->服务的标签里勾选安全Web服务器(HTTPS)。

3、然后退出Apache,再打开启动就可以了 ,一开始我没有退出,直接在那重启,就是不可以,一定要先停止,在开启即可

<think> 我们正在处理一个编译错误,错误信息是:在文件`replication_asynchronous_connection_failover.pb.cc`的第2469行,出现了“no matching function for call to ‘google::protobuf::Arena::CreateInternal<protobuf_replication_asynchronous_connection_failover::Managed>(google::protobuf::Arena*&)’”的错误。 这个错误通常发生在使用Protocol Buffers(protobuf)的Arena分配时,编译器找不到匹配的`CreateInternal`函数模板实例。可能的原因包括: 1. 模板实例化失败:可能因为模板参数类型不匹配或者所需的构造函数不可访问。 2. 编译器无法推导模板参数:在这种情况下,我们需要显式指定模板参数。 3. 头文件版本不匹配:可能使用的protobuf库版本与生成代码的protoc版本不一致。 根据错误信息,我们尝试创建的类型是`protobuf_replication_asynchronous_connection_failover::Managed`。我们需要检查这个类型是否适合在Arena上创建。 在protobuf中,使用Arena分配对象时,通常会调用`Arena::Create`或者`Arena::CreateMessage`。但是,在生成的代码内部,可能会调用`CreateInternal`。 解决方案步骤: 1. **检查protobuf版本兼容性**:确保生成该.cc文件的protoc版本与链接的protobuf库版本一致。如果不一致,重新使用相同版本的protoc生成代码。 2. **检查类型定义**:查看`replication_asynchronous_connection_failover.proto`文件中`Managed`消息的定义,确保它没有被定义为不可构造(例如,没有私有构造函数等)。 3. **检查生成代码**:打开生成的文件,查看出错行(2469行)附近的代码。通常,生成的代码会类似这样: ```cpp Managed* new_object = Arena::CreateInternal<Managed>(arena); ``` 4. **显式指定模板参数**:虽然生成的代码一般不会出错,但有时编译器需要更多的帮助。我们可以尝试修改生成的代码(注意:修改生成的代码不是推荐做法,因为重新生成时会覆盖,但可以临时验证问题): 将出错行改为: ```cpp Managed* new_object = Arena::CreateInternal<Managed>(arena, reinterpret_cast<Managed*>(0)); ``` 或者使用C++11的`nullptr`: ```cpp Managed* new_object = Arena::CreateInternal<Managed>(arena, nullptr); ``` 这样做的目的是帮助编译器推导模板参数。 5. **升级或降级protobuf版本**:如果版本不一致,且无法重新生成代码(例如,代码是第三方提供的),则考虑升级或降级protobuf库以匹配生成代码的版本。 6. **检查编译器支持**:确保编译器支持protobuf使用的C++特性(如移动语义、右值引用等)。 但是,请注意:直接修改protobuf生成的代码是不被推荐的,因为重新生成时会覆盖。所以,首要解决方案是确保protoc和protobuf库版本一致。 根据经验,这个错误最常见的原因是版本不匹配。因此,请先检查版本。 如何检查版本? - 在生成代码时使用的protoc版本:运行`protoc --version` - 链接的protobuf库版本:查看编译时链接的库文件(如libprotobuf.so或libprotobuf.a)的版本。 如果版本不一致,请重新生成代码:使用与链接库相同版本的protoc重新编译.proto文件。 如果版本一致,那么可能是protobuf库的一个bug。在这种情况下,考虑升级protobuf到最新版本,或者查看protobuf的issue tracker中是否有类似问题。 由于这个错误发生在MySQL的代码中,而MySQL可能使用了特定版本的protobuf,所以建议按照MySQL文档的指导来编译。 另外,注意这个路径:`/media/zhang/qtcpp/mysql-boost-8.0.32/mysql-8.0.32/`,看起来是在编译MySQL。MySQL从8.0开始使用protobuf来序列化一些数据。确保你按照MySQL的构建说明,正确设置了protobuf的依赖。 如果问题仍然存在,可以尝试在MySQL的社区或bug系统中搜索类似问题。 总结步骤: 1. 确认protoc和protobuf库版本一致。 2. 如果不一致,重新生成protobuf代码(使用正确的protoc)或调整protobuf库版本。 3. 如果一致,检查编译器选项,确保C++标准(如C++11或更高)已启用。 4. 如果仍然不行,尝试在MySQL的构建系统中排除protobuf的编译问题,或者寻求MySQL社区支持。 由于这个错误信息指向了模板实例化失败,而模板实例化失败的具体原因可能很复杂,因此版本一致性检查是最可能的解决途径。 注意:在重新生成protobuf代码时,需要确保使用相同的protoc和相同的.proto文件,并且生成命令与原始生成命令一致(比如是否使用了`--protobuf-lite`选项等)。 在MySQL的编译过程中,通常会有生成protobuf代码的步骤,可以在MySQL的编译文档中查找相关信息。 如果上述方法都不能解决问题,那么可能需要查看protobuf库的源代码,了解`CreateInternal`函数的模板参数要求,并确保`Managed`类型满足这些要求。 但是,由于`Managed`类型是由protoc生成的,它应该满足protobuf库的要求。所以,再次强调,版本不一致是最大的嫌疑。 因此,我建议首先检查并确保protoc和protobuf库的版本一致。 </think> 针对编译错误 `no matching function for call to ‘google::protobuf::Arena::CreateInternal<...>’`,以下是系统性的解决方案: ### 错误原因分析 该错误通常由以下原因导致: 1. **Protocol Buffers 版本不匹配** `.pb.cc` 文件使用的 protobuf 生成器 (`protoc`) 版本与项目链接的 protobuf 库版本不一致[^1] 2. **模板实例化失败** 编译器无法识别 `CreateInternal` 模板函数对 `Managed` 类型的实例化,通常由于: - 类型未正确定义 - 构造函数访问权限问题 - C++标准不兼容 3. **头文件包含问题** 缺少必要的 protobuf 头文件或宏定义 ### 解决方案步骤 #### 1. 验证 protobuf 版本一致性 ```bash # 检查 protoc 编译器版本 protoc --version # 检查链接库版本 ldd /path/to/your/binary | grep protobuf ``` **必须确保生成 `.pb.cc` 的 `protoc` 版本与链接的 libprotobuf 版本完全一致**。若不一致: ```bash # 重新生成协议文件(在 .proto 文件目录) protoc --cpp_out=. replication_asynchronous_connection_failover.proto ``` #### 2. 检查类型定义 在 `replication_asynchronous_connection_failover.proto` 中确认 `Managed` 消息的定义: ```protobuf message Managed { required string host = 1; required uint32 port = 2; // ... 其他字段 } ``` 需确保: - 没有自定义构造函数限制 - 字段无冲突定义 #### 3. 添加显式模板实例化(临时方案) 在报错文件顶部添加: ```cpp #include <google/protobuf/arena.h> // 显式实例化模板 template<> protobuf_replication_asynchronous_connection_failover::Managed* google::protobuf::Arena::CreateInternal<protobuf_replication_asynchronous_connection_failover::Managed>(Arena* arena) { return CreateMaybeMessage<protobuf_replication_asynchronous_connection_failover::Managed>(arena); } ``` #### 4. 检查编译选项 在 `CMakeLists.txt` 中确保: ```cmake # 要求C++11或更高标准 set(CMAKE_CXX_STANDARD 11) # 添加protobuf头文件路径 include_directories(${PROTOBUF_INCLUDE_DIRS}) ``` #### 5. 清理并重新编译 ```bash make clean rm CMakeCache.txt cmake . -DPROTOBUF_VERSION=<your_version> make ``` ### 预防措施 1. 在项目中固定 protobuf 版本(推荐 v3.21+) 2. 使用 `find_package(Protobuf REQUIRED)` 确保版本一致性 3. 将 proto 文件生成步骤集成到构建系统中 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值