前言
tiger是基于C++ 11标准编写, 用于构建可扩展的分布式服务框架。整体设计思路清晰,理解成本低。不管是作为服务器的入门学习还是商业服务器的构建,tiger都是一个不错的选择。
GitHub
配置系统
使用配置前需要先声明,即约定优于配置,如果没有提前声明配置不会解析对应字段
- 支持
std基本数据类型std::string,std::vector,std::list,std::set,set::unordered_set,std::map,std::unordered_map
- 支持自定义类型(需要自己写对应的偏特化模板)
日志系统
- 支持标准控制台输出
- 支持文件输出
- 支持格式自定义
标识 说明 标识 说明 标识 说明 m 消息 p 日志级别 r 累计毫秒数 c 日志名称 t 线程id n 换行 d 时间 f 文件名 l 行号 T Tab F 协程id N 线程名称
线程系统
基于pthread封装,线程类构造之后线程即开始运行,构造函数在线程真正开始运行之后才返回。使用了范围锁来实现互斥(即构造函数来加锁,析构函数来释放锁),这种方式简化锁的操作,也可以避免忘记释放锁导致的死锁问题
协程系统
基于ucontext封装的对称协程,对外只提供yield和resume接口。大大降低了使用者对协程的理解和使用成本
协程调度器
对协程系统做的进一步封装,实现了一个N-M的协程调度器,即N个线程运行M个协程,协程可以在线程之间进行切换,也可以绑定到指定线程运行
定时器
采用最小堆设计,基于epoll超时实现定时器功能,精度毫秒级,支持在指定超时时间结束之后执行回调函数
I/O管理器
继承自协程调度器,封装了epoll,支持为socket fd注册读写事件回调函数。使用方便,灵活,扩展性高
Hook
hook系统底层相关API。hook是控制到线程粒度的,可以自由选择是否开启。通过hook可以让一些不具备异步功能的API,展现出异步的功能
- 实现
sock相关API - 实现
sleep系列函数
Socket
分装地址类为使用者提供统一接口,降低使用者对Linux的网络编程相关API和操作的理解和使用成本,从而提高开发效率
ByteArray序列化
ByteArray二进制序列化模块,提供对二进制的常用操作
- 支持读写基础数据类型
- 支持字节序转换
- 支持序列化到文件和从文件反序列化
Stream
将文件、socket封装成统一的接口。接口和设计的统一,便于后续的扩展和维护
TCPServer
基于Socket类,封装了一个通用的TCPServer的服务器类,提供简单的API,可以快速绑定一个或多个地址,监听端口,启动服务,accept连接,处理socket连接等功能。降低使用者对网络编程的理解和使用成本
HTTP
采用Ragel(有限状态机,性能媲美汇编),实现HTTP/1.1的简单协议实现和uri的解析。基于Reactor网络模型实现HTTP网络服务器
- 支持
HTTP客户端(HTTPConnection) - 支持
HTTP服务端(HTTPSession) - 支持
HTTP连接池(HTTPConnectionPool) - 支持
HTTPS
示例
HTTP服务
#include "tiger.h"
class Hello : public tiger::http::Servlet {
public:
int32_t handle(tiger::http::HTTPRequest::ptr request,
tiger::http::HTTPResponse::ptr response,
tiger::http::HTTPSession::ptr session) override {
response->set_body("Hello! I'm tiger!");
return 0;
}
};
class Bye : public tiger::http::Servlet {
public:
int32_t handle(tiger::http::HTTPRequest::ptr request,
tiger::http::HTTPResponse::ptr response,
tiger::http::HTTPSession::ptr session) override {
response->set_body("Bye!");
return 0;
}
};
int main() {
tiger::SingletonLoggerMgr::Instance()->add_loggers("tiger", "../conf/tiger.yml");
tiger::Thread::SetName("HTTP_SERVER");
TIGER_LOG_D(tiger::TEST_LOG) << "[http_server test start]";
auto iom = std::make_shared<tiger::IOManager>("HTTP_SERVER", true, 1);
iom->schedule([]() {
auto server = std::make_shared<tiger::http::HTTPServer>();
auto addr = tiger::IPAddress::LookupAny("0.0.0.0:8080");
auto ssl_addr = tiger::IPAddress::LookupAny("0.0.0.0:8081");
server->bind(addr, false);
server->bind(ssl_addr, true);
auto dsp = server->get_servlet_dispatch();
dsp->add_servlet("/hello", std::make_shared<Hello>());
dsp->add_servlet("/bye", std::make_shared<Bye>());
dsp->add_servlet(
"/close", [server](tiger::http::HTTPRequest::ptr request,
tiger::http::HTTPResponse::ptr response,
tiger::http::HTTPSession::ptr session) {
server->stop();
tiger::IOManager::GetThreadIOM()->stop();
return 0;
});
server->load_certificates("./tiger.crt", "./tiger.key");
server->start();
});
iom->start();
TIGER_LOG_D(tiger::TEST_LOG) << "[http_server test end]";
}
TCP服务
#include "tiger.h"
class EchoServer : public tiger::TCPServer {
public:
void handle_client(tiger::Socket::ptr client) override {
TIGER_LOG_D(tiger::TEST_LOG) << "[handle client:" << client << "]";
auto buf = std::make_shared<tiger::ByteArray>();
while (true) {
buf->clear();
std::vector<iovec> iovs;
buf->get_enable_write_buffers(iovs, 1024);
int rt = client->recv(&iovs[0], iovs.size());
if (rt == 0) {
TIGER_LOG_I(tiger::TEST_LOG) << "[has closed client:" << client << "]";
break;
} else if (rt < 0) {
TIGER_LOG_E(tiger::TEST_LOG) << "[client error"
<< " erron:" << strerror(errno) << "]";
break;
}
buf->set_position(buf->get_position() + rt);
buf->set_position(0);
const std::string &msg = buf->to_string();
TIGER_LOG_D(tiger::TEST_LOG) << "[Echo receive: " << msg << "]";
client->send(msg.c_str(), msg.size());
if (msg.find("stop") == 0) {
TIGER_LOG_I(tiger::TEST_LOG) << "[ECHO STOP]";
stop();
tiger::IOManager::GetThreadIOM()->stop();
}
}
}
};
void run() {
auto addr = tiger::Address::LookupAny("0.0.0.0:8080");
auto ech_server = std::make_shared<EchoServer>();
ech_server->bind(addr);
ech_server->start();
}
int main() {
tiger::SingletonLoggerMgr::Instance()->add_loggers("tiger", "../conf/tiger.yml");
tiger::Thread::SetName("TCPServer");
TIGER_LOG_D(tiger::TEST_LOG) << "[tcp_server test start]";
auto iom = std::make_shared<tiger::IOManager>("TCPServer", true, 1);
iom->schedule(run);
iom->start();
TIGER_LOG_D(tiger::TEST_LOG) << "[tcp_server test end]";
return 0;
}
该博客介绍了一个基于标准编写的可扩展分布式服务框架。涵盖配置、日志、线程、协程等系统,还包括定时器、I/O管理器等组件。采用多种设计降低使用成本,如协程调度器、Socket封装等,支持HTTP和TCP服务,适用于服务器学习与构建。
1777

被折叠的 条评论
为什么被折叠?



