1 回答

TA貢獻1834條經驗 獲得超8個贊
只要只有工作人員發起連接,您就不必擔心 NAT。gRPC 支持任一方向(或兩者)的流式傳輸。這意味著您的所有需求都可以僅使用調度程序上的一臺服務器來實現;調度程序不需要連接回工作人員。
根據您的描述,您的服務可能如下所示:
syntax = "proto3";
import "google/protobuf/empty.proto";
service Scheduler {
rpc GetJobs(GetJobsRequest) returns (stream GetJobsResponse) {}
rpc ReportWorkerStatus(stream ReportWorkerStatusRequest) returns (google.protobuf.Empty) {}
rpc ReportJobStatus(stream JobStatus) returns (stream JobAction) {}
}
enum JobType {
JOB_TYPE_UNSPECIFIED = 0;
JOB_TYPE_CONSOLE = 1;
JOB_TYPE_EXEC = 2;
}
message GetJobsRequest {
// List of job types this worker is willing to accept.
repeated JobType types = 1;
}
message GetJobsResponse {
string jobId = 0;
JobType type = 1;
string fileName = 2;
bytes fileContent = 3;
// etc.
}
message ReportWorkerStatusRequest {
float cpuLoad = 0;
uint64 availableDiskSpace = 1;
uint64 availableMemory = 2;
// etc.
// List of filenames or file hashes, or whatever else you need to precisely
// report the presence of files.
repeated string haveFiles = 2;
}
其中大部分是偏好問題(oneof例如,您可以使用而不是枚舉),但希望從客戶端到服務器的單個連接足以滿足您的要求。
維護一組可用的工作人員非常簡單:
func (s *Server) GetJobs(req *pb.GetJobRequest, stream pb.Scheduler_GetJobsServer) error {
ctx := stream.Context()
s.scheduler.AddWorker(req)
defer s.scheduler.RemoveWorker(req)
for {
job, err := s.scheduler.GetJob(ctx, req)
switch {
case ctx.Err() != nil: // client disconnected
return nil
case err != nil:
return err
}
if err := stream.Send(job); err != nil {
return err
}
}
}
基礎教程包括所有類型流的示例,包括 Go 中的服務器和客戶端實現。
至于注冊,這通常只是意味著創建某種憑證,供工作人員在與服務器通信時使用。這可能是一個隨機生成的令牌(服務器可以使用它來加載關聯的元數據),或者用戶名/密碼組合,或者 TLS 客戶端證書,或類似的。詳細信息將取決于您的基礎設施和設置工作人員時所需的工作流程。
- 1 回答
- 0 關注
- 102 瀏覽
添加回答
舉報