【问题标题】:Reflection for async api异步 api 的反射
【发布时间】:2019-03-20 23:49:34
【问题描述】:

我们有 2 个服务,让我们调用 S 和 G。S 有一系列步骤,比如 a,b,c,d,e,f,在步骤 d 调用服务 G。G 通常需要很多处理导致大量超时问题的调用的时间(跨越几分钟)。为了解决这个问题,我们计划使 G 的 API 异步。 G 有近 20 个需要异步的 API。我在设计这个时有 2 个问题:

  1. 使这些异步的理想方法是使用 SQS 或 SNS 主题并让 S 监听它们。但这是一个侵入性更改,需要对代码进行大量重构,在这种情况下拆分步骤 a、b、c、d、e、f。我们正在寻找快速的东西。因此,我们计划将请求 id 存储在某个键值存储中,并让 G 的 API 在基本健全性检查后返回成功,并在后台继续处理请求。一旦完成,结果就会在键值存储中更新,同时 G 会定期轮询存储。这看起来是正确的方法吗?

  2. 要使 G 的 API 异步,我们必须为所有 20 个 API 更改/编写大量代码。我正在考虑公开一个使用反射来识别在运行时调用哪个方法的单一 API。我知道与反射相关的问题,例如没有编译时错误检测、难以重构、性能较慢,并且由于我们在面向外部客户端的 API 中引入反射,因此对传递的方法名称进行完整性检查会遇到很多问题。唯一的优点是它使我的代码更干净,干扰最小。

我想知道解决上述问题的方法。

谢谢

【问题讨论】:

    标签: java asynchronous reflection api-design


    【解决方案1】:

    将 G 的 API 设为异步并不能使其快速。它只允许与步骤 e 和 f 并行运行。如果这些步骤不需要太多时间,那么总体时间不会显着减少。

    因此,您需要回答的第一个问题是并行化是否有帮助。如果您的任务主要是顺序的,那么并行化将无济于事,甚至会使事情变慢。如果您的任务可以并行化,则可以将其表示为执行图。

    当您确定并行化有意义时,您可以选择,对于每个并行分支,它是作为线程实现还是作为异步过程调用 (APC) 实现。线程更容易编程,但会消耗一些内存(每个线程 0.5-1.0 兆字节)。如果执行图中有成百上千个并行分支,通常值得应用异步编程。我在你的任务中看不到这么多的并行化,所以我建议使用线程而不是异步过程。

    永远不要使用轮询 - 多线程和异步编程都有足够的方法及时响应事件。

    至于第二个问题,无论如何都需要一些手工工作。假设你有 API:

    interface SyncApi {
        boolean isPositive(int v1);
        int sum(int v1, int v2);
    }
    

    那么你必须写

    interface AsyncApi {
        Future<Boolean> isPositive(int v1);
        Future <Integer> sum(int v1, int v2);
    }
    

    当厌倦了 SyncApi.java 时,您可以制作一个创建 AsyncApi.java 的工具,但无论如何,您在编译时需要 AsyncApi 接口,以便能够编写对该接口的调用。

    在给定 SyncApi 实例时创建 AsyncApi 实例的适配器,可以在运行时使用 Java Proxy 机器创建。

    【讨论】:

    • 我同意它不会让它变得更快,但它有助于提高系统的可用性。我们还不确定并行化会对业务用例产生什么影响。 S 没有收到很多请求,因此我们可以让线程等待一段时间,直到处理结果。另外你对第二个问题有什么看法?
    • 所以你这里不支持使用反射?
    • @katherine class Proxy 是反射包的一部分。我的意思是,如果你想使用反射,那么我建议使用 java.lang.reflect.Proxy。
    猜你喜欢
    • 2016-07-22
    • 2022-01-19
    • 2022-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-08
    • 2019-05-26
    相关资源
    最近更新 更多