Drogon — 高性能 Web 框架
Drogon 是 C++ 最快的 Web 框架之一,基于 Boost.Asio,支持 HTTP/WebSocket/协程,TechEmpower 基准测试中名列前茅。
安装
bash
# Ubuntu
sudo apt install libjsoncpp-dev libssl-dev uuid-dev zlib1g-dev
git clone https://github.com/drogonframework/drogon
cd drogon && git submodule update --init
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build && sudo cmake --install build
# vcpkg
vcpkg install drogon
# CMake
find_package(Drogon REQUIRED)
target_link_libraries(myapp PRIVATE Drogon::Drogon)快速开始
cpp
#include <drogon/drogon.h>
int main() {
// 注册路由
drogon::app()
.addListener("0.0.0.0", 8080)
.setThreadNum(4);
// 简单路由
drogon::app().registerHandler("/",
[](const drogon::HttpRequestPtr& req,
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
auto resp = drogon::HttpResponse::newHttpResponse();
resp->setBody("Hello, Drogon!");
callback(resp);
});
// JSON 响应
drogon::app().registerHandler("/api/hello",
[](const drogon::HttpRequestPtr& req, auto&& callback) {
Json::Value json;
json["message"] = "Hello, World!";
json["version"] = "1.0";
auto resp = drogon::HttpResponse::newHttpJsonResponse(json);
callback(resp);
});
drogon::app().run();
}控制器(Controller)
cpp
#include <drogon/HttpController.h>
// HTTP 控制器
class UserController : public drogon::HttpController<UserController> {
public:
METHOD_LIST_BEGIN
ADD_METHOD_TO(UserController::getUser, "/api/users/{id}", drogon::Get);
ADD_METHOD_TO(UserController::createUser, "/api/users", drogon::Post);
ADD_METHOD_TO(UserController::listUsers, "/api/users", drogon::Get);
METHOD_LIST_END
// GET /api/users/{id}
void getUser(const drogon::HttpRequestPtr& req,
std::function<void(const drogon::HttpResponsePtr&)>&& callback,
int id) {
Json::Value json;
json["id"] = id;
json["name"] = "Alice";
callback(drogon::HttpResponse::newHttpJsonResponse(json));
}
// POST /api/users
void createUser(const drogon::HttpRequestPtr& req,
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
auto body = req->getJsonObject();
if (!body) {
auto resp = drogon::HttpResponse::newHttpResponse();
resp->setStatusCode(drogon::k400BadRequest);
resp->setBody("Invalid JSON");
callback(resp);
return;
}
std::string name = (*body)["name"].asString();
Json::Value result;
result["id"] = 1;
result["name"] = name;
result["created"] = true;
auto resp = drogon::HttpResponse::newHttpJsonResponse(result);
resp->setStatusCode(drogon::k201Created);
callback(resp);
}
void listUsers(const drogon::HttpRequestPtr& req,
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
// 查询参数
auto page = req->getParameter("page");
auto limit = req->getParameter("limit");
Json::Value users(Json::arrayValue);
// ... 查询数据库
callback(drogon::HttpResponse::newHttpJsonResponse(users));
}
};协程控制器(推荐)
cpp
#include <drogon/HttpCoroController.h>
class ApiController : public drogon::HttpCoroController<ApiController> {
public:
METHOD_LIST_BEGIN
ADD_METHOD_TO(ApiController::getUser, "/api/users/{id}", drogon::Get);
METHOD_LIST_END
// 协程风格,代码更清晰
drogon::Task<> getUser(drogon::HttpRequestPtr req,
std::function<void(const drogon::HttpResponsePtr&)> callback,
int id) {
// co_await 异步数据库查询
auto result = co_await drogon::orm::CoroMapper<User>(drogon::app().getDbClient())
.findByPrimaryKey(id);
Json::Value json;
json["id"] = result.getValueOfId();
json["name"] = result.getValueOfName();
callback(drogon::HttpResponse::newHttpJsonResponse(json));
}
};中间件与过滤器
cpp
#include <drogon/HttpFilter.h>
// 认证过滤器
class AuthFilter : public drogon::HttpFilter<AuthFilter> {
public:
void doFilter(const drogon::HttpRequestPtr& req,
drogon::FilterCallback&& fcb,
drogon::FilterChainCallback&& fccb) override {
auto token = req->getHeader("Authorization");
if (token.empty() || !verify_token(token)) {
auto resp = drogon::HttpResponse::newHttpResponse();
resp->setStatusCode(drogon::k401Unauthorized);
Json::Value json;
json["error"] = "Unauthorized";
resp->setBody(json.toStyledString());
fcb(resp); // 拦截请求
return;
}
fccb(); // 放行
}
};
// 在控制器上应用过滤器
class ProtectedController : public drogon::HttpController<ProtectedController> {
public:
METHOD_LIST_BEGIN
ADD_METHOD_TO(ProtectedController::secret,
"/api/secret", drogon::Get,
"AuthFilter"); // 应用过滤器
METHOD_LIST_END
void secret(const drogon::HttpRequestPtr& req, auto&& callback) {
// 只有通过认证才能到达这里
callback(drogon::HttpResponse::newHttpResponse());
}
};数据库集成
cpp
#include <drogon/orm/DbClient.h>
// 配置数据库(config.json)
// {
// "db_clients": [{
// "name": "default",
// "rdbms": "postgresql",
// "host": "localhost",
// "port": 5432,
// "dbname": "mydb",
// "user": "postgres",
// "passwd": "password",
// "connection_number": 10
// }]
// }
// 协程数据库查询
drogon::Task<> queryUsers() {
auto db = drogon::app().getDbClient();
// 原始 SQL
auto result = co_await db->execSqlCoro(
"SELECT id, name FROM users WHERE age > $1", 18);
for (auto& row : result) {
std::cout << row["id"].as<int>() << ": "
<< row["name"].as<std::string>() << "\n";
}
// ORM(需要 drogon_ctl 生成模型)
auto users = co_await drogon::orm::CoroMapper<User>(db)
.orderBy(User::Cols::_age)
.limit(10)
.findAll();
}配置文件
json
// config.json
{
"listeners": [{"address": "0.0.0.0", "port": 8080}],
"threads_num": 4,
"log": {
"log_path": "./logs",
"logfile_base_name": "drogon",
"log_size_limit": 104857600
},
"app": {
"document_root": "./static",
"upload_path": "./uploads"
}
}cpp
int main() {
drogon::app().loadConfigFile("config.json").run();
}关键认知
Drogon 的高性能来自全异步 + 协程架构,每个请求不占用独立线程。协程控制器(HttpCoroController)是推荐用法,代码可读性接近同步。生产部署时配合 Nginx 反向代理处理静态文件和 SSL。