Apache APISIX को gRPC-Web के साथ एकीकृत करना

Fei Han

January 25, 2022

Ecosystem

gRPC वेब परिचय

मूल रूप से Google द्वारा विकसित, gRPC एक उच्च-प्रदर्शन रिमोट प्रोसीजर कॉल फ्रेमवर्क है जो HTTP/2 पर लागू किया गया है। हालांकि, क्योंकि ब्राउज़र सीधे HTTP/2 को एक्सपोज़ नहीं करते हैं, वेब एप्लिकेशन सीधे gRPC का उपयोग नहीं कर सकते हैं। gRPC वेब एक मानकीकृत प्रोटोकॉल है जो इस समस्या को हल करता है।

पहला gRPC-वेब कार्यान्वयन 2018 में एक JavaScript लाइब्रेरी के रूप में जारी किया गया था, जिसके माध्यम से वेब एप्लिकेशन सीधे gRPC सेवा के साथ संचार कर सकते हैं। इसका सिद्धांत HTTP/1.1 और HTTP/2 के साथ संगत एक एंड-टू-एंड gRPC पाइपलाइन बनाना है। ब्राउज़र तब एक नियमित HTTP अनुरोध भेजता है, और ब्राउज़र और सर्वर के बीच स्थित एक gRPC-वेब प्रॉक्सी अनुरोध और प्रतिक्रिया का अनुवाद करता है। gRPC के समान, gRPC वेब वेब क्लाइंट और बैकएंड gRPC सेवा के बीच एक पूर्वनिर्धारित अनुबंध का उपयोग करता है। प्रोटोकॉल बफ़र्स का उपयोग संदेशों को सीरियलाइज़ और एनकोड करने के लिए किया जाता है।

gRPC-वेब कैसे काम करता है

gRPC वेब के साथ, उपयोगकर्ता ब्राउज़र या Node क्लाइंट का उपयोग करके सीधे बैकएंड gRPC एप्लिकेशन को कॉल कर सकते हैं। हालांकि, ब्राउज़र साइड पर gRPC-वेब का उपयोग करके gRPC सेवाओं को कॉल करने में कुछ सीमाएं हैं।

  • क्लाइंट-साइड स्ट्रीमिंग और द्विदिश स्ट्रीमिंग कॉल समर्थित नहीं हैं।
  • क्रॉस-डोमेन gRPC सेवाओं को कॉल करने के लिए सर्वर साइड पर CORS कॉन्फ़िगर किया जाना चाहिए।
  • gRPC सर्वर साइड को gRPC-वेब का समर्थन करने के लिए कॉन्फ़िगर किया जाना चाहिए, या ब्राउज़र और सर्वर के बीच कॉल का अनुवाद करने के लिए एक तृतीय-पक्ष सेवा एजेंट उपलब्ध होना चाहिए।

Apache APISIX gRPC वेब प्रॉक्सी

Apache APISIX प्लगइन के माध्यम से gRPC वेब प्रोटोकॉल के प्रॉक्सी का समर्थन करता है, जो grpc-web प्लगइन में gRPC वेब और gRPC सर्वर के बीच संचार होने पर प्रोटोकॉल रूपांतरण और डेटा कोडेक कार्य को पूरा करता है, और इसका संचार प्रक्रिया निम्नलिखित है।

gRPC वेब क्लाइंट -> Apache APISIX (प्रोटोकॉल रूपांतरण और डेटा कोडेक) -> gRPC सर्वर

निम्नलिखित एक पूर्ण उदाहरण है जो दिखाता है कि कैसे एक gRPC वेब क्लाइंट बनाया जाए और Apache APISIX के माध्यम से gRPC वेब अनुरोधों को प्रॉक्सी किया जाए। निम्नलिखित उदाहरण में, हम Go को gRPC सर्वर सर्वर हैंडलर के रूप में और Node को gRPC वेब क्लाइंट अनुरोधकर्ता के रूप में उपयोग करेंगे।

प्रोटोकॉल बफ़र कॉन्फ़िगर करें

