免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: wlmqgzm
打印 上一主题 下一主题

[C++] ASIO,无锁,高并发,高可靠, 统一,网络架构,抗DOS,低端4核心服务器CPU 每秒87万QPS ECHO [复制链接]

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
21 [报告]
发表于 2015-10-19 10:38 |只看该作者
本帖最后由 yulihua49 于 2015-10-19 10:39 编辑
wlmqgzm 发表于 2015-10-15 00:04
我实现了无锁(mutex)的高并发高可靠网络服务器架构, 很高兴.

Boost asio 很强大, 做了一个代码中完全无锁 ...


不错。开源不?
API容易使用否?
给个API的例子看看。

论坛徽章:
9
程序设计版块每日发帖之星
日期:2015-10-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-01 06:20:00程序设计版块每日发帖之星
日期:2015-11-02 06:20:00每日论坛发贴之星
日期:2015-11-02 06:20:00程序设计版块每日发帖之星
日期:2015-11-03 06:20:00程序设计版块每日发帖之星
日期:2015-11-04 06:20:00程序设计版块每日发帖之星
日期:2015-11-06 06:20:00数据库技术版块每周发帖之星
日期:2015-12-02 15:02:47数据库技术版块每日发帖之星
日期:2015-12-08 06:20:00
22 [报告]
发表于 2015-10-19 10:43 |只看该作者
本帖最后由 wlmqgzm 于 2015-10-19 12:29 编辑

回复 21# yulihua49

class Asio_tcp_server
{
  public:
    Asio_tcp_server( boost::asio::io_service &ios_public_in,  boost::asio::io_service &ios_serial_in,  unsigned short port );
    ~Asio_tcp_server();
    void set_process( std::function< void (std::vector<char> &  ,  std::vector<char> & ) >  function_in );
    void set_socket_debug(  int socket_handle, bool bool_debug=true );

//  这个是内部实现, 用户需要只调用一次此命令,  就永远不管了.
void Asio_tcp_server::set_process( std::function<void(std::vector<char> &,std::vector<char> &)>  function_in )
{
   function_process = function_in;
   return;
}


//  这里才是真正处理数据的地方,  
//  调用一次 void set_process( std::function< void (std::vector<char> &  ,  std::vector<char> & ) >  function_in );
//  设置以后, 就可以, 这个是可以在运行中修改的,  
//  可以进行版本切换实验, 或者升级时定时切换版本, 不需要人到现场,
//  或者可以根据某些情况, 自动选择版本或者处理方式, 很方便

下面是范例, ECHO服务器的全部调用代码
// input是客户端发过来的数据, input数据可能不是一个完整的数据包, 下次收到的数据包, 会附加到input后面
//  处理多少input数据, 代码要清理多少input数据, output进入时是空的,  代码要设置返回给客户端的内容,
default_function_process( std::vector<char> &vt_input,
     std::vector<char>  &vt_output )
{
  copy_vector_char( vt_input, vt_output );
  //  所有的输入数据都处理完毕,  清除输入数据
  vt_input.clear();
  return;
}

代码才刚做, 还有很多测试, 改进的余地,  现在只考虑做代码, 其他事情, 类似开源,.以后在想.
应该说, 这个应该是目前所有网络服务器中, 调用API接口最简单的, 呵呵呵呵

论坛徽章:
9
程序设计版块每日发帖之星
日期:2015-10-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-01 06:20:00程序设计版块每日发帖之星
日期:2015-11-02 06:20:00每日论坛发贴之星
日期:2015-11-02 06:20:00程序设计版块每日发帖之星
日期:2015-11-03 06:20:00程序设计版块每日发帖之星
日期:2015-11-04 06:20:00程序设计版块每日发帖之星
日期:2015-11-06 06:20:00数据库技术版块每周发帖之星
日期:2015-12-02 15:02:47数据库技术版块每日发帖之星
日期:2015-12-08 06:20:00
23 [报告]
发表于 2015-10-19 11:01 |只看该作者
本帖最后由 wlmqgzm 于 2015-10-19 11:26 编辑

线程池调用API
class Asio_thread_pool
{
  public:
     Asio_thread_pool( float float_multi=1.0 );   // multi 是放大倍数, 就是逻辑CPU X multi = ios_public 线程数,  默认是1倍, 建议可以设置1-4倍, , 部分情况下适当提高倍数, 可以提高性能表现
     ~Asio_thread_pool();
     unsigned int thread_count( void) ;       // 返回 ios_publicc 线程数,  内部无任何处理, 只取一个值
     boost::asio::io_service   ios_public;     //  ios_public  是多处理器CPU均可以并发处理的构件, 对于高性能并发任务在此处理
     boost::asio::io_service   ios_serial;    // ios_serial 固定只能单CPU线程运行, 无任何并发, 因此, 处理集中放置的数据完全不使用锁
  private:

我的包括线程池的全部测试代码
    Asio_thread_pool  pool1(2);
    boost::asio::io_service::work  work_serial( pool1.ios_serial );   //  本行可选, 设置后ASIO调度采用自带循环调度, 否则采用我做的外循环调度代码,效率, 理论上可能ASIO内循环更高 , 还没有测试过, 不设置, 地址池也一样工作, 推荐设置
    boost::asio::io_service::work  work_public( pool1.ios_public );  //  本行可选, 设置后ASIO调度采用自带循环调度, 否则采用我做的外循环调度代码,效率, 理论上可能ASIO内循环更高 , 还没有测试过, 不设置, 地址池也一样工作, 推荐设置
    Asio_tcp_server  serv( pool1.ios_public,  pool1.ios_serial, port );
//  这里没有SET function,  因为我内置了一个默认ECHO服务器

