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

我之前分享了Java和Go语言版本的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 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.grpcimport com.funtester.base.constaint.FixedThreadimport com.funtester.frame.SourceCodeimport com.funtester.frame.execute.Concurrentimport com.funtester.fungrpc.HelloRequestimport com.funtester.fungrpc.HelloServiceGrpcimport io.grpc.ManagedChannelimport io.grpc.ManagedChannelBuilderclass 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.grpcimport com.funtester.base.event.FunCountimport com.funtester.frame.SourceCodeimport com.funtester.frame.execute.FunEventConcurrentimport com.funtester.fungrpc.HelloRequestimport com.funtester.fungrpc.HelloServiceGrpcimport io.grpc.ManagedChannelimport io.grpc.ManagedChannelBuilderclass 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.grpcimport com.funtester.base.constaint.FunThreadimport com.funtester.frame.SourceCodeimport com.funtester.frame.execute.FunConcurrentimport com.funtester.fungrpc.HelloRequestimport com.funtester.fungrpc.HelloServiceGrpcimport io.grpc.ManagedChannelimport io.grpc.ManagedChannelBuilderimport java.util.concurrent.atomic.AtomicIntegerclass 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.grpcimport com.funtester.frame.SourceCodeimport com.funtester.frame.execute.FunQpsConcurrentimport com.funtester.fungrpc.HelloRequestimport com.funtester.fungrpc.HelloServiceGrpcimport io.grpc.ManagedChannelimport io.grpc.ManagedChannelBuilderclass 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挖掘机·性能征服者·头顶锅盖」

郑重声明:本文内容及图片均整理自互联网,不代表本站立场,版权归原作者所有,如有侵权请联系管理员(admin#wlmqw.com)删除。
(0)
用户投稿
上一篇 2022年7月8日
下一篇 2022年7月8日

相关推荐

联系我们

联系邮箱:admin#wlmqw.com
工作时间:周一至周五,10:30-18:30,节假日休息