1、线程共享地址空间,从而可以高效地共享数据。
2、非阻塞IO+IO多路复用模型
while(!done)
{
int timeout_ms=max(1000,getNextTimedCallback());
int retval=::poll(fds,nfds,timeout_ms);
if(retval<0)
{
//处理错误,回调用户error handler
}else{
//处理到期的timers,回调用户timers handler
if(retval>0)
{
//处理IO事件,回调用户IO event handler
}
}
}
基于事件驱动的编程模型本质的缺点,它要求事件回调函数必须是非阻塞的。对于涉及网络IO的请求响应式协议,它容易割裂业务逻辑,使其散布于多个回调函数之中,相对不容易理解和维护。
3、多线程服务器常用模型
3.1 one loop per thread
event loop代表了线程的主循环,需要让哪一个线程干活,就把timer或IO channel注册到哪一个线程的loop。
3.2 线程池
typedef boost::function<void()>Functor;
BlockingQueue<Functor>taskQueue;//线程的阻塞队列
void workerThread()
{
while(running)
{
Functor task=taskQueu.task();//this block
task();
}
}
//启动容量为N的线程池:
int N=num_of_computing_threads;
for(int i=0;i<N;++i)
{
create_thread(&workerThread);
}
//使用
Foo foo;
boost::function<void()>task=boost::bind(&Foo::calc,&foo);
taskQueue.post(task);
4、进程间通信只用TCP
选择socket的好处: 跨主机,具有伸缩性。TCP port由一个进程独占,且操作系统会自动回收,说明即使程序意外退出,也不会给系统留下垃圾。如果一个进程崩溃了,操作系统会关闭连接,另一个进程几乎立刻能感知。
tcpdump和wireshark解决进程间协议和状态争端的好帮手,也是性能分析器。tcpcopy压力测试。
一个分布式系统是由运行在多台机器上的多个进程组成,进程之间采用TCP长连接。
5、系统性能的基本概念
QPS(TPS):每秒钟request/事务 数量
并发数: 系统同时处理的request/事务数
响应时间: 一般取平均响应时间
QPS(TPS)= 并发数/平均响应时间