相信很多后端开发,在平时的开发中,都有使用过 gRPC 和 Dubbo 这两种 RPC 框架。
Dubbo 是阿里巴巴公司开源的一个Java高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成。
gRPC是Google开发的高性能、通用的开源RPC框架,其由Google主要面向移动应用开发并基于HTTP/2协议标准而设计,基于ProtoBuf(Protocol Buffers)序列化协议开发,且支持众多开发语言。
gRPC 和 Dubbo 性能测试
那么如何判断 gRPC 和 Dubbo 哪个更适合你呢?我们不妨先从最基础的性能测试入手。
性能测试可以帮助我们评估系统、应用程序或网站在不同负载和压力下的表现。我们将在下文中使用 Java 环境分别针对 gRPC 和 Dubbo 发起性能测试,查看需要耗费的时间来判断性能。
gRPC
下载 gRPC 项目
需要到 github 上去把 grpc-java 给拷贝下来到本地。
git clone https: //github.com/grpc/grpc-java
改造 gRPC 项目
进入到 grpc-java 的 examples 中, 有:
- HelloWorldServer.java
- HelloWorldClient.java
/*
* Copyright 2015 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc.examples.helloworld;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.StatusRuntimeException;
import io.grpc.examples.helloworld.HelloRequest.Builder;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* A simple client that requests a greeting from the {@link HelloWorldServer}.
*/
public class HelloWorldClient {
private static final Logger logger = Logger.getLogger(HelloWorldClient.class.getName());
private final ManagedChannel channel;
private final GreeterGrpc.GreeterBlockingStub blockingStub;
private final Long testScale = 1000000L;
/** Construct client connecting to HelloWorld server at {@code host:port}. */
public HelloWorldClient(String host, int port) {
this(ManagedChannelBuilder.forAddress(host, port)
// Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
// needing certificates.
.usePlaintext()
.build());
}
/** Construct client for accessing HelloWorld server using the existing channel. */
HelloWorldClient(ManagedChannel channel) {
this.channel = channel;
blockingStub = GreeterGrpc.newBlockingStub(channel);
}
public void shutdown() throws InterruptedException {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
}
/** Say hello to server. */
public void greet(String name) {
logger.info("Will try to greet " + name + " ...");
Long start = Instant.now().getEpochSecond();
HelloReply response;
HelloRequestOrBuilder request = HelloRequest.newBuilder().setName(name);
try {
for(int idx = 0 ; idx <= testScale; idx ++){
((Builder) request).setName(String.format("%s:%d", name, idx));
response = blockingStub.sayHello(((Builder) request).build());
System.out.println(String.format("Greeting: %s" , response.getMessage()));
((Builder) request).clear();
}
} catch (StatusRuntimeException e) {
logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
return;
}
Long durTime = Instant.now().getEpochSecond() - start;
System.out.println(String.format("spend time: %d can handle %d per second", durTime,
testScale/durTime));
}
/**
* Greet server. If provided, the first element of {@code args} is the name to use in the
* greeting.
/ public static void main(String[] args) throws Exception { HelloWorldClient client = new HelloWorldClient("localhost", 50051); try { / Access a service running on the local machine on port 50051 / String user = "world"; if (args.length > 0) { user = args[0]; / Use the arg as the name to greet if provided */
}
client.greet(user);
} finally {
client.shutdown();
}
}
}
运行、查看运行时间
最后使用 maven 去启动项目,且循环 1000000 次。
mvn exec:java -Dexec.mainClass=io.grpc.examples.helloworld.HelloWorldServer
mvn exec:java -Dexec.mainClass=io.grpc.examples.helloworld.HelloWorldClient
测出来的时间大概为:
spend time: 126 can handle 7936 per second
Dubbo
zookeeper 在本地启动
zkServer.sh start
Dubbo 本地服务启动
@Service(version = "1.0.0")
public class HelloServiceImpl implements HelloService {
@Override
public String SayHello(String name) {
return "Hello , "+name;
}
}
@RestController
public class HelloController {
private final Long testScale = 1000000L;
@Reference(version = "1.0.0")
HelloService helloService;
@GetMapping("sayHello")
public String sayHello( String name){
name = " world";
Long now = Instant.now().getEpochSecond();
for(int idx = 0; idx < testScale; idx++){
System.out.println( helloService.SayHello(String.format("%s:%d",name,idx)));
}
Long duration = Instant.now().getEpochSecond() - now;
System.out.println(String.format("can handle %d per second", testScale/duration));
return String.format("can handle %d per second", testScale/duration);
}
}
运行结果
我们进行运行,并查看耗时结果:
can handle 12987 per second
小结
7936 VS 12987。
这么一试验,还是 Dubbo 的性能更胜一筹啊!怪不得 Dubbo 在近几年在国内越来越火,受到越来越多人的欢迎!
Apifox 支持调试 gRPC、Dubbo
其实 gRPC、Dubbo 说到底都是基于 RPC 的两个框架,所以选择一款能调试 RPC 接口的 API 工具非常重要,而 Apifox 能很好地胜任这一工作。
创建 gRPC 项目
Apifox 支持基于 .proto 文件的 gRPC 调试,包括一元调用和流式调用。在创建项目时「选择 gRPC 项目」-->「导入 .proto 文件」,无需写代码即可直接调用 gRPC 接口。
在调试 gRPC 接口之前,也需要先导入作为 API 定义的 .proto 文件。如果一个 .proto 文件依赖于其他 .proto 文件,那么需要手动添加依赖关系目录。
一元调用
只需要在地址栏填写 URL 后点击「调用」按钮,即可发起一元调用。
流式调用
流式调用包含服务端流、客户端流、双向流。
在发起调用之后,你可以在 Message 标签下撰写消息并发送。Apifox 提供了一个时间线视图,按照时间顺序集中展示调用状态、发送的消息、收到的消息。点击消息之后,可以非常方便地查看消息的详情。
创建 Dubbo 项目
Apifox 支持创建 Dubbo 项目,在创建项目时选择「 Dubbo 项目」。
Dubbo 项目管理目前处于测试阶段,敬请期待。
导入阿里云 EDAS
在阿里云控制台中获取 EDAS 的相关信息,导入接口时填写相关信息。
导入后即可在由 Apifox 提供的可视化页面设计或调试 Dubbo 接口!
关于 Apifox
欢迎体验一下,完全免费的哦:在线使用 Apifox。
我将 Apifox 概括为三点,通过这三点,我们可以就可以知道 Apifox 真的是一款非常强大、多功能的 API 工具。
- 集成了 API 文档、API 调试、API Mock、API 自动化测试 API 一体化协作平台
- 拥有更先进的 API 设计/开发/测试工具
- Apifox = Postman + Swagger + Mock + JMeter
学习更多: