GRPC的helloworld demo示例

近期研究RPC框架,第一个研究的是GRPC,虽然GRPC应用远远没有Dubbo\Dubbox广泛,但作为google发布的支持Http2协议的RPC还是有很高关注度的,分析来自于外网:http://www.cnblogs.com/yjmyzz/p/grpc-hello-world.html ,由于外部的代码不易获取,为了测试,自己适当调整,下载后可跑通。

本例子采用了protobuf的maven插件来实现.proto文件的生成,插件配置:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>2.5</version>
</plugin>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.0</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.0.0:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:0.8.0:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>

</plugin>

工程protbuffer就是协议定义工程,grpcserver是server端,grpc-client是client端。

默认先注释掉上面的插件代码,只有第一次需要根据。proto文件生成对应java文件类时放开,执行mvn install生成后再Target目录下有source包,把对应包copy到src/java下面,执行mvn install发布protbuffer工程.

一、grpc-contract

还是按老套路,把服务涉及的对象定义、接口定义抽象出来,下面是项目结构图:

pom.xml的内容如下:

<?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>protobuf.test</groupId>
    <artifactId>protbuffer-contract</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.0.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-all</artifactId>
            <version>0.8.0</version>
        </dependency>
    </dependencies>
    <build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.4.0.Final</version>
            </extension>
        </extensions>
        <!--用于根据proto文件生成java类的插件-->
       <plugins>
             <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-clean-plugin</artifactId>
                <version>2.5</version>
            </plugin>
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.5.0</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:3.0.0:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:0.8.0:exe:${os.detected.classifier}</pluginArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>

            </plugin>

            <!--生成源代码jar包的插件(可选)-->
            <plugin>
                <artifactId>maven-source-plugin</artifactId>
                <version>2.4</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>jar-no-fork</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

demo_service.proto内容如下:

syntax = "proto3";

import "demo_service_dto.proto";

package com.protobuf.test.grpc.demo.service;

option java_multiple_files = true;
option java_outer_classname = "DemoServiceDto";

service DemoService {
    rpc Ping (com.protobuf.test.grpc.demo.dto.PingRequest) returns (com.protobuf.test.grpc.demo.dto.PingResponse) {}

    rpc getPersonList (com.protobuf.test.grpc.demo.dto.QueryParameter) returns (com.protobuf.test.grpc.demo.dto.PersonList) {}
}

demo_service_dto.proto内容:

syntax = "proto3";

package com.protobuf.test.grpc.demo.dto;

option java_multiple_files = true;
option java_outer_classname = "DemoServiceDto";

message PingRequest {
     string in=1;
}

message PingResponse {
     string out=1;
}

message QueryParameter {
     int32 ageStart = 1;
     int32 ageEnd = 2;
}

message Person {
     int32 age = 1;
     string name = 2;
     bool sex=3;
     double salary=4;
     int32 childrenCount=5;
}

message PersonList{
     repeated Person items=1;
}

mvn install 后,会自动在target下生成相应的java class类再把类copy到src/main/java下面

二、grpc-server

pom.xml如下

<?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>protobuffer.test</groupId>
    <artifactId>grpc-server</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.0.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-all</artifactId>
            <version>0.8.0</version>
        </dependency>
        <dependency>
            <groupId>protobuf.test</groupId>
            <artifactId>protbuffer-contract</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

先对服务接口提供实现:

package com.protobuf.test.grpc.demo.service;
import com.protobuf.test.grpc.demo.service.DemoServiceGrpc;
import com.protobuf.test.grpc.demo.dto.*;
import io.grpc.stub.StreamObserver;

import java.util.ArrayList;
import java.util.List;


public class DemoServiceImpl implements DemoServiceGrpc.DemoService{

    public void ping(PingRequest pingRequest, StreamObserver<PingResponse> streamObserver) {
        PingResponse reply = PingResponse.newBuilder().setOut("pong => " + pingRequest.getIn()).build();
        streamObserver.onValue(reply);
        streamObserver.onCompleted();
    }

    public void getPersonList(QueryParameter queryParameter, StreamObserver<PersonList> streamObserver) {
        System.out.println("AgeStarton-AgeEnd:"+queryParameter.getAgeStart() + "-" + queryParameter.getAgeEnd());
        PersonList.Builder personListBuilder = PersonList.newBuilder();
        Person.Builder builder = Person.newBuilder();
        List<Person> list = new ArrayList<Person>();
        int start=queryParameter.getAgeStart();
        int end=queryParameter.getAgeEnd();
        for (int i = start; i < end; i++) {
            list.add(builder.setAge(i).setChildrenCount(i).setName("test" + i).setSex(true).build());
        }
        personListBuilder.addAllItems(list);
        streamObserver.onValue(personListBuilder.build());
        streamObserver.onCompleted();
    }
}

server端实现:

package com.protobuf.test.grpc.demo.server;

import com.protobuf.test.grpc.demo.service.DemoServiceGrpc;
import com.protobuf.test.grpc.demo.service.DemoServiceImpl;
import io.grpc.ServerImpl;
import io.grpc.inprocess.InProcessServerBuilder;
import io.grpc.netty.NettyServerBuilder;

/**
 * Created by liuzhimeng on 2017/10/31.
 */
public class DemoServiceServer {
    private int port = 50051;
    private ServerImpl server;

    private void start() throws Exception {
        server = NettyServerBuilder.forPort(port)
                .addService(DemoServiceGrpc.bindService(new DemoServiceImpl()))
                .build().start();

        server = InProcessServerBuilder.forName("testServer")
                .addService(DemoServiceGrpc.bindService(new DemoServiceImpl()))
                .build().start();

        System.out.println("Server started, listening on " + port);
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                System.out.println("*** shutting down gRPC server since JVM is shutting down");
                DemoServiceServer.this.stop();
                System.out.println("*** server shut down");
            }
        });
    }
    private void stop() {
        if (server != null) {
            server.shutdown();
        }
    }


    public static void main(String[] args) throws Exception {
        final DemoServiceServer server = new DemoServiceServer();
        server.start();
    }
}

三、grpc-client

pom.xml

<?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>protobuffer.test</groupId>
    <artifactId>grpc-client</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.0.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-all</artifactId>
            <version>0.8.0</version>
        </dependency>
        <dependency>
            <groupId>protobuf.test</groupId>
            <artifactId>protbuffer-contract</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

client端实现:

package com.protobuf.test.grpc.client;

import com.protobuf.test.grpc.demo.dto.*;
import com.protobuf.test.grpc.demo.service.DemoServiceGrpc;
import io.grpc.ChannelImpl;
import io.grpc.netty.NegotiationType;
import io.grpc.netty.NettyChannelBuilder;

import java.util.concurrent.TimeUnit;

/**
 * Created by liuzhimeng on 2017/10/31.
 */
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 =1;
            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(6).build();
    }
}

启动server端后测试:

Will try to ping a ...
ping: pong => a
Will try to getPersonList ageStart: 5
ageEnd: 6
 ...
items count: 1
age: 5
name: "test5"
sex: true
childrenCount: 5

rgpc 1 次NettyServer调用,耗时:80毫秒,平均12次/秒
 

转载于:https://my.oschina.net/u/1998081/blog/1576605

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值