总体架构

Application:一个服务端代表一个Application,主要是读取用户的配置文件,根据配置文件初始化代理,启用网络线程和业务线程。

TC-epollServer:管理业务模块和网络模块。

网络模块:NetThread

网络模块中有TC_Epoller作为io复用,TC_socket可以建立socket的连接,ConnectionList是网络连接的的记录,这个模块主要和数据的收发有关。

业务模块: HandleGroup与Handle

这些是业务模块,Handle是一个业务线程,Handlegroup是一组业务线程,业务线程是调用用户定义好的rpc服务。将结果放到缓存中等待网络模块的发送。

流程

分为网络线程和业务线程,首先会有一个网络线程进行监听,接受到新的连接后,构造一个connection实例,并选择处理这个连接的其他网络线程,请求需要被读后,暂存到接收队列中,等待业务线程来接收,这就是业务线程做的事情。业务线程做完之后,要进行数据的发送,此时网络线程便又会加入到流程中。

网络模块

1.首先创建TC_EpollServer,此管理着网络模块和业务模块,通过new来创建出epollserver,在创建epollserver时,网络模块的NetThread同时会被创建出来。

2.进行网络部分的初始化:即创建监听队列,之后接收客户端的连接,建立epoll,将套接字注册到epoll中。

3.每个网络线程都有自己的epoll,只有一个线程有监听套接字,防止发生惊群现象。是一种单线程监听,多线程处理的一种方式。产生连接套接字室分发到其他不同的线程中,同时有一个连接管理链表,应该是一个线程拥有一个链表,管理连接状态。

业务模块

1.业务模块存在着问题即业务模块负责的主要是从队列中取出数据包进行rpc调用,在rpc调用时需要将找到对应的本地服务,如何找到将会是一个问题?

方法:业务线程通Bindadapter的ID索引到服务的ID,再从服务ID索引到用户自定义的ServantImp的生成器。(在服务ID中通过反射到相应的ServantImp类)通过生成器去调用相应的方法。

void ServantHelperManager::setAdapterServant(const string &sAdapter, const string &sServant) { _adapter_servant[sAdapter] = sServant; _servant_adapter[sServant] = sAdapter; }

在实现Bindadapter的ID到服务的ID时用到了中间的类ServantHelperManager来进行映射,执行ServantHelperManager:: addServant<T>():服务的ID映射到相应的方法中时也用到了ServantHelperManager。其中的T是StringServantImp后面的过程就是c++映射的过程。_servant_creator是map<string, ServantHelperCreationPtr>这是其中的映射关系,ServantHelperCreationPtr是访问rpc方法的一个指针也叫做类生成器。

/**
 * Servant
 */
class ServantHelperCreation : public TC_HandleBase
{
public:
    virtual ServantPtr create(const string &s) = 0;
};
typedef TC_AutoPtr<ServantHelperCreation> ServantHelperCreationPtr;
 
//
/**
 * Servant
 */
template<class T>
struct ServantCreation : public ServantHelperCreation
{
    ServantPtr create(const string &s) { T *p = new T; p->setName(s); return p; }
};

2.创建业务线程组,将线程组和BindAdapter,TC_EpollServer关联起来。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部