【work记录:c++web聊天服务器】修复了终止Muduo服务器段错误的bug|将boost服务器改成集群|修复了集群后发送消息只能接收到第一条消息的bug

日期:2025.4.25(凌晨) 2025.5.8(凌晨) 2025.5.11

学习内容:

  • 注册功能

  • 添加好友

  • 修复了终止Muduo服务器段错误的bug

  • 将boost服务器改成集群

  • 修复了集群后发送消息只能接收到第一条消息的bug

个人总结:

首先先表示歉意,鸽了太久了这个项目。

由于这个月基本都是比赛,导致向比赛倾斜(实际是放松的更多,旅游月了直接)。

效果还是可以的,拿了块西安邀请金和重庆金。算是圆了没有国金的遗憾(邀请金也是金)

后面还有南昌和长春的,估计要铁牌预定了。

然后来稍微说一点点关于这个项目的内容:

以下部分内容来自之前写的:

注册功能|添加好友

阿巴阿巴,我是真的不想写前端啦。

这次主要是实现了注册功能和添加好友功能。

注册的页面就直接复制了登录的界面,都差不多,注册成功之后会发送给客户端注册成功的ID是多少,然后等待4秒就会跳转回登录页面。

修复了终止Muduo服务器段错误的bug

这里的段错误我忘了是哪里的问题了,但是当时是用了gdb调试core发现出来的,不得不说还是非常方便的,太好用了,直接就可以输出出来哪里有段错误的信息。只能说很香

将boost服务器改成集群

这里阐述一下,我们之前的进度是只有一个boost服务器与muduo服务器做对接,但是我们之前的只有muduo服务器的时候还是集群服务器,可以服务器之间通过那个redis来相互对接。所以我们也要实现这个,确切的讲,我们希望用户可以分布在很多的boost服务器里,这样也可以优化性能的同时,也不用担心所有用户都会瘫痪的问题等。

换个说法,之前我们集群是用来muduo服务器分布各个用户,因为muduo服务器里有一个存有用户的表,里面也存有各个的Connection,但是现在显然这个任务我们交给boost去做了,所以我们现在改成集群也应该是用boost集群去做,其实改起来非常的简单,毕竟我们之前的设计还算不错,在boost和muduo里都存有各个连接的表,muduo里有用户id对应连接的boost,boost里有用户id对应连接的connection,在之前的设计里我们是直接muduo找到对应的boost然后发送消息给boost,现在我们要将boost改成集群了后,其实没有什么影响,或者说其实对于我们整个的这个逻辑流程都没有任何的影响,可以无条件负担直接上nginx,算是改起来非常轻松的了。

直接上一下nginx的配置就好了。

stream{
    upstream SerVer{
        server 127.0.0.1:8080 weight=1 max_fails=3 fail_timeout=30s;
        server 127.0.0.1:8081 weight=1 max_fails=3 fail_timeout=30s;
        server 127.0.0.1:8082 weight=1 max_fails=3 fail_timeout=30s;
    }

    server{
        proxy_connect_timeout 1s;
        listen 8000;
        proxy_pass SerVer;
        tcp_nodelay on;
    }
}

我们直接改一下这个之前写的web端里连接的端口为8000,然后开了三个server去均衡就好了。

这里为什么开三个,是因为后面的bug。。。也是这个玩意卡了我好几天

修复了集群后发送消息只能接收到第一条消息的bug

这个bug,非常的诡异。

boost改成了集群之后,我们发送消息给对方的时候,对方都只能接收到我们发送的第一条消息,而这个限制会随着每一次的对方发送消息之后被刷新掉。

什么意思呢?

就是说,A给B发消息两条,B只能接收到第一条,此时如果B再给A发送消息两条,A也只能接收到第一条消息,然后A再给B发送两条消息,B还是只能接收到A的这两条消息的第一条消息,非常的诡异只能说。

随后我排查了一下,发现问题出现在,第一条消息正常,但是第二条消息由muduo发送给id对应的boost服务器的时候,那个boost服务器根本就收不到。

调试日志输出的时候不会有输出,本来以为有可能是收到了但是没有显示出来,重写了好几次的boost服务器的异步读写,但是还是没用,然后打开了浏览器的消息栏那里,发现压根就没有接收到这个消息。

所以我猜测可能是缓冲区的问题?目前其实尚不明了。

但是我注意到,如果muduo转发给boost的时候如果两个用户都在同一个服务器上面就没有问题,也就是说我们每一次接受完一次消息之后,如果当前的boost服务器会发送出去消息,形成接受一次,就发送一次的这种模式的话,就不会有什么问题。

这也是我猜测是不是缓冲区的问题的原因之一,随后可能会去系统的学习一下boost服务器。

但是目前写了一个很弱智的东西去解决,就是我们每一次接受消息之后就会发送一条没有任何意义的消息给muduo,以此来刷新掉,这样这个诡异的bug就也比较诡异的修复好了。

void ConnectionMgr::RecvFromMuduo()
{
    if (_is_reading_header)
    {
        RecvFromMuduoHead();
    }
    else
    {
        RecvFromMuduoBody();
    }
}

void ConnectionMgr::RecvFromMuduoHead()
{

    async_read(_muduo_socket, boost::asio::buffer(recv_buf_head), [this](boost::system::error_code ec, size_t)
               {
                   if (ec)
                   {
                       std::cout << "ERROR: RECVFROMMUDUO head: " << ec.message() << std::endl;
                       _muduo_socket.close();
                       return;
                   }

                   int head_len;
                   memcpy(&head_len, recv_buf_head.data(), 4); // TODO
                   std::cout << "head_len: " << head_len << std::endl;
                   recv_buf_body.resize(head_len);
                   _is_reading_header = false;
                   RecvFromMuduoBody(); });
}

void ConnectionMgr::RecvFromMuduoBody()
{

    async_read(_muduo_socket, boost::asio::buffer(recv_buf_body), [this](boost::system::error_code ec, size_t)
               {
                   if (ec)
                   {
                       std::cout << "ERROR: RECVFROMMUDUO body: " << ec.message() << std::endl;
                       _muduo_socket.close();
                       return;
                   }
                   std::string json_str(recv_buf_body.data(), recv_buf_body.size());
                   solve(json_str);
                   _is_reading_header = true;

                   auto it = _map_cons.begin();
                   json js;
                   js["1"] = 1;
                   SendToMuduo(it->second,js.dump());

                   RecvFromMuduoHead(); });
}

中间的:

auto it = _map_cons.begin();
json js;
js["1"] = 1;
SendToMuduo(it->second,js.dump());

就是我刚才提到的发送一条没有意义的代码。

然后我们的bug就修复好了233333

本来是想找出来具体的问题的,但是发现果然个人能力比较有限。唉,菜就得多练多学。

来源链接:https://www.cnblogs.com/advisedy/p/18872439

© 版权声明
THE END
支持一下吧
点赞13 分享
评论 抢沙发
头像
请文明发言!
提交
头像

昵称

取消
昵称表情代码快捷回复

    暂无评论内容