libhv FAQ

libhv是一个类似于libevent、libev、libuv的跨平台网络库,提供了更简单的接口和更丰富的协议。

项目地址:https://github.com/ithewei/libhv.git
码云镜像:https://gitee.com/ithewei/libhv.git
QQ技术交流群:739352073
libhv博客专栏:https://hewei.blog.csdn.net/category_9866493.html
libhv源码分析:https://blog.csdn.net/qu1993/category_10637982.html

Q:libhv和libevent、libev、libuv有什么不同

A:

  • libevent最为古老、有历史包袱,bufferevent虽为精妙,却也难以上手;
  • libev可以说是libevent的简化版,代码极为精简,但宏定义用的过多,代码可读性不强,且在Windows上实现不佳;
  • libuv是nodejs的c底层库,最先也是由libevent+对Windows IOCP支持,后来才改写自成一体,同时实现了管道、文件的异步读写,很强大,但结构体比较多,封装比较深;
  • libhv本身是参考了libevent、libev、libuv的实现思路,它们的核心都是事件循环(即在一个事件循环中处理IO、定时器等事件),但提供的接口最为精简,API接近原生系统调用,最容易上手;
  • 具体这几个库的写法比较见https://github.com/ithewei/libhv/tree/master/echo-servers
  • 当然这几个库的性能是接近的,都将非阻塞IO多路复用用到了极致
  • 更详细介绍见国产开源库libhv为何能被awesome-c和awesome-cpp收录

Q:libhv的定位

A:精妙小巧跨平台,简单实用易上手

  • base封装了很多跨平台的代码,如hatomic原子操作、hthread线程、hmutex线程同步,当然这都是基于configure/cmake自动生成的hconfig.hhplatform.h两个头文件中提供的平台宏、编译器宏等实现的;
  • event模块则实现了事件循环(包括IO、timer、idle),不同的平台有不同的实现,如Linux使用epollWindows使用IOCPMac使用kqueueSolaris使用evport,感兴趣的可以读一读event下的源码;
  • http模块则基于event模块实现了本世纪最为通用的应用层协议http协议,包括http服务端和客户端,libhv中examples下提供的httpd,性能可媲美nginx服务;
  • 不妨勇敢的说,libhv是c++编写HTTP API服务端/客户端最简单的库,没有之一

Q:libhv的发展规划

A:基于event模块实现更多的常见应用层协议,如MQTTrediskafkamysql等;

Q:libhv性能如何

A:上面说了,libhv、libevent、libev、libuv几个库是性能是接近的,它们都将非阻塞IO多路复用用到了极致,可使用echo-servers下提供的benchmark.sh简单做个压力测试,在我个人开发机上QPS都在28K左右,不存在量级差距;
此外libhv中提供的httpd QPS甚至略微超过nginx;

Q:libhv稳定性如何,是否商用

A:libhv自2018年5月创建,至今已有两年多迭代,400+提交,广泛用于公司IoT和HTTP API服务中,此外QQ群里也是有不少水友成功用在各种项目中,反馈很好;
请放心使用,开源且保证长期维护,QQ群里也有很多大神积极解答。

Q:libhv如何入门

A:

  • 建议先从运行项目根目录下getting_started.sh脚本开始, 你会被libhv的httpd所展示的便利性所吸引;
  • unittestexamples下的示例代码;
  • 源码阅读推荐路线base->event->http

Q:libhv如何使用

A:libhv可通过Makefilecmake编译出动态库和静态库,make install后包含相关头文件(base模块下头文件比较分散,可直接#include "hv.h")和链接库文件即可使用;当然libhv模块划分清晰,低耦合,你也可以直接把源文件拿到自己项目中去编译,如日志功能hlog.hhlog.c就可以直接拿去用。

Q:libhv在Windows下如何编译

A:Windows下编译libhv请先使用cmake生成VS工程。
附VS各版本下载地址VS2008 ~ VS2019下载地址
cmake官网下载过慢的可以到gitee下载cmake releasehttps://gitee.com/ithewei/cmake-release
cmake不会使用的请自行百度

Q:Windows下编译不过

A:Windows下VS编译最低要求VS2015(包括VS2015)版本,这是因为http模块中使用了一个modern c++ JSON解析库nlohmann::json,该json库使用方法见https://github.com/nlohmann/json

Q:Windows下链接不过

A: Windows下cmake生成vs工程,打开hv.sln编译后会生成头文件include/hv、静态库lib/hv_static.lib和动态库lib/hv.dll,所以有动态库和静态库两种链库方式:

1、动态导入库hv.lib + 动态库hv.dll

方案一:工程-> 属性 -> Linker -> Input -> Addtional Dependencies 加 hv.lib
方案二:代码里添加#pragma comment(lib, "hv.lib")

2、静态库声明宏HV_STATICLIB + 静态库hv_static.lib

  • 工程–>属性–>c/c++–>预处理器–>预处理器定义中添加HV_STATICLIB预编译宏,以屏蔽hexport.h头文件中动态库导入宏#define HV_EXPORT __declspec(dllimport)
    如使用curl静态库类似加CURL_STATICLIB预编译宏
  • 工程-> 属性 -> Linker -> Input -> Addtional Dependencies 加 hv_static.lib
    代码里添加#pragma comment(lib, "hv_static.lib")

Q:httpd如何开启https功能

A:libhv中集成了openssl来支持SSL/TLS加密通信,通过打开config.mkCMakeList.txtWITH_OPENSSL选项,编译即可。

Makefile方式:

./configure --with-openssl
make clean && make && sudo make install

cmake方式:

mkdir build
cd build
cmake .. -DWITH_OPENSSL=ON
cmake --build .
sudo cmake --install .

ldd lib/libhv.so包含libssl.so、libcrypto.so表示已链接openssl

测试https:

bin/httpd -s restart -d
bin/curl -v http://localhost:8080
bin/curl -v https://localhost:8443
# curl -v https://127.0.0.1:8443 --insecure

当然你也可以用nginxhttps代理。

Windows下请自行下载或编译openssl,将openssl头文件include和库文件lib(包括libssl.dll.a=>ssl.liblibcrypto.dll.a=>crypto.lib)放到libhv可搜索路径(如libhv根目录下includelib)。
giteeWindows openssl已编译好的https://gitee.com/ithewei/openssl-release.git

Q:httpd如何上传、下载文件

A:上传文件推荐使用Content-Type: multipart/form-data,服务端示例见examples/httpd/handler.h中的/upload ,客户端测试可使用curl命令bin/curl -v localhost:8080/v1/api/upload -F "file=@LICENSE"
(传输文件一般使用form-data格式,使用json传输二进制文件需要base64编码成可打印文本,3字节变4字节增加了负载;对于大文件分片传输可自行百度HTTP头Range的使用)
下载文件就不用多说了,web服务器本身就是文件服务器,httpd中已实现了web服务器,类似于curl http://ip:port/index.html,下载文件curl http://ip:port/path/to/filename响应中的body即是文件内容

Q:c++已经跨平台,base模块为何要封装跨平台操作

A:
1、c++标准库提取的是所有操作系统的共性,所以它甚至不能像其它语言(没有操作系统包袱,只需要满足主流操作系统)那样提供通用的时间日期操作,也没有提供差异化的锁(自旋锁、读写锁),你可以发现java中锁的类型一大堆,而c++只有一个mutex;至于没有提供标准网络库,更是c++一直被诟病之处。
2、event模块是纯c实现的,libevent、libuv也是如此,底层库使用c++性能有损、库大小、复杂度也会增加,并不会带来编码上的简化。如果只把libhv当作libevent来使用,关闭WITH_HTTP选项,是可以做到不依赖stdc++的。event模块本身也是封装了各种操作系统的IO多路复用机制(如linux的epollbsd的kqueue通用的select、poll等),提供出了统一的非阻塞IO接口。
3、http模块使用c++的考量,是为了接口使用上的便利性(HttpRequestHttpResponse中使用了map、string来表示headers、bodyjson、form、kv来存储各种Content-Type解析后的结构化数据,Get、Set模板函数屏蔽了int、float、string之间的类型转化),你如果使用过libeventevhttp就会发现,c写这些会非常痛苦。
4、没有任何贬低或者褒奖c、c++,归根结底它们只是有各自特色的编程语言,只是你实现业务的工具,避其糟粕、用其精华、为你所有,才是其价值。
如果你是写数据库的CRUD应用,提供http api服务,我也并不推荐使用libhv,使用golang、python、ruby它不香吗?c++ http库使用场景可能就是需要将c接口SDK的算法功能以http api服务的方式提供出去。

Q:libhv提倡的编程范式?

A:
c/c++本身是一种支持多编程范式的语言,简单的函数式编程,流行的OOP面向对象编程、还有c++的GP泛型编程,也就是模板编程。语言没有谁好谁坏,只有其适用场景,编程范式亦是如此。c with class我认为恰恰是c++最精华之处。

所以event模块中将IO、timer、idle统一抽象成事件,方便放入事件队列中统一调度,也是一种OOP的思想,而http模块中也不是全是class,也有很多函数式,强行封装成类,反而显得别扭。

而模板编程的核心是使静态类型语言具有动态类型的泛化,STL就是泛型编程的典范,其提供的容器如vector、list、deque、map、set、算法如max、min、sort、count、find、search、transform,应该是每个c++ coder应该熟练掌握的,即使如此,它的源码可读性还是很低,所以没有一定的功底和必要性,不推荐烂用模板编程。

ithewei CSDN认证博客专家 c/c++ Qt libhv
编程之路,其路漫漫,吾将上下而求索
https://github.com/ithewei
https://hewei.blog.csdn.net
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 代码科技 设计师:Amelia_0503 返回首页