Chinaunix首页 | 论坛 | 博客
  • 博客访问: 8136464
  • 博文数量: 594
  • 博客积分: 13065
  • 博客等级: 上将
  • 技术积分: 10324
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-26 16:44
个人简介

推荐: blog.csdn.net/aquester https://github.com/eyjian https://www.cnblogs.com/aquester http://blog.chinaunix.net/uid/20682147.html

文章分类

全部博文(594)

分类: Mysql/postgreSQL

2014-06-24 13:06:08

与慢速设备通讯异步化方案.pdf像MySQL、被对接的银行系统等,都可称作慢速设备。它们的共同特点是只提供了同步调用接口,而且响应通常会比较慢。

 

一般业务系统在业务线程或进程中,直接调用它们提供的API进行访问,如下图所示:

 

 

结果造成了以下两大问题:

1) 性能低:同步阻塞方式;

2) 可靠性差:业务系统和慢速设备强耦合。

 

性能低,是因为慢速设备不能快速响应返回结果;可靠性差,是因为业务系统和慢速设备没有解耦合,比如当慢速设备的API因异常被长时间挂起时,会导致业务系统的线程或进程也一同被挂起。

 

要解决性能低,就需要异步化,也就是业务系统可异步访问慢速设备;要解决可靠性差,就需要两者间解耦合。

 

下图所示的方案,针对这两个问题进行了优化,即实现了异步化,也做到了解耦合:

 

 

以MySQL为例,业务系统在向MySQL发起SQL操作时,不再直接调用MySQLAPI,而是将SQL放入到队列中,然后立即返回。

针对每一个MySQL实例,都会有一个侍服线程,与它建立一对一对绑定关系,也就是这个线程专门为它服务的,如果有多个MySQL实例,则有相应个数的侍服线程,侍服线程不会跨MySQL实例。

侍服线程会实时监听队列,当有数据时,立即取出来,然后调用MySQLAPI执行SQL操作,这个过程是同步的,侍服线程会阻塞,直到MySQL返回结果。

 

对于MySQL返回的结果,有两种业务系统的方式:一是由侍服线程回调业务,对结果的处理权在侍服线程;二是将结果存入结果队列,然后业务可以以epoll的方式取出结果,这种方式可以让对结果的处理权回归到业务线程。

 

1) 侍服线程回调业务实现方式

 

下面以伪代码方式,展现实现方式:

void mysql_thread()

{

while (true)

{

sql = _sql_queue.pop(); // 阻塞等待队列中有SQL,如果有,则取出SQL

result = mysql.query(sql); // 调用MySQL接口,进行SQL操作,结果存在result

 

service->callback(result); // 回调业务接口,让业务对结果进行处理

}

}

 

2) 以epoll的方式取出结果

这种方式让对结果的处理权回归到业务线程。实现方式非常简单,只需要结果队列是可以epoll的即可,通常可以借助eventfdpipe来包装一个队列,让这队列可以epoll监听。侍服线程只需要将结果存入结果队列,然后会自动唤醒处于等待状态的epoll

 

异步化方案不能支持事务,关键原因是事务和MySQL连接有绑定关系,同一个连接不支持多个并发的事务

 

阅读(4955) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~