逐步实现TCP服务端Step05-2:查询数据库

这是一个服务间协作的实例,client向mainsvrd请求服务,mainsvrd根据需要向dbsvrd发起查询请求,dbsvrd查询MySQL数据库,将结果返回给mainsvrd。最后,mainsvrd完成相关业务,将结果返回给客户。

proxy的具体实现,见antframe中的proxy工程。proxy的作用是将消息转发给指定实体。每个实体由类型和ID来标识,proxy必须要掌握所有连入自己的实体的基本信息,如:实体类型,ID,IP等等。这些信息可以在连接建立后,由实体告知proxy,这就意味着proxy要完全依赖于各实体。为保险起见,在配置文件中给出各实体的基本信息,以此信息为准,对各实体通告的信息进行校验,无法匹配的,就认为是非法实体,并将连接断开。

看一下proxy的配置文件,按目前的版本,配置文件一律命名为default.cfg 。其中的[ENTITY]分节用于配置各实体信息。
从各配置项的名字也能看出其意义。因为这次只需要一个mainsvrd,一个dbsvrd来组成系统,所以MainsvrdNum和DBsvrdNum均设置为一即可,没有除二者之外的其他实体存在,所以OtherNum置为零。另外,为保持配置文件的格式,也是为方便处理,将各实体的详细信息分到相应的配置文件中单独描述。也就是下面的mainsvrds.ini、dbsvrds.ini和othersvrds.ini文件,hash2db.map比较特别,在有多个dbsvrd实体的情况下,它指定了hash值到dbsvrd的对应规则。

因为proxy程序在加载不同配置文件的时候,就可知道当前的实体类型,实体类型不需要在配置中设置。剩下的就是实体的ID和IP了。mainsvrds.ini和dbsvrds.ini的格式完全一样,假设mainsvrd和dbsvrd这两个服务实体的ID均为1,而且,把这二者与proxy部署到同一台机器上,那么这两个实体的IP设置为127.0.0.1即可。
再说一下hash2db.map,第一列为hash值/索引号,第二列和第三列为dbsvrd的ID,对应于同一个hash值的两个dbsvrd,一个是主,另一个作为备用。对于目前只使用一个dbsvrd实体的情况,将所有的ID置为1即可。

对于mainsvrd,基本结构没有变化,只是要加入新的业务处理逻辑。

讨论一下dbsvrd的实现。显然,dbsvrd工作时要等待MySQL的响应,dbsvrd的基本形式应该是多线程的。至少要有两个线程,主线程负责收取来自proxy的消息,工作线程负责处理具体业务,主要是对MySQL实施查询操作。最终的返回消息也应该由工作线程来发,毕竟业务是由工作线程处理的。工作线程应该维护一个队列,主线程会将消息投递到这个队列中供线程处理。

若要使用多个工作线程,可用proxy首部中的key值对线程个数取模,以此来检索当前消息的处理线程。

dbsvrd的具体实现见antframe中的dbsvrd工程。


<==  index  ==>