跳到主要内容

rpc_service

简介

提供RPC服务

一个RPC服务集群拥有一个中心节点(master),其他节点都是普通节点(slave);中心节点同时也具有一个普通节点的功能。

集群中的每个节点都必须有一个唯一的id(由rpc服务的ip和端口组成一个唯一的id)。

提示

中心节点区别于普通节点的地方是:中心节点存储/共享集群里各普通节点的信息。

一个普通节点只有在中心节点正确登记之后,才会被集群中的其他节点访问。

分布在各个节点上的可供RPC方式访问的资源,都具有一个RPC地址,该地址在集群内是唯一的。

格式:[id]|[catalog]|[RID]

  • id: 节点的唯一id(特别的,当RPC地址中的id是'/'时,对应的是中心节点)

  • catalog: 资源类别;需要提供这种类别的定位函数以便定位到资源对象或者函数方法;可以通过rpc_entry设置定位函数

  • RID: 资源在节点上的id;提供给catalog对应的定位函数用于定位资源的对象或者函数方法

例如

  • "127.0.0.1|m|M000062134CB8003F":"127.0.0.1:5555|m|M000062134CB8003F";其中127.0.0.1是资源所在节点的id,m是资源的类别,M000062134CB8003F是资源的id

  • "/|D|abc.gs":'/'是指中心节点,'D'是指访问的资源是一个模块对象,'abc.gs'是模块文件的名称

默认支持两种资源类别:

  • D: RPC调用目标节点上的daemon模块(通过find_object定位daemon模块)

  • G: RPC调用目标节点上的全局函数

应用

实际的应用可以参考示例项目server1中的game.mods.remote

组件接口

FRpcRelay.gs

提供RPC中继调用功能的组件

需要提供中继处理RPC请求的对象需要继承本组件

函数原型函数作用
void relay_post(string target, string method, ...)中继处理POST请求
mixed relay_get(string target, string method, ...)中继处理GET请求

RpcUtil.gs

RPC地址相关的一些功能函数;比如生成RPC地址、通RPC地址发起RPC调用等。

函数原型函数作用
string make_rpc_address(string target, string catalog, string id, string relay = nil)生成资源RPC地址
RpcAddress parse_rpc_address(string rpc_address)解析资源RPC地址
bool string.PING(string rpc_address)检查指定资源RPC地址对应的对象是否存在
mixed array.PING(array rpc_address_list)获取一组资源RPC地址对应的对象是否存在
void string.POST(string rpc_address, string method, ...)向一个资源RPC地址发起POST(非阻塞)调用
mixed string.GET(string rpc_address, string method, ...)向一个资源RPC地址发起GET(阻塞)调用
void array.POST(array rpc_address_list, string method, ...)向一组资源RPC地址发起POST(非阻塞)调用
mixed array.GET(array rpc_address_list, string method, ...)向一组资源RPC地址发起GET(阻塞)调用
void string.POST_OTHER(string rpc_address, string obfile, string method, ...)向一个资源RPC地址上的指定目标发起POST(非阻塞)调用
mixed string.GET_OTHER(string rpc_address, string obfile, string method, ...)向一个资源RPC地址上的指定目标发起GET(非阻塞)调用
void array.POST_OTHER(array arr, string obfile, string method, ...)向一组资源RPC地址上的指定目标发起POST(非阻塞)调用
mixed array.GET_OTHER(array arr, string obfile, string method, ...)向一组资源RPC地址上的指定目标发起GET(阻塞)调用
void set_rpc_trace(bool enable)开启/关闭调试输出

rpc_config.gs

RPC服务配置

函数原型函数作用
void init(map config)初始化配置
void set(string key, mixed value)设置配置
mixed get(string path, mixed default_value = nil)获取配置
mixed calc(string path, ...)计算配置
string get_mask_id()获取主控的服务器ID
string get_mask_token()获取用于指代主控的服务器标识
void dump()调试接口 - 输出配置信息

rpc_master.gs

主节点上管理所有从节点信息的模块

函数原型函数作用
bool add_slave(string id, map info)添加一个从节点
map get_slave_info(string id)获取从节点信息
void walk_all_slaves(function func)遍历所有从节点
map get_master_info()获取主节点信息

