مرحبا يا هبر! أقدم إليكم ترجمة المقال
"Go، gRPC and Docker" من إعداد Mat Evans.
هناك العديد من المقالات حول مشاركة Go و Docker. من السهل جدًا إنشاء حاويات يمكنها التفاعل مع العملاء وفيما بينها. فيما يلي مثال صغير لكيفية القيام بذلك على المستوى الأساسي.
ماذا نخلق؟
سننشئ عميلًا وخادمًا بسيطًا للغاية ،
ونتفاعل مع بعضنا البعض باستخدام
gRPC . سيكون الخادم موجودًا داخل حاوية
Docker حتى يمكن نشره بسهولة.
لنفترض أننا بحاجة إلى خدمة تتلقى سلسلة من عميل وترجع سلسلة بترتيب أحرف عكسي. على سبيل المثال ، أرسل "قطة" واحصل على "حالي" كرد.
.proto ملف
يصف ملف
.proto ما هي العمليات التي
ستنفذها خدمتنا والبيانات التي سيتم تبادلها. إنشاء مجلد
proto في المشروع ، وملف
revers.proto فيه
syntax = "proto3"; package reverse; service Reverse { rpc Do(Request) returns (Response) {} } message Request { string message = 1; } message Response { string message = 1; }
يتم تمييز الوظيفة التي يتم استدعاءها عن بعد على الخادم وإرجاع البيانات إلى العميل كـ
rpc . يتم وضع علامة على هياكل البيانات المستخدمة لتبادل المعلومات بين العقد المتفاعلة
كرسالة . يجب تعيين رقم تسلسل لكل حقل رسالة. في هذه الحالة ، لدينا وظيفة يتلقى
طلب الرسائل من العميل وإرجاع رسائل
الاستجابة .
بمجرد إنشاء ملف
.proto ، من الضروري الحصول على ملف
.go الخاص
بخدمتنا . للقيام بذلك ، قم بتشغيل أمر وحدة التحكم التالية في مجلد
proto :
$ protoc -I . reverse.proto --go_out=plugins=grpc:.
بالطبع ، تحتاج أولاً إلى
إنشاء gRPC .
سيؤدي تنفيذ الأمر أعلاه إلى إنشاء ملف
.go جديد يحتوي على طرق لإنشاء العميل والخادم والرسائل التي يتبادلونها. إذا
اتصلنا بـ godoc ،
فسنرى ما يلي:
$ godoc . PACKAGE DOCUMENTATION package reverse import "." Package reverse is a generated protocol buffer package. It is generated from these files: reverse.proto It has these top-level messages: Request Response ....
زبون
سيكون من الرائع لو عمل العميل مثل هذا:
reverse "this is a test" tset a si siht
إليك الرمز الذي ينشئ عميل
gRPC باستخدام هياكل البيانات التي تم إنشاؤها من ملف
.proto :
package main import ( "context" "fmt" "os" pb "github.com/matzhouse/go-grpc/proto" "google.golang.org/grpc" "google.golang.org/grpc/grpclog" ) func main() { opts := []grpc.DialOption{ grpc.WithInsecure(), } args := os.Args conn, err := grpc.Dial("127.0.0.1:5300", opts...) if err != nil { grpclog.Fatalf("fail to dial: %v", err) } defer conn.Close() client := pb.NewReverseClient(conn) request := &pb.Request{ Message: args[1], } response, err := client.Do(context.Background(), request) if err != nil { grpclog.Fatalf("fail to dial: %v", err) } fmt.Println(response.Message) }
الخادم
سيستخدم الخادم نفس ملف
.go الذي تم إنشاؤه. ومع ذلك ، فإنه يحدد واجهة الخادم فقط ، ولكن يتعين علينا تنفيذ المنطق بمفردنا:
package main import ( "net" pb "github.com/matzhouse/go-grpc/proto" "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/grpclog" ) func main() { listener, err := net.Listen("tcp", ":5300") if err != nil { grpclog.Fatalf("failed to listen: %v", err) } opts := []grpc.ServerOption{} grpcServer := grpc.NewServer(opts...) pb.RegisterReverseServer(grpcServer, &server{}) grpcServer.Serve(listener) } type server struct{} func (s *server) Do(c context.Context, request *pb.Request) (response *pb.Response, err error) { n := 0
عامل ميناء
أفترض أنك تعرف ما
هو عامل الميناء وما هو عليه. هنا لدينا
Dockerfile :
FROM golang:1.12 ADD . /go/src/github.com/matzhouse/go-grpc/server RUN go install github.com/matzhouse/go-grpc/server ENTRYPOINT ["/go/bin/server"] EXPOSE 5300
تتم كتابة رمز التجميع لصورة
Docker هنا. سنقوم بتحليلها سطرا سطرا.
FROM golang:1.12
يعني هذا الأمر أننا نريد إنشاء صورة
لتطبيقنا على أساس صورة تم إنشاؤها مسبقًا ، وهي
golang . هذه صورة
Docker مع بيئة تم تكوينها بالفعل لإنشاء وتشغيل البرامج المكتوبة في
Go .
ADD . /go/src/github.com/matzhouse/go-grpc/server
يقوم هذا الأمر بنسخ الكود المصدري
لتطبيقنا في حاوية
GOPATH / src .
RUN go install github.com/matzhouse/go-grpc/server
يجمع هذا الأمر طلبنا من المصادر المنسوخة إلى الحاوية
ويثبته في مجلد حاوية
GOPATH / bin .
ENTRYPOINT ["/go/bin/server"]
يقوم هذا الأمر بتكوين الحاوية لتعمل كبرنامج قابل للتنفيذ. في ذلك ، نشير إلى المسار إلى التطبيق القابل للتنفيذ ، وإذا لزم الأمر ، وسيطات سطر الأوامر.
EXPOSE 5300
باستخدام هذا الأمر ، نقوم بإخبار الحاوية بالمنافذ التي يجب الوصول إليها من الخارج.
بداية الخادم
نحن بحاجة إلى تشغيل الحاوية من خلال تطبيق الخادم الخاص بنا.
تحتاج أولاً إلى بناء الصورة بناءً على إرشادات
Dockerfile :
$ sudo docker build -t matzhouse/grpc-server . Sending build context to Docker daemon 31.76 MB Step 1/5 : FROM golang ---> a0c61f0b0796 Step 2/5 : ADD . /go/src/github.com/matzhouse/go-grpc ---> 9508be6501c1 Removing intermediate container 94dc6e3a9a20 Step 3/5 : RUN go install github.com/matzhouse/go-grpc/server ---> Running in f3e0b993a420 ---> f7a0370b7f7d Removing intermediate container f3e0b993a420 Step 4/5 : ENTRYPOINT /go/bin/server ---> Running in 9c9619e45df4 ---> fb34dfe1c0ea Removing intermediate container 9c9619e45df4 Step 5/5 : EXPOSE 5300 ---> Running in 0403390af135 ---> 008e09b9aebd Removing intermediate container 0403390af135 Successfully built 008e09b9aebd
الآن يمكننا أن نرى هذه الصورة في القائمة:
$ docker images REPOSITORY TAG IMAGE ID ... matzhouse/grpc-server latest 008e09b9aebd ...
! ممتاز لدينا صورة لتطبيق الخادم الخاص بنا ، حيث يمكنك تشغيل الحاوية الخاصة به باستخدام الأمر التالي:
$ docker run -it -p 5300:5300 matzhouse/grpc-server
في هذه الحالة ، ما يسمى
ميناء الشحن . لاحظ أننا نحتاج إلى كل من بيان
EXPOSE ووسيطة -p .
إطلاق العميل
لن يوفر تطبيق الحاوية للعميل مزايا كبيرة ، لذلك دعونا نبدأها بالطريقة المعتادة:
$ go build -o reverse $ ./reverse "this is a test" tset a si siht
شكرا للقراءة!