成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一文搞懂RPC,So Easy!

開發 前端
RPC主要依賴于客戶端與服務端建立socket鏈接;而HTTP REST實現通訊的代價比較高,這是RPC的一個優勢體現。

什么是RPC

RPC的中文是“遠程過程調用”,對應的英文全稱是:Remote Procedure Call,可以簡單理解為一個節點請求另一個節點提供的服務。

請先自行思考一下什么是“本地過程調用”,可以更好的理解“遠程過程調用”。

知識點:RPC主要依賴于客戶端與服務端建立socket鏈接;而HTTP REST實現通訊的代價比較高,這是RPC的一個優勢體現。(gRPC使用http2.0)

為什么用RPC

就是因為無法在同一個進程內,或者無法在同一個服務器上通過本地調用的方式實現我們的需求。

HTTP能滿足需求但是不夠高效,所以我們需要使用RPC。

知乎大神的回答[1]

RPC的優勢

  1. RPC能夠跨多種開發工具和平臺
  2. RPC能夠跨語言調用
  3. RPC能夠提高系統的可擴展性,解耦,提高復用
  4. RPC相較于HTTP 1.1,傳輸效率更高,性能消耗更小,自帶負載均衡策略,自動實現服務治理

RPC和HTTP對比

  • RPC主要用于公司內部的服務調用,性能消耗低,傳輸效率高,服務治理方便。
  • HTTP主要用于對外的異構環境,瀏覽器接口調用,APP接口調用,第三方接口調用等。
  • RPC和HTTP的詳細對別[2]可以看這篇文章,不作為本篇的重點

RPC的使用邊界

通過和HTTP的對比,我們可以倒推出RPC的邊界:對外的異構環境,瀏覽器接口調用,APP接口調用,第三方接口調用。

上述這些都不適合RPC,不知道RPC不適合做什么,比知道RPC能做什么更重要。

RPC入門1:net/rpc

基本構成

  1. RPC的基本構成:服務端,客戶端
  2. 服務端基本構成:結構體,請求結構體,響應結構體
  3. 客戶端基本構成:請求結構體,響應結構體

代碼示例

rpc_service.go

package main

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

type Arith struct {

}

//請求結構體
type ArithRequest struct {
A int
B int
}

//響應結構體
type ArithResponse struct {
Pro int //乘積
Quo int //
Rem int //余數
}

//乘積方法
func (this *Arith) Multiply(req ArithRequest,res *ArithResponse) error{
res.Pro = req.A * req.B
return nil
}

//除法運算方法
func (this *Arith) Divide(req ArithRequest,res *ArithResponse) error{
if req.B ==0 {
return errors.New("divide by zero")
}
res.Quo = req.A / req.B
res.Rem = req.A % req.B
return nil
}

func main() {
//注冊rpc服務
rpc.Register(new(Arith))
//采用http協議作為rpc載體
rpc.HandleHTTP()

lis,err := net.Listen("tcp","127.0.0.1:8095")
if err!=nil {
log.Fatalln("fatal error:",err)
}

fmt.Fprintf(os.Stdout,"%s","start connection\n")

//常規啟動http服務
http.Serve(lis,nil)
}

rpc_client.go

package main

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

//算數運算請求結構體
type ArithRequest struct {
A int
B int
}

//響應結構體
type ArithResponse struct {
Pro int //
Quo int //
Rem int //余數
}

func main() {
conn,err := rpc.DialHTTP("tcp","127.0.0.1:8095")
if err!=nil {
log.Fatalln("dialing error:",err)
}

req := ArithRequest{10,20}
var res ArithResponse

err = conn.Call("Arith.Multiply",req,&res) //乘法運算
if err!=nil {
log.Fatalln("arith error:",err)
}
fmt.Printf("%d * %d = %d\n",req.A,req.B,res.Pro)

//除法運算
err = conn.Call("Arith.Divide",req,&res)
if err!=nil {
log.Fatalln("arith error:",err)
}
fmt.Printf("%d / %d = %d 余數是:%d",req.A,req.B,res.Quo,res.Rem)
}

