PHP分布式架构RPC介绍以及手写RPC框架

分布式解决什么问题?

举个例子:当网站有10万个访问,已经没法处理这么多访问请求。通常,我们可以提高服务器的配置,其次我们还可以添加服务器来分流处理,如果一台机器只能处理6万个请求,那么我们再加一台服务器,把请求分配到两台服务器,那么就可以处理10万请求了。

加服务器有两种方式实现,一种是用负载均衡的方式;另一种用分布式的方式。负载均衡其实就是把原来的代码复制到另一台服务器,两台服务器的代码是一样的,这也叫水平拆分;分布式是基于业务拆分,把一个项目中的模块分别部署到不同的服务器,这种基于服务的拆分,也叫垂直拆分

RPC介绍

RPC(Remote Procedure Call)-- 远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式程序在内的应用程序更加容易。

RPC在使用形式上像调用本地函数(或方法)一样去调用远程的函数(或方法)。

实现分布式部署 跨语言...

 

架构演变

MVC架构:当业务规模很小时,将所有功能都部署在同一个进程中,通过双机或者负载均衡器实现负载分流;此时,分离前后台逻辑的MVC架构是关键。

RPC架构:当垂直应用越来越多,应用之间交互不可避免,将核心和公共业务抽取出来,作为独立的服务,实现前后台逻辑分离。此时,用于提高业务复用及拆分的RPC框架是关键。

SOA架构:随着业务发展,服务数量越来越多,服务生命周期管控和运行态的治理成为瓶颈,此时用于提升服务质量的SOA服务治理是关键。

微服务架构:通过服务的原子化拆分,以及微服务的独立打包、部署和升级,小团队的交付周期将缩短,运维成本也将大幅度下降。

RPC与REST区别

REST,即Representational State Transfer的缩写。翻译过来是表现层状态转换

REST 通常采用 http+JSON 实现。

RPC http/socket+JSON xml 二进制…

RESTful 一般定义处理 resource 对外提供接口服务

RPC 对内提供服务

REST也是一种RPC

RPC 设计模式 思想 REST

RPC基于的协议 以及数据形式

关于协议:

RPC框架与具体的协议无关,RPC 可基于 HTTP 或 TCP 协议。

TCP 是传输层协议,HTTP 是应用层协议,而传输层较应用层更加底层,在数据传输方面,越底层越快,因此,在一般情况下,TCP 一定比 HTTP 快。

关于数据形式:

基于XML的RPC

基于JSON的RPC

基于二进制的RPC

RPC调用流程

 

1)、服务消费方(Client)调用以本地调用方式调用服务;

2)、Client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体;

3)、Client stub找到服务地址,通过Socket将消息发送到服务端;

4)、Server stub收到消息后进行解码;

5)、Server stub根据解码结果调用服务端本地的服务;

6)、本地服务执行并将结果返回给Server stub;

7)、Server stub将返回结果打包成消息;

8)、Server stub通过Socket将消息发送至客户端;

9)、Client stub接收到消息,并进行解码;

10)、服务消费方(RPC Client)得到最终的服务调用结果。

手写简单的RPC框架,server.php

class Server{
	public $socket;
	public $class;
	public $method;
	public $param;
	public $serviceDir="service";
		
	public function __construct($ip,$port){
		$this->create($ip,$port);

		while(true){
			$conSock = socket_accept($this->socket);
			$protocol = socket_read($conSock,2048);
			$this->doProtocol($protocol);

			$file = $this->serviceDir."/".$this->class.".php";

			if(file_exists($file)){
				require_once $file;
				$obj = new $this->class;
				$method = $this->method;
				$res = $obj->$method($this->param);
			}else{
				$res = $file." not exists!!";
			}
			socket_write($conSock,$res,strlen($res));
			socket_close($conSock);
		}
	}

	private function doProtocol($protocol){
		preg_match("/RPC-CLASS:(.*)/",$protocol,$class);
		preg_match("/RPC-METHOD:(.*)/",$protocol,$method);
		preg_match("/RPC-PARAM:(.*)/",$protocol,$param);
		$this->class = $class[1];
		$this->method = $method[1];
		$this->param = $param[1];
	}

	private function create($ip,$port){
		$this->socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
		socket_set_option($this->socket,SOL_SOCKET,SO_REUSEADDR,true);
		socket_bind($this->socket,$ip,$port);
		socket_listen($this->socket);
	}
}

new Server(0,6666);

 

client.php

class Client{
	public $host;
	public $ip;
	public $class;
	public $socket;
	public $protocol = null;

	public function __construct($url){
		$url = parse_url($url);
		$this->host = $url["host"];
		$this->port = $url["port"];
		$this->class = basename($url["path"]);

		$this->connect();
	}

	private function connect(){
		$this->socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
		socket_connect($this->socket,$this->host,$this->port);
	}

	public function __call($method,$param){
		$param = json_encode($param);
		$this->protocol .="RPC-CLASS:$this->class\n";
		$this->protocol .="RPC-METHOD:$method\n";
		$this->protocol .="RPC-PARAM:$param\n";
		socket_write($this->socket,$this->protocol,strlen($this->protocol));
		$data = socket_read($this->socket,2048);
		//socket_close($this->socket);
		return $data;
	}
}

$param = ["name"=>"lampol","age"=>22];
$client = new Client("http://127.0.0.1:6666/Test");
echo $client->test2($param);

 

先运行服务端 php server.php

在运行客户端 php client.php

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值