swoole RPC调用

什么是rpc?

RPC全称为Remote Procedure Call,翻译过来为“远程过程调用”。目前,主流的平台中都支持各种远程调用技术,以满足分布式系统架构中不同的系统之间的远程通信和相互调用,也是实现微服务当中的重要的环节。

调用方式:总是由Client向Server发出一个执行若干过程请求,Server接受请求,使用客户端提供的参数,计算完成之后将结果返回给客户端。

为什么需要RPC?

如果是自己的一个单体应用,只是自己一个人开发,流量特别小的情况,不需要RPC,但是在进入公司尤其是大型互联网公司就有可能面临这个问题。

1、分布式部署及微服务

当我们的系统访问量增大、业务增多时,我们会发现一台单机运行此系统已经无法承受。此时,我们可以将业务拆分成几个互不关联的应用,分别部署在各自机器上,以划清逻辑并减小压力。

2、不同技术选型

公司业务规模扩大,有可能引入不同的语言,比如A团队要开发CPU密集型的采用java语言,B团队要开发IO密集型的采用了PHP,不同语言之间如何通讯

遇到的问题

1)要搭建一个新服务,免不了需要依赖其它团队的服务,而现在他人的服务都在远端,怎么调用?

2)其它团队使用的语言并不是PHP,不同语言之间如何进行调用?

如何调用服务?

由于各服务部署在不同机器,服务间的调用免不了网络通信过程,服务消费方每调用一个服务都要写一坨网络通信相关的代码,不仅复杂而且极易出错。

如果有一种方式能让我们像调用本地服务一样调用远程服务,而让调用者对网络通信这些细节透明,那么将大大提高生产力,比如服务消费方在执行

$client->getUserInfo()时,实质上调用的是远端的服务。这种方式其实就是RPC。

rpc客户端调用流程

服务治理

客户端通过发送一个规定的rpc协议,请求服务的注册中心,由服务注册中心检索可用服务,并且实现调用转发,服务内容由代码服务器在启动的时候,注册到服务中心。服务中心暂时利用redis存储内容。

原理图:

  • 1、通过redis方式存储代码服务器发送过来的注册服:利用redis集合进行存储服务

  • 2、多端口混合协议监听接收注册服务: 客户端如果是普通的网页端只需要,接收普通的http请求,但是是硬件设备需要接收tcp的协议,不同协议统一转换,同时查询可用服务发送到服务端

  • 3、提供RPC服务,服务调用

  • 4、心跳维持、健康检查、绑定服务器:定时检测代码服务端健康状态,如果服务宕机,从服务列表当中删除

  • 5、协议的统一转换:将客户端的不同协议的请求在转发到代码服务架构时,转换成统一的协议,去请求

  • 6、负载均衡

    通过查看服务端的连接数、任务排队数、系统负载、内存状态,决定当前的rpc客户端请求会得到哪台机器的地址

系统负载参考这篇文章 :http://www.ruanyifeng.com/blog/2011/07/linux_load_average_explained.html

6.1、通过redis字符串类型保存每台服务器状态

注册服务之后代码服务端,定时发送当前机器状态,存储在redis当中提供给服务端选择,通过redis字符串存储某个服务当前的服务器相关状态key为当前的,在调用服务时根据情况,比如系统状态更好加分,连接数更少加分

目前先设置三项

[
       'load'=>0.1, //15分钟负载
       'connection_num'=>20,  //连接数
       tasking'=>2   //任务排队数
]

6.2、通过评分算法获取状态最好的机器

通过评分算法实现不同选项的评分,选取状态最好的一台服务机器,返回给客户端,通过匹配redis集合当中的服务名,得到不同服务的地址,并且通过读取redis存储的字符类型获取服务状态,利用评分算法选取

代码服务端

  • 1、注册服务到注册中心:在进程启动时将当前的代码服务端提供的服务,发送请求注册到注册中心

  • 2、接收服务中心的服务调用: 默认触发onRequest事件

  • 3、心跳维持:通过发送心跳包维持代码服务在线状态

客户端

  • 1、异步客户端、同步客户端创建

  • 2、通过请求服务中心获取到健康的服务地址

  • 3、通过请求服务中心获取代码

注意事项:

1、协议规定

根据相应的协议规范,并且能够携带验证标识,来决定调用远程代码服务器上面的某个类当中的某个方法,响应相应的服务

2、服务中心存储

用redis作为存储工具,也可以使用swoole_table或者其它的存储工具

扩展的原理图:

Last updated