当前位置: 首页 > news >正文

C++GO语言微服务基础技术①

目录

01-项目简介

02-单体式架构

03-微服务优缺点

04-单体式和微服务区别

05-RPC简介

06-RPC使用步骤

07-注册RPC服务函数接口

08-绑定服务和调用方法函数接口

09-rpc服务端和客户端编码实现

10-json的rpc

11-rpc的封装

12-rpc封装小结


01-项目简介

# 单体式和微服务## 单体式架构服务 —— 过往大家熟悉的服务器。特性:1.  复杂性随着开发越来越高, 遇到问题解决困难。
2.  技术债务逐渐上升。
3.  耦合度高,维护成本大!1. 出现bug, 不容易排查2. 解决旧bug, 会出新bug
4.  持续交付时间较长。
5.  技术选型成本高,风险大。
6.  扩展性较差1. 垂直扩展:通过增加单个系统程的负荷来实现扩展。2. 水平扩展:通过增加更多的系统成员来实现扩展。

02-单体式架构

## 微服务- 优点:1.  职责单一2.  轻量级通信3.  独立性4.  迭代开发。
- 缺点:1.  运维成本高2.  分部式复杂度3.  接口成本高4.  重复性劳动5.  业务分离困难。

03-微服务优缺点

04-单体式和微服务区别

# RPC 协议## 什么是RPCRemote Procedure Call Protocol   —— 远程过程调用协议!IPC: 进程间通信 RPC:远程进通信 —— 应用层协议(http协议同层)。底层使用 TCP 实现。> 回顾:
>
> OSI 7 层模型架构:物、数、网、传、会、表、应
>
> TCP/IP 4 层架构:链路层、网络层、传输层、应用层- 理解RPC:- **==像调用本地函数一样,去调用远程函数。==**- 通过rpc协议,传递:函数名、函数参数。达到在本地,调用远端函数,得返回值到本地的目标。- 为什么微服务使用 RPC:1.  每个服务都被封装成 进程。彼此”独立“。2.  进程和进程之间,可以使用不同的语言实现。

05-RPC简介

### RPC 入门使用远程 —— 网络!!> 回顾:Go语言 一般性 网络socket通信 
>
> server端:
>
> ​		net.Listen()  —— listener      创建监听器
>
> ​		listener.Accpet()  —— conn   启动监听,建立连接
>
> ​		conn.read() 
>
> ​        conn.write()
>
> ​        defer conn.Close() / listener.Close()
>
> client端:
>
> ​		net.Dial()  —— conn
>
> ​		conn.Write() 
>
> ​		conn.Read()
>
> ​        defer conn.Close()

06-RPC使用步骤

### RPC 使用的步骤---- 服务端:1.  注册 rpc 服务对象。给对象绑定方法( 1. 定义类, 2. 绑定类方法 )```gorpc.RegisterName("服务名",回调对象)```2.  创建监听器 ```golistener, err := net.Listen()```3.  建立连接```goconn, err := listener.Accept()```4.  将连接 绑定 rpc 服务。```gorpc.ServeConn(conn)```

07-注册RPC服务函数接口

---- 客户端:1. 用 rpc 连接服务器。```goconn, err := rpc.Dial()```2. 调用远程函数。```goconn.Call("服务名.方法名", 传入参数, 传出参数)```## RPC 相关函数1. 注册 rpc 服务```gofunc (server *Server) RegisterName(name string, rcvr interface{}) error参1:服务名。字符串类型。参2:对应 rpc 对象。 该对象绑定方法要满足如下条件:1)方法必须是导出的 —— 包外可见。 首字母大写。2)方法必须有两个参数, 都是导出类型、內建类型。3)方法的第二个参数必须是 “指针” (传出参数)4)方法只有一个 error 接口类型的 返回值。举例:type World stuct {}		func (this *World) HelloWorld (name string, resp *string) error { }rpc.RegisterName("服务名", new(World))```

08-绑定服务和调用方法函数接口

2. 绑定 rpc 服务```gofunc (server *Server) ServeConn(conn io.ReadWriteCloser)conn: 成功建立好连接的 socket —— conn```3. 调用远程函数:```gofunc (client *Client) Call(serviceMethod string, args interface{}, reply interface{}) errorserviceMethod: “服务名.方法名”args:传入参数。 方法需要的数据。reply:传出参数。定义 var 变量,&变量名  完成传参。

09-rpc服务端和客户端编码实现

## 编码实现server端```go
package mainimport ("net/rpc""fmt""net"
)// 定义类对象
type World struct {
}// 绑定类方法
func (this *World) HelloWorld (name string, resp *string) error {*resp = name + " 你好!"return nil
}func main()  {// 1. 注册RPC服务, 绑定对象方法err := rpc.RegisterName("hello", new(World))if err != nil {fmt.Println("注册 rpc 服务失败!", err)return}// 2. 设置监听listener, err := net.Listen("tcp", "127.0.0.1:8800")if err != nil {fmt.Println("net.Listen err:", err)return}defer listener.Close()fmt.Println("开始监听 ...")// 3. 建立链接conn, err := listener.Accept()if err != nil {fmt.Println("Accept() err:", err)return}defer conn.Close()fmt.Println("链接成功...")// 4. 绑定服务rpc.ServeConn(conn)
}

10-json的rpc

client端```go
package mainimport ("net/rpc""fmt"
)func main()  {// 1. 用 rpc 链接服务器 --Dial()conn, err := rpc.Dial("tcp", "127.0.0.1:8800")if err != nil {fmt.Println("Dial err:", err)return}defer conn.Close()// 2. 调用远程函数var reply string 		// 接受返回值 --- 传出参数err = conn.Call("hello.HelloWorld", "李白", &reply)if err != nil {fmt.Println("Call:", err)return}fmt.Println(reply)
}
```

11-rpc的封装

## json 版 rpc- 使用 nc -l 127.0.0.1 880 充当服务器。
-  02-client.go 充当 客户端。 发起通信。 —— 乱码。 - 因为:RPC 使用了go语言特有的数据序列化 gob。 其他编程语言不能解析。
- 使用 通用的 序列化、反序列化。 —— json、protobuf### 修改客户端修改客户端,使用jsonrpc:```go
conn, err := jsonrpc.Dial("tcp", "127.0.0.1:8800")
```使用 nc -l 127.0.0.1 880 充当服务器。看到结果:​		{"method":"hello.HelloWorld","params":["李白"],"id":0}### 修改服务器端修改服务器端,使用 jsonrpc:```go
jsonrpc.ServeConn(conn)
```使用 nc 127.0.0.1 880 充当客户端。看到结果:​			echo -e '{"method":"hello.HelloWorld","params":["李白"],"id":0}' | nc 127.0.0.1 8800**如果,绑定方法返回值的 error 不为空? 无论传出参数是否有值,服务端都不会返回数据。** 

12-rpc封装小结

## rpc 封装#### 服务端封装1. ```go// 定义接口type xxx interface {方法名(传入参数,传出参数) error}例:type MyInterface interface {HelloWorld(string, *string) error}```2. ```go// 封装注册服务方法func RegisterService (i MyInterface) {rpc.RegisterName("hello", i)}```#### 客户端封装1. ```go// 定义类type MyClient struct {c *rpc.Client}```2. ```go// 绑定类方法func (this *MyClient)HelloWorld(a string, b *string) error {return  this.c.Call("hello.HelloWorld", a, b)}```3. ```go// 初始客户端func InitClient(addr string) error {conn, _ := jsonrpc.Dial("tcp", adddr)return MyClient{c:conn}}```# protobuf
http://www.xdnf.cn/news/338365.html

相关文章:

  • IDEA 2024 版本配置热部署
  • 【计算机网络】--tcp三次握手
  • 【Pandas】pandas DataFrame ewm
  • 2024年 AI大模型我该买一张什么显卡?
  • 好消息!PyCharm 社区版现已支持直接选择 WSL 终端为默认终端
  • 最新Spring Security实战教程(十四)OAuth2.0精讲 - 四种授权模式与资源服务器搭建
  • 【hadoop】Sqoop数据迁移工具的安装部署
  • 22、近端策略优化算法(PPO)论文笔记
  • 深入理解Spring缓存注解:@Cacheable与@CacheEvict
  • 避免数据丢失:在存储测试数据之前,要做好Redis持久化
  • SyntaxError: Non-UTF-8 code starting with ‘\xe5‘ in file
  • 仓储车间安全革命:AI叉车防撞装置系统如何化解操作风险
  • 晶振:智能设备的“心跳”如何支撑5G与航天
  • Spring Boot 启动原理的核心机制
  • STM32-模电
  • 关于汇编语言与程序设计——单总线温度采集与显示的应用
  • React 笔记[1] hello world
  • 【程序员AI入门:应用开发】8.LangChain的核心抽象
  • 基于springboot+vue的校园部门资料管理系统
  • 2025最新免费视频号下载工具!支持Win/Mac,一键解析原画质+封面
  • 小刚说C语言刷题—1341银行存款问题
  • 到达最后一个房间的最少时间II 类似棋盘转移规律查找
  • python打卡day19
  • 爱普生FC2012SN晶振在TWS蓝牙耳机中的应用优势
  • 代理服务器
  • 《Zabbix Proxy分布式监控实战:从安装到配置全解析》
  • uniapp|获取当前用户定位、与系统设定位置计算相隔米数、实现打卡签到(可自定义设定位置、位置有效范围米数)
  • 【本地搭建npm私服】使用Verdaccio
  • K8s中的containerPort与port、targetPort、nodePort的关系:
  • ping_test_parallel.sh 并行网络扫描脚本