サーバープロセス
サーバーのオプションパラメータを定義する
主な方法は、RpcServerOptions
オブジェクトを定義することです。オブジェクトに対して、サーバーの基本構成を行うことができます。RpcServerOptions
主なパラメーターは次のとおりです。
//配置线程数量
sofa::pbrpc::RpcServerOptions options;
options.work_thread_num = 4; //工作线程数为4
サーバー制御オブジェクトを定義する
主なメソッドはRpcServer
オブジェクトをインスタンス化することです。このクラスの主なメソッドは次のとおりです。
- 開始
- やめる
- Run
クラスによってインスタンス化されたオブジェクトは、RpcServerOptions
初期化する必要があります。RpcServer
クラスにはRpcServerOptions
パラメーターが含まれているためRpcServer
、RpcServerOptions
指定された構成に従って動作していると理解できます。
sofa::pbrpc::RpcServerOptions options;
...对options进行配置
sofa::pbrpc::RpcServer rpc_server(options);
サーバーサービスを開始する
サービスを開始する方法は非常に簡単で、Start関数を呼び出すだけです。Start関数で渡す必要のあるパラメーターは、サーバーのIPとポートです。
この関数を使用する場合、アドレス情報を文字列の形式で渡すだけで済みます。主な形式はip:port
、関数の戻り値の型がブール型であるため、戻り値によって正常に実行されたかどうかを判断できます。値。
if(rpc_server.Start("0.0.0.0:3000"))
{
cout<<"Start Server success"<<endl;
}
else
{
cout<<"Start Server failed"<<endl;
}
サーバーサービスの登録
登録サービスの簡単な理解は、サーバーの機能ロジックです。通常、このクラスは自分で作成する必要があります。同時に、このクラスは継承する必要がありますsofa::pbrpc::test::EchoServer
。このクラスはsofa::pbrpc::test::EchoServer
インターフェイスクラスとして理解できます。エコーこのクラスの関数は、純粋仮想関数であるサーバーロジック処理関数であるため、書き直す必要があります。
//本次服务器主要的功能为实现两个数的相加,request、response是一个格式为protobuf的消息类
class TestEcho_Server():public sofa::pbrpc::test::EchoServer //继承对应的处理类
{
public:
TestEcho_Server();
~TestEho_Server();
private:
vritual void Echo(google::protobuf::RpcController* controller ,
const sofa:pbrpc::test::EchoRequest* request,
sofa::pbrpc::test::EchoResponse* response,
google::protobuf::Closure* done)
{
sofa::pbrpc::RpcController* cntl = static_cast<sofa::pbrpc::RpcController*>(controller);
//获取请求消息
int val1 = request->val1();
int val2 = request->val2();
int sum = val1 + val2;
//设置响应消息
response->set_sum(sum);
done->Run();
}
};
int main()
{
//注册操作,定义执行方式
sofa::pbrpc::test::EchoServer* echo_server = new TestEcho_Server();
if(rpc_server.RegisterService(echo_server))
{
cout<<"Register Server success"<<endl;
}
}
サービス開始
rpc_server.Run()
サービス終了
rpc_server.Stop();
クライアントプロセスの同期
クライアントオブジェクトを定義する
実装メソッドはsofa::pbrpc::RpcClientOptions
オブジェクトであり、スレッド数など、クライアントプログラムの基本的な構成を実行できます。
sofa::pbrpc::RpcClientOptions client_options;
client_options.work_thread_num = 8;
sofa::pbrpc::RpcClient rpc_client(client_options);
このオブジェクトの主な機能は、チャネルをマークすることです。
チャネルチャネルを定義する
サーバー側のサービスアドレスで渡す必要があるメッセージチャネルを表すRpcChannelオブジェクトを定義します。
sofa::pbrpc::RpcChannel rpc_channel(&rpc_client, "127.0.0.1:3000");
要求および応答メッセージオブジェクトを定義する
メッセージをリクエストするときに、メッセージに値を割り当てることができます。
sofa::pbrpc::test::EchoRequest request;
request.val1(1);
request.val2(1);
sofa::pbrpc::test::EchoResponse response;
応答オブジェクトはサーバー側で割り当てられるため、訪問の終了後は、応答に基づいて対応するメッセージを取得するだけで済みます。
接続コントローラーを定義する
接続コントローラーでは、タイムアウト待機時間、圧縮方法など、この接続のいくつかの基本設定を行うことができます。
sofa::pbrpc::RpcController controller;
controller.SetTimeout(3000);
サーバーとの接続を確立します
サーバーとの接続を確立するときは、EchoServer_Stubオブジェクトをインスタンス化するだけでよく、オブジェクトのコンストラクターに必要なパラメーターはチャネルチャネルです。
sofa::pbrpc::test::EchoServer_Stub stub(&rpc_channel);
電話を掛ける
呼び出しを開始する際の主なメソッドは、Echo関数を呼び出すことです。特定のパラメーターは、コントローラーへの接続、要求メッセージ、応答メッセージ、および呼び出しメソッドです。呼び出しメソッドがNULLの場合、同期呼び出しを意味します。通話が終了したら、コントローラーに接続して、通話が成功したかどうかを確認できます。
stub.Echo(&controller, &request, &response, NULL);
if(!controller.Failed())
{
cout<<"调用成功"<<endl;
}
非同期クライアントプロセス
非同期クライアントプロセスと同期クライアントプロセスの主な違いは、追加のコールバック関数があることです。同時に、Echoを実行するときに、destroy関数を渡すだけです。
このシミュレーションでは、クライアントが100,000メッセージを要求します。同期処理時間は基本的に約30秒、非同期処理時間は約3秒です。基本的に、100,000件のリクエストが失われることはありません。
//服务器代码
#include <sofa/pbrpc/pbrpc.h>
#include<signal.h>
#include "echo_service.pb.h"
#include<iostream>
class EchoServerFunc:public sofa::pbrpc::test::EchoServer
{
public:
EchoServerFunc(){
}
virtual ~EchoServerFunc(){
}
private:
virtual void Echo(google::protobuf::RpcController* _cntl,
const sofa::pbrpc::test::EchoRequest* request,
sofa::pbrpc::test::EchoResponse* response,
google::protobuf::Closure* done)
{
sofa::pbrpc::RpcController* cntl = static_cast<sofa::pbrpc::RpcController*>(_cntl);
int number1,number2;
int sum;
number1 = request->number1();
number2 = request->number2();
sum = number1 + number2;
//SLOG(NOTICE, "Echo(): request address is %s: number1 = %d: number2 = %d:",cntl->RemoteAddress().c_str(), request->number1(),request->number2());
response->set_sum(sum);
done->Run();
}
};
int main()
{
SOFA_PBRPC_SET_LOG_LEVEL(NOTICE);
sofa::pbrpc::RpcServerOptions server_options;
int work_thread_num,io_service_pool_size;
std::cout<<"请输入work_thread_num与io_service_pool_size的值"<<std::endl;
std::cin>>work_thread_num>>io_service_pool_size;
server_options.work_thread_num = work_thread_num;
server_options.io_service_pool_size = io_service_pool_size;
sofa::pbrpc::RpcServer rpc_server(server_options);
if(!rpc_server.Start("0.0.0.0:12321"))
{
SLOG(ERROR,"rpc_server start failed");
return EXIT_FAILURE;
}
sofa::pbrpc::test::EchoServer* echo_server = new EchoServerFunc();
if(!rpc_server.RegisterService(echo_server))
{
SLOG(ERROR,"register Service failed");
return EXIT_FAILURE;
}
rpc_server.Run();
rpc_server.Stop();
return EXIT_SUCCESS;
}
#include <sofa/pbrpc/pbrpc.h>
#include "echo_service.pb.h"
#include<iostream>
#include<time.h>
using namespace std;
sofa::pbrpc::RpcClientOptions client_options;
int main()
{
SOFA_PBRPC_SET_LOG_LEVEL(NOTICE);
sofa::pbrpc::RpcChannelOptions channel_options;
int work_thread_num,callback_thread_num;
std::cout<<"请输入work_thread_num的值与callback_pthread_num的值"<<std::endl;
std::cin>>work_thread_num>>callback_thread_num;
client_options.work_thread_num = work_thread_num;
client_options.callback_thread_num = callback_thread_num;
sofa::pbrpc::RpcClient rpc_client(client_options);
sofa::pbrpc::RpcChannel rpc_channel(&rpc_client,"127.0.0.1:12321",channel_options);
sofa::pbrpc::RpcController* cntl = new sofa::pbrpc::RpcController();
sofa::pbrpc::test::EchoRequest* request = new sofa::pbrpc::test::EchoRequest();
sofa::pbrpc::test::EchoResponse* response = new sofa::pbrpc::test::EchoResponse();
sofa::pbrpc::test::EchoServer_Stub* stub = new sofa::pbrpc::test::EchoServer_Stub(&rpc_channel);
int i = 100000;
int successCount = 0;
struct timeval tv1,tv2;
gettimeofday(&tv1,NULL);
while(i>0)
{
i--;
cntl->Reset();
cntl->SetTimeout(2000);
int number1,number2;
//std::cin>>number1>>number2;
number1 = i;
number2 = i-1;
request->set_number1(number1);
request->set_number2(number2);
stub->Echo(cntl,request,response,NULL);
if(!cntl->Failed())
{
//SLOG(NOTICE,"response message %d",response->sum());
successCount++;
}
else
{
//SLOG(ERROR,"request failed %s:",cntl->ErrorText().c_str());
}
}
std::cout<<"成功数:"<<successCount<<endl;
gettimeofday(&tv2,NULL);
cout<<"运行时间:"<<tv2.tv_sec*1000+tv2.tv_usec/1000 - tv1.tv_sec*1000-tv1.tv_usec/1000<<endl;
delete cntl;
delete request;
delete response;
delete stub;
return EXIT_SUCCESS;
}
//异步客户端代码
#include<sofa/pbrpc/pbrpc.h>
#include"echo_service.pb.h"
#include<unistd.h>
#include<pthread.h>
#include<time.h>
#include<iostream>
int sum = 0;
pthread_mutex_t mutex1;
pthread_mutex_t mutex2;
static int failedCount = 0;
static int successCount = 0;
void EchoCallback(sofa::pbrpc::RpcController* controller,
sofa::pbrpc::test::EchoRequest* request,
sofa::pbrpc::test::EchoResponse* response
)
{
if(controller->Failed())
{
//SLOG(ERROR,"rpc client failed");
pthread_mutex_lock(&mutex1);
failedCount++;
pthread_mutex_unlock(&mutex1);
}
else
{
pthread_mutex_lock(&mutex1);
successCount++;
pthread_mutex_unlock(&mutex1);
//SLOG(NOTICE,"%d + %d = %d",request->number1(),request->number2(),response->sum());
}
pthread_mutex_lock(&mutex2);
sum ++;
pthread_mutex_unlock(&mutex2);
}
int main()
{
pthread_mutex_init(&mutex1,NULL);
pthread_mutex_init(&mutex2,NULL);
SOFA_PBRPC_SET_LOG_LEVEL(NOTICE);
sofa::pbrpc::RpcClientOptions client_options;
int work_thread_num = 8;
int callback_thread_num = 8;
//std::cout<<"请输入work_thread_num与callback_thread_num的个数";
//std::cin>>work_thread_num>>callback_thread_num;
client_options.work_thread_num = work_thread_num;
client_options.callback_thread_num = callback_thread_num;
sofa::pbrpc::RpcClient rpc_client(client_options);
sofa::pbrpc::RpcChannelOptions channel_options;
sofa::pbrpc::RpcChannel rpc_channel(&rpc_client,"127.0.0.1:12321",channel_options);
sofa::pbrpc::test::EchoRequest request;
sofa::pbrpc::test::EchoResponse response;
sofa::pbrpc::test::EchoServer_Stub stub(&rpc_channel);
struct timeval tv1,tv2;
gettimeofday(&tv1,NULL);
int count = 200000;
while(count > 0)
{
sofa::pbrpc::RpcController controller;
request.set_number1(1);
request.set_number2(1);
controller.Reset();
controller.SetTimeout(10000);
google::protobuf::Closure* done = sofa::pbrpc::NewClosure(&EchoCallback, &controller,&request, &response);
stub.Echo(&controller,&request,&response,done);
count--;
}
while(sum<200000)
{
usleep(20000);
}
gettimeofday(&tv2,NULL);
std::cout<<"程序运行时间为:"<<tv2.tv_sec*1000+tv2.tv_usec/1000 - tv1.tv_sec*1000-tv1.tv_usec/1000<<std::endl;
std::cout<<"成功次数:"<<successCount<<std::endl;
std::cout<<"失败次数:"<<failedCount<<std::endl;
return EXIT_SUCCESS;
}
以下のデータはこのマシンで測定されたものであり、構成が異なれば結果も異なる場合があります。
複数の非同期クライアントによって測定されたデータ。