美文网首页
88.go微服务之RPC实践

88.go微服务之RPC实践

作者: 厚土火焱 | 来源:发表于2021-03-21 20:44 被阅读0次

微服务是现在大多数新项目会采用的架构。服务端提供服务,客户端调用服务端的功能,就像调用一个函数一样。微服务的更新升级,只要接口没有变化,客户端完全可以无影响地升级到新功能。这就是微服务的第一个体验。
随之而来的,就是每个微服务都可以用任意计算机语言实现,方便了不同技术团队的协作。
而整个软件系统的构成,也不同于以往的实现方式了。这样的构成,更灵活和强大。当然随着服务数量的增加,也增加了服务的管理难度。
go语言的RPC服务实现起来非常简单。可以利用tcp或http协议来传递数据。
我们通过一个计算矩形面积和周长的微服务实例来学习rpc服务的编写方法。
首先,实现server端(server.go),定义一个矩形

//  声明矩形结构体
type Rect struct {

}

再定义矩形的参数

//  声明参数结构体
type Params struct {
    //  宽,高
    Width, Height int
}

因为计算面积和周长的RPC服务是远程调用,那么在服务端计算,通过获取和改变内存变量的值实现调用远程微服务像本地函数一样的效果。所以,传入的参数除了宽和高以外,还有一个供承载计算结果的整形指针。如果发生错误,就返回error,无错误的时候,return nil 就可以了。

//  计算矩形面积
func (r *Rect) Area(p Params, ret *int) error {
    *ret = p.Width * p.Height
    return nil
}
//  计算周长
func (r *Rect) Perimeter(p Params, ret *int) error {
    *ret = (p.Width + p.Height) * 2
    return nil
}

在主函数中,首先要注册服务

    //  注册服务
    rect := new(Rect)
    rpc.Register(rect)

然后绑定服务到http协议

// 服务绑定http协议
    rpc.HandleHTTP()

最后服务器开始监听服务,等待客户端来调用。这个服务我们使用8080端口。

//  监听服务,等待客户端调用(求面积和周长的方法)
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        log.Fatal(err)
    }

至此,微服务server端代码已经写完。
下面开始编写微服务client端代码(client.go)。
client端要和server端拥有相同的参数结构体。即

//  参数
type Params struct {
    Width, Height int
}

client远程连接server,这里采用tcp协议,还需要提前知道server的地址和通讯端口。以下代码建立远程连接,并得到一个实例rp。

//  连接远程的RPC服务
    rp, err := rpc.DialHTTP("tcp", "127.0.0.1:8080")
    if err != nil {
        log.Println(err)
    }

为了获取计算结果和提供计算参数,声明2个变量。一个保存结果,一个保存参数。

    //  结果
    ret := 0
    //  参数
    p := Params{50 ,100}

调用远程服务(面积)

//  1. 求面积
    err2 := rp.Call("Rect.Area", p, &ret)
    if err2 != nil {
        log.Println(err2)
    }else{
        fmt.Println("面积:", ret)
    }

调用远程服务(周长)

//  2. 求周长
    err3 := rp.Call("Rect.Perimeter", p, &ret)
    if err3 != nil {
        log.Println(err3)
    }else {
        fmt.Println("周长:", ret)
    }

运行客户端client.go,由于此时server未启动,所以客户端会得到一个连接被拒绝的结果。

2021/03/21 20:23:48 dial tcp 127.0.0.1:8080: connectex: 由于目标计算机积极拒绝,无法连接。
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x1 addr=0x10 pc=0x109e944]
...

启动server端,再次运行client端,得到运行结果

面积: 5000
周长: 300

server.go 完整代码

/**
* Package: rpcServer
* Description: This package is rpcServer example
* Author: Jian Junbo
* Email: junbojian@qq.com
* Date:  2021/3/21 17:31
* Copyright ©2021 Jian Junbo & Shanxi Xiyue Mancang Technology Co., Ltd. All rights reserved.
**/
package main

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