    while(1) {  //  这里只是循环sleep,  退出后, 上面的 class会依次释放, 最终安全退出
      usleep(1000000);
      std::cin>>str_in;
      if( "quit"==str_in )   break;
      }
大约四行代码, 就实现了一个ECHO 网络服务器

论坛徽章:
9
程序设计版块每日发帖之星
日期:2015-10-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-01 06:20:00程序设计版块每日发帖之星
日期:2015-11-02 06:20:00每日论坛发贴之星
日期:2015-11-02 06:20:00程序设计版块每日发帖之星
日期:2015-11-03 06:20:00程序设计版块每日发帖之星
日期:2015-11-04 06:20:00程序设计版块每日发帖之星
日期:2015-11-06 06:20:00数据库技术版块每周发帖之星
日期:2015-12-02 15:02:47数据库技术版块每日发帖之星
日期:2015-12-08 06:20:00
24 [报告]
发表于 2015-10-19 11:40 |只看该作者
本帖最后由 wlmqgzm 于 2015-10-19 12:00 编辑

我的地址池, 测试代码, 也是高可靠性设计, 不会丢失一个任务包.  
主程序退出后, 后台会继续完成已经提交的任务.

Log: Time=2015-10-19T11:38:43.670560, Line=54, File="/cpp/mysql1/asio_thread_pool.hpp", Func="Asio_thread_pool", Msg="Asio_thread_pool start for  ios_public thread_count=2"
Log: Time=2015-10-19T11:38:43.670621, Line=159, File="/cpp/mysql1/asio_thread_pool.hpp", Func="test_asio_thread_pool", Msg="test main thread game over."
0.000012s wall, 0.000000s user + 0.000000s system = 0.000000s CPU (n/a%)    //注意这里: 主进程已经退出,  调用了boost::timer::auto_cpu_timer 的析构函数
Log: Time=2015-10-19T11:38:43.870671, Line=123, File="/cpp/mysql1/asio_thread_pool.hpp", Func="calc_sum", Msg="run3 begin. "
Log: Time=2015-10-19T11:38:43.870685, Line=123, File="/cpp/mysql1/asio_thread_pool.hpp", Func="calc_sum", Msg="run1 begin. "
Log: Time=2015-10-19T11:38:43.870787, Line=130, File="/cpp/mysql1/asio_thread_pool.hpp", Func="calc_sum", Msg="run1 end. sum=5000050000"
Log: Time=2015-10-19T11:38:43.870817, Line=123, File="/cpp/mysql1/asio_thread_pool.hpp", Func="calc_sum", Msg="run4 begin. "
Log: Time=2015-10-19T11:38:43.870696, Line=123, File="/cpp/mysql1/asio_thread_pool.hpp", Func="calc_sum", Msg="run2 begin. "
Log: Time=2015-10-19T11:38:43.880792, Line=130, File="/cpp/mysql1/asio_thread_pool.hpp", Func="calc_sum", Msg="run4 end. sum=50000005000000"
Log: Time=2015-10-19T11:38:43.881228, Line=123, File="/cpp/mysql1/asio_thread_pool.hpp", Func="calc_sum", Msg="run6 begin. "
Log: Time=2015-10-19T11:38:43.881268, Line=130, File="/cpp/mysql1/asio_thread_pool.hpp", Func="calc_sum", Msg="run6 end. sum=5000050000"
Log: Time=2015-10-19T11:38:43.881275, Line=123, File="/cpp/mysql1/asio_thread_pool.hpp", Func="calc_sum", Msg="run7 begin. "
Log: Time=2015-10-19T11:38:43.885651, Line=130, File="/cpp/mysql1/asio_thread_pool.hpp", Func="calc_sum", Msg="run7 end. sum=50000005000000"
Log: Time=2015-10-19T11:38:43.888127, Line=123, File="/cpp/mysql1/asio_thread_pool.hpp", Func="calc_sum", Msg="run8 begin. "
Log: Time=2015-10-19T11:38:43.888171, Line=130, File="/cpp/mysql1/asio_thread_pool.hpp", Func="calc_sum", Msg="run8 end. sum=500500"
Log: Time=2015-10-19T11:38:43.888305, Line=123, File="/cpp/mysql1/asio_thread_pool.hpp", Func="calc_sum", Msg="run9 begin. "
Log: Time=2015-10-19T11:38:43.888595, Line=130, File="/cpp/mysql1/asio_thread_pool.hpp", Func="calc_sum", Msg="run9 end. sum=500000500000"
Log: Time=2015-10-19T11:38:43.905807, Line=130, File="/cpp/mysql1/asio_thread_pool.hpp", Func="calc_sum", Msg="run3 end. sum=5000000050000000"
Log: Time=2015-10-19T11:38:43.905874, Line=123, File="/cpp/mysql1/asio_thread_pool.hpp", Func="calc_sum", Msg="run5 begin. "
Log: Time=2015-10-19T11:38:43.944729, Line=130, File="/cpp/mysql1/asio_thread_pool.hpp", Func="calc_sum", Msg="run5 end. sum=5000000050000000"
Log: Time=2015-10-19T11:38:43.944760, Line=123, File="/cpp/mysql1/asio_thread_pool.hpp", Func="calc_sum", Msg="run10 begin. "
Log: Time=2015-10-19T11:38:43.944767, Line=130, File="/cpp/mysql1/asio_thread_pool.hpp", Func="calc_sum", Msg="run10 end. sum=55"
Log: Time=2015-10-19T11:38:44.186242, Line=130, File="/cpp/mysql1/asio_thread_pool.hpp", Func="calc_sum", Msg="run2 end. sum=500000000500000000"
Log: Time=2015-10-19T11:38:44.186328, Line=63, File="/cpp/mysql1/asio_thread_pool.hpp", Func="~Asio_thread_pool", Msg="~Asio_thread_pool()."
guo@guo-desktop:/cpp/mysql1/bin/Release$

// 注意主进程退出前后: 上下2个时间有200毫秒的间隔, 这个也是高可靠性设计的体现, 防止调用的主线程还没有彻底初始化完毕,或者正在初始化,  出现各种奇怪的无法定位的问题,
//  后面线程库启动时, 未来即使有超大对象, 主线程的各变量经过200毫秒的等待, 应该都初始化完成, 可以安全的使用了, 呵呵呵呵.  
//  高可靠性设计  无处不在, 细节决定成败

论坛徽章:
9
程序设计版块每日发帖之星
日期:2015-10-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-01 06:20:00程序设计版块每日发帖之星
日期:2015-11-02 06:20:00每日论坛发贴之星
日期:2015-11-02 06:20:00程序设计版块每日发帖之星
日期:2015-11-03 06:20:00程序设计版块每日发帖之星
日期:2015-11-04 06:20:00程序设计版块每日发帖之星
日期:2015-11-06 06:20:00数据库技术版块每周发帖之星
日期:2015-12-02 15:02:47数据库技术版块每日发帖之星
日期:2015-12-08 06:20:00
25 [报告]
发表于 2015-10-19 11:41 |只看该作者
本帖最后由 wlmqgzm 于 2015-10-19 11:47 编辑

上面结果的  线程池的测试代码:

void calc_sum(unsigned int id, unsigned long long int_max)  // 就是一个简单的从1---int_max的加法累加计算代码
{
  std::string str_msg;
  unsigned long long sum;
  unsigned long long i;

  str_msg = "run";
  str_msg += std::to_string(id);
  str_msg += " begin. ";
  log_message_str(str_msg,5);
  sum = 0 ;
  for(i=0; i<=int_max; ++i )  sum += i;
  str_msg = "run";
  str_msg += std::to_string(id);
  str_msg += " end. sum=";
  str_msg += std::to_string(sum);
  log_message_str(str_msg,5);
  return;
}


void test_asio_thread_pool(void)
{

  Asio_thread_pool  pool1;
  //unsigned int thread_count = pool1.thread_count;

  boost::asio::io_service &io_service1 = pool1.ios_public;
  boost::asio::io_service &io_service2 = pool1.ios_serial;
  boost::asio::io_service::work  work1( io_service1 );   //  即使没有此work定义, 由于线程池采用高可靠设计, 不会丢失未完成的任务包, 会继续执行, 直到完成任务.
  boost::asio::io_service::work  work2( io_service2 );   //  即使没有此work定义, 由于线程池采用高可靠设计, 不会丢失未完成的任务包, 会继续执行, 直到完成任务.

  boost::timer::auto_cpu_timer   a2;

io_service1.post(std::bind(calc_sum,1,100000));
io_service1.post(std::bind(calc_sum,2,1000000000));
io_service2.post(std::bind(calc_sum,3,100000000));
io_service1.post(std::bind(calc_sum,4,10000000));
io_service2.post(std::bind(calc_sum,5,100000000));
io_service1.post(std::bind(calc_sum,6,100000));
io_service1.post(std::bind(calc_sum,7,10000000));
io_service1.post(std::bind(calc_sum,8,1000));
io_service1.post(std::bind(calc_sum,9,1000000));
io_service2.post(std::bind(calc_sum,10,10));

  log_message("test main thread game over.",5);
  return;
}

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
26 [报告]
发表于 2015-10-19 13:07 |只看该作者

//  后面线程库启动时, 未来即使有超大对象, 主线程的各变量经过200毫秒的等待, 应该都初始化完成, 可以安全的使用了, 呵呵呵呵.  
//  高可靠性设计  无处不在, 细节决定成败

。。。

论坛徽章:
3
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:032015年亚洲杯之中国
日期:2015-04-22 15:52:45
27 [报告]
发表于 2015-10-19 13:35 |只看该作者
hellioncu 发表于 2015-10-19 13:07

//  后面线程库启动时, 未来即使有超大对象, 主线程的各变量经过200毫秒的等待, 应该都初始化完成, 可以 ...


echo server建议不要用本机回环地址测试...

我注意到了这句.....不是民用级别的......

这........军用?

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
28 [报告]
发表于 2015-10-19 13:54 |只看该作者
回复 20# wlmqgzm

每秒33万QPS新建连接


每秒33万到底是QPS还是新建连接?我确定一定以及肯定新建连接不可能有这么快。

论坛徽章:
9
程序设计版块每日发帖之星
日期:2015-10-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-01 06:20:00程序设计版块每日发帖之星
日期:2015-11-02 06:20:00每日论坛发贴之星
日期:2015-11-02 06:20:00程序设计版块每日发帖之星
日期:2015-11-03 06:20:00程序设计版块每日发帖之星
日期:2015-11-04 06:20:00程序设计版块每日发帖之星
日期:2015-11-06 06:20:00数据库技术版块每周发帖之星
日期:2015-12-02 15:02:47数据库技术版块每日发帖之星
日期:2015-12-08 06:20:00
29 [报告]
发表于 2015-10-19 14:41 |只看该作者
回复 27# hanxin83


