开发者社区 问答 正文

带有Undertow的MockServer

我目前正在尝试创建一个模拟服务器,该服务器以200ms的睡眠时间生成静态json响应(100KB)。我在启动时从光盘中读取了Json一次,并将其作为字符串存储在实例变量中,并针对每个请求进行渲染。

public class Bot {

    private String json;

    public Bot() {
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("huge.json");
    InputStreamReader inputStreamReader = new InputStreamReader(inputStream);

        try {
            JSONObject jsonObject = (JSONObject) new JSONParser().parse(inputStreamReader);
            json = jsonObject.toJSONString();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    @GET
    @Path("/endpoint")
    @Produces(MediaType.APPLICATION_JSON)
    public Response api(@QueryParam("sleep") String sleep) {

        if (sleep != null && !sleep.isEmpty() && Integer.valueOf(sleep) > 0) {
            try {
                Thread.sleep(Integer.valueOf(sleep));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }


        return Response.status(200).entity(json).build();
      }
  }

另外我的下排设置看起来像这样-

final Undertow.Builder builder = Undertow.builder()
            //.addHttpsListener("port", "0.0.0.0", sslContext)
            .addHttpListener(4080, "0.0.0.0")
            .setSocketOption(Options.SSL_CLIENT_AUTH_MODE, SslClientAuthMode.REQUESTED)
            .setSocketOption(Options.CONNECTION_LOW_WATER, 20000)
            .setSocketOption(Options.CONNECTION_HIGH_WATER, 21000)
            .setBufferSize(1024 * 16)
            .setIoThreads(Math.max(config.minIOThreads, Runtime.getRuntime().availableProcessors() - 1))
            .setSocketOption(Options.BACKLOG, 2048)
            .setServerOption(UndertowOptions.ALWAYS_SET_DATE, true)
            .setServerOption(UndertowOptions.SSL_USER_CIPHER_SUITES_ORDER, true)
            .setServerOption(Options.SSL_ENABLED_CIPHER_SUITES, CIPHER_SUITES)
            .setHandler(Handlers.header(Handlers.path().addPrefixPath("/", getRestEasyServlet(config)),
                    Headers.SERVER_STRING, "Mock Server"))
            .setWorkerThreads(20000);

    undertow = builder.build();
    undertow.start();

我正在以非常基本的最小并发/线程数为1运行apache基准测试。

ab -t 9999 -k -n 10000 -c 1 host

我原以为只有1个保持活动连接(工作线程将休眠200毫秒,并将json写入连接,最终连接将返回到池中,ab将重用此连接以发送后续请求)考虑到我要睡200ms,我将得到5的rps。但是我注意到,当我监视进程套接字时,会创建很多管道,最终它们会由于TooManyFile open Exception而最大化。

我不确定我在这里缺少什么。

展开
收起
垚tutu 2019-12-04 17:12:03 807 分享 版权
阿里云 AI 助理回答

看起来你正在使用Java构建一个RESTful API,该API从一个大的JSON文件读取数据并在每个请求上以静态内容响应,同时可选地模拟延迟。为了优化和管理这样的服务,你可以考虑以下几点,并结合阿里云的产品和服务来提升性能和效率:

  1. 对象存储OSS(Object Storage Service): 如果你的JSON文件非常大或者需要频繁更新,考虑将文件存储在阿里云的OSS中而不是直接放在应用服务器的磁盘上。这样可以减轻服务器的存储压力,同时利用OSS的高可用性和高性能访问能力。

  2. ECS(Elastic Compute Service)或函数计算FC(Function Compute):

    • ECS: 用于部署传统的基于服务器的应用。确保选择合适的实例类型以满足性能需求,特别是CPU和内存配置,以及网络带宽。
    • 函数计算FC: 如果你的服务不需要一直运行且对启动时间没有严格要求,可以考虑使用函数计算。它会根据请求自动伸缩,按实际执行时间计费,非常适合处理短暂、突发的请求。
  3. EDAS(Enterprise Distributed Application Service): 使用EDAS可以更方便地部署和管理你的Java应用,包括自动配置、监控、日志收集等功能,简化运维工作。

  4. 应用性能管理和监控: 利用阿里云ARMS(Application Real-Time Monitoring Service)来监控你的应用性能,包括响应时间、吞吐量等,帮助你及时发现并解决问题。

  5. 关于模拟延迟: 在你的代码中,如果想要实现sleep参数控制的延迟,记得将字符串转换为整数,并使用Thread.sleep()方法。注意,这可能会阻塞线程,对于高并发场景可能不是最佳实践。可以考虑异步处理或者使用更复杂的框架如Vert.x来非阻塞地处理这类逻辑。

修改你的代码示例中的延迟部分如下:

long sleepTime = 200; // 默认睡眠时间200ms
if (sleep != null) {
    try {
        sleepTime = Long.parseLong(sleep);
    } catch (NumberFormatException e) {
        // 处理无效的sleep参数
    }
}
try {
    Thread.sleep(sleepTime);
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();
    // 处理中断异常
}

综上所述,通过合理选择阿里云的服务和优化代码逻辑,你可以有效提升服务的稳定性和响应速度。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答