go自帶rpc框架生產環境使用demo

基礎使用

序列化使用自帶gob協議

server

package mainimport ("net""net/rpc"
)// 定義一個handler結構體
type HelloService struct {
}// 定義handler方法,大小寫,參數,返回值都是固定的,否則無法注冊
func (receiver *HelloService) Hello(req string, rep *string) error {*rep = "hello " + reqreturn nil
}func main() {
//1. 實例化一個serverlisten, _ := net.Listen("tcp", ":8001")//2. 注冊handler_ = rpc.RegisterName("HelloService", &HelloService{})// 3. 啟動服務for {conn, _ := listen.Accept()go rpc.ServeConn(conn) //避免阻塞}}}

client

package mainimport ("fmt""net/rpc"
)func main() {//1. 建立連接client, _ := rpc.Dial("tcp", "localhost:8001")var data *string = new(string)err := client.Call("HelloService.Hello", "matthew", data)if err != nil {fmt.Println("調用失敗")}fmt.Println("success: ", *data)
}

注:兩個文件需要在不同包下面

使用json序列化

server

package mainimport ("net""net/rpc""net/rpc/jsonrpc"
)// 定義一個handler結構體
type HelloService struct {
}// 定義handler方法,大小寫,參數,返回值都是固定的,否則無法注冊
func (receiver *HelloService) Hello(req string, rep *string) error {*rep = "hello " + reqreturn nil
}func main() {jsonserver()
}/*
*
go 默認的序列化反序列化協議是gob
*/
func gobserver() {//1. 實例化一個serverlisten, _ := net.Listen("tcp", ":8001")//2. 注冊handler_ = rpc.RegisterName("HelloService", &HelloService{})// 3. 啟動服務for {conn, _ := listen.Accept()go rpc.ServeConn(conn) //避免阻塞}
}/*
*
使用json來序列化和反序列化
*/
func jsonserver() {//1. 實例化一個serverlisten, _ := net.Listen("tcp", ":8001")//2. 注冊handler_ = rpc.RegisterName("HelloService", &HelloService{})// 3. 啟動服務for {conn, _ := listen.Accept()go rpc.ServeCodec(jsonrpc.NewServerCodec(conn)) //避免阻塞}}

client

package mainimport ("fmt""net""net/rpc""net/rpc/jsonrpc"
)func main() {jsonRpcClient()
}func jsonRpcClient() {//1. 建立連接client, _ := net.Dial("tcp", "localhost:8001")var data *string = new(string)codeclient := rpc.NewClientWithCodec(jsonrpc.NewClientCodec(client))err := codeclient.Call("HelloService.Hello", "matthew", data)if err != nil {fmt.Println("調用失敗")}fmt.Println("success: ", *data)
}

構建一個規范的rpc項目框架

如果想構建生產環境使用的rpc服務,不但要能實現業務,還要有良好的架構設計

  • client 客戶端
    • client_proxy/stub 客戶端代理封裝
    • handler 句柄封裝
  • server 服務端
    • server_proxy/stub 服務端函數封裝
    • handler 句柄封裝

句柄相當于服務端和客戶端互相通信的通道,告訴雙方可以提供的方法

在這里插入圖片描述

client.go

package mainimport ("fmt""learngo/chw01/nicerpc/client_stub_proxy"
)func main() {stub := client_stub_proxy.NewHelloServiceStub("tcp", "localhost:9001")res := new(string)stub.Hello("matthew", res)fmt.Println(*res)
}

client_stub_proxy

package client_stub_proxyimport ("fmt""learngo/chw01/nicerpc/handler""net/rpc"
)/**
存放客戶端proxy或者stub,封裝已經注冊的服務和方法列表,用于客戶端快速調用專注業務
*/type HelloServiceStub struct {*rpc.Client
}// 構造函數返回一個,服務代理并攜帶客戶端
func NewHelloServiceStub(protcol, address string) HelloServiceStub {client, err := rpc.Dial(protcol, address)if err != nil {fmt.Println(err)panic("rpc client start panic")}return HelloServiceStub{client}
}/*
*
封裝了HelloService服務的Hello方法
*/
func (cs *HelloServiceStub) Hello(req string, reply *string) error {err := cs.Call(handler.HelloServiceName+".Hello", req, reply)return err
}

hander.go

package handler/*
*
定義所有的handler名稱,可以被client,server兩端引入對齊
*/
const HelloServiceName = "hander/HelloService"// 定義一個handler結構體
type HelloService struct {
}// 定義handler方法,大小寫,參數,返回值都是固定的,否則無法注冊
func (receiver *HelloService) Hello(req string, rep *string) error {*rep = "hello " + reqreturn nil
}

server.go

package mainimport ("fmt""learngo/chw01/nicerpc/handler""learngo/chw01/nicerpc/server_proxy_stub""net""net/rpc"
)func main() {var address string = ":9001"//實例化一個serverlisten, err := net.Listen("tcp", address)if err != nil {panic("server start error " + address)}fmt.Println("server start success on address: ", address)//注冊方法server_proxy_stub.RegisterHelloServicer(&handler.HelloService{})//啟動服務for {conn, err := listen.Accept()if err != nil {fmt.Println("connect error", err)}rpc.ServeConn(conn)}
}

server_proxy_stub

package server_proxy_stubimport ("learngo/chw01/nicerpc/handler""net/rpc"
)/**
封裝所有server的方法(業務邏輯)
*//*
*
多態:頂一個HelloServie的接口,凡是實現了該接口方法的struct都繼承了接口
*/
type HelloServicer interface {Hello(req string, reply *string) error
}// 當前的方法只能用來HelloService一種結構體,我們關注的不是結構體而是結構體的方法
func RegisterHelloService(srv *handler.HelloService) error {return rpc.RegisterName(handler.HelloServiceName, srv)
}// 對比上面的注冊,通過接口來注冊更加靈活。所有實現了HelloServicer接口的struct都可以直接使用該方法
func RegisterHelloServicer(srv *handler.HelloService) error {return rpc.RegisterName(handler.HelloServiceName, srv)
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/210185.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/210185.shtml
英文地址,請注明出處:http://en.pswp.cn/news/210185.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數據庫事務:保障數據一致性的基石

目錄 1. 什么是數據庫事務? 1.1 ACID特性解析 2. 事務的實現與控制 2.1 事務的開始和結束 2.2 事務的隔離級別 3. 并發控制與事務管理 3.1 并發控制的挑戰 3.2 鎖和并發控制算法 4. 最佳實踐與性能優化 4.1 事務的劃分 4.2 批處理操作 5. 事務的未來發展…

Qt OpenCV 學習(文章鏈接匯總)

Qt OpenCV 學習(一):環境搭建 Qt OpenCV 學習(二):兩個簡單圖片識別案例 Qt OpenCV 學習(三):跟蹤視頻中的運動物體 Qt OpenCV 學習(四)&#xff…

SpringSecurity6 | 自定義登錄頁面

?作者簡介:大家好,我是Leo,熱愛Java后端開發者,一個想要與大家共同進步的男人😉😉 🍎個人主頁:Leo的博客 💞當前專欄: Java從入門到精通 ?特色專欄&#xf…

高工氫電年會 | 未勢能源解超朋博士受邀出席并做主題演講

12月4日,以“戰略重構 商業覺醒”為主題的2023高工氫電年會在深圳舉辦,未勢能源副總裁解超朋博士受邀出席開幕式論壇,以《把握機遇、直面挑戰,迎接氫車規模化推廣時代》為主題發表演講,并參與圓桌論壇研討。 氫勢已來&…

【Linux】resolv.conf 文件

resolv.conf resolv.conf 文件 是 DNS 的 client 端使用的文件,用于設置 DNS 服務器的 ip 地址以及 DNS 域名,還可以配置域名搜索順序等等。主要包含如下關鍵字:nameserver、domain、search、sortlist、options。設置的格式都是 關鍵字空格 …

管理類聯考——數學——真題篇——按知識分類——數據

文章目錄 排列組合2023真題(2023-05)-數據分析-排列組合-組合-C運算-至少-需反面思考真題(2023-08)-數據分析-排列組合-相鄰不相鄰-捆綁法插空法-插空法注意空位比座位多1個,是用A;捆綁法內部排序用A&#…

Linux(centos, ubuntu) 快速安裝anaconda;5秒安裝anaconda

1.下載Anaconda安裝腳本: 首先,訪問Anaconda的官方下載頁面:https://www.anaconda.com/products/distribution 在頁面上,選擇適用于Linux的Python 3.x版本的Anaconda安裝腳本。也可以使用wget或curl命令從終端下載。示例: wget …

2023中國(海南)國際高爾夫旅游文化博覽會 暨國際商界峰層·全球華人高爾夫精英巡回賽 全國潁商自貿港行盛大啟幕

2023中國(海南)國際高爾夫旅游文化博覽會(以下簡稱“海高博”)暨全國潁商走進海南自貿港于12月7-9日在海口觀瀾湖盛大開幕。該活動由中國國際貿易促進委員會海南省委員會、海南省旅游和文化廣電體育廳主辦,中國國際商會…

C語言中getchar函數

在 C 語言中,getchar() 是一個標準庫函數,用于從標準輸入(通常是鍵盤)讀取單個字符。它的函數原型如下: int getchar(void);getchar() 函數的工作原理如下: 當調用 getchar() 函數時,它會等待…

最新版本11.17的YOLOv8加入注意力方法

本文基于11.17版本,以往版本略有不同,可查看改進YOLOv8,教你YOLOv8如何添加20多種注意力機制進行參考 放入注意力代碼,以biformer注意力為例 import torch import torch.nn as nn import torch.nn.functional as Fdef position(H, W, is_cuda=

探索 Python 中鏈表的實現:從基礎到高級

# 更多資料獲取 📚 個人網站:ipengtao.com 鏈表是一種基礎的數據結構,它由一系列節點組成,每個節點都包含數據和指向下一個節點的引用。在Python中,可以使用類來實現鏈表,本文將介紹如何實現鏈表&#xff…

c語言編程題經典100例——(90~95例)

1,寫一個函數,實現數字的加密和解密。 下面是一個簡單的C語言函數,可以實現數字的加密和解密。這個函數采用簡單的加密算法,將輸入的數字乘以一個固定的密鑰,然后加上一個固定的偏移量。解密過程就是將加密后的數字減去偏移量&am…

《C++新經典設計模式》之第18章 備忘錄模式

《C新經典設計模式》之第18章 備忘錄模式 備忘錄模式.cpp 備忘錄模式.cpp #include <iostream> #include <vector> #include <memory> using namespace std;// 保存對象內部狀態&#xff0c;必要時恢復 // 在不破壞封裝性的前提下&#xff0c;捕獲對象的內部…

(C)一些題11

1. #include<stdio.h> #include<string.h> void main() { char *s1"ABCDEF"&#xff0c;*s2"aB"&#xff1b; s1; s2; puts(s1)&#xff1b; puts(s2)&#xff1b; printf("%d\n",strcmp(s1,s2))&#xff1b; } 答案&#xff1…

【密碼學引論】認證

認證是許多應用系統中安全保護的第一道設防認證和加密的區別&#xff1a;加密用來確保數據的保密性&#xff0c;而認證用來確保報文發送者和接受者的真實性和報文的完整性。認證和數字簽名的區別&#xff1a; 認證總是基于某種收發雙方共享的保密數據來認證被鑒別對象的真實性&…

關于linux開機自啟動

1、系統啟動流程 2、 init、 inittab、 init.d、 rcx.d /etc/inittab是Linux系統中的一個配置文件&#xff0c;用于定義系統的運行級別和相應的操作。其語法格式如下&#xff1a; 標簽&#xff1a;運行級別&#xff1a;操作&#xff1a;進程 label:runlevel:action:process下面…

每天一點python——day90

#每天一點Python——90 #類的創建 創建類的語法&#xff1a; class 類名&#xff1a;pass【縮進之后寫類里面的內容】 [類里面寫什么沒有想好之前&#xff0c;可以用pass進行占位.可以不報錯]#演示&#xff1a; class Lei:pass #以上就上一個類被創建的樣例注意事項&#xff1a…

PHP基礎 - 注釋變量

一. 語言開始標識 在PHP中,文件的開頭需要使用語言開始標識來指定該文件是PHP代碼。標識通常為"<?php",也可以是"<?",但建議使用"<?php"以確保代碼的兼容性和可讀性。 <?php // PHP代碼從這里開始寫 二. PHP注釋 注釋是用…

[英語學習][11][Word Power Made Easy]的精讀與翻譯優化

[序言] 這次翻譯, 譯者有點點水平. 有些比較難表達的, 都能正確地翻譯出來. 但有點很奇怪, 難的地方譯者翻譯正確, 容易的地方又錯了. [英文學習的目標] 提升自身的英語水平, 對日后編程技能的提升有很大幫助. 希望大家這次能學到東西, 同時加入我的社區討論與交流英語相關的…

遇到這個問題怎么辦

1. 問題現象 話說近日博主的團隊中&#xff0c;有一個小盆友遇到了一個問題&#xff0c;即使用RSA進行加解密的時候&#xff0c;拋異常了&#xff1a; java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: DerInputStream.getLeng…