rpc_service.gs

函数原型函数作用
bool start(map para)启动RPC服务
void stop()停止RPC服务

rpc_serviced.gs

这里实现RPC服务的主要功能

开启RPC网络服务

在中心节点登记本节点信息

向资源RPC地址发起POST/GET调用

一般情况下,没有直接必要使用本模块中的接口,应该使用rpc_util或者rpc_service中的。

函数原型函数作用
bool start()开启服务
void stop()停止服务
mixed remote_get(string address, string method, array args)向一个资源RPC地址发起GET(阻塞)调用
array remote_get_multi(array address_list, string method, array args)向一组资源RPC地址发起GET(阻塞)调用
void remote_post(string address, string method, array args)向一个资源RPC地址发起POST(非阻塞)调用
void remote_post_multi(array address_list, string method, array args)向一组资源RPC地址发起POST(非阻塞)调用

rpc_slave.gs

从节点访问主节点获取集群中所有节点信息的模块

函数原型函数作用
map fetch_master_info()作为从节点时,访问主节点获取主节点的完整信息
bool register_self()作为从节点时,访问主节点登记自身完整信息
map get_slave_info(string id)作为从节点,访问主节点获取从节点的完整信息

CustomRpcConfig

继承自 RpcConfig

RPC服务配置

成员变量

变量名类型初始值须初始化描述
ipmixednil可选本节点的IP
portmixednil可选本节点的端口
idstringnil可选本节点的ID(一般由IP/端口组成)
mastermixednil可选本节点作为从节点时连接的主节点服务器信息
{ "ip" : ip, "port" : port }
as_mastermixednil可选本节点作为主节点时额外登记的一些信息
{}
as_slavemixednil可选本节点作为从节点时额外登记的一些信息
{}
port_recv_sizeint0可选RPC网络连接的接收缓冲区大小
max_send_sizeint0可选RPC网络连接允许发送的最大数据包长度
rpc_timeoutint0可选默认超时时长(单位:秒;默认为30秒)
mask_tokenstringnil可选指代主节点的标识
mask_idstringnil可选主节点的ID

成员方法

函数原型函数作用

样例

// 开启服务的sample

#pragma parallel

import gs.lang.*;
import gs.util.*;

import pkg.rpc_service;

void create()
{
// 启动rpc服务
// 既作为主节点又作为从节点
map para = {
// 本节点的ip和端口
"ip" : "127.0.0.1",
"port" : 7432,

// 作为从节点时 - 登记的额外信息
"as_slave" : {
},

// 作为从节点时 - 主节点的ip和端口
"master" : {
"ip" : "127.0.0.1",
"port" : 7432,
},

// 作为主节点时 - 登记的额外信息
"as_master" : {
"test" : 1,
},

// RPC网络连接的最大接收缓冲区大小
"port_recv_size" : 1024 * 512,

// RPC请求超时时长
"rpc_timeout" : 15,

// POST调用应答消息的处理协程数量
"post_coroutine_num" : 4,
};
rpc_service.start(para);
}

public int calc(...)
{
int total = 0;
for (int v : $<)
total += v;

return total;
}

public void say(string word)
{
printf("%s\n", word);
}

// 演示一下通过远程调用调用自己的方法
public void sample()
{
// 启动配置
string addr1= make_rpc_address(__FILE__, "D", "/");
mixed result = addr1.GET("calc", 1, 2, 3, 4, 5);
printf("result1=%M\n", result);
addr1.POST("say", "hello");

string addr2 = make_rpc_address(__FILE__, "D", "/");
mixed result2 = addr2.GET("calc", 11, 12, 13, 14, 15);
printf("result2=%M\n", result2);
addr2.POST("say", "world");

string addr3= make_rpc_address(__FILE__, "D", "127.0.0.1:7432");
mixed result3 = addr3.GET("calc", 1, 2, 3, 4, 5);
printf("result3=%M\n", result3);
addr1.POST("say", "hello3");

string addr4 = make_rpc_address(__FILE__, "D", "127.0.0.1:7432");
mixed result4 = addr4.GET("calc", 11, 12, 13, 14, 15);
printf("result4=%M\n", result4);
addr2.POST("say", "world4");
}