zoukankan      html  css  js  c++  java
  • 与慢速设备通讯异步化方案

    像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连接有绑定关系,同一个连接不支持多个并发的事务

  • 相关阅读:
    平台升级至spring 4.3.0 运行稳定
    java过滤特殊字符的正则表达式
    xheditor-文件上传-java-支持html5-application/octet-stream
    java用正则方法验证文件名是否合法
    Java实现在线预览Word,Excel,Ppt文档
    为什么用freemarker视图?
    Java中判断String不为空的问题性能比较
    解决org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource
    Java Swing 使用非本地字体
    第三方包jintellitype实现Java设置全局热键
  • 原文地址:https://www.cnblogs.com/aquester/p/9891592.html
Copyright © 2011-2022 走看看