服务器架构
-
每个节点表示不同的服务器; 节点中包含其需要实现的函数.
-
箭头: 客户端$\rightarrow$服务端, 箭头上表示需要提供的接口.
实现步骤
step-1
根据$match$客户端和服务端定义的接口编写.thrift
: 定义命名空间cpp match_service
; 结构体User
;
函数add/remove_user
.
step-2
通过定义的接口和thrift
命令生成cpp
文件, 作为匹配系统的服务端. 并将其中的
Match_server.skeleton.cpp
移动至其..
, 命名为main.cpp
. (thrift
生成的服务端代码).
并稍微修改一些代码.
step-3
通过定义的接口和thrift
命令生成py
文件, 作为匹配系统的客户端. 创建client.py
, 稍微修改官网上
python
客户端的代码, 尝试向服务端发送请求.
其中Match-remote
是thrift
生成的服务端代码, 可以删除.
step-4
修改client.py
, 使其可以输入参数, 通过参数调用不同接口.
step-5
生产者/消费者模型:
-
生产
task
:MatchHandler
. 接受match_client
的传来的task
. 为了防止互斥访问,
将任务加入消息队列. -
消费
task
:consume_task
. 将task
放入匹配池中进一步做匹配或删除处理. -
匹配池–
pool
. 接受consume_task
给的实际匹配用户.根据任务类型添加或删除用户
并简单的匹配池中的前两个用户(如果有的话). -
过程:
client.py
传来一个user
, 加上任务类型构成一个task
放入消息队列中(防止同时操作);cousume_task
作为一直运行的线程消耗消息队列中的内容, 将其放入匹配池pool
中; 匹配池做匹配处理. -
实现: 在
match_server
的main.cpp
中加入Task
结构体作为生产/消费对象; 利用互斥锁和条件变量构造
一个消息队列; 实现一个consume_task
从消息队列中取出内容; 实现一个匹配池实现用户匹配.
step-6
引入已有的save.thrift
接口, 生成cpp
文件作为数据存储的客户端; 对应的服务端已在myserver
上实现.
删除生成文件中的Save_server.skeleton.cpp
—thrift
生成的服务端代码.
将官网上cpp client
的代码复制进main.cpp
中作为pool
的save_result
的部分函数.
加入缺少的.h
、删除部分示例代码, 调用已实现的接口.
到这里我们已基本用thrift
定义的接口实现上述的服务器功能. 下面进一步修改匹配逻辑,
将单线程修改为多线程环境.
step-7
修改匹配逻辑: 如果两个用户的分值相差不超过50
, 则匹配.
修改cousume_task
消费者逻辑:
- 当消息队列中没有
task
时, 不阻塞自己而是每一秒都尝试匹配用户(pool
中).
step-8
通过官网样例代码, 将单线程修改为多线程: 加入少的头文件; 加入server main
中的代码;
加入class Factory
并修改部分代码.
step-final
加入等待时间; 每个用户进入匹配后每多等待1
秒, 其可匹配范围增加x
.
-
在
pool
中加入wt
与user
同步操作. -
每次匹配操作前, 让
wt
均加1
. -
为满足每次匹配时大约经过
1
秒,consume_task
仅在消息队列为空时, 每1
秒进行一次匹配操作.
(因为我们认为输入的用户很少, 大部分时间消息队列都为空, 所以这里操作可行). -
在匹配操作时判断两个用户的分差是否小于两者的等待时间$\times$
x
.
赞
谢谢😄
牛牛牛
谢谢😄