gRPC-Web의 Proxy를 Nginx로 사용해 보았습니다.
gRPC-Web이 공식 릴리스. 웹 브라우저에서 gRPC를 직접 호출 가능하게
어떤 구조가 되고 있는가 하면···
Client(ブラウザ) -> Proxy -> gRPCサーバー
라고 하는 식으로 Proxy를 개입시켜 브라우저와 gRPC 서버와의 교환을 실시하고 있습니다.
이번에는이 프록시의 이야기입니다.
이 프록시는 공식 문서와 그 예에서도 Envoy를 사용합니다.
htps : // 기주 b. 코 m / grpc / grpc - b
실제로 Envoy를 이용하면 순조롭게 도입할 수 있습니다.
단지 IP 제한을 할 수 없거나 (이쪽 할 수있는 것 같으면 지적 부탁드립니다), Yaml로 쓰지 않으면 안된다거나 뭔가 가려운 곳에 손이 닿지 않습니다.
그래서 프록시를 Nginx로 만들려고합니다.
Nginx에서도 gRPC 프록시를 할 수 있습니다.
Introducing gRPC Support with NGINX 1.13.10
이번 만드는 샘플은 여기에 배치하고 있습니다.
htps : // 기주 b. 코 m/모리 x1500/grp-우우 b 긴긴 x
proto 파일 만들기
먼저 proto 파일을 만들고 인터페이스를 정의합니다.
이름이 건네지면, 「Hello, ○○」라고 반환할 뿐의 API입니다.
proto/hello.proto
syntax = "proto3";
package hello;
message HelloRequest {
string name = 1;
}
message HelloResponse {
string message = 1;
}
service HelloService {
rpc Hello(HelloRequest) returns (HelloResponse) {}
}
여기에서 클라이언트와 서버 코드를 생성합니다.
이번에는 편리한 znly/protoc을 사용합니다.
$ docker run --rm -v $(pwd):$(pwd) \
-w $(pwd) znly/protoc:0.4.0 \
-I ./proto \
--js_out=import_style=commonjs,binary:./client/assets/_proto \
--go_out=plugins=grpc:./server/proto/ \
--grpc-web_out=import_style=commonjs,mode=grpcweb:./client/assets/_proto \
proto/hello.proto
$ tree .
.
├── README.md
├── client
│ └── assets
│ └── _proto
│ ├── hello_grpc_web_pb.js
│ └── hello_pb.js
├── proto
│ └── hello.proto
└── server
└── proto
└── hello.pb.go
gRPC 서버 만들기
빨리 만들어 봅시다.
Golang에서 만듭니다.
main.go
는 생략합니다.server/grpc/server.go
package grpc
import (
"context"
"fmt"
pb "github.com/morix1500/grpc-web-nginx/server/proto"
"google.golang.org/grpc"
"net"
)
type HelloService struct{}
func (h HelloService) Run() int {
s := grpc.NewServer()
pb.RegisterHelloServiceServer(s, h)
lis, err := net.Listen("tcp", ":5000")
if err != nil {
fmt.Printf("%+v\n", err)
return 1
}
if err := s.Serve(lis); err != nil {
fmt.Printf("%+v\n", err)
return 1
}
return 0
}
func (h HelloService) Hello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloResponse, error) {
return &pb.HelloResponse{
Message: "Hello, " + in.Name,
}, nil
}
다음 명령으로 시작할 수 있습니다.
$ cd server/
$ go run main.go
gRPC 클라이언트 만들기
클라이언트는 브라우저이므로 JavaScript입니다.
이번에는 Nuxt.js에서 바삭 바삭하게 만들어 보겠습니다.
client/pages/index.vue
<template>
<div>
<h1>Test</h1>
<div>
<input type="input" v-model="name" />
<button @click="hello">send</button>
<p>Message: {{ message }}</p>
</div>
</div>
</template>
<script>
import {HelloServiceClient} from "~/assets/_proto/hello_grpc_web_pb"
import {HelloRequest, HelloResponse} from "~/assets/_proto/hello_pb"
export default {
asyncData() {
return {
name: "",
message: "",
}
},
methods: {
hello() {
let req = new HelloRequest()
req.setName(this.name)
const client = new HelloServiceClient("https://127.0.0.1:8080", {}, {})
client.hello(req, {}, (err, ret) => {
this.message = ret.getMessage()
})
}
}
}
</script>
https://127.0.0.1:8080
이번 Proxy에 gRPC 통신을 시도하고 있습니다.무엇인가 입력하고, Send 버튼을 누르면, 「Hello ○○」라고 하는 것이 화면에 표시됩니다.
아직 프록시가 없기 때문에 이것은 작동하지 않습니다.
그건 그렇고,이 응용 프로그램을 이동하려면 다음 명령입니다.
$ cd client/
$ npm install
$ npm run dev
# ブラウザでアクセス
http://localhost:3000
Nginx 구축
자 본제입니다.
Nginx는 Docker로 해보자.
docker-compose.yaml
version: "3"
services:
proxy:
image: nginx:1.15.6-alpine
ports:
- "8080:8080"
expose:
- "8080"
volumes:
- ./proxy/nginx/common:/etc/nginx/common
- ./proxy/nginx/conf.d:/etc/nginx/conf.d
- ./proxy/keys:/ssl
proxy/nginx/conf.d/sample.conf
server {
listen 8080 ssl http2;
server_name host.docker.internal;
ssl_certificate /ssl/localhost+1.pem;
ssl_certificate_key /ssl/localhost+1-key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
access_log /dev/stdout;
error_log /dev/stderr debug;
location ~ \.(html|js)$ {
root /var/www/html;
}
location /hello.HelloService/Hello {
grpc_set_header Content-Type application/grpc;
grpc_pass host.docker.internal:5000;
include common/cors.conf;
}
}
여기 간은 여기
location /hello.HelloService/Hello {
grpc_set_header Content-Type application/grpc;
grpc_pass host.docker.internal:5000;
include common/cors.conf;
}
location에서 서비스명과 함수명을 기재하면, 그 마다의 설정을 할 수 있으므로
서비스나 함수 단위로 액세스 제어 등을 할 수 있습니다.
그리고
grpc_set_header Content-Type application/grpc;
이것이 없으면 gRPC-Web에서 gRPC 서버로의 프록시가 올바르지 않습니다.그리고는 로컬용의 증명서도 발행합니다. 다음은 Mac의 예입니다.
$ brew install mkcert
$ mkcert -install
$ mkcert localhost 127.0.0.1
$ mv localhost+1* proxy/keys/.
그럼 Nginx도 기동해 갑니다.
$ docker-compose up
확인
브라우저로 만든 클라이언트에 액세스합니다.
「타로」라고 입력하면, 「Hello, 타로」라고 돌아왔습니다.
이제 gRPC-Web과 gRPC 서버에서 소통 확인할 수 있었습니다!
마지막으로
익숙한 Nginx에서도 무사히 사용할 수 있다는 것을 알았습니다.
단지 gRPC-Web은 제한이 있으며 사용에는 주의가 필요합니다.
웹 브라우저에서 gRPC 양방향 통신이 가능한지 조사했다
현재 저는 double jump.tokyo 주식회사님으로부터 gRPC 기반의 구축의 업무 위탁을 받아 가고 있습니다.
그 업무의 일환으로서 이러한 기술 검증을 실시했습니다.
Reference
이 문제에 관하여(gRPC-Web의 Proxy를 Nginx로 사용해 보았습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Morix1500/items/065da20d98ab5e559ea6텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)