    工程应用上, 以前在某大型通讯设备企业工作过, 知道到底层库的不容易.  

    当年开发公司设备底层库的牛人, 就曾经痛苦的反思过自己的不足, 以及给公司带来的损失, 发了一篇长文, 给各有关人员,  介绍自己的无知,  普及有关知识并道歉  .
   
    现在 通讯系统 通讯设备的, 内部系统无论那个重启动, 都不会丢失一个数据包, 可靠性有了很大保证.

    目前,  无业游民,  还没有找工作, 腿又骨折了, 休息中, 突然感觉, 民用级别的网络库, 还是没有这么细的考虑, 先做个库实验一下.  这个就是项目的由来.

论坛徽章:
9
程序设计版块每日发帖之星
日期:2015-10-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-01 06:20:00程序设计版块每日发帖之星
日期:2015-11-02 06:20:00每日论坛发贴之星
日期:2015-11-02 06:20:00程序设计版块每日发帖之星
日期:2015-11-03 06:20:00程序设计版块每日发帖之星
日期:2015-11-04 06:20:00程序设计版块每日发帖之星
日期:2015-11-06 06:20:00数据库技术版块每周发帖之星
日期:2015-12-02 15:02:47数据库技术版块每日发帖之星
日期:2015-12-08 06:20:00
30 [报告]
发表于 2015-10-19 14:41 |只看该作者
本帖最后由 wlmqgzm 于 2015-10-19 15:05 编辑

回复 28# windoze


   每秒33万 不是新建连接. 我重新测过, 回头贴测试结果

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP