GO语言微服务(1)原生RPC

发布于:2022-10-29 ⋅ 阅读:(433) ⋅ 点赞:(0)

提到微服务,老生常谈的就是服务间的通信,主要有两种方式


同步调用:rpc   远程过程调用

rpc协议:主要包括

1、传输协议(http1.1、http2.0、wensocket协议、http3.0)

2、传输格式(JSON、Protobuf、xml)

异步调用:消息队列  kafka,activeMQ,rocketMQ


net/rpc包

先来了解socket通信

server端  伪代码

listener  :=net.listen()   //获取监听器对象

conn :=listener.Accept() //等待连接

conn.read() //读到客户端发送的数据

conn.write() //向客户端发送数据

conn.close() //关闭连接

listener.close //关闭监听器

client端    伪代码

conn :=net.Dial() //连接服务端

conn.write() //发送数据

conn.read() // 接收返回数据

conn.close() // 关闭连接

RPC使用

server端

//注册rpc服务对象

rpc.RegisterName("服务名",回调函数)

//创建监听器

listener,err := net.Listen()

//建立连接

conn ,err := listener.Accept()

//绑定rpc服务到连接上

rpc.ServeConn(conn)

client端

//连接rpc服务端

conn,err ;=rpc.Dial()

//调用服务

conn.Call("服务名.方法名",传入参数,传出参数)

贴一下代码

server端

package main

import (
	"log"
	"net"
	"net/rpc"
	"strconv"
	"time"
)

// 定义服务
type Order struct{}

func (this *Order) GetOrder(req string, resp *string) error {
	*resp = req + strconv.Itoa(int(time.Now().UnixNano()))
	return nil
}
func main() {
	//注册rpc服务
	rpc.RegisterName("order", new(Order))
	//设置监听
	listener, err := net.Listen("tcp", "127.0.0.1:80")
	if err != nil {
		log.Fatal("监听错误")
	}
	defer listener.Close()
	//获取链接
	accept, err := listener.Accept()
	if err != nil {
		log.Fatal("获取连接错误")
	}
	defer accept.Close()
	//绑定服务与链接
	rpc.ServeConn(accept)
}

client端

package main

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

func main() {
	//连接客户端
	client, err := rpc.Dial("tcp", "127.0.0.1:80")
	if err != nil {
		log.Fatal("连接服务的错误")
	}
	defer client.Close()
	//调用服务
	var resp string
	err = client.Call("order.GetOrder", "lijialin", &resp)
	fmt.Println(err)
	fmt.Println(resp)
}

了解了原始RPC,我们可以对原始RPC进行封装,为后面学习GRPC做铺垫

先来说一下为什么要封装:如下图所示,Order结构体绑定的方法是有一定限制条件的,如果写错了,那么在编译时是不会报错的,但是在运行时会报错,本着报错宜早不宜迟的原则,我们可以是由接口对服务实现类进行限制。

 第一步:新建文件packaging.go用于定义接口(该文件如果你是要框架可以让框架生成,但是了解他会加深你对GRPC框架的印象)

 定义好接口我们在编写服务时如果格式不对,会在编译时发现没有如下图所示的标记

 额外的,我们可以对注册服务进行封装,防止字符串写错

 在packaging文件中声明注册函数

 修改注册服务的代码

 再来看客户端,如下图所示我们可以对rpc.Dial方法进行封装

还可以对client.Call这段代码进行封装(因为目前这些字符串是写死的,服务名和方法名如果写错不死很尬)

 因此我们定义结构体MyClient嵌套rpc.Client的指针对象,并绑定Call方法

更改main.go文件的代码

 对于rpc.Dial()方法的封装我自己觉得没什么必要

 

 OK今天的学习到此结束,累他妈死老子了

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到