为何RPC
在微服务这个时代,不论是传输还是内网调用,以及跨语言的传输,RPC都是不二的选择。GRPC是Google基于protocol buffer传输协议开发的一个RPC框架,支持多语言之间的通信,下面,我会基于Java语言和golang语言做一个跨语言调用例子,Java做client端,golang做服务端
计算器proto接口定义:
syntax = "proto3";
option go_package = "client";
//请求
message Request {
double num1 = 1;
double num2 = 2;
OperateType opType = 3;
}
//操作类型
enum OperateType {
Addition = 0;
Division = 1;
Multiplication = 2;
Subtraction = 3;
}
message Response {
double result = 1;
}
//定义服务
service Operate {
rpc Calculate (Request) returns (Response);
}
生成go源码:
官方给go语言的生成提供了插件,用这个命令就可以快速生成go端的相关代码,为了简便期间,我写成了一个简单的脚本:
#!/usr/bin/env bash
find ./ -name '*.proto'|xargs protoc --go_out=plugins=grpc:.
这个脚本的作用是寻找当前文件下的所有proto文件,并在其所在文件夹下生成源码
编写server端:
接口:
package main
import (
"context"
"errors"
"google.golang.org/grpc"
"log"
"net"
"testgo/proto"
"testgo/service"
)
const (
port = ":9543"
)
type server struct {
}
func (server) Calculate(ctx context.Context, in *client.Request) (resp *client.Response, e error) {
log.Printf("Received request")
defer func() {
// 必须要先声明defer,否则不能捕获到panic异常
if err := recover(); err != nil {
e = errors.New(err.(string)) // 这里的err其实就是panic传入的内容
}
}()
c := service.Calculate{
Num1: in.Num1, Num2: in.Num2,}
var result float64
switch in.OpType {
case client.OperateType_Addition:
result = c.Operate(service.Addition)
case client.OperateType_Division:
result = c.Operate(service.Division)
case client.OperateType_Multiplication:
result = c.Operate(service.Multiplication)
case client.OperateType_Subtraction:
result = c.Operate(service.Subtraction)
}
return &client.Response{
Result: result,}, nil
}
func main() {
lis, err := net.Listen