पहला कदम प्रोटोकॉल बफ़र कंपाइलर और संबंधित प्लगइन्स को इंस्टॉल करना है।

  1. protoc और proto-grpc-* इंस्टॉल करें।

    प्रोटोकॉल बफ़र कंपाइलर protoc और .proto के लिए Go, JavaScript, और gRPC वेब इंटरफ़ेस कोड जनरेट करने के लिए protoc-gen-go और protoc-gen-grpc-web प्लगइन्स को आपके सिस्टम पर इंस्टॉल किया जाना चाहिए, क्लाइंट और सर्वर-साइड एप्लिकेशन लिखने से पहले।

    कृपया निम्नलिखित स्क्रिप्ट चलाएं ताकि उपरोक्त घटकों को इंस्टॉल किया जा सके।

    #!/usr/bin/env bash set -ex PROTOBUF_VERSION="3.19.0" wget https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOBUF_VERSION}/protoc-${PROTOBUF_VERSION}-linux-x86_64.zip unzip protoc-${PROTOBUF_VERSION}-linux-x86_64.zip mv bin/protoc /usr/local/bin/protoc mv include/google /usr/local/include/ chmod +x /usr/local/bin/protoc PROTO_GO_PLUGIN_VER="1.2.0" wget https://github.com/grpc/grpc-go/releases/download/cmd/protoc-gen-go-grpc/v${PROTO_GO_PLUGIN_VER}/protoc-gen-go-grpc.v${PROTO_GO_PLUGIN_VER}.linux.amd64.tar.gz tar -zxvf protoc-gen-go-grpc.v${PROTO_GO_PLUGIN_VER}.linux.amd64.tar.gz mv protoc-gen-go-grpc /usr/local/bin/protoc-gen-go chmod +x /usr/local/bin/protoc-gen-go PROTO_JS_PLUGIN_VER="1.3.0" wget https://github.com/grpc/grpc-web/releases/download/${PROTO_JS_PLUGIN_VER}/protoc-gen-grpc-web-${PROTO_JS_PLUGIN_VER}-linux-x86_64 mv protoc-gen-grpc-web-${PROTO_JS_PLUGIN_VER}-linux-x86_64 /usr/local/bin/protoc-gen-grpc-web chmod +x /usr/local/bin/protoc-gen-grpc-web
  2. SayHello उदाहरण proto फ़ाइल बनाएं।

    // a6/echo.proto syntax = "proto3"; package a6; option go_package = "./;a6"; message EchoRequest { string message = 1; } message EchoResponse { string message = 1; } service EchoService { rpc Echo(EchoRequest) returns (EchoResponse); }

सर्वर-साइड एप्लिकेशन कॉन्फ़िगर करें

  1. सर्वर-साइड Go कच्चे संदेश और सेवा/क्लाइंट स्टब्स जनरेट करें।

    protoc -I./a6 echo.proto --go_out=plugins=grpc:./a6
  2. सर्वर-साइड हैंडलर इंटरफ़ेस को लागू करें।

    // a6/echo.impl.go package a6 import ( "errors" "golang.org/x/net/context" ) type EchoServiceImpl struct { } func (esi *EchoServiceImpl) Echo(ctx context.Context, in *EchoRequest) (*EchoResponse, error) { if len(in.Message) <= 0 { return nil, errors.New("message invalid") } return &EchoResponse{Message: "response: " + in.Message}, nil }
  3. सर्वर-साइड एप्लिकेशन रनटाइम एंट्री फ़ाइल।

    // server.go package main import ( "fmt" "log" "net" "apisix.apache.org/example/a6" "google.golang.org/grpc" ) func main() { lis, err := net.Listen("tcp", fmt.Sprintf(":%d", 50001)) if err != nil { log.Fatalf("failed to listen: %v", err) } grpcServer := grpc.NewServer() a6.RegisterEchoServiceServer(grpcServer, &a6.EchoServiceImpl{}) if err = grpcServer.Serve(lis); err != nil { log.Fatalf("failed to serve: %s", err) } }
  4. सर्वर-साइड सेवा को कंपाइल और शुरू करें।

    go build -o grpc-server server.go ./grpc-server

