匹配系统整体架构
架构如下图所示:
匹配服务器逻辑
生产者消费者模型与消息队列
add_user
和remove_user
可以看作一个Task.- 在匹配服务器中, 有生产者线程与消费者线程.
- 生产者线程通过
match_client
调用add_user
或者remove_user
产生 (多线程服务器, 每次调用add_user/remove_user
, 服务端都会单开一个新的线程处理), 生产者线程接受请求, 产生一个Task放入消息队列中. - 消费者线程从MQ中取出Task, 然后处理Task.
- 生产者线程通过
- 具体可以通过如下思路实现:
- MQ可以使用一个普通队列, 一个
mutex
和一个条件变量实现. - 生产者线程首先获取
mutex
, 将Task放入MQ中, 然后唤醒被条件变量阻塞的线程, 最后释放锁即可. - 消费者线程是一个死循环, 循环内首先获取
mutex
, 然后判断MQ是否为空:- 如果为空, 那么直接释放锁, 之后隔1s后, 调用用户池的匹配函数 (每1s尝试匹配一次).
- 如果不空, 那么将Task从MQ取出后, 先释放锁, 然后调用用户池的相关函数添加/删除用户.
- 用户池的匹配函数需要调用数据库服务
save_data
来进行存储.
- MQ可以使用一个普通队列, 一个
匹配算法
匹配算法比较简单, 假设一个用户有分值score
, 这个用户就可以和用户池中的[score - t * 50, score + t * 50]
的用户进行匹配, 其中t
是时间, 可匹配的范围随着时间递增.