您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > JAVA

gRPC三种Java客户端性能测试实践

时间:2022-07-07 11:01:14  来源:  作者:FunTester

我之前分享了JAVAGo语言版本的gRPC接口的服务端和客户端的开发,使用的基本都是基础的原声API,旧文如下:

  • Grpc服务开发和接口测试初探【Java】 2022-04-20
  • gRPC服务开发和接口测试初探【Go】 2022-05-07
  • gRPC三种客户端类型实践【Java版】 2022-05-11

经过一段时间的摸索和尝试,我觉得又可以了,今天给大家分享一下三种Java客户端的性能测试实践,其中主要是com.funtester.fungrpc.HelloServiceGrpc#newBlockingStub的性能测试实践。因为在实际的业务测试中这个用的最多,还有阻塞的客户端对于性能测试的指标统计和监控比较友好,对于多接口串联的业务测试来说更贴近HTTP接口的测试,这样能让很多用例思路直接复用。

基于以上,下面开始正题。

PS:本篇文章只做性能测试实践,不会测试各类状况下极限性能,所以硬件配置和软件参数就不单独分享了。

服务端

依旧采用了之前的fun_grpc项目的SDK内容。服务端代码如下:

package com.funtester.grpc;

import com.funtester.frame.execute.ThreadPoolUtil;
import io.grpc.Server;
import io.grpc.ServerBuilder;

import java.io.IOException;
import java.util.concurrent.ThreadPoolExecutor;

public class Service {

    public static void mAIn(String[] args) throws IOException, InterruptedException {
        ThreadPoolExecutor pool = ThreadPoolUtil.createFixedPool(10, "gRPC");
        Server server = ServerBuilder
                .forPort(12345)
                .executor(pool)
                .addService(new HelloServiceImpl())
                .build();

        server.start();
        server.awaitTermination();
    }

}

实际业务处理类:

package com.funtester.grpc;

import com.funtester.frame.SourceCode;
import com.funtester.fungrpc.HelloRequest;
import com.funtester.fungrpc.HelloResponse;
import com.funtester.fungrpc.HelloServiceGrpc;
import com.funtester.utils.Time;
import io.grpc.stub.StreamObserver;
import org.Apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class HelloServiceImpl extends HelloServiceGrpc.HelloServiceImplBase {

    private static final Logger logger = LogManager.getLogger(HelloServiceImpl.class);

    @Override
    public void executeHi(HelloRequest request, StreamObserver<HelloResponse> responseobserver) {
        HelloResponse response = HelloResponse.newBuilder()
                .setMsg("你好 " + request.getName()+ Time.getDate())
                .build();
        SourceCode.sleep(1.0);
        logger.info("用户{}来了",request.getName());
        responseObserver.onNext(response);
        responseObserver.onCompleted();
    }

}

业务上休眠了1s,然后返回响应内容。

客户端

客户端实际使用相对简单,这里就不再分享了,有兴趣的可以读一读文章开头的三篇文章。

静态模型

首先分享一下静态模型的内容,所谓静态内容指的是用例执行之前就设定好了执行的整个过程,用例执行过程除了终止以外没有其他干预措施。

线程模型

下面是基于静态线程模型的性能测试用例:

package com.funtest.grpc

import com.funtester.base.constaint.FixedThread
import com.funtester.frame.SourceCode
import com.funtester.frame.execute.Concurrent
import com.funtester.fungrpc.HelloRequest
import com.funtester.fungrpc.HelloServiceGrpc
import io.grpc.ManagedChannel
import io.grpc.ManagedChannelBuilder

class FixedThreadModel extends SourceCode {

    static int times

    static HelloServiceGrpc.HelloServiceBlockingStub helloServiceBlockingStub

    static HelloRequest requst

    public static void main(String[] args) {
        ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("localhost", 12345)
                .usePlaintext().build()

        helloServiceBlockingStub = HelloServiceGrpc.newBlockingStub(managedChannel).withCompression("gzip")
        requst = HelloRequest.newBuilder()
                .setName("FunTester")
                .build()
        RUNUP_TIME = 0
        times = 2000
        new Concurrent(new FunTester(), 10, "静态线程模型").start()

        managedChannel.shutdown()

    }

    private static class FunTester extends FixedThread {


        FunTester() {
            super(null, times, true)
        }

        @Override
        protected void doing() throws Exception {
            helloServiceBlockingStub.executeHi(requst)
        }

        @Override
        FunTester clone() {
            return new FunTester()
        }
    }

}

QPS模型

下面是基于静态QPS模型的压测用例。

package com.funtest.grpc

import com.funtester.base.event.FunCount
import com.funtester.frame.SourceCode
import com.funtester.frame.execute.FunEventConcurrent
import com.funtester.fungrpc.HelloRequest
import com.funtester.fungrpc.HelloServiceGrpc
import io.grpc.ManagedChannel
import io.grpc.ManagedChannelBuilder

class FixedQpsModel extends SourceCode {

    static HelloServiceGrpc.HelloServiceBlockingStub helloServiceBlockingStub

    static HelloRequest requst

    public static void main(String[] args) {
        ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("localhost", 12345)
                .usePlaintext().build()

        helloServiceBlockingStub = HelloServiceGrpc.newBlockingStub(managedChannel).withCompression("gzip")
        requst = HelloRequest.newBuilder()
                .setName("FunTester")
                .build()
        def count = new FunCount(1, 1, 2, 1000, 10, "静态QPS模型")

        def test= {
            helloServiceBlockingStub.executeHi(requst)
        }
        new FunEventConcurrent(test,count).start()
        managedChannel.shutdown()

    }

}

以上是两个常用的静态模型的演示,还有其他的动态模型这里就不演示了。

动态模型

下面到了喜闻乐见的动态模型的part,动态模型值得是用例执行时都是以固定的最小压力值(通常为1个QPS或者1个线程)启动,然后再用例执行过程中不断调整(调整步长、增减)用例的压力。

动态线程模型

由于动态模型是不限制用例运行时间,所以取消了关闭channel的方法。

package com.funtest.grpc

import com.funtester.base.constaint.FunThread
import com.funtester.frame.SourceCode
import com.funtester.frame.execute.FunConcurrent
import com.funtester.fungrpc.HelloRequest
import com.funtester.fungrpc.HelloServiceGrpc
import io.grpc.ManagedChannel
import io.grpc.ManagedChannelBuilder

import java.util.concurrent.atomic.AtomicInteger

class FunThreadModel extends SourceCode {

    static int times

    static HelloServiceGrpc.HelloServiceBlockingStub helloServiceBlockingStub

    static HelloRequest requst

    static AtomicInteger index = new AtomicInteger(0)

    static def desc = "动态线程模型"

    public static void main(String[] args) {
        ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("localhost", 12345)
                .usePlaintext().build()

        helloServiceBlockingStub = HelloServiceGrpc.newBlockingStub(managedChannel).withCompression("gzip")
        requst = HelloRequest.newBuilder()
                .setName("FunTester")
                .build()
        new FunConcurrent(new FunTester()).start()
    }

    private static class FunTester extends FunThread {


        FunTester() {
            super(null, desc + index.getAndIncrement())
        }

        @Override
        protected void doing() throws Exception {
            helloServiceBlockingStub.executeHi(requst)
        }

        @Override
        FunTester clone() {
            return new FunTester()
        }
    }

}

动态QPS模型

动态QPS模型是我现在最常用的模型,优势多多,除了某些强用户绑定需求外,动态QPS模型都是第一选择。

package com.funtest.grpc


import com.funtester.frame.SourceCode
import com.funtester.frame.execute.FunQpsConcurrent
import com.funtester.fungrpc.HelloRequest
import com.funtester.fungrpc.HelloServiceGrpc
import io.grpc.ManagedChannel
import io.grpc.ManagedChannelBuilder

class FunQpsModel extends SourceCode {

    static HelloServiceGrpc.HelloServiceBlockingStub helloServiceBlockingStub

    static HelloRequest requst

    public static void main(String[] args) {
        ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("localhost", 12345)
                .usePlaintext().build()

        helloServiceBlockingStub = HelloServiceGrpc.newBlockingStub(managedChannel).withCompression("gzip")
        requst = HelloRequest.newBuilder()
                .setName("FunTester")
                .build()
        def test= {
            helloServiceBlockingStub.executeHi(requst)
        }
        new FunQpsConcurrent(test).start()

    }

}

以上就是常用的gRPC阻塞客户端四种模型的性能测试全部内容了,欢迎继续关注FunTester。

「BUG挖掘机·性能征服者·头顶锅盖」



Tags:gRPC   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
如何通过三行配置解决在Kubernetes中的gRPC扩展问题
一切都始于我向我们的高级软件工程师提出的一个问题: “忘掉通信速度。你真的觉得在gRPC中开发通信比REST更好吗?” 我不想听到的答案立刻就来了:“绝对是的。”在我提出这个问...【详细内容】
2023-11-07  Search: gRPC  点击:(366)  评论:(0)  加入收藏
在 Kubernetes 环境中实现 gRPC 负载均衡
前言前段时间写过一篇 gRPC 的入门文章,在最后还留了一个坑没有填:图片也就是 gRPC 的负载均衡问题,因为当时的业务请求量不算大,再加上公司没有对 Istio 这类服务网格比较熟悉...【详细内容】
2023-10-17  Search: gRPC  点击:(400)  评论:(0)  加入收藏
在Kubernetes中实现gRPC流量负载均衡
在尝试将gRPC服务部署到Kubernetes集群中时,一些用户(包括我)面临的挑战之一是实现适当的负载均衡。在深入了解如何平衡gRPC的方式之前,我们首先需要回答一个问题,即为什么需要平...【详细内容】
2023-10-09  Search: gRPC  点击:(295)  评论:(0)  加入收藏
gRPC对比REST,在Spring Boot 中使用gRPC
1 为什么选择 gRPCgRPC是一种高性能的先进RPC(远程过程调用)框架,是开源的,并且兼容不同的环境。它使用协议缓冲区作为消息交换格式。不同语言中的 gRPC 客户端和服务器通信示例...【详细内容】
2023-07-17  Search: gRPC  点击:(118)  评论:(0)  加入收藏
Nginx如何实现gRPC反向代理
Nginx可以用来实现gRPC的反向代理,这里简要介绍一下如何配置Nginx实现grpc反向代理。要实现grpc反向代理,需要进行以下步骤: 安装gRPC和protobuf在Nginx服务器上安装好gRPC和pr...【详细内容】
2023-04-21  Search: gRPC  点击:(460)  评论:(0)  加入收藏
Spring Boot+Nacos+gRPC,一个区别于 OpenFeign 的微服务通信方案!
gRPC 的基础知识前面跟小伙伴们分享了很多了,今天再写一篇给这个小小的系列收个尾。我们前面介绍的都是 gRPC 的基本用法,最终目的当然是希望能够在 Spring Boot 中用上这个...【详细内容】
2023-04-04  Search: gRPC  点击:(234)  评论:(0)  加入收藏
如何用一个端口同时暴露 HTTP1/2、gRPC、Dubbo 协议?
本文我们将介绍 Apache Dubbo 灵活的多协议设计原则,基于这一设计,在 Dubbo 框架底层可灵活的选用 HTTP/2、HTTP/REST、TCP、gRPC、JsonRPC、Hessian2 等任一 RPC 通信协议,同...【详细内容】
2023-03-17  Search: gRPC  点击:(85)  评论:(0)  加入收藏
技术选型:如何选择REST、GraphQL 和 gRPC
REST、GraphQL 和 gRPC 是现代 Web 应用程序中最流行的 3 种 API 开发技术。那么在做技术选型时,三者要如何选择呢?在本文中,我们将一起对比 REST、GraphQL 和 gRPC 的特性和用...【详细内容】
2023-03-17  Search: gRPC  点击:(290)  评论:(0)  加入收藏
Go 语言怎么一键生成一个 gRPC 服务?
本文我们介绍怎么使用命令行工具 micro new 创建一个 gRPC 服务,并且怎么构建和运行服务。​01 介绍Go 开源项目 Micro​ 为我们提供一套微服务解决方案,它主要包含两个部分...【详细内容】
2023-03-06  Search: gRPC  点击:(167)  评论:(0)  加入收藏
gRPC三种Java客户端性能测试实践
我之前分享了Java和Go语言版本的gRPC接口的服务端和客户端的开发,使用的基本都是基础的原声API,旧文如下: Grpc服务开发和接口测试初探【Java】 2022-04-20 gRPC服务开发和接口...【详细内容】
2022-07-07  Search: gRPC  点击:(263)  评论:(0)  加入收藏
▌简易百科推荐
Java 8 内存管理原理解析及内存故障排查实践
本文介绍Java8虚拟机的内存区域划分、内存垃圾回收工作原理解析、虚拟机内存分配配置,以及各垃圾收集器优缺点及场景应用、实践内存故障场景排查诊断,方便读者面临内存故障时...【详细内容】
2024-03-20  vivo互联网技术    Tags:Java 8   点击:(18)  评论:(0)  加入收藏
如何编写高性能的Java代码
作者 | 波哥审校 | 重楼在当今软件开发领域,编写高性能的Java代码是至关重要的。Java作为一种流行的编程语言,拥有强大的生态系统和丰富的工具链,但是要写出性能优异的Java代码...【详细内容】
2024-03-20    51CTO  Tags:Java代码   点击:(25)  评论:(0)  加入收藏
在Java应用程序中释放峰值性能:配置文件引导优化(PGO)概述
译者 | 李睿审校 | 重楼在Java开发领域,优化应用程序的性能是开发人员的持续追求。配置文件引导优化(Profile-Guided Optimization,PGO)是一种功能强大的技术,能够显著地提高Ja...【详细内容】
2024-03-18    51CTO  Tags:Java   点击:(34)  评论:(0)  加入收藏
Java生产环境下性能监控与调优详解
堆是 JVM 内存中最大的一块内存空间,该内存被所有线程共享,几乎所有对象和数组都被分配到了堆内存中。堆被划分为新生代和老年代,新生代又被进一步划分为 Eden 和 Survivor 区,...【详细内容】
2024-02-04  大雷家吃饭    Tags:Java   点击:(63)  评论:(0)  加入收藏
在项目中如何避免和解决Java内存泄漏问题
在Java中,内存泄漏通常指的是程序中存在一些不再使用的对象或数据结构仍然保持对内存的引用,从而导致这些对象无法被垃圾回收器回收,最终导致内存占用不断增加,进而影响程序的性...【详细内容】
2024-02-01  编程技术汇  今日头条  Tags:Java   点击:(78)  评论:(0)  加入收藏
Java中的缓存技术及其使用场景
Java中的缓存技术是一种优化手段,用于提高应用程序的性能和响应速度。缓存技术通过将计算结果或者经常访问的数据存储在快速访问的存储介质中,以便下次需要时可以更快地获取。...【详细内容】
2024-01-30  编程技术汇    Tags:Java   点击:(78)  评论:(0)  加入收藏
JDK17 与 JDK11 特性差异浅谈
从 JDK11 到 JDK17 ,Java 的发展经历了一系列重要的里程碑。其中最重要的是 JDK17 的发布,这是一个长期支持(LTS)版本,它将获得长期的更新和支持,有助于保持程序的稳定性和可靠性...【详细内容】
2024-01-26  政采云技术  51CTO  Tags:JDK17   点击:(100)  评论:(0)  加入收藏
Java并发编程高阶技术
随着计算机硬件的发展,多核处理器的普及和内存容量的增加,利用多线程实现异步并发成为提升程序性能的重要途径。在Java中,多线程的使用能够更好地发挥硬件资源,提高程序的响应...【详细内容】
2024-01-19  大雷家吃饭    Tags:Java   点击:(111)  评论:(0)  加入收藏
这篇文章彻底让你了解Java与RPA
前段时间更新系统的时候,发现多了一个名为Power Automate的应用,打开了解后发现是一个自动化应用,根据其描述,可以自动执行所有日常任务,说的还是比较夸张,简单用了下,对于office、...【详细内容】
2024-01-17  Java技术指北  微信公众号  Tags:Java   点击:(108)  评论:(0)  加入收藏
Java 在 2023 年仍然流行的 25 个原因
译者 | 刘汪洋审校 | 重楼学习 Java 的过程中,我意识到在 90 年代末 OOP 正值鼎盛时期,Java 作为能够真正实现这些概念的语言显得尤为突出(尽管我此前学过 C++,但相比 Java 影响...【详细内容】
2024-01-10  刘汪洋  51CTO  Tags:Java   点击:(82)  评论:(0)  加入收藏
站内最新
站内热门
站内头条