Go微服务: 基于net/rpc/jsonrpc模块实现微服务跨语言调用

概述

  • Golang 提供 net/rpc/jsonrpc 库来实现rpc方法
  • 采用 json 方式进行数据编解码,支持跨语言调用

这里实现跨语言示例

1 )go 服务端

go 复制代码
package main  
  
import ( 
	"log"  
	"net"  
	"net/rpc"  
	"net/rpc/jsonrpc"
)  
  
// 定义服务接口  
type Arith int  
  
// 定义接口方法,参数和返回值都应该是指针类型  
func (t *Arith) Multiply(args *Args, reply *int) error {
	*reply = args.A * args.B
	log.Print("参数", args)
	return nil  
}  
  
// Args 是传递给服务的参数结构  
type Args struct {  
	A, B int  
}  
  
func main() {  
	arith := new(Arith)  
	rpc.Register(arith)  
  
	l, err := net.Listen("tcp", ":1234")  
	if err != nil {  
		log.Fatal("listen error:", err)  
	}  
	defer l.Close()  
  
	for {  
		conn, err := l.Accept()  
		if err != nil {  
			log.Print("accept error:", err)  
			continue  
		}  
  
		// 使用 jsonrpc 包处理连接  
		go func() {  
			jsonrpc.ServeConn(conn)  
			conn.Close()  
		}()  
	}  
}

2 )nodejs 客户端1

js 复制代码
const net = require('net');  
const readline = require('readline');  
  
// 创建一个 TCP 客户端  
const client = new net.Socket();  
  
// 连接到服务器  
client.connect(1234, 'localhost', () => {  
  console.log('Connected to server!');  
  
  // 发送请求到服务器  
  const request = JSON.stringify({  
    jsonrpc: "2.0",  
    method: "Arith.Multiply",  
    params: [{ A: 7, B: 8 }],  
    id: 1  
  });  
  
  client.write(request + '\n');  
});  
  
// 处理从服务器返回的数据  
const rl = readline.createInterface({  
  input: client,  
  output: process.stdout,  
  terminal: false  
});  
  
rl.on('line', (line) => {  
  const response = JSON.parse(line);  
  console.log('Server response:', response.result);  
  client.end();  
});  
  
client.on('error', (err) => {  
  console.error('Socket error:', err);  
});  
  
client.on('close', () => {  
  console.log('Connection closed');  
});

3 )nodejs 客户端2

js 复制代码
const jayson = require('jayson');  
const client = jayson.client.tcp({  
  port: 1234,  
  host: 'localhost'  
});  
  
// 定义要调用的方法以及参数  
const request = {  
  jsonrpc: "2.0",  
  method: "Arith.Multiply",  
  params: [{ A: 7, B: 8 }],  
  id: 1  
};  
  
// 发送请求并处理响应  
client.request(request, function(err, response) {  
  if (err) {  
    console.error('请求出错:', err);  
    return;  
  }  
    
  console.log('服务器响应:', response.result); // 输出乘法的结果  
});

4 )go 客户端3

js 复制代码
package main

import (
	"fmt"
	"net"
	"net/rpc"
	"net/rpc/jsonrpc"
)

type Args struct {  
	A int `json:"A"`  
	B int `json:"B"`  
}  

func main() {
	// 1. 用 net.Dial和rpc微服务端建立连接
	conn, err1 := net.Dial("tcp", "127.0.0.1:1234")
	if err1 != nil {
		fmt.Println(err1)
	}
	// 2. 当客户端退出的时候关闭连接
	defer conn.Close()

	// 3、建立基于json编解码的rpc服务
	client := rpc.NewClientWithCodec(jsonrpc.NewClientCodec(conn))

	// 4. 调用远程函数
	var reply int
	err2 := client.Call("Arith.Multiply", Args{A: 7, B: 8}, &reply)
	if err2 != nil {
		fmt.Println(err2)
	}
	// 5. 获取微服务返回的数据
	fmt.Println(reply)
}

总结

  • 这里演示了,基于go语言为服务端,nodejs 和 golang 为客户端的3种示范
  • 注意,上面 nodejs版本中的 params 的格式与 golang 中的区别
  • 标准库的RPC默认采用Go语言特有的gob编码,没法实现跨语言调用
  • golang官方还提供了 net/rpc/jsonrpc 库实现RPC方法
  • JSON RPC采用JSON进行数据编解码,因而支持跨语言调用
  • 但目前的jsonrpc库是基于tcp协议实现的,暂时不支持使用http进行数据传输
  • 另外,Mac环境,在没有服务端服务时,可用 nc 工具调试客户端
    • $ nc -l 127.0.0.1 1234
  • linux下需要安装, $ yum install -y nc
  • nc是netcat的简写,是一个功能强大的网络工具,有着网络界的瑞士军刀美誉
  • nc命令的主要作用如下:
    • 实现任意TCP/UDP端口的侦听,nc可以作为server以TCP或UDP方式侦听指定端口
    • 端口的扫描,nc可以作为client发起TCP或UDP连接
    • 机器之间传输文件
    • 机器之间网络测速
相关推荐
有梦想的咸鱼_2 小时前
go实现并发安全hashtable 拉链法
开发语言·golang·哈希算法
掘金-我是哪吒3 小时前
微服务mysql,redis,elasticsearch, kibana,cassandra,mongodb, kafka
redis·mysql·mongodb·elasticsearch·微服务
茶馆大橘4 小时前
微服务系列六:分布式事务与seata
分布式·docker·微服务·nacos·seata·springcloud
杜杜的man7 小时前
【go从零单排】go中的结构体struct和method
开发语言·后端·golang
幼儿园老大*7 小时前
走进 Go 语言基础语法
开发语言·后端·学习·golang·go
半桶水专家7 小时前
go语言中package详解
开发语言·golang·xcode
llllinuuu7 小时前
Go语言结构体、方法与接口
开发语言·后端·golang
cookies_s_s7 小时前
Golang--协程和管道
开发语言·后端·golang
王大锤43917 小时前
golang通用后台管理系统07(后台与若依前端对接)
开发语言·前端·golang
产幻少年7 小时前
golang函数
golang