क्लाइंट प्रोग्राम कॉन्फ़िगर करें

  1. क्लाइंट-साइड proto कोड जनरेट करें।

    क्लाइंट-साइड JavaScript कच्चे संदेश, सेवा/क्लाइंट स्टब्स और gRPC वेब के JavaScript के लिए इंटरफ़ेस कोड जनरेट करें।

    gRPC वेब के लिए proto प्लगइन दो मोड में कोड जनरेशन प्रदान करता है।

    1. mode=grpcwebtext: डिफ़ॉल्ट जनरेट किया गया कोड पेलोड को grpc-web-text फॉर्मेट में भेजता है।

    • Content-type: application/grpc-web-text

    • पेलोड base64 एन्कोडिंग का उपयोग करता है

    • मोनैडिक और सर्वर स्ट्रीमिंग कॉल का समर्थन करता है

    1. mode=grpcweb: पेलोड को बाइनरी protobuf फॉर्मेट में भेजता है।

    • Content-type: application/grpc-web+proto
    • पेलोड बाइनरी protobuf फॉर्मेट में होता है
    • वर्तमान में केवल मोनैडिक कॉल समर्थित हैं
    protoc -I=./a6 echo.proto --js_out=import_style=commonjs:./a6 --grpc-web_out=import_style=commonjs,mode=grpcweb:./a6
  2. क्लाइंट-साइड निर्भरताएं इंस्टॉल करें।

    npm i grpc-web npm i google-protobuf
  3. क्लाइंट-साइड पर एंट्री फ़ाइल को निष्पादित करें।

    // client.js const {EchoRequest} = require('./a6/echo_pb'); const {EchoServiceClient} = require('./a6/echo_grpc_web_pb'); // Apache APISIX के प्रवेश बिंदु से कनेक्ट करें let echoService = new EchoServiceClient('http://127.0.0.1:9080'); let request = new EchoRequest(); request.setMessage("hello") echoService.echo(request, {}, function (err, response) { if (err) { console.log(err.code); console.log(err.message); } else { console.log(response.getMessage()); } });
  4. अंतिम प्रोजेक्ट संरचना

    $ tree . ├── a6 │ ├── echo.impl.go │ ├── echo.pb.go │ ├── echo.proto │ ├── echo_grpc_web_pb.js │ └── echo_pb.js ├── client.js ├── server.go ├── go.mod ├── go.sum ├── package.json └── package-lock.json

उपरोक्त चरणों को पूरा करने के बाद, आपने gRPC सर्वर सर्वर एप्लिकेशन और gRPC वेब क्लाइंट एप्लिकेशन को कॉन्फ़िगर कर लिया है, और सर्वर एप्लिकेशन को शुरू कर दिया है, जो पोर्ट 50001 पर अनुरोध प्राप्त करेगा।

Apache APISIX कॉन्फ़िगर करें

अगला, Apache APISIX रूटिंग प्लगइन कॉन्फ़िगरेशन में grpc-web प्लगइन को सक्षम करें ताकि gRPC वेब अनुरोधों को प्रॉक्सी किया जा सके।

  1. grpc-web प्रॉक्सी प्लगइन सक्षम करें।

    रूटिंग को प्रीफ़िक्स मिलान का उपयोग करना चाहिए (जैसे, /* या /grpc/example/*), क्योंकि gRPC वेब क्लाइंट URI में proto में घोषित पैकेज नाम, सेवा इंटरफ़ेस नाम, मेथड नाम आदि पास करता है (जैसे, /path/a6.EchoService/Echo), पूर्ण मिलान का उपयोग करने से प्लगइन URI से proto जानकारी निकालने से रोकता है

    $ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { "uri":"/*", // प्रीफ़िक्स मिलान मोड "plugins":{ "grpc-web":{} // gRPC वेब प्लगइन सक्षम करें }, "upstream":{ "scheme":"grpc", "type":"roundrobin", "nodes":{ "127.0.0.1:50001":1 // gRPC सर्वर लिसन पते और पोर्ट } } }'
  2. gRPC वेब प्रॉक्सी अनुरोधों को मान्य करें।

    gRPC वेब प्रोटोकॉल अनुरोध को Node से client.js निष्पादित करके Apache APISIX को भेजा जा सकता है।

    उपरोक्त क्लाइंट-साइड और सर्वर-साइड प्रोसेसिंग लॉजिक क्रमशः हैं: क्लाइंट सर्वर को hello सामग्री के साथ एक संदेश भेजता है, सर्वर संदेश प्राप्त करता है और response: hello के साथ प्रतिक्रिया देता है, और निष्पादन परिणाम निम्नलिखित है।

    $ node client.js response: hello
  3. grpc-web प्रॉक्सी प्लगइन अक्षम करें।

    बस रूटिंग प्लगइन कॉन्फ़िगरेशन से grpc-web विशेषता को हटा दें।

    $ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { "uri":"/*", "plugins":{ }, "upstream":{ "scheme":"grpc", "type":"roundrobin", "nodes":{ "127.0.0.1:50001":1 } } }'

सारांश

यह लेख आपको Apache APISIX में grpc-web का उपयोग करने के बारे में हाथों-हाथ अनुभव प्रदान करता है।

GitHub Discussions में चर्चा शुरू करने या मेलिंग सूची के माध्यम से संचार करने के लिए स्वतंत्र महसूस करें।

Tags: