简介
本文介绍如何将chatserver设置为分布式服务,并且实现statusserver的负载均衡处理,根据每个chatserver现有的连接数匹配最小的chatserver返回给GateServer并返回给客户端。
为了实现这一系列分布式设计,我们需要先完善chatserver,增加grpc客户端和服务端。这样能实现两个chatserver之间端对端的通信。
visual studio中右键chatserver项目选择添加新文件ChatGrpcClient, 会为我们生成ChatGrpcClient.h和ChatGrpcClient.cpp文件。
连接池客户端
先实现ChatConPool连接池
1 | class ChatConPool { |
然后利用单例模式实现grpc通信的客户端
1 | class ChatGrpcClient: public Singleton<ChatGrpcClient> |
实现具体的ChatGrpcClient
1 | ChatGrpcClient::ChatGrpcClient() |
连接池服务端
向ChatServer中添加ChatServiceImpl类,自动生成头文件和源文件
1 | class ChatServiceImpl final : public ChatService::Service |
实现服务逻辑,先简单写成不处理直接返回。
1 | ChatServiceImpl::ChatServiceImpl() |
并且完善chatserver配置
1 | [GateServer] |
增加了PeerServer字段,存储对端server列表,通过逗号分隔,可以通过逗号切割对端服务器名字,再根据名字去配置里查找对应字段。
对应的chatserver复制一份,改名为chatserver2,然后修改config.ini配置。要和server1配置不同,实现端对端的配置。具体详见服务器代码。
服务器连接数管理
每当服务器chatserver启动后,都要重新设置一下用户连接数管理,并且我们每个chatserver既要有tcp服务监听也要有grpc服务监听
1 | using namespace std; |
我们在服务器启动后将本服务器的登录数量设置为0.
同样的道理,我们将服务器关闭后,也要删除对应key。
用户连接管理
因为我们用户登录后,要将连接(session)和用户uid绑定。为以后登陆踢人做准备。所以新增UserMgr管理类.
其声明如下
1 | class CSession; |
其实现如下
1 | UserMgr:: ~UserMgr() { |
RmvUserSession 暂时屏蔽,以后做登录踢人后能保证有序移除用户ip操作。
当有连接异常时,可以调用移除用户Session的接口
1 | void CServer::ClearSession(std::string session_id) { |
聊天服务完善用户登录,当用户登录后, 设置其uid对应的serverip。以及更新其所在服务器的连接数。
1 | void LogicSystem::LoginHandler(shared_ptr<CSession> session, const short &msg_id, const string &msg_data) { |
状态服务
状态服务更新配置
1 | [StatusServer] |
配置文件同样增加了chatservers列表,用来管理多个服务,接下来实现根据连接数动态返回chatserverip的功能
1 | Status StatusServiceImpl::GetChatServer(ServerContext* context, |
getChatServer用来获取最小连接数的chatserver 名字
1 | ChatServer StatusServiceImpl::getChatServer() { |
测试
分别启动两个chatserver,gateserver,以及statusserver,并且启动两个客户端登录,
分别查看登录信息,发现两个客户端被分配到不同的chatserver了,说明我们实现了负载均衡的分配方式。
源码连接
https://gitee.com/secondtonone1/llfcchat