Golang - gRPC + grpc - web + nginx 서비스 구축
11019 단어 grpc
본 고 는 Golang - gRPC, grpc - web + nginx 구축 과정 과 중간 에 발생 한 문제 프로젝트 코드 를 기록 하고 자 한다.
1. gRPC 가 무엇 인지 이해 하기
gRPC 의 묘사 인터넷 은 이미 매우 많 고 gRPC 대체적으로 두 가지 지식 과 관련된다.
(1)、RPC Remote Procedure Call
RPC 의 핵심 은 로 컬 에서 원 격 (메모리 에 접근 할 수 있 는) 방법 을 호출 하 는 것 이다.
2. hello 세계 구축
실현 절차
1. 인터페이스 와 데이터 형식 정의
syntax = "proto3";
package api;
//
service HelloWorldService {
//
rpc SayHello (HelloRequest) returns (HelloResponse) {}
}
//
message HelloRequest {
//
string name = 1;
}
//
message HelloResponse {
//
string message = 1;
}
2. 인터페이스 코드 생 성
mv protoc-3.11.4-osx-x86_64/bin/protoc /usr/local/bin
go get -u github.com/golang/protobuf/protoc-gen-go
package api
//go:generate protoc -I. --go_out=plugins=grpc:. ./hello.proto
func init() {}
3. gRPC 서버 엔 드 코드 작성
package hello
type Service struct {}
package hello
import (
"context"
api "grpc-demo/api/proto/v1"
)
func (hello Service) SayHello (_ context.Context, params *api.HelloRequest) (res *api.HelloResponse, err error) {
res = &api.HelloResponse{
Message: "server response: hello " + params.Name,
}
return res, nil
}
package api
import (
"google.golang.org/grpc"
api "grpc-demo/api/proto/v1"
"grpc-demo/api/service/hello"
"log"
"net"
"strconv"
)
func RungGRPCServer (grpcPort int16) {
// grpc server
grpcServer := grpc.NewServer()
// RegisterHelloWorldServiceServer
api.RegisterHelloWorldServiceServer(grpcServer, &hello.Service{})
//
listen, e := net.Listen("tcp", ":"+strconv.Itoa(int(grpcPort)))
if e != nil {
log.Fatal(e)
}
//
log.Printf("serve gRPC server: 127.0.0.1:%d", grpcPort)
if err := grpcServer.Serve(listen); err != nil {
log.Printf("failed to serve: %v", err)
return
}
}
package main
import "grpc-demo/api"
func main () {
c := make(chan bool, 1)
go api.RungGRPCServer(9999)
package main
import (
"context"
"google.golang.org/grpc"
api "grpc-demo/api/proto/v1"
"log"
"os"
)
const (
address = "localhost:9999"
)
func main() {
conn, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := api.NewHelloWorldServiceClient(conn)
name := "world"
if len(os.Args) > 1 {
name = os.Args[1]
}
r, err := c.SayHello(context.Background(), &api.HelloRequest{Name: name})
if err != nil {
log.Fatalf("call say hello fail: %v", err)
}
log.Println(r.Message)
}
이제 간단 한 gRPC 프로그램 이 완성 되 었 습 니 다.
3. 협조 grpc-web
grpc - web 는 웹 엔 드 의 grpcClient 프로젝트 입 니 다. 현재 브 라 우 저 에서 grpc 프로 토 콜 을 직접 지원 하지 못 하 는 방안 을 해결 하려 면 프 록 시 서비스 와 함께 사용 해 야 합 니 다. grpc - web 구축 은 다음 과 같은 몇 단계 로 나 눌 수 있 습 니 다.
1. grpc - web client 코드 생 성
# bin
mv ~/Downloads/protoc-gen-grpc-web-1.0.7-darwin-x86_64 /usr/local/bin/protoc-gen-grpc-web
#
chmod +x /usr/local/bin/protoc-gen-grpc-web
#!/bin/bash
PROJ_ROOT="$(dirname "$(dirname "$(readlink "$0")")")"
protoc \
-I ${PROJ_ROOT}/src/api/v1 \
--js_out=import_style=commonjs:${PROJ_ROOT}/src/api/v1 \
--grpc-web_out=import_style=typescript,mode=grpcweb:${PROJ_ROOT}/src/api/v1 \
${PROJ_ROOT}/src/api/v1/hello.proto
{
"name": "js",
"version": "1.0.0",
"dependencies": {},
"main": "src/main.js",
"devDependencies": {
"google-protobuf": "^3.11.4",
"grpc-web": "^1.0.7",
"webpack": "^4.16.5",
"webpack-cli": "^3.1.0"
}
}
const { HelloRequest } = require('./api/v1/hello_pb');
const { HelloWorldServiceClient } = require('./api/v1/hello_grpc_web_pb');
// , grpc
var client = new HelloWorldServiceClient('http://localhost:8199',
null, null);
// simple unary call
var request = new HelloRequest();
request.setName('World');
client.sayHello(request, {}, (err, response) => {
document.getElementById("response").innerHTML = response.getMessage();
});
gRPC-Web Demode
error get message
yarn install
npx webpack src/main.js
server {
listen 8199;
server_name _;
access_log /tmp/grpc.log;
error_log /tmp/grpc.log debug;
location ~ \.(html|js)$ {
root /var/www/html;
}
location / {
# !! Content-Type application/grpc
# grpc-web application/grpc-web+proto || application/grpc-web+text ( js grpc-web_out mode , grpcweb application/grpc-web+proto)
grpc_set_header Content-Type application/grpc;
grpc_pass localhost:9999;
# , nginx
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Transfer-Encoding,Custom-Header-1,X-Accept-Content-Transfer-Encoding,X-Accept-Response-Streaming,X-User-Agent,X-Grpc-Web';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Transfer-Encoding,Custom-Header-1,X-Accept-Content-Transfer-Encoding,X-Accept-Response-Streaming,X-User-Agent,X-Grpc-Web';
add_header 'Access-Control-Expose-Headers' 'Content-Transfer-Encoding, grpc-message,grpc-status';
}
}
}
3. 전단 항목 실행
1. [grpc 응답 헤드 중 grpc - message] grpc: received message larger than max (1094795585 vs. 4194304) (nginx 로그 나 curl - vvv 모드 를 통 해 볼 수 있 습 니 다)
mode = grpcwebtext 를 사용 할 때 표시 되 는 메시지 크기 문제 (단, 크게 평가 하 더 라 도 안 됩 니 다. 이 값 은 1094795585 입 니 다. 약 1094 M 입 니 다. 분명히 grpc 에서 받 은 값 이 잘못 되 었 습 니 다. nginx 쪽 에서 어떤 설정 이나 확장 을 해 야 할 지 추측 하고 grpc - web - text 형식 데 이 터 를 변환 합 니 다) 방안: mode = grpcweb 을 사용 합 니 다.
2. [nginx] upstream rejected request with error 2 while reading response header from upstream
구 글 은 원인 이 무엇 인지 아무 도 말 하지 않 았 지만, 아래 의 요청 머리 를 늘 려 문 제 를 해결 했다.
프로젝트: grpc set header Content - Type application / grpc;
3. grpc - web 현재 서버 error 에 있 을 때 두 번 의 리 셋 함수 가 실 행 됩 니 다. issue 현재 master 에 통합 되 었 습 니 다. 발표 날 짜 는 알 수 없습니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
gRPC 서비스용 RESTful API를 추가하는 데 5분go-zero는 개발자에게 뛰어난 RESTful 및 gRPC 서비스 개발 경험을 제공했지만 더 많은 기대가 생겼습니다. gRPC 및 HTTP 인터페이스를 모두 원합니다 사용자가 말하는 것을 볼 수 있습니다. User...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.