運行結果

先啟動服務端,再啟動客戶端連接服務端

//服務端console
start connection

//客戶端console
10 * 20 = 200
10 / 20 = 0 余數是:10

RPC入門2:net/rpc/jsonrpc

實現跨語言調用

jsonrpc_server.go

package main

import (
"errors"
"fmt"
"log"
"net"
"net/rpc"
"net/rpc/jsonrpc"
"os"
)

type Arith struct {

}

//請求結構體
type ArithRequest struct {
A int
B int
}

//響應結構體
type ArithResponse struct {
Pro int //乘積
Quo int //
Rem int //余數
}

//乘積方法
func (this *Arith) Multiply(req ArithRequest,res *ArithResponse) error{
res.Pro = req.A * req.B
return nil
}

//除法運算方法
func (this *Arith) Divide(req ArithRequest,res *ArithResponse) error{
if req.B ==0 {
return errors.New("divide by zero")
}
res.Quo = req.A / req.B
res.Rem = req.A % req.B
return nil
}

func main() {
//注冊rpc服務
rpc.Register(new(Arith))
//采用http協議作為rpc載體
rpc.HandleHTTP()

lis,err := net.Listen("tcp","127.0.0.1:8096")
if err!=nil {
log.Fatalln("fatal error:",err)
}

fmt.Fprintf(os.Stdout,"%s","start connection\n")

//接收客戶端請求 并發處理 jsonrpc
for {
conn,err :=lis.Accept() //接收客戶端連接請求
if err!=nil {
continue
}

//并發處理客戶端請求
go func(conn net.Conn) {
fmt.Fprintf(os.Stdout,"%s","new client in coming\n")
jsonrpc.ServeConn(conn)
}(conn)
}

//常規啟動http服務
//http.Serve(lis,nil)
}

jsonrpc_client.go

package main

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

//算數運算請求結構體
type ArithRequest struct {
A int
B int
}

//響應結構體
type ArithResponse struct {
Pro int //
Quo int //
Rem int //余數
}

func main() {
// 只有這里不一樣
conn,err := jsonrpc.Dial("tcp","127.0.0.1:8096")
if err!=nil {
log.Fatalln("dialing error:",err)
}

req := ArithRequest{9,2}
var res ArithResponse

err = conn.Call("Arith.Multiply",req,&res) //乘法運算
if err!=nil {
log.Fatalln("arith error:",err)
}
fmt.Printf("%d * %d = %d\n",req.A,req.B,res.Pro)

//除法運算
err = conn.Call("Arith.Divide",req,&res)
if err!=nil {
log.Fatalln("arith error:",err)
}
fmt.Printf("%d / %d = %d 余數是:%d",req.A,req.B,res.Quo,res.Rem)
}

運行結果

先啟動服務端,再啟動客戶端連接服務端

//服務端console
start connection

//客戶端console
9 * 2 = 18
9 / 2 = 4 余數是:1

//服務端console
new client in coming

RPC入門3:go php跨語言調用

Go作為服務端,PHP作為客戶端

jsonrpc_server.go:和入門2服務端的代碼一樣

下面是PHP代碼

jsonrpc_client.php

<?php
class JsonRPC
{

private $conn;

function __construct($host, $port)
{
$this->conn = fsockopen($host, $port, $errno, $errstr, 3);
if (!$this->conn) {
return false;
}
}

public function Call($method, $params)
{
if (!$this->conn) {
return false;
}
$err = fwrite($this->conn, json_encode(array(
'method' => $method,
'params' => array($params),
'id' => 0,
)) . "\n");
if ($err === false) {
return false;
}
stream_set_timeout($this->conn, 0, 3000);
$line = fgets($this->conn);
if ($line === false) {
return NULL;
}
return json_decode($line, true);
}
}

