1. 程式人生 > >springcloud框架下采用Grpc實現遠端過程呼叫

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<SendMailResponse> 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.git1、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
程式碼結構:

核心程式碼:
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
程式碼結構
核心程式碼:
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<Response> 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();
   }
}

相關推薦

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 Protoco

mvc框架,怎樣cookie實現下次自動登入

登入時有個下次自動登入的checkBox。點了它下次就可以自動登入了 具體流程我都曉得,就是細節的地方有些搞不定。我只要解決3個問題: (1)登入時如果點了checkbox,則在本機產生一個cookie,用來儲存使用者名稱和密碼; (2)點選安全退出時,將cookie刪

在VCADO實現BLOB(Binary)資料的儲存,讀取,修改,刪除。

在VC下采用ADO實現BLOB(Binary)資料的儲存,讀取,修改,刪除。 作者:邵盛鬆 2009-09-05 前言 1關於的BLOB(Binary)資料的儲存和讀取功能主要參考了MSDN上的一篇

SpringCloud(一) springboot實現簡單服務呼叫

分享一下我老師大神的人工智慧教程吧。零基礎,通俗易懂!風趣幽默!http://www.captainbed.net/ 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

PHP實現遠端過程呼叫RPC

一、初識RPC RPC(Remote Procedure Call)—遠端過程呼叫,它是一種通過網路從遠端計算機程式上請求服務,而不需要了解底層網路技術的協議。 二、工作原理 執行時,一次客戶機對伺服器的RPC呼叫,其內部操作大致有如下十步: 1.呼叫客戶端控制代碼;執行傳送引數

.NetRabbitMQ的使用(8) -- 遠端過程呼叫RPC

RPC是在計算中是一種常見的模式,是通常我要用訊息佇列來實現RPC有3個關鍵點: 1. 服務的定址 2. 訊息的接收 3. 訊息的關聯 在RabbitMQ的.net客戶端裡,提供了2個類:SimpleRpcClient 和 SimpleRpcServer

metasploit msgrpc c++實現遠端過程呼叫

想入手metasploit原始碼,又不知道從何而入,看了下UI部分,發現已經存在了armitage、msfgui、以及現在的收費web。瀏覽了下《Metasploit Remote API4.1 Guide》 運用msgrpc時需要填寫正確的post型別: POST /ap

.NetRabbitMQ的使用(7) -- 遠端過程呼叫RPC

RPC是在計算中是一種常見的模式,是通常我要用訊息佇列來實現RPC有3個關鍵點: 1. 服務的定址 2. 訊息的接收 3. 訊息的關聯 在RabbitMQ的.net客戶端裡,提供了2個類:SimpleRpcClient 和 SimpleRpcServer 來讓我們

BootNettyRpc: Netty 實現的 RPC 框架

ofo 文件配置 RR 實現 端口 監控 ble tin cto 什麽是 BootNettyRpc?BootNettyRpc 是一個采用Netty實現的Rpc框架,適用於Spring Boot項目,支持Spring Cloud。 目前支持的版本為Spring Boot 1.

實現自己的大發888平臺開發框架Java Socket)

exe provide lang 輸出流 reflect cati trace 客戶端 hand 大發888平臺開發實現原理圖: 1、Service API對應服務接口。 HelloService.java代碼如下: package com.shan.rpc.service

第67課:Spark SQLJava和Scala實現Join的案例綜合實戰(鞏固前面學習的Spark SQL知識)

內容:     1.SparkSQL案例分析     2.SparkSQL下采用Java和Scala實現案例 一、SparkSQL下采用Java和Scala實現案例 學生成績: {"name":"Michael","score":98} {"name":"Andy"

Net GET/POST/SOAP方式動態呼叫WebService C#實現

 一直以來,我們都為動態呼叫WebService方法而煩惱。在.Net環境下,最常用的方法就是採用代理類來呼叫WebService,可以通過改變代理類的Url屬性來實現動態呼叫,但當xmlns改變時就會出錯,似乎要重新繫結Webservice並重新編譯後才能再次執行。我

java nio--Selector實現Socket通信

lock finish taf 取數 block static isempty inpu col server: 1 /** 2 * 選擇器服務端 3 * Created by ascend on 2017/6/9 9:30. 4 */ 5 pu

JSActiveXObject實現戶在提交表單時屏蔽敏感詞的功能

使用 安全 lag this 繼續 file oar dex body 本例中敏感詞ciku.txt放在C盤根目錄下,采用的ActiveXObject插件獲取本地文件內容。使用此插件不需網上下插件,直接用如下js代碼即可。 瀏覽器需修改interner安全選項的級別,啟用A

linuxbinary方式安裝mysql步驟

glibc zxvf sql 創建用戶 啟動服務 star 安裝mysql mysql目錄 初始化 1、下載binary文件   在http://dev.mysql.com/downloads/mysql/官網上下載 mysql-5.6.36-linux-glibc2.5-

SSM框架分頁的實現(封裝page.java和List<?>)

添加 interface jsp頁面 har show 初始化 ring array dex 之前寫過一篇博客 java分頁的實現(後臺工具類和前臺jsp頁面),介紹了分頁的原理。 今天整合了Spring和SpringMVC和MyBatis,做了增刪改查和分頁,之前的邏輯

【My97datepicker】在IE9‘yyyy-MM’格式時會出現11111111

pic .com epic wid == des picker his var 解決辦法是在WdatePicker.js的結尾加上一個方法。 也就是在PX後面加上如下代碼(註意要先加分號再加下面的代碼): var userAgent = n

PHP實現”服務器推”技術的聊天室

blank 有趣 自動 www. plain .com 都是 inter 自己 傳統的B/S結構的應用程序,都是采用”客戶端拉”結束來實現客戶端和服務器端的數據交換。 本文將通過結合Ticks(可以參看我的另外一篇文章:關於PHP你可能不知道的-PHP的事件驅動化設計)

PostSharp實現

odex n! ride ces nbsp string rri aspect body 1、創建控制臺程序 2、通過Nuget添加PostSharp引用 3、定義註入類(實現方法的Entry,Exit,Exception,Success功能),如: [Serializab

sshexpect實現自動輸入密碼登錄、拷貝

cep .html tro from 效果 方式 目標 led 交互 1. 引言 最近做了一個項目,需要頻繁與另一臺主機進行文件的傳輸;中間想到了很多方式:FTP、samba、curl等,但是還是感覺scp最好用。 SCP使用教程可參閱:http://www.jb51.