海浩 發表於 2025-5-12 13:12:00

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

<h1 id="日期2025425凌晨-202558凌晨-2025511">日期:2025.4.25(凌晨) 2025.5.8(凌晨) 2025.5.11</h1>
<h2 id="学习内容">学习内容:</h2>
<ul>
<li>
<p>注册功能</p>
</li>
<li>
<p>添加好友</p>
</li>
<li>
<p>修复了终止Muduo服务器段错误的bug</p>
</li>
<li>
<p>将boost服务器改成集群</p>
</li>
<li>
<p>修复了集群后发送消息只能接收到第一条消息的bug</p>
</li>
</ul>
<h2 id="个人总结">个人总结:</h2>
<p>首先先表示歉意,鸽了太久了这个项目。</p>
<p>由于这个月基本都是比赛,导致向比赛倾斜(实际是放松的更多,旅游月了直接)。</p>
<p>效果还是可以的,拿了块西安邀请金和重庆金。算是圆了没有国金的遗憾(邀请金也是金)</p>
<p>后面还有南昌和长春的,估计要铁牌预定了。</p>
<p>然后来稍微说一点点关于这个项目的内容:</p>
<p>以下部分内容来自之前写的:</p>
<h3 id="注册功能添加好友">注册功能|添加好友</h3>
<p>阿巴阿巴,我是真的不想写前端啦。</p>
<p>这次主要是实现了注册功能和添加好友功能。</p>
<p>注册的页面就直接复制了登录的界面,都差不多,注册成功之后会发送给客户端注册成功的ID是多少,然后等待4秒就会跳转回登录页面。</p>
<h3 id="修复了终止muduo服务器段错误的bug">修复了终止Muduo服务器段错误的bug</h3>
<p>这里的段错误我忘了是哪里的问题了,但是当时是用了gdb调试core发现出来的,不得不说还是非常方便的,太好用了,直接就可以输出出来哪里有段错误的信息。只能说很香</p>
<h3 id="将boost服务器改成集群">将boost服务器改成集群</h3>
<p>这里阐述一下,我们之前的进度是只有一个boost服务器与muduo服务器做对接,但是我们之前的只有muduo服务器的时候还是集群服务器,可以服务器之间通过那个redis来相互对接。所以我们也要实现这个,确切的讲,我们希望用户可以分布在很多的boost服务器里,这样也可以优化性能的同时,也不用担心所有用户都会瘫痪的问题等。</p>
<p>换个说法,之前我们集群是用来muduo服务器分布各个用户,因为muduo服务器里有一个存有用户的表,里面也存有各个的Connection,但是现在显然这个任务我们交给boost去做了,所以我们现在改成集群也应该是用boost集群去做,其实改起来非常的简单,毕竟我们之前的设计还算不错,在boost和muduo里都存有各个连接的表,muduo里有用户id对应连接的boost,boost里有用户id对应连接的connection,在之前的设计里我们是直接muduo找到对应的boost然后发送消息给boost,现在我们要将boost改成集群了后,其实没有什么影响,或者说其实对于我们整个的这个逻辑流程都没有任何的影响,可以无条件负担直接上nginx,算是改起来非常轻松的了。</p>
<p>直接上一下nginx的配置就好了。</p>
<pre><code class="language-vim">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;
    }
}

</code></pre>
<p>我们直接改一下这个之前写的web端里连接的端口为8000,然后开了三个server去均衡就好了。</p>
<p>这里为什么开三个,是因为后面的bug。。。也是这个玩意卡了我好几天</p>
<h3 id="修复了集群后发送消息只能接收到第一条消息的bug">修复了集群后发送消息只能接收到第一条消息的bug</h3>
<p>这个bug,非常的诡异。</p>
<p>boost改成了集群之后,我们发送消息给对方的时候,对方都只能接收到我们发送的第一条消息,而这个限制会随着每一次的对方发送消息之后被刷新掉。</p>
<p>什么意思呢?</p>
<p>就是说,A给B发消息两条,B只能接收到第一条,此时如果B再给A发送消息两条,A也只能接收到第一条消息,然后A再给B发送两条消息,B还是只能接收到A的这两条消息的第一条消息,非常的诡异只能说。</p>
<p>随后我排查了一下,发现问题出现在,第一条消息正常,但是第二条消息由muduo发送给id对应的boost服务器的时候,那个boost服务器根本就收不到。</p>
<p>调试日志输出的时候不会有输出,本来以为有可能是收到了但是没有显示出来,重写了好几次的boost服务器的异步读写,但是还是没用,然后打开了浏览器的消息栏那里,发现压根就没有接收到这个消息。</p>
<p>所以我猜测可能是缓冲区的问题?目前其实尚不明了。</p>
<p>但是我注意到,如果muduo转发给boost的时候如果两个用户都在同一个服务器上面就没有问题,也就是说我们每一次接受完一次消息之后,如果当前的boost服务器会发送出去消息,形成接受一次,就发送一次的这种模式的话,就不会有什么问题。</p>
<p>这也是我猜测是不是缓冲区的问题的原因之一,随后可能会去系统的学习一下boost服务器。</p>
<p>但是目前写了一个很弱智的东西去解决,就是我们每一次接受消息之后就会发送一条没有任何意义的消息给muduo,以此来刷新掉,这样这个诡异的bug就也比较诡异的修复好了。</p>
<pre><code class="language-c++">void ConnectionMgr::RecvFromMuduo()
{
    if (_is_reading_header)
    {
      RecvFromMuduoHead();
    }
    else
    {
      RecvFromMuduoBody();
    }
}

void ConnectionMgr::RecvFromMuduoHead()
{

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

                   int head_len;
                   memcpy(&amp;head_len, recv_buf_head.data(), 4); // TODO
                   std::cout &lt;&lt; "head_len: " &lt;&lt; head_len &lt;&lt; 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), (boost::system::error_code ec, size_t)
               {
                   if (ec)
                   {
                     std::cout &lt;&lt; "ERROR: RECVFROMMUDUO body: " &lt;&lt; ec.message() &lt;&lt; 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-&gt;second,js.dump());

                   RecvFromMuduoHead(); });
}
</code></pre>
<p>中间的:</p>
<pre><code class="language-c++">auto it = _map_cons.begin();
json js;
js["1"] = 1;
SendToMuduo(it-&gt;second,js.dump());
</code></pre>
<p>就是我刚才提到的发送一条没有意义的代码。</p>
<p>然后我们的bug就修复好了233333</p>
<p>本来是想找出来具体的问题的,但是发现果然个人能力比较有限。唉,菜就得多练多学。</p><br><br>
来源:https://www.cnblogs.com/advisedy/p/18872439
頁: [1]
查看完整版本: 【work记录:c++web聊天服务器】修复了终止Muduo服务器段错误的bug|将boost服务器改成集群|修复了集群后发送消息只能接收到第一条消息的bug