$client = new JsonRPC("127.0.0.1", 8096);
$args = array('A' => 9, 'B' => 2);
$r = $client->Call("Arith.Multiply", $args);
printf("%d * %d = %d\n", $args['A'], $args['B'], $r['result']['Pro']);
$r = $client->Call("Arith.Divide", array('A' => 9, 'B' => 2));
printf("%d / %d, Quo is %d, Rem is %d\n", $args['A'], $args['B'], $r['result']['Quo'], $r['result']['Rem']);

如何在本地啟動PHP[3] 不作為本文重點,可以看這篇文章。

運行結果

本地啟動PHP服務:

??http://127.0.0.1/jsonrpc_client.php??

運行結果如下:

9 * 2 = 18 9 / 2, Quo is 4, Rem is 1

總結

一文入門RPC,就是如此絲滑,So Easy!

歡迎還在用單體架構,沒有使用RPC的同學們操練起來,尤其是PHP的小伙伴們,卷起來吧。該學學Go語言啦~

相關資料

[1]知乎大神的回答: https://www.zhihu.com/question/25536695

[2]RPC和HTTP的詳細對別: http://www.ccutu.com/244407.html

[3]如何在本地啟動PHP: ??https://blog.csdn.net/resilient/article/details/80770531??

本文轉載自微信公眾號「 程序員升級打怪之旅」,作者「王中陽Go」,可以通過以下二維碼關注。

轉載本文請聯系「 程序員升級打怪之旅」公眾號。

責任編輯:武曉燕 來源: 程序員升職加薪之旅
相關推薦

2022-02-14 21:17:21

RPC框架協議

2022-03-24 08:51:48

Redis互聯網NoSQL

2024-04-12 12:19:08

語言模型AI

2021-03-22 10:05:59

netstat命令Linux

2023-09-08 08:20:46

ThreadLoca多線程工具

2023-09-15 12:00:01

API應用程序接口

2023-09-02 21:27:09

2021-02-28 20:53:37

Cookie存儲瀏覽器

2023-05-22 13:27:17

2021-03-04 00:09:31

MySQL體系架構

2020-12-07 06:19:50

監控前端用戶

2023-03-06 21:29:41

mmap技術操作系統

2020-09-03 06:35:44

Linux權限文件

2021-07-08 10:08:03

DvaJS前端Dva

2024-07-12 14:46:20

2022-07-15 08:16:56

Stream函數式編程

2022-08-15 15:39:23

JavaScript面向對象數據

2023-08-24 16:50:45

2019-11-19 08:00:00

神經網絡AI人工智能

2021-06-30 08:45:02

內存管理面試
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩视频 中文字幕 | 欧美日韩成人 | 九九亚洲 | 国产精品久久久久久婷婷天堂 | 成人亚洲视频 | 日日干干夜夜 | 欧美精品在线看 | 日韩欧美在线视频播放 | 久草在线| 日韩一区二区在线播放 | 91精品国产综合久久精品 | 99精品福利视频 | 波多野结衣一二三区 | 免费99精品国产自在在线 | 九九热热九九 | 久久久一二三区 | 国产精品日韩欧美一区二区三区 | 久久国产精品久久久久 | 伊人二区| 91就要激情 | 免费观看一级毛片 | 欧美日韩综合视频 | 免费观看一级黄色录像 | 国产一区二区三区四区在线观看 | 精品久久久久香蕉网 | 精品96久久久久久中文字幕无 | 毛片在线看片 | 免费久久久 | 亚洲成人黄色 | 欧美一区免费 | 中文字幕高清av | 国产 欧美 日韩 一区 | 亚洲欧美一区二区三区视频 | 中日韩欧美一级片 | 日韩欧美在线视频 | 欧美另类日韩 | 天天干狠狠干 | 久久精品网 | 国产aaaaav久久久一区二区 | 欧美八区| 日韩成人av在线 |