RPC
What is the RPC
- Remote Procedure Call (RPC) in Chinese is called “Remote Procedure Call”, which can be simply understood as a node requesting services provided by another node
- Understanding “local procedure call” can better understand “remote procedure call”
- RPC mainly depends on the socket connection between the client and the server. However, THE cost of HTTP REST communication is relatively high, which is an advantage of RPC.
- See here for RPC details
Why RPC
Because we can’t implement our requirements locally in the same process or on the same server. HTTP is adequate but not efficient, so we need to use RPC.
- Zhihu daishen answered
The advantage of the RPC
- RPC can span multiple development tools and platforms
- RPC can be called across languages
- RPC can improve system scalability, decoupling and reuse
- Compared with HTTP, RPC has higher transmission efficiency and lower performance consumption. It has a load balancing policy and automatically implements service governance
RPC versus HTTP
- RPC is mainly used for service invocation within an enterprise, with low performance consumption, high transmission efficiency, and convenient service governance.
- HTTP is mainly used for external heterogeneous environments, such as browser interface invocation, APP interface invocation, and third-party interface invocation.
- A detailed comparison between RPC and HTTP
RPC usage boundaries
- By comparing with HTTP, we can deduce the boundary of RPC: external heterogeneous environment, browser interface call, APP interface call, third-party interface call.
- None of this applies to RPC, and it is more important to know what RPC does not do than what RPC does.
Introduction to RPC 1: NET/RPC
Basic composition
- The basic composition of RPC: server and client
- Server basic composition: structure, request structure, response structure
- Client basic composition: request structure, response structure
Code sample
rpc_service.go
package main
import (
"errors"
"fmt"
"log"
"net"
"net/http"
"net/rpc"
"os"
)
type Arith struct{}// Request structure
type ArithRequest struct {
A int
B int
}
// Response structure
type ArithResponse struct {
Pro int / / product
Quo int / /,
Rem int / / remainder
}
// Product method
func (this *Arith) Multiply(req ArithRequest,res *ArithResponse) error{
res.Pro = req.A * req.B
return nil
}
// Divide
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(a) {
// Register the RPC service
rpc.Register(new(Arith))
// Use HTTP as RPC carrier
rpc.HandleHTTP()
lis,err := net.Listen("tcp"."127.0.0.1:8095")
iferr! =nil {
log.Fatalln("fatal error:",err)
}
fmt.Fprintf(os.Stdout,"%s"."start connection\n")
// Start the HTTP service normally
http.Serve(lis,nil)}Copy the code
rpc_client.go
package main
import (
"fmt"
"log"
"net/rpc"
)
// Arithmetic operation request structure
type ArithRequest struct {
A int
B int
}
// Response structure
type ArithResponse struct {
Pro int / / by
Quo int / /,
Rem int / / remainder
}
func main(a) {
conn,err := rpc.DialHTTP("tcp"."127.0.0.1:8095")
iferr! =nil {
log.Fatalln("dialing error:",err)
}
req := ArithRequest{10.20}
var res ArithResponse
err = conn.Call("Arith.Multiply",req,&res) // Multiply
iferr! =nil {
log.Fatalln("arith error:",err)
}
fmt.Printf("%d * %d = %d\n",req.A,req.B,res.Pro)
// Divide
err = conn.Call("Arith.Divide",req,&res)
iferr! =nil {
log.Fatalln("arith error:",err)
}
fmt.Printf("%d / %d = %d remainder :%d",req.A,req.B,res.Quo,res.Rem)
}
Copy the code
The results
- Start the server and then connect the client to the server
// Server console start connection // Client console 10 x 20 = 200 10/20 = 0 The remainder is 10Copy the code
RPC Introduction 2: NET/RPC/jsonRPC
Implement cross-language invocation
jsonrpc_server.go
package main
import (
"errors"
"fmt"
"log"
"net"
"net/rpc"
"net/rpc/jsonrpc"
"os"
)
type Arith struct{}// Request structure
type ArithRequest struct {
A int
B int
}
// Response structure
type ArithResponse struct {
Pro int / / product
Quo int / /,
Rem int / / remainder
}
// Product method
func (this *Arith) Multiply(req ArithRequest,res *ArithResponse) error{
res.Pro = req.A * req.B
return nil
}
// Divide
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(a) {
// Register the RPC service
rpc.Register(new(Arith))
// Use HTTP as RPC carrier
rpc.HandleHTTP()
lis,err := net.Listen("tcp"."127.0.0.1:8096")
iferr! =nil {
log.Fatalln("fatal error:",err)
}
fmt.Fprintf(os.Stdout,"%s"."start connection\n")
// Receive client requests and process jSONRPC concurrently
for {
conn,err :=lis.Accept() // Receive client connection requests
iferr! =nil {
continue
}
// Process client requests concurrently
go func(conn net.Conn) {
fmt.Fprintf(os.Stdout,"%s"."new client in coming\n")
jsonrpc.ServeConn(conn)
}(conn)
}
// Start the HTTP service normally
//http.Serve(lis,nil)
}
Copy the code
jsonrpc_client.go
package main
import (
"fmt"
"log"
"net/rpc/jsonrpc"
)
// Arithmetic operation request structure
type ArithRequest struct {
A int
B int
}
// Response structure
type ArithResponse struct {
Pro int / / by
Quo int / /,
Rem int / / remainder
}
func main(a) {
// The only difference is here
conn,err := jsonrpc.Dial("tcp"."127.0.0.1:8096")
iferr! =nil {
log.Fatalln("dialing error:",err)
}
req := ArithRequest{9.2}
var res ArithResponse
err = conn.Call("Arith.Multiply",req,&res) // Multiply
iferr! =nil {
log.Fatalln("arith error:",err)
}
fmt.Printf("%d * %d = %d\n",req.A,req.B,res.Pro)
// Divide
err = conn.Call("Arith.Divide",req,&res)
iferr! =nil {
log.Fatalln("arith error:",err)
}
fmt.Printf("%d / %d = %d remainder :%d",req.A,req.B,res.Quo,res.Rem)
}
Copy the code
The results
- Start the server and then connect the client to the server
// Server console start connection // Client console 9 * 2 = 18 9/2 = 4 The remainder is :1 // Server console new client in comingCopy the code
RPC Primer 3: Go PHP cross-language calls
Go serves as the server and PHP serves as the client
Jsonrpc_server. go: The same code as the starter 2 server
jsonrpc_client.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']);
Copy the code
How do I start PHP locally
The results
// start the PHP service locally: http://127.0.0.1/jsonrpc_client.php, run the following result: 9 * 2 = 18 9/2, Quo is 4, Rem is 1Copy the code
Refer to the blog
- RPC related Blog
- Mac starts PHP locally
Noun explanation
- Thrift: An interface description language and binary communication protocol used as a framework for RPC.
thinking
How to use RPC gracefully for Web development
I will share them in my next blog
Last But Not Least
Sincerely thank the handsome boys and girls can see here, if you think this article is written well 😄
Ask to like 👍, ask to follow ❤️, ask to share 👥, want to become one piece king for me very useful!!
If you can pay attention to my public number, then I am more happy than the lottery win ❤️❤️❤️❤️