springcloud框架下采用Grpc实现远程过程调用

一、RPC 简介
 参考:
       http://itindex.net/detail/52530-rpc-%E6%A1%86%E6%9E%B6-%E5%88%86%E6%9E%90
 简介:
   RPC(Remote Procedure Call Protocol)——远程过程调用协议。使得程序像访问本地资源一样,去访问远端系统资源。更具体的将,像调用本地api一样,调用远端api。
 
 RPC调用框架 :
     RMI实现: 利用java.rmi包实现,基于Java远程方法协议(Java Remote Method Protocol) 和java的原生序列化。 
     Hessian: 是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能。 基于HTTP协议,采用二进制编解码。 
     protobuf-rpc-pro : 是一个Java类库,提供了基于 Google 的 Protocol Buffers 协议的远程方法调用的框架。基于 Netty 底层的 NIO 技术。支持 TCP 重用/ keep-alive、SSL加密、RPC 调用取消操作、嵌入式日志等功能。 
     THRIFT: 是一种可伸缩的跨语言服务的软件框架。它拥有功能强大的代码生成引擎,无缝地支持C + +,C#,Java,Python和PHP和Ruby。thrift允许你定义一个描述文件,描述数据类型和服务接口。依据该文件,编译器方便地生成RPC客户端和服务器通信代码。 底层通讯基于SOCKET。 
     AVRO:标准性的云计算的数据交换和 存储的Protocol。支持HTTP,TCP两种协议。
二、GRPC原理 参考:https://juejin.im/entry/59bb30f76fb9a00a616f1b73 背景: 基于HTTP/2之上的二进制协议(Protobuf序列化机制) 一个连接可以多路复用,并发处理多个请求和响应 多语言的类库实现 服务定义文件和自动代码生成(.proto文件和protobuf编译工具) 可以对框架进行功能定制和扩展(例如: 对接Zookeeper,域名解析服务,SLB服务等) 流程: 三、GRPC例子 源码:[email protected]:xiangqian19831224/grpc-example.git 1、client
package com.rpc.mail;
import java.util.concurrent.TimeUnit;
import com.rpc.mail.SendMailServiceGrpc.SendMailServiceBlockingStub;
import io.grpc.ManagedChannel;
import io.grpc.netty.NettyChannelBuilder;

public class GrpcClient {
   public static void main(String[] args) throws Exception {
      ManagedChannel channel = NettyChannelBuilder.forAddress("127.0.0.1", 8080).usePlaintext(true).build();
      //同步调用(异步调用的话,就是:SendMailServiceGrpc.newFutureStub(channel))
      SendMailServiceBlockingStub stub = SendMailServiceGrpc.newBlockingStub(channel);

      //设置请求参数
      SendMailRequest param = SendMailRequest.newBuilder().setRecipient("[email protected]").setTitle("运维邮件").setContent("SOA服务挂了").build();
      SendMailResponse resp = stub.sendMail(param);
      System.out.println(resp.getMsg() + "\t" + resp.getCode());

      //close
      channel.shutdown().awaitTermination(1, TimeUnit.SECONDS);
   }
}

2、server
 
SendMailServiceBlockingStub
package com.rpc.mail;

import io.grpc.Server;
import io.grpc.netty.NettyServerBuilder;

public class GrpcServer {
   public static void main(String[] args) throws Exception {
      Server server = NettyServerBuilder.forPort(8080).addService(SendMailServiceGrpc.bindService(new SendMailServiceImpl())).build();
      server.start();
      System.out.println("server startup at 8080");
      server.awaitTermination();
   }
}
package com.rpc.mail;

import io.grpc.stub.StreamObserver;

public class SendMailServiceImpl implements SendMailServiceGrpc.SendMailService {
   public void sendMail(SendMailRequest request, StreamObserver responseObserver) {
      System.out.println(request.getRecipient() + "\t" + request.getTitle() + "\t" + request.getContent());
      //这里是具体的业务逻辑
      SendMailResponse resp = SendMailResponse.newBuilder().setCode(0).setMsg("OK").build();
      //设置返回结果
      responseObserver.onNext(resp);
      responseObserver.onCompleted();
   }
}

四、客户端代码分析

1、客户端整体流程

2、后续再扩展原理部分
如果要迅速掌握rpc原理,请参考代码: [email protected]:xiangqian19831224/RPC.git

五、springcloud实现一个最简单的搜索分布式框架
参考代码:[email protected]:xiangqian19831224/springcloud-grpc-search.git
1、eureka-server构建
package com.ec.search;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
@EnableDiscoveryClient
public class EurekaServerApplication {

   public static void main(String[] args) {
      SpringApplication.run(EurekaServerApplication.class, args);
   }
}

2、client
代码结构:
springcloud框架下采用Grpc实现远程过程调用_第1张图片
核心代码:
eureka中的命名解析通用
SearchServiceClient:
package com.ec.search;

import com.ec.search.eureka.EurekaNameResolverProvider;
import com.netflix.discovery.EurekaClientConfig;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.util.RoundRobinLoadBalancerFactory;
import org.ec.search.grpc.services.Request;
import org.ec.search.grpc.services.Response;
import org.ec.search.grpc.services.SearchServiceGrpc;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;

/**
 * TODO: comment here
 */
@Service
public class SearchServiceClient {
   private Logger logger = LoggerFactory.getLogger(SearchServiceClient.class);

   @Autowired
   EurekaClientConfig eurekaClientConfig;

   private SearchServiceGrpc.SearchServiceBlockingStub searchServiceBlockingStub;

   public String search(String query, int pageNum, int pageSize, int type){
      Request.Builder builder = Request.newBuilder();
      builder.setQuery(query);
      builder.setPageNum(pageNum);
      builder.setPageSize(pageSize);
      Request request = builder.build();

      Response response = searchServiceBlockingStub.searchByQuery(request);
      String docs = response.getDocs();
      return docs;
   }

   @PostConstruct
   private void initializeClient() {

      ManagedChannel channel = ManagedChannelBuilder
            .forTarget("eureka://grpc-server")//搜索引擎的分片名称
            .nameResolverFactory(new EurekaNameResolverProvider(eurekaClientConfig, "grpc.port"))//搜索引擎分片端口
            .loadBalancerFactory(RoundRobinLoadBalancerFactory.getInstance())
            .usePlaintext(true)
            .build();

      searchServiceBlockingStub = SearchServiceGrpc.newBlockingStub(channel);
   }
}


3、server
代码结构
springcloud框架下采用Grpc实现远程过程调用_第2张图片
核心代码:
package com.ec.search;

import io.grpc.stub.StreamObserver;
import org.ec.search.grpc.services.Request;
import org.ec.search.grpc.services.Response;
import org.ec.search.grpc.services.SearchServiceGrpc;
import org.lognet.springboot.grpc.GRpcService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * TODO: comment here
 */
@GRpcService
public class SearchGrpcService extends SearchServiceGrpc.SearchServiceImplBase {
   private Logger logger = LoggerFactory.getLogger(SearchGrpcService.class);

   @Override
   public  void searchByQuery(Request request, StreamObserver responseObserver){
      logger.debug("Request: " + request);
      Response.Builder builder = Response.newBuilder();
      builder.setQuery(request.getQuery());
      builder.setDocs("[服务成功]"); //返回结果
      Response response = builder.build();

      responseObserver.onNext(response);
      responseObserver.onCompleted();
   }
}


你可能感兴趣的:(搜索引擎)