rpc框架之gRPC 学习 - hello world
2015-09-26 15:48
447 查看
grpc是google在github于2015年开源的一款RPC框架,虽然protobuf很早google就开源了,但是google一直没推出正式的开源框架,导致github上基于protobuf的rpc五花八门,国内比较著名的有百度的sofa-pbrpc,但是遗憾的是soft-pbrpc没有对应的java实现版本。rgpc还有一个独立的官网:http://www.grpc.io/,目前已经支持的语言有 C, C++, Java, Go, Node.js, Python, Ruby, Objective-C, PHP 、 C#. grpc最大的特点是基于protobuf + http2 协议,http2协议虽然还未正式定稿,但从目前得知的内容来看,潜力巨大。下面是grpc基本的hello world的示例:
一、grpc-contract
还是按老套路,把服务涉及的对象定义、接口定义抽象出来,下面是项目结构图:
View Code
Client端代码:
在笔记本测试的结果:
Will try to ping a ...
ping: pong => a
rgpc 100000 次NettyServer调用,耗时:36409毫秒,平均2746次/秒
基本上在每秒3k次的数量级,相对thrift(1w+)、avro(5k+)来讲,目前的差距还是很明显的,但是新事物成长总是需要时间,再给google一段时间,相信以后会让大家感到惊艳的。
在序列化方面,也做了一个跟之前thrift、avro类似的测试:
输出:
Protobuf 3.0 二进制序列后的byte数组长度:4
1 - 1
在2进制序列化后的大小方面,protobuf 3大体跟thrift的TCompactProtocal(大小5)接近,比avro(大小2)略差。
文中示例源码下载:http://code.taobao.org/svn/grpc-demo/
参考文章:
RPC框架性能基本比较测试
Schema evolution in Avro, Protocol Buffers and Thrift
jvm-serializers
RPC综述 - PB, Thrift, Avro
一、grpc-contract
还是按老套路,把服务涉及的对象定义、接口定义抽象出来,下面是项目结构图:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>yjmyzz.grpc</groupId> <artifactId>grpc-client</artifactId> <version>1.0</version> <dependencies> <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>3.0.0-beta-1</version> </dependency> <dependency> <groupId>yjmyzz.grpc</groupId> <artifactId>grpc-contract</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-all</artifactId> <version>0.8.0</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> </dependencies> </project>
View Code
Client端代码:
package yjmyzz.grpc.study.client; import io.grpc.ChannelImpl; import io.grpc.netty.NegotiationType; import io.grpc.netty.NettyChannelBuilder; import yjmyzz.grpc.study.dto.PersonList; import yjmyzz.grpc.study.dto.PingRequest; import yjmyzz.grpc.study.dto.PingResponse; import yjmyzz.grpc.study.dto.QueryParameter; import yjmyzz.grpc.study.service.DemoServiceGrpc; import java.util.concurrent.TimeUnit; public class DemoServiceClient { private final ChannelImpl channel; private final DemoServiceGrpc.DemoServiceBlockingStub blockingStub; public DemoServiceClient(String host, int port) { channel = NettyChannelBuilder.forAddress(host, port).negotiationType(NegotiationType.PLAINTEXT) .build(); blockingStub = DemoServiceGrpc.newBlockingStub(channel); } public void shutdown() throws InterruptedException { channel.shutdown().awaitTermination(5, TimeUnit.SECONDS); } public void ping(String name) { try { System.out.println("Will try to ping " + name + " ..."); PingRequest request = PingRequest.newBuilder().setIn(name).build(); PingResponse response = blockingStub.ping(request); System.out.println("ping: " + response.getOut()); } catch (RuntimeException e) { System.out.println("RPC failed:" + e.getMessage()); return; } } public void getPersonList(QueryParameter parameter) { try { //System.out.println("Will try to getPersonList " + parameter + " ..."); PersonList response = blockingStub.getPersonList(parameter); //System.out.println("items count: " + response.getItemsCount()); // for (Person p : response.getItemsList()) { // System.out.println(p); // } } catch (RuntimeException e) { System.out.println("RPC failed:" + e.getMessage()); return; } } public static void main(String[] args) throws Exception { DemoServiceClient client = new DemoServiceClient("localhost", 50051); try { client.ping("a"); int max = 100000; Long start = System.currentTimeMillis(); for (int i = 0; i < max; i++) { client.getPersonList(getParameter()); } Long end = System.currentTimeMillis(); Long elapse = end - start; int perform = Double.valueOf(max / (elapse / 1000d)).intValue(); System.out.print("rgpc " + max + " 次NettyServer调用,耗时:" + elapse + "毫秒,平均" + perform + "次/秒"); } finally { client.shutdown(); } } private static QueryParameter getParameter() { return QueryParameter.newBuilder().setAgeStart(5).setAgeEnd(50).build(); } }
在笔记本测试的结果:
Will try to ping a ...
ping: pong => a
rgpc 100000 次NettyServer调用,耗时:36409毫秒,平均2746次/秒
基本上在每秒3k次的数量级,相对thrift(1w+)、avro(5k+)来讲,目前的差距还是很明显的,但是新事物成长总是需要时间,再给google一段时间,相信以后会让大家感到惊艳的。
在序列化方面,也做了一个跟之前thrift、avro类似的测试:
@Test public void test() throws InvalidProtocolBufferException { QueryParameter queryParameter = QueryParameter.newBuilder().setAgeStart(1).setAgeEnd(5).build(); byte[] bytes1 = queryParameter.toByteArray(); System.out.println("Protobuf 3.0 二进制序列后的byte数组长度:" + bytes1.length); QueryParameter result = QueryParameter.parseFrom(bytes1); System.out.println(queryParameter.getAgeStart() + " - " + result.getAgeStart()); }
输出:
Protobuf 3.0 二进制序列后的byte数组长度:4
1 - 1
在2进制序列化后的大小方面,protobuf 3大体跟thrift的TCompactProtocal(大小5)接近,比avro(大小2)略差。
文中示例源码下载:http://code.taobao.org/svn/grpc-demo/
参考文章:
RPC框架性能基本比较测试
Schema evolution in Avro, Protocol Buffers and Thrift
jvm-serializers
RPC综述 - PB, Thrift, Avro
相关文章推荐
- Ext.onready详解
- 关于ogrebullet中如何判断两个物体何时碰撞的问题
- 【POJ 3265】Problem Solving
- Apache配置介绍
- 新建安卓工程报错
- iOS中一种网络层与业务层的设计方案
- ios8 右滑返回不能禁止
- jQuery实现瀑布流
- structure-object structure-object-pointer
- 【原创】LogCat信息演示Activity生命周期
- POJ2018 最大平均值问题
- [LeetCode]203 Remove Linked List Elements
- poj3624charm bracelet【背包】
- 浅谈2015新版 U-Boot
- C基础--队列的构造
- linux安装mysql
- iOS基础-UIControl及其子类
- 剑指Offer-5-从尾到头打印链表
- RARP逆地址解析协议
- oracle 使用技巧