国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

怎么做淘寶客網(wǎng)站做淘客拼多多代運營一般多少錢

怎么做淘寶客網(wǎng)站做淘客,拼多多代運營一般多少錢,石家莊營銷型網(wǎng)站制作,可口可樂網(wǎng)絡(luò)營銷策劃方案Go管理工具 早期 Go 語言不使用 go module 進行包管理,而是使用 go path 進行包管理,這種管理方式十分老舊,兩者最顯著的區(qū)別就是:Go Path 創(chuàng)建之后沒有 go.mod 文件被創(chuàng)建出來,而 go module 模式會創(chuàng)建出一個 go.mod…

Go管理工具

早期 Go 語言不使用 go module 進行包管理,而是使用 go path 進行包管理,這種管理方式十分老舊,兩者最顯著的區(qū)別就是:Go Path 創(chuàng)建之后沒有 go.mod 文件被創(chuàng)建出來,而 go module 模式會創(chuàng)建出一個 go.mod 文件用于管理包信息

現(xiàn)在就是:盡量使用 Go Modules 模式

另外,我們在引入包的時候,可以先進行 import 再通過編譯器來下載內(nèi)容,這樣能讓我們更簡便的處理包關(guān)系

Go 編碼規(guī)范

命名規(guī)范

命名首字母大寫 被視為 Public,小寫被視為 Private

包名和目錄名應(yīng)為小寫,不帶有下劃線與駝峰

文件名應(yīng)為全小寫,其中可能帶有的多個單詞以下劃線分隔

對于接口的命名,我們應(yīng)該在末尾加上 ‘er’ 來標(biāo)注

常量使用全大寫命名,中間使用下劃線隔開

Go 語言中的包分為三種:Go 語言自帶的標(biāo)準(zhǔn)庫中的包、第三方包、自己寫的包

RPC

rpc 是指 remote procedure call 也就是遠程節(jié)點調(diào)用,其實就是一個節(jié)點調(diào)用另一個節(jié)點

這之中最關(guān)鍵的三個問題是:Call的id映射、序列化與反序列化、網(wǎng)絡(luò)傳輸

Call id 映射問題解決的是:系統(tǒng)A的程序想要遠程調(diào)用系統(tǒng)B的程序時,B中有許多個程序,到底調(diào)用哪個程序的問題,也就是說,B系統(tǒng)中的每個程序都具有一個唯一 id,只要其他系統(tǒng)在發(fā)起遠程調(diào)用時攜帶自己要調(diào)用程序的 Call id,系統(tǒng)B就能成功識別他想要運行的程序

我們的調(diào)用邏輯是:

將傳遞的參數(shù)使用 json 協(xié)議進行傳輸(類似的協(xié)議還有 xml、protobuf、msgpack)另外現(xiàn)在網(wǎng)絡(luò)調(diào)用有兩個端:客戶端用于發(fā)送數(shù)據(jù),服務(wù)器端用于接收數(shù)據(jù)

另外一個問題就是:JSON 不是一個高性能的編碼協(xié)議,我們在追求極致性能的時候可能不會優(yōu)先考慮 json

另外:json 的優(yōu)勢在于其通用性,可擴展性,幾乎所有的系統(tǒng)都支持 json,但其另外的問題就是其過于靈活,不能將其作為程序的對象存儲來代替struct

而我們的網(wǎng)絡(luò)協(xié)議是看不懂 struct 的,其只能識別二進制的流,故而我們必須將我們轉(zhuǎn)換的數(shù)據(jù)轉(zhuǎn)換成二進制的流才可以進行傳輸

在一次 RPC 過程中,服務(wù)器端和客戶端分別要做的事情:

客戶端:

1. 建立連接:tcp \ http
2. 將我們要發(fā)送的數(shù)據(jù)序列化為 json 字符串 - 序列化
3. 發(fā)送,實際上發(fā)送的是二進制流
4. 等待服務(wù)器結(jié)果
5. 服務(wù)器返回結(jié)果,客戶端將結(jié)果反序列化為可識別數(shù)據(jù)

服務(wù)器端:

1. 監(jiān)聽網(wǎng)絡(luò)端口(80)
2. 讀取客戶端發(fā)來的二進制數(shù)據(jù),并將其轉(zhuǎn)換成Employee對象,反序列化
3. 處理數(shù)據(jù),生成一個帶有更完成信息的對象,例如:R,其中封裝了404、201等信息
4. 將處理的數(shù)據(jù)結(jié)果轉(zhuǎn)換成 json 二進制, 序列化 發(fā)送給客戶端

