腾讯IM后台架构升级:1.4亿在线的高可用挑战与解决方案

需积分: 0 3 下载量 149 浏览量 更新于2024-08-16 收藏 1.39MB PPT 举报
IDC的实际可用性对于任何在线服务提供商都至关重要,特别是对于像腾讯这样的巨头,其即时通讯(IM)平台QQIM每日承载着7亿活跃账户,1.4亿同时在线用户,以及过万台服务器,服务请求量达到百亿级。腾讯的技术团队在2011年10月31日的腾讯大讲堂活动中,分享了他们如何从早期的IM后台架构演变过程中应对这一挑战,实现99.99%的高可用性。 最初的IM后台1.0阶段,设计主要针对十万级以下的在线用户,业务功能简单,主要包括接入服务器、存储服务器,以及基础的数据结构如UIN(统一身份标识符)和好友列表。核心数据结构如在线状态、IP/Port和好友表位置,支持登录、实时通知和定期拉取等功能。然而,当用户数量突破百万级时,这种架构开始显现瓶颈,例如接入服务器的内存压力增大,每个在线用户占用约2KB,导致性能和扩展性受限。 为了满足更高的业务需求,如视频、语音和文件传输等实时宽带业务,以及支持更多用户类型和资料,腾讯推出了IM后台1.5版本。这个升级引入了长连接服务器,能够处理无法直接连接的客户端的实时数据传输,并实现了存储服务器的轻重分离,确保核心服务器的稳定性,而扩展服务器则可以快速响应业务增长。这一代架构的引入显著提升了系统的可扩展性和对大规模并发的支持。 然而,即使有这些改进,当用户规模进一步达到亿级时,仅依赖一个IDC显然不足以保证未来的发展。腾讯认识到老架构的局限性,强调了进行容灾改造的重要性,这意味着必须将服务分散到多个数据中心(B或C级别),以提高服务的可靠性。在面对亿级在线的同时,团队也积累了丰富的经验,认识到对海量服务的理解是通过长期的实践中不断学习和优化得来的。 腾讯的IM后台架构演变历程展示了在面对海量用户和高可用性要求时,技术团队如何通过迭代升级和架构优化来应对挑战,同时也揭示了在云计算时代,保持系统弹性、冗余和可扩展性的必要性。这对于任何追求高可用性和业务连续性的IT企业来说,都具有重要的启示作用。

void DlgCheck::OnSize(UINT nType, int cx, int cy) { CDialogEx::OnSize(nType, cx, cy); if (nType == SIZE_RESTORED || nType == SIZE_MAXIMIZED) { float fsp[2]; POINT Newp; //获取现在对话框的大小 CRect recta; GetClientRect(&recta); //取客户区大小 Newp.x = recta.right - recta.left; Newp.y = recta.bottom - recta.top; fsp[0] = (float)Newp.x / Old.x; fsp[1] = (float)Newp.y / Old.y; CRect Rect; int woc; CPoint OldTLPoint, TLPoint; //左上角 CPoint OldBRPoint, BRPoint; //右下角 HWND hwndChild = ::GetWindow(m_hWnd, GW_CHILD); //列出所有控件 while (hwndChild) { woc = ::GetDlgCtrlID(hwndChild);//取得ID GetDlgItem(woc)->GetWindowRect(Rect); ScreenToClient(Rect); OldTLPoint = Rect.TopLeft(); TLPoint.x = long(OldTLPoint.x * fsp[0]); TLPoint.y = long(OldTLPoint.y * fsp[1]); OldBRPoint = Rect.BottomRight(); BRPoint.x = long(OldBRPoint.x * fsp[0]); BRPoint.y = long(OldBRPoint.y * fsp[1]); Rect.SetRect(TLPoint, BRPoint); GetDlgItem(woc)->MoveWindow(Rect, TRUE); hwndChild = ::GetWindow(hwndChild, GW_HWNDNEXT); } Old = Newp; } if (this->IsPicDerec) { this->drawDerection();//此处因不明原因无法绘制成功,必须绘制两次,待修复 } if (this->IsPicShow) { cv::Mat res = this->getPic().clone(); if (!this->getBackPic().empty()) { vector<vectorcv::Point> contours; cv::findContours(this->getBackPic(), contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);//查找外层轮廓 cv::drawContours(res, contours, -1, cv::Scalar(255)); } else { res = this->getPic(); } if (res.empty()) { AfxMessageBox("Empty res"); } this->DrawcvMat(res, IDC_Picture); } if (this->IsPicDerec) { this->drawDerection(); } }为什么第一次drawDerection()绘制的图片没有显示?

2023-05-30 上传