go的net/rpc用法

一:PRC是什么?

RPC(Remote Procedure Call) 远程过程调用,是一个计算通信协议。该协议允许一台计算机上的程序调用另外一台计算机上的程序。
远程过程调用就是2个不在同一台计算机上的程序方法,根据一定的规则可以彼此进行调用

二:为什么要用RPC

当一个公司跨部门合作,或者跨公司合作时,你不想暴露自己项目太多的数据,而只允许对方获取特定的数据时候,你就可以用RPC了。 还有就是方法参数确定了后,函数内部的实现不管你怎么变化,都不会影响彼此

那你要问: 我用RESTful 不是一样吗?
那就来说说这2者的区别:
1:RPC的客户端和服务端是紧耦合的,客户端要知道调用过程的名字,过程的参数以及类型,顺序
RESTful是基于HTTP的语义来操作资源,参数的顺序一般关系不大,也容易通过代理转换链接和资源的位置,从这一点说,RESTful更灵活

2:他们操作不一样。 RPC操作的是过程和方法。 RESTful操作的是资源,不是方法

3:RESTful执行的是对资源的操作,增加、查找、修改和删除等,主要是CURD,所以如果你要实现一个特定目的的操作,比如为名字姓张的学生的数学成绩都加上10这样的操作, RESTful的API设计起来就不是那么直观或者有意义。在这种情况下, RPC的实现更有意义,它可以实现一个 Student.Increment(Name, Score) 的方法供客户端调用

4:如果我们用socket实现RPC,那么就能获取性能上的优势。在大并发的情况下,RPC的性能优于RESTful

所以通常情况下,我们对内是用rpc提供服务,对外用RESTful提供服务

三:golang中的rpc

golang官方给我们提供了一个net/rpc的库使用,它支持tpc,http,JSONRPC数据传输。但是它只能用于go内部使用,为什么?因为它使用了一个go自带的库(encoding/gob)来编码和解码。如果需要跨平台那么需要其它的rpc框架了,比如thrift,gRPC等等

net/rpc的远程调用还有一些附加条件:

  1. 函数必须是导出的(首字母大写)
  2. 必须有两个导出类型的参数
  3. 第一个参数是接收的参数,第二个参数是返回给客- 户端的参数,第二个参数必须是指针类型的
  4. 函数还要有一个返回值error

举个例子,正确的RPC函数格式如下:
func (t *T) MethodName(argType T1, replyType *T2) error
T、T1和T2类型必须能被encoding/gob包编解码。

四:net/rpc 库

服务端代码:rpc_server.go

package main

import (
    "errors"
    "log"
    "net"
    "net/http"
    "net/rpc"
)

type Args struct {
    A, B int
}

type Quotient struct {
    Quo, Rem int
}

type Arith int

func (t *Arith) Multiply(args *Args, reply *int) error {
    *reply = args.A * args.B
    return nil
}

func (t *Arith) Divide(args *Args, quo *Quotient) error {
    if args.B == 0 {
        return errors.New("divide by zero")
    }
    quo.Quo = args.A / args.B
    quo.Rem = args.A % args.B
    return nil
}

func main() {
    arith := new(Arith)
    rpc.Register(arith)
    rpc.HandleHTTP()
    l, e := net.Listen("tcp", ":1212")
    if e != nil {
        log.Fatal("listen error: ", e)
    }
    http.Serve(l, nil)
}

简单分析一下上面的例子,先实例化了一个Arith对象arith,然后给arith注册了rpc服务,然后把rpc挂载到http服务上面,当http服务打开的时候我们就可以通过rpc客户端来调用arith中符合rpc标准的的方法了

 

客户端代码:rpc_client.go

package main

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

type Args struct {
    A, B int
}

type Quotient struct {
    Quo, Rem int
}

func main() {
    client, err := rpc.DialHTTP("tcp", "127.0.0.1:1212")
    if err != nil {
        log.Fatal("dialing: ", err)
    }

    args := &Args{7, 8}
    var reply int
    err = client.Call("Arith.Multiply", args, &reply)
    if err != nil {
        log.Fatal("arith error: ", err)
    }
    fmt.Printf("Arith: %d*%d=%d\n", args.A, args.B, reply)

    quotient := new(Quotient)
    divCall := client.Go("Arith.Divide", args, quotient, nil)
    replyCall := <-divCall.Done
    if replyCall.Error != nil {
        log.Fatal("arith error: ", replyCall.Error)
    }
    fmt.Printf("Arith: %d/%d = %d...%d", args.A, args.B, quotient.Quo, quotient.Rem)
}

简单说明下,先用rpc的DialHTTP方法连接服务器端,调用服务器端的函数就要使用Call方法了,Call方法的参数和返回值已经很清晰的表述出rpc整体的调用逻辑了
运行服务器端跑起来,

$ go run rpc_server.go

再把客户端跑起来,这时候客户端会输出:
$ go run rpc_client.go
Arith: 7*8=56
Arith: 7/8 = 0...7

参考:
https://www.cnblogs.com/andyidea/p/6525714.html

 

转载于:https://www.cnblogs.com/jiujuan/p/9363637.html