我們的序列化技術(shù)不一定非要使用 json、我們還可以選擇:xml、protobuf、msgpack 等

我們只要解決了 序列化問題,其實就解決了數(shù)據(jù)互通問題,其實也就屏蔽了我們相互調(diào)用時的語言不同的問題(java、python、go)

網(wǎng)絡(luò)問題:

我們使用 http 與 tcp 最大的區(qū)別就是:

http是一次性的,建立連接之后,一旦收到數(shù)據(jù)的返回,tcp 連接就斷開,而 tcp 連接是可以復(fù)用的,解決了 tcp 連接要重新建立的問題

另外,我們也可以使用 http2.0 來解決這個問題,http2.0 支持長連接,可以解決連接的建立問題

一個簡單的例子:(服務(wù)器端)

func main() {http.HandleFunc("/add", func(w http.ResponseWriter, r *http.Request) {// 這里面寫邏輯_ = r.ParseForm() // 解析參數(shù),可能會報錯fmt.Println("path: ", r.URL.Path)a, _ := strconv.Atoi(r.Form["a"][0])b, _ := strconv.Atoi(r.Form["a"][0])// 進行返回w.Header().Set("Content-Type", "application/json")// 構(gòu)建返回體jData, _ := json.Marshal(map[string]int{"data": a + b,})// 真正寫入w.Write(jData)})// 設(shè)置監(jiān)聽的端口_ = http.ListenAndServe(":8000", nil)
}

上面這個例子就典型的解決了:

Call ID問題:使用URL路徑指明要調(diào)用的方法

數(shù)據(jù)傳輸協(xié)議:Http 的參數(shù)傳遞協(xié)議

但這里的問題是:使用的是 http1.0的協(xié)議,性能低,手寫http,數(shù)據(jù)需要自己解析,效率低

客戶端舉例:

我們也可以不寫客戶端,直接使用瀏覽器來發(fā)送請求解決問題,

我們訪問:127.0.0.1:8000/add?a=1&b=4

RPC 技術(shù)原理:

客戶端發(fā)送請求,由客戶端存根處理,客戶端存根將請求整理成協(xié)議對應(yīng)的格式進行發(fā)送,將其發(fā)送到服務(wù)器端,由服務(wù)器端接收這之后發(fā)送給服務(wù)器端存根進行解碼,再返回給服務(wù)器處理

RPC 開發(fā)(Hello World級別)

創(chuàng)建目錄結(jié)構(gòu)

Project

server

server.go

client

client.go

server.go:

type HelloService struct {
}// 給這個類綁定這個方法
func (s *HelloService) Hello(request string, reply *string) error {// 通過修改 reply 值來進行返回*reply = "hello, " + requestreturn nil
}/*
*
1. 實例化一個server
2. 注冊邏輯
3. 開啟服務(wù)
*/
func main() {// 第一步:實例化 serverlistener, _ := net.Listen("tcp", ":1234")// 第二步:將我們的 struct 注冊進 RPC// 我們?nèi)绻研螀⒘斜碇械膮?shù)定義為 interface{} 就代表這個參數(shù)我們可以任意傳入_ = rpc.RegisterName("HelloService", &HelloService{})// 第三部:啟動服務(wù),綁定rpcconn, _ := listener.Accept()rpc.ServeConn(conn)
}

client.go:

func main() {// Dial() 意思是撥號,也就是嘗試進行連接,同時進行Gob進行編碼client, err := rpc.Dial("tcp", "localhost:1234")if err != nil {panic("鏈接失敗")}// 注意這種方式會直接開辟一片空間,并且給這片空間的 string 賦予初值 ''//var reply string// 如果以下面這種方式就復(fù)雜一點var replyy *string = new(string)// 發(fā)送請求,請求對應(yīng)的方法,其后面的參數(shù)是傳入的參數(shù),根據(jù)我們方法的編寫,我們最后一個參數(shù)用來接收數(shù)據(jù)err = client.Call("HelloService.Hello", "Chen", replyy)if err != nil {panic("方法調(diào)用出錯")}fmt.Println(*replyy)}hello, Chen

注意在上面的代碼中,實例化 server、啟動服務(wù)都是由 net 包完成的,但單獨 net 包是不能完成一整個流程的,這是因為還有 call id 的匹配以及序列化機制是由 rpc 來完成的

另外的是:GRPC在此時還不夠簡潔,使用效率不夠高,這體現(xiàn)在包括客戶端在調(diào)用時不能直接調(diào)用方法,而是需要明確方法名等

同時,上面這種最基本的rpc使用的編碼解碼協(xié)議是 Gob,這只能在 go 語言中進行通信,其不支持跨語言

使用JSON協(xié)議的RPC

建立目錄結(jié)構(gòu):

json_rpc_test

server

server.go

client

client.go

server.go

type HelloService struct {
}func (s *HelloService) Hello(request string, reply *string) error {// 通過修改 reply 值來進行返回*reply = "hello, " + requestreturn nil
}
func main() {listener, _ := net.Listen("tcp", ":1234")_ = rpc.RegisterName("HelloService", &HelloService{})// 允許服務(wù)器處理多次請求:for {conn, _ := listener.Accept()// 使用自定義協(xié)議進行修改go rpc.ServeCodec(jsonrpc.NewServerCodec(conn)) // 這里不加 go 協(xié)程會出現(xiàn)多個請求的并發(fā)問題}
}

client.go

func main() {// 使用基礎(chǔ)的撥號,不進行編碼,編碼在后面進行conn, err := net.Dial("tcp", "localhost:1234")if err != nil {panic("鏈接失敗")}// 進行 json 編碼client := rpc.NewClientWithCodec(jsonrpc.NewClientCodec(conn))var replyy *string = new(string)err = client.Call("HelloService.Hello", "Chen", replyy)if err != nil {panic("方法調(diào)用出錯")}fmt.Println(*replyy)}

測試 RPC 的跨語言特性:

使用 python 的socket 編程發(fā)送一個json (不使用http,因為我們服務(wù)器沒有使用http,無法進行解析)

import json
import socketrequest = {"id":0,"params":["Zhang"],"method":"HelloService.Hello"
}client = socket.create_connection(("localhost", 1234))
client.sendall(json.dumps(request).encode())# 獲取服務(wù)器返回的數(shù)據(jù)
rsp = client.recv(1024)
rsp = json.loads(rsp.decode())
print(rsp["result"])hello, Zhang

使用 java:

    public static void main(String[] args) {try {// Connect to the serverSocket socket = new Socket("localhost", 1234);// Create a JSON requestString jsonRequest = "{\"id\": 0, \"method\": \"HelloService.Hello\", \"params\": [\"Yang\"]}";// Send the JSON request to the serverOutputStream outputStream = socket.getOutputStream();outputStream.write(jsonRequest.getBytes());outputStream.flush();// Receive the response from the serverBufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));String response = reader.readLine();System.out.println("Response from server: " + response);// Close the socketsocket.close();} catch (IOException e) {e.printStackTrace();}}Response from server: {"id":0,"result":"hello, Yang","error":null}

使用 HTTP 協(xié)議 + JSON 的RPC

其實在這一步,已經(jīng)有成熟框架可以使用,這里為了學(xué)習(xí),我們使用rpc搭建一個自己的框架

構(gòu)建目錄:

http_rpc_test

server

server.go

client

client.go

server.go

type HelloService struct {
}func (s *HelloService) Hello(request string, reply *string) error {// 通過修改 reply 值來進行返回*reply = "hello, " + requestreturn nil
}
func main() {_ = rpc.RegisterName("HelloService", &HelloService{})http.HandleFunc("/jsonrpc", func(w http.ResponseWriter, r *http.Request) {var conn io.ReadWriteCloser = struct {io.Writerio.ReadCloser}{ReadCloser: r.Body,Writer: w,}rpc.ServeRequest(jsonrpc.NewServerCodec(conn))})http.ListenAndServe(":1234", nil)
}

在這里就可以使用其他語言發(fā)送 http 請求,獲取結(jié)果了

將方法改造成調(diào)用式的方法

以基礎(chǔ)的 HelloWorld 級別代碼為例,構(gòu)建目錄:

new_helloworld

server

server.go

client

client.go

handler

handler.go

server_proxy

server_proxy.go

client_proxy

client_proxy.go

我們通過定義一個公共文件,來實現(xiàn):

handler.go

const HelloServiceName = "handler/HelloService"type HelloService struct{}// 給這個類綁定這個方法
func (s *HelloService) Hello(request string, reply *string) error {// 通過修改 reply 值來進行返回*reply = "hello, " + requestreturn nil
}

server.go

func main() {// 第一步:實例化 serverlistener, _ := net.Listen("tcp", ":1234")// 第二步:將我們的 struct 注冊進 RPC// 我們?nèi)绻研螀⒘斜碇械膮?shù)定義為 interface{} 就代表這個參數(shù)我們可以任意傳入_ = rpc.RegisterName(handler.HelloServiceName, &handler.HelloService{})// 第三部:啟動服務(wù),綁定rpcfor {conn, _ := listener.Accept()go rpc.ServeConn(conn)}

client.go

func main() {// Dial() 意思是撥號,也就是嘗試進行連接client := client_proxy.NewHelloServiceClient("tcp", "127.0.0.1:1234")// 注意這種方式會直接開辟一片空間,并且給這片空間的 string 賦予初值 ''//var reply string// 如果以下面這種方式就復(fù)雜一點var replyy *string = new(string)// 發(fā)送請求,請求對應(yīng)的方法,其后面的參數(shù)是傳入的參數(shù),根據(jù)我們方法的編寫,我們最后一個參數(shù)用來接收數(shù)據(jù)_ = client.Hello("Chen", replyy)fmt.Println(*replyy)
}

server_proxy.go

type HellosSrvicer interface {Hello(request string, reply *string) error
}func RegisterHelloService(srv HellosSrvicer) error {return rpc.RegisterName(handler.HelloServiceName, srv)
}

client_proxy.go

type HelloServiceStub struct {*rpc.Client
}// 初始化,在Go中使用 Newxxx進行初始化
func NewHelloServiceClient(protcol, address string) HelloServiceStub {conn, err := rpc.Dial(protcol, address)if err != nil {panic("connect error")}return HelloServiceStub{conn}
}func (c *HelloServiceStub) Hello(request string, reply *string) error {err := c.Call(handler.HelloServiceName+".Hello", request, reply)return err
}
http://aloenet.com.cn/news/29373.html

相關(guān)文章:

  • 佰匯康網(wǎng)站建設(shè)河南seo快速排名
  • 南京網(wǎng)站建設(shè)案例蘇州做網(wǎng)站哪家比較好
  • 嘉興網(wǎng)站制作軟件如何做一個網(wǎng)站
  • 有沒有幫人做簡歷的網(wǎng)站營銷型網(wǎng)站和普通網(wǎng)站
  • 只做襯衣網(wǎng)站百度seo排名優(yōu)化技巧分享
  • 帝國cms企業(yè)網(wǎng)站模板網(wǎng)站優(yōu)化方案案例
  • 怎么做網(wǎng)站能夠增加人氣鏈接提交入口
  • 政府網(wǎng)站建設(shè)方案范文—工作方案seo專員崗位職責(zé)
  • wordpress文章審核發(fā)郵件國內(nèi)seo公司
  • 高端做網(wǎng)站哪家好臨沂seo
  • 人大兩學(xué)一做專題網(wǎng)站深圳營銷型網(wǎng)站開發(fā)
  • 建應(yīng)用網(wǎng)站百度pc網(wǎng)頁版
  • 網(wǎng)站格式圖片全國唯一一個沒有疫情的城市
  • 杭州 網(wǎng)站建設(shè)seo引擎優(yōu)化方案
  • 淘寶客網(wǎng)站怎么做推廣windows優(yōu)化大師要會員
  • 無錫大型網(wǎng)站建設(shè)公司公司網(wǎng)頁制作需要多少錢
  • 經(jīng)營閱讀網(wǎng)站需要怎么做排名優(yōu)化方法
  • 建設(shè)政府網(wǎng)站的目的意義百度推廣每年600元什么費用
  • 做調(diào)查賺錢的網(wǎng)站有哪些南寧優(yōu)化網(wǎng)站收費
  • 種植園網(wǎng)站模板無錫百度正規(guī)推廣
  • 桂林做網(wǎng)站的公司全國疫情最新數(shù)據(jù)
  • 計算機做網(wǎng)站開發(fā)需要什么證書seo這個職位是干什么的
  • 靈感集網(wǎng)站網(wǎng)絡(luò)營銷概念
  • 北京城鄉(xiāng)和住房建設(shè)部網(wǎng)站seo專員是干什么的
  • 網(wǎng)站建設(shè)開發(fā)能力很強的企業(yè)外貿(mào)公司一般怎么找客戶
  • ae素材網(wǎng)關(guān)鍵詞是網(wǎng)站seo的核心工作
  • 千助網(wǎng)站公司免費招收手游代理
  • 重慶付費網(wǎng)站推廣友情鏈接交換工具
  • 來賓市住房和城鄉(xiāng)建設(shè)局網(wǎng)站網(wǎng)站運營師
  • dnf做漢堡怎么玩間網(wǎng)站怎么做好網(wǎng)絡(luò)推廣銷售