//  声明矩形结构体
type Rect struct {

}
//  声明参数结构体
type Params struct {
    //  宽,高
    Width, Height int
}
//  计算矩形面积
func (r *Rect) Area(p Params, ret *int) error {
    *ret = p.Width * p.Height
    return nil
}
//  计算周长
func (r *Rect) Perimeter(p Params, ret *int) error {
    *ret = (p.Width + p.Height) * 2
    return nil
}

func main() {
    //  注册服务
    rect := new(Rect)
    rpc.Register(rect)
    // 服务绑定http协议
    rpc.HandleHTTP()
    //  监听服务,等待客户端调用(求面积和周长的方法)
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        log.Fatal(err)
    }
}

client.go 完整代码

/**
* Package: rpcClient
* Description: This package is rpcClient example.
* Author: Jian Junbo
* Email: junbojian@qq.com
* Date:  2021/3/21 18:31
* Copyright ©2021 Jian Junbo & Shanxi Xiyue Mancang Technology Co., Ltd. All rights reserved.
**/
package main

import (
    "fmt"
    "log"
    "net/rpc"
)
//  参数
type Params struct {
    Width, Height int
}

//  主函数调用服务
func main() {
    //  连接远程的RPC服务
    rp, err := rpc.DialHTTP("tcp", "127.0.0.1:8080")
    if err != nil {
        log.Println(err)
    }
    //  * 调用服务方法
    //  结果
    ret := 0
    //  参数
    p := Params{50 ,100}
    //  1. 求面积
    err2 := rp.Call("Rect.Area", p, &ret)
    if err2 != nil {
        log.Println(err2)
    }else{
        fmt.Println("面积:", ret)
    }

    //  2. 求周长
    err3 := rp.Call("Rect.Perimeter", p, &ret)
    if err3 != nil {
        log.Println(err3)
    }else {
        fmt.Println("周长:", ret)
    }
}

相关文章

  • 88.go微服务之RPC实践

    微服务是现在大多数新项目会采用的架构。服务端提供服务,客户端调用服务端的功能,就像调用一个函数一样。微服务的更新升...

  • go微服务

    毛剑:Bilibili 的 Go 服务实践 一、微服务演进: 梳理业务边界 资源隔离部署 内外网服务隔离 RPC框...

  • 网络通信优化之通信协议:如何优化RPC网络通信?

    网络通信优化之通信协议:如何优化RPC网络通信? RPC 通信是大型服务框架的核心 我们经常讨论微服务,首要应该了...

  • Dubbo

    Dubbo(服务治理框架) RPC 各服务都要实现rpc协议,才能实现服务间的调用 rpc:远程过程调用协议,是一...

  • 搭建、挂载nfs及卸载

    搭建 1、 安装 nfs 和 rpc 2、运行 rpc 和 nfs (先启动RPC服务,然后再启动NFS服务) ...

  • 基于Netty的高性能JAVA的RPC框架

    RPC的实现 1. RPC客户端 2. RPC服务端 RPC客户端的实现 RPC客户端和RPC服务器端需要一个相同...

  • 【Dubbo】Dubbo 简介

    Apache Dubbo 是一款微服务框架,为大规模微服务实践提供高性能 RPC 通信、流量治理、可观测性等解决方...

  • 架构师凭什么拿60万年薪?从微服务框架说起

    微服务架构专题 RPC原理 RPC是什么? RPC(Remote Procedure Call Protocol)...

  • 2020-11-06

    多语言微服务版本管理实践 版本化、优雅、简单实现微服务之间的rpc通讯 首先划分业务架构 淘宝、京东、天猫属于业务...

  • RabbitMQ笔记二十二 :异步RPC之一(java clie

    异步RPC(Remote procedure call) Server:提供服务的服务,即RPC模型中的Serve...

网友评论

      本文标题:88.go微服务之RPC实践

      本文链接:https://www.haomeiwen.com/subject/mbcocltx.html