2021SC@SDUSC
workflow可用于构建rpc框架
workflow的主要功能有实现自定义协议client/server,构建自己的RPC系统。RPC即远程过程调用协议,简单说是一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,需要通过网络来表达调用的语义和传达调用的数据。
寻址的意思是 A服务器上的应用应该怎么告诉底层的RPC框架,以什么方法连接到B服务器以及特定的端口,方法的名称是什么。
通常情况下需要提供B机器(主机名或IP地址)以及特定的端口,然后指定调用的方法、传入的参数、返回值等信息,这样完成一个服务的调用。
域名服务协议
DNS(域名服务协议)是一种分布式网络目录服务,用于域名与IP地址的相互转换。
workflow框架直接调用系统函数getaddrinfo()获取域名转换的结果,返回值:0表示成功,非0代表出错,需要包含头文件 #include<netdb.h>,。
int getaddrinfo( const char *hostname, const char *service, const struct addrinfo *hints, struct addrinfo **result );
hostname:一个主机名或者地址串(IPv4的点分十进制串或者IPv6的16进制串)
service:服务名可以是十进制的端口号,也可以是已定义的服务名称,如ftp、http等
hints:可以是一个空指针,也可以是一个指向addrinfo结构体的指针,调用者在这个结构中填入关于期望返回的信息类型。
result:本函数通过result指针参数返回一个指向addrinfo结构体链表的指针,结构体的定义如下。
typedef struct addrinfo {
int ai_flags; //AI_PASSIVE,AI_CANONNAME,AI_NUMERICHOST
int ai_family; //AF_INET,AF_INET6
int ai_socktype; //SOCK_STREAM,SOCK_DGRAM
int ai_protocol; //IPPROTO_IP, IPPROTO_IPV4, IPPROTO_IPV6 etc.
size_t ai_addrlen; //must be zero or a null pointer
char* ai_canonname; //must be zero or a null pointer
struct sockaddr* ai_addr; //must be zero or a null pointer
struct addrinfo* ai_next; //must be zero or a null pointer
}
ai_flags用来指定如何处理地址和名字,AI_PASSIVE 套接字地址用于监听绑定;AI_CANONNAME表示需要一个规范名,AI_NUMERICHOST以数字格式返回主机地址。
SOCK_STREAM:有序、可靠、双向的面向连接字节流,SOCK_DGRAM:长度固定的、无连接的不可靠报文传输。
相关数据结构
为了提高效率,workflow设计了 DNS Cache (对用户透明)。下面的代码为全局DNS配置,TTL(Time To Live) 表示DNS记录在DNS Cache上的时间。
struct WFGlobalSettings
{
struct EndpointParams endpoint_params;
unsigned int dns_ttl_default; ///< in seconds, DNS TTL when network request success
unsigned int dns_ttl_min; ///< in seconds, DNS TTL when network request fail
int dns_threads;
int poller_threads;
int handler_threads;
int compute_threads; ///< auto-set by system CPU number if value<=0
};
/**
* @brief Default Workflow Library Global Settings
*/
static constexpr struct WFGlobalSettings GLOBAL_SETTINGS_DEFAULT =
{
/* .endpoint_params = */ ENDPOINT_PARAMS_DEFAULT,
/* .dns_ttl_default = */ 12 * 3600,
/* .dns_ttl_min = */ 180,
/* .dns_threads = */ 8,
/* .poller_threads = */ 2,
/* .handler_threads = */ 20,
/* .compute_threads = */ -1
};
dns-thread:DNS线程池线程数,默认为8;
dns_ttl_default 为DNS Cache中默认的ttl,单位是s,默认为12小时。
dns_threads_min表示dns最短生效时间,用于通信失败是否重新尝试dns的决策。
每次通信都会检查TTL来决定要不要重新进行DNS解析。 默认检查dns_ttl_default,通信失败重试时才会去检查dns_ttl_min。dns Cache进程退出会消失,其他配置也只对当前进程有效。
struct EndpointParams
{
size_t max_connections;
int connect_timeout;
int response_timeout;
int ssl_connect_timeout;
};
static constexpr struct EndpointParams ENDPOINT_PARAMS_DEFAULT =
{
.max_connections = 200,
.connect_timeout = 10 * 1000,
.response_timeout = 10 * 1000,
.ssl_connect_timeout = 10 * 1000,
};
EndpointParams为与超时相关的配置 ,max_connections用信号量限制最多连接数为200个,connect_timeout: 与目标建立连接的超时,单位是ms,所以默认为10秒。response_timeout: 等待目标响应的超时,默认为10秒,代表成功发送到目标、或从目标读取到一块数据的超时。 ssl_connect_timeout: 与目标完成SSL握手的超时,默认为10秒。
参考资料:
RPC基本原理 - 萨姆大叔 - 博客园 (cnblogs.com)
getaddrinfo()函数详解 - hapus - 博客园 (cnblogs.com)
addrinfo结构体原型 - hapus - 博客园 (cnblogs.com)
几个重要的话题 - 关于超时 - 《Sogou C++ Workflow v0.9.0 使用教程》 - 书栈网 · BookStack