<think>好的,用户遇到了Go模块中标准库包缺失的问题,需要解决。首先,我需要理清可能的原因和对应的解决方案。根据用户提到的错误信息,可能涉及标准库包如delve、liner、go.starlark.net、blackfriday、telemetry等,这些可能并非Go官方标准库的一部分,而是第三方包。用户可能误解了这些包属于标准库,或者在GOPATH下找不到它们,导致构建失败。 首先,标准库包通常不需要手动安装,它们随Go安装一起提供。如果出现缺失,可能是Go环境安装不完整或版本不匹配。需要检查Go版本,使用go version确认,并考虑重新安装或升级。另外,GOPATH和GOMODULE的配置可能有问题。Go Modules启用后,依赖管理不再依赖GOPATH,但若项目未正确初始化模块,可能导致问题。用户需要确认是否在项目目录下执行了go mod init,并确保go.mod文件存在。 其次,提到的包如delve(调试工具)、blackfriday(Markdown处理器)、go.starlark.net(嵌入Starlark语言)等,都是第三方库。用户可能没有正确获取这些依赖。需要使用go get命令安装,例如go get github.com/russross/blackfriday/v2。同时,检查go.mod和go.sum是否包含这些依赖,必要时手动添加并运行go mod tidy。 另外,GOPATH的环境变量设置可能被覆盖或错误,需要检查GOPATH是否指向正确目录,并确认这些第三方包是否被下载到GOPATH下的pkg/mod中。若使用Go Modules,GOPATH的角色已经弱化,主要依赖项目内的go.mod管理。 还有可能涉及特定工具的配置问题,例如Delve调试器需要确保其版本与Go版本兼容,或者重新安装Delve(go install github.com/go-delve/delve/cmd/dlv@latest)。对于telemetry相关的错误,可能与Go 1.15+的遥测功能有关,但通常不影响构建,除非有特定环境限制,可以尝试禁用遥测(GOTELEMETRY=off)。 总结解决方案步骤:1. 确认Go环境正确安装;2. 初始化Go模块;3. 使用go get安装缺失的第三方包;4. 检查并更新依赖;5. 处理工具链问题;6. 环境变量检查。同时,用户可能需要区分标准库和第三方包,正确管理依赖。</think>### 逐步解决方案:Go模块中标准库包缺失问题 #### 1. **确认包的真实性质** - **标准库包**:Go的标准库包(如`fmt`、`net/http`)无需手动安装,随Go环境自动提供。若提示缺失,可能是环境配置问题。 - **第三方包**:例如: - `delve`:调试工具([github.com/go-delve/delve](https://github.com/go-delve/delve)) - `blackfriday`:Markdown处理器([github.com/russross/blackfriday](https://github.com/russross/blackfriday)) - `go.starlark.net`:Starlark语言嵌入库([go.starlark.net](https://github.com/google/starlark-go)) 若误将第三方包当作标准库,需通过`go get`安装: ```bash go get github.com/russross/blackfriday/v2 go get go.starlark.net/@latest ``` #### 2. **检查Go环境配置** - **确认Go版本**: ```bash go version # 需≥1.11(支持Go Modules) ``` - **重新安装Go环境**: 若标准库缺失(如`fmt`报错),重新安装Go并检查环境变量`GOROOT`和`GOPATH`[^3]。 #### 3. **初始化Go模块** - 在项目根目录执行: ```bash go mod init <module-name> # 初始化模块 go mod tidy # 自动添加/移除依赖 ``` - 手动添加缺失包到`go.mod`: ```go require ( github.com/go-delve/delve v1.20.1 go.starlark.net v0.0.0-20230831151026-0... ) ``` #### 4. **解决特定包问题** - **Delve调试工具**: ```bash go install github.com/go-delve/delve/cmd/dlv@latest ``` - **Telemetry错误**: 禁用遥测(临时): ```bash export GOTELEMETRY=off ``` #### 5. **检查GOPATH与模块兼容性** - Go Modules启用后,依赖默认存储在`$GOPATH/pkg/mod`,无需手动操作。 - 确认环境变量: ```bash go env GOPATH # 查看当前GOPATH go env GOMOD # 确认当前模块路径 ``` #### 6. **更新依赖版本** - 强制更新所有依赖: ```bash go get -u ./... ``` --- ### 关键命令总结 | 问题类型 | 命令示例 | |--------------------|--------------------------------------------------------------------------| | 安装第三方包 | `go get github.com/russross/blackfriday/v2` | | 初始化模块 | `go mod init example.com/project` | | 清理无效依赖 | `go mod tidy` | | 更新所有依赖 | `go get -u ./...` | | 重新安装Delve | `go install github.com/go-delve/delve/cmd/dlv@latest` | --- ### 相关问题 1. **如何区分Go标准库和第三方包?** > 标准库列表见[官方文档](https://pkg.go.dev/std),未列出的均为第三方包。 2. **Go Modules与GOPATH的关系是什么?** > Modules启用后,依赖优先从`go.mod`管理,存储于`$GOPATH/pkg/mod`,不再依赖`GOPATH/src`。 3. **如何修复`missing go.sum entry`错误?** > 运行`go mod tidy`或`go mod verify`同步依赖校验。 4. **Go 1.16+的默认模块行为有何变化?** > `go install`默认安装到`GOBIN`,且需显式指定`@version`(如`@latest`)。 --- ### 引用标注 [^1]: 关于Git库和中间件的引用,见Webhooks工具库说明。 [^2]: 视频处理库如FFmpeg绑定,参考相关Go包文档。 : Go Modules的官方定义和操作指南,详见Go官方博客。 [^4]: DevOps工具链的集成方法,参考Go生态工具分类。 [^5]: Go到其他语言的编译工具,如GopherJS,需注意版本兼容性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值