标签归档:server

RSS feed of server

最后更新于 .

博客这几天由于服务器的问题打不开,在这里跟大家抱歉啦 老读者应该都知道,笔者有两个开源项目,分别是: fuload: 性能测试工具,可以用来给服务器做压力测试 bayonet: 基于两层状态机的epoll服务器框架 对于fuload的介绍,请看这里: fuload开源压力测试框架完成! 对于bayonet的介绍,请看这里: 有限状态机的C++实现(1)-epoll状态机 有限状态机的C++实现(2)-bayonet开源网络服务器框架 之前由于工作等原因,bayonet一直被搁置,最近有时间,所以就抓紧把bayonet完成了,目前功能上基本已经OK了,我简单列一下功能点:

  1. 接管了网络,调用方只需要关心业务逻辑
  2. 配置的方式,快速切换TCP-UDP
  3. 快速的增加加状态机的状态,业务可以无限拓展

代码编写中,也用到了很多技术,如引用计数来保证野指针不被访问(通过引用计数解决野指针的问题(C&C++)),延迟析构对象,等等。 由于详细介绍是个很庞大的工作,所以这里就直接放出一个基于bayonet写的http代理,我们来看一下,只需要多少代码:

#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include ...

最后更新于 .

接着上一篇文章: 有限状态机的C++实现(1)-epoll状态机,我们今天来介绍更复杂和深入的部分。 为什么会在标题中提到bayonet这个开源项目呢?笔者本人一直想要写一套架构优美、功能完善的异步server框架,也看过很多朋友、同事实现的版本,虽然功能上基本能满足需求,但是架构上我却始终觉得是有瑕疵的,直到后来和同事讨论,发现可以让一个客户端请求的到来作为一个session,而之后的每一次与其他server的交互都可以看作是一次状态转化,才感觉架构比较合理了。 简单来说即,一个session从开始到介绍会经历两种状态机的变化:

  • 1.业务逻辑层面的状态变化,例如先验证登录态,再验证权限,再获取用户资料
  • 2.每一个与其他server交互的socket自身的状态变化,如recv、send、等,而socket的状态变化会触发逻辑层的状态变化。

按照这种思路,目前的代码开发已经完成了70%,即可以正常的进行一个session的开始和结束,主要还缺一些细节的代码,比如超时的检测及超时之后的处理,健全的统计之类。好了,我们来用vs看一下代码的整体类图(图压缩比较严重,请单击后查看):

1

每个类的用处已经在途中简单说明了,这里就不再赘述,我们重点来看一下用这个框架来实现一个逻辑server时需要做哪些事情。 svr2目录下的main.cpp即实现了一个最简单的server,我们按部分来看其实现:

1.逻辑层状态的定义

class CAppFsmLogic1 : public CAppFsmBase ...

最后更新于 .

最近需要给一个现网server增加过载保护的功能,借此机会也思考了很多,简单谈谈我对这两个概念的理解和实现方法。
一.负载均衡
简单来说,就是按照目标server的参数进行合理分配,这个参数可以是失败率,也可以是响应时间,也可以是请求量,甚至是随机数。
我们来按照从简单到复杂逐个看一下几种实现。
1.轮询式
逻辑比较简单,直接看代码:

vector vecServer;
while(1)
{
    Server* server = vecServer[curIndex % vecServer.size()];
    curIndex ++;
}

如上代码就是一个简单的轮询式分配方法,这种方法优点实现简单,cpu计算少,缺点就是无法动态判断server的状态,当后端有一台server挂掉的时候,会至少1/vecServer.size()的请求。(最为严重的情况是由于单台后端server的超时导致前段全部挂死)。而且这种分配方法有一个bug,就是当每次请求结束后就释放内存,那么curIndex永远都只会为0,即每次都请求第一个server。
2.定死权重式
这种方式适用于那种需要实现就规定后端server的权重,比如A比Bserver的响应速度快,我们希望A接受的请求比B多。

//假设A,B, C server的权重分别为 10 5 2
typedef struct ...