gRPC 첫 시도

9928 단어 showdevgorestgrpc
그래서 지난 몇 달 동안 나는 gRPC에 관한 질문을 여러 번 받았다.나는 간단명료하게 이 글을 읽은 적이 있으며, 만약 필요하다면, 그것으로 옮기는 것은 결코 어렵지 않다고 생각했지만, 지금까지 나는 어떠한 실천 경험도 얻지 못했다.지금 상황이 달라졌어요.

그렇다면 gRPC는 무엇입니까?


g는 구글을 대표한다. 왜냐하면 그들은 이미 2015년에 gRPC를 창립했기 때문이다.RPC 섹션은 원격 프로세스 호출을 나타냅니다.RPC는 새로운 처리 방식이 아닙니다. 단지 다른 기계에서 당신의 기계에서 하나의 과정을 호출할 뿐입니다.그것의 현대적 의미는 논의된 기계가 구름 위의 어느 곳에 있을 수 있다는 데 있다. (예를 들어 GCP)
마찬가지로 gRPC는 HTTP/2를 사용합니다.따라서 HTTP/2는 HTTP/1.1(예: REST에서 기본적으로 사용)에 비해 다음과 같은 주요 이점을 제공합니다.
  • 이것은 2진법이지 텍스트
  • 이 아니다
  • 그것은 완전히 다중 복용한 것이지 순서와 막힌
  • 이 아니다
  • 연결을 사용하여 병행
  • 헤더 압축을 사용하여 비용을 감소합니다
  • 은 서버가 브라우저 캐시에 응답을 적극적으로 추가할 수 있도록 합니다.
  • 그래서 더 통속적인 말로 말하자면 Http2는 2진법이기 때문에 더 빠르다. 이것은 지연이 더 좋다는 것을 의미한다.HTTP/1.1의 정렬화 및 반정렬화 속도는 느립니다.
    그것은 또한 프로토타입을 사용하여 json 대상을 대신하여 통신을 한다.json의 유일한 장점은 더 큰 지역 사회가 있다는 것이다.그래, 내가 제이슨에 대해 잘 알고 있을지도 몰라. 쓰기도 간단하고 초보자에게도 이해하기 쉬워.
    프로토타입 얘기 좀 하자.기본적으로 XML을 고려하지만 더 작고, 더 빠르고, 더 간단하다..proto 파일을 정의하기만 하면 (예를 들어 내 응용 프로그램에서 바로 볼 수 있습니다), 명령 하나만 있으면 전체 파일과 클래스를 생성할 수 있습니다.그러니 아무 걱정 마세요. 도서관에서 해 드릴게요.
    이것이 바로 소개된 내용이다.응용 프로그램으로 넘어갑시다.

    응용 프로그램


    이 프로그램은 결국 매우 간단하다.전방에서 정사각형과 원형을 빨리 누르기만 하면 됩니다.그러나 가장 멋있는 것은 전방에서 명중할 REST 마이크로서비스와 그 아래에 있는 두 개의 gRPC 마이크로서비스를 사용하여 당신의 높은 점수를 추적하고 얻으며 다음에 나타날 대상의 크기를 계산하는 것입니다.
    네가 물체를 명중시키는 속도가 빠를수록 다음 물체는 작아지고 속도가 느릴수록 다음 물체는 커진다.
    앞에서 말한 바와 같이 이 게임은 매우 간단하다.나는 전단이 어떻게 작동하는지 진정으로 토론하지 않을 것이다. 왜냐하면 그것은 단지 index.html 파일이기 때문이다. 그 중에서 가장 어려운 것은 REST 마이크로 서비스의 몇 개ajax 호출이다.
    하지만 첫 번째 gRPC 마이크로서비스에 들어가겠습니다.

    gRPC Highscore 마이크로서비스


    그래서 이 마이크로서비스는 두 가지 일을 했다. 그것이 바로 하이스코어를 얻는 것과 하이스코어를 설정하는 것이다.창의적이지는 않지만 계속합시다.나는 지금까지 이 프로젝트가 로켓 과학이라고 말한 적이 없다😁
  • 1)을 정의합니다.원형 파일
  • 프로필에서 말한 바와 같이 gRPC는protobuf를 사용합니다. 이를 사용하기 위해 우리는 먼저 .proto 파일을 정의합니다.우리는 높은 점수를 얻기 위해 어떤 것도 보낼 필요가 없기 때문에, 단지 그것을 읽을 뿐이다. 이 부분은 어떤 내용도 얻지 않고, 설정된 높은 점수는 점수를 얻고, 그 점수가 현재 저장된 점수보다 더 좋은지 볼 것이다.
    syntax = "proto3";
    
    option go_package = "game";
    
    service Game{
        rpc SetHighScore(SetHighScoreRequest) returns (SetHighScoreResponse);
        rpc GetHighScore(GetHighScoreRequest) returns (GetHighScoreResponse);
    }
    
    message SetHighScoreRequest {
        double high_score = 1;
    }
    
    message SetHighScoreResponse {
        bool set = 1;
    }
    
    message GetHighScoreRequest {}
    
    message GetHighScoreResponse {
        double high_score = 1;
    }
    
    비올라.이렇게 간단해.우리 빨리 토론합시다.syntax 부분은 우리가 사용하고 있는 프로토 버전을 설명했을 뿐, 프로토3는 최신 사용 가능한 버전이기 때문에 우리는 계속할 것이다.option go_package은 단지 내가 만든 .go 파일이 game 패키지에 있다는 것을 의미할 뿐이다.service은 사실상 gRPC의 주요 부분입니다. 두 개의 rpc을 우리가 호출하려고 하는 원격 기기의 과정이나 함수로 상상할 수 있습니다.내가 처음에 말했듯이 JSON을 사용하지 않았기 때문에 우리는 두 개의 메시지 서명을 정의했다. 이것은 우리가 무엇을 보내야 gRPC를 사용할 수 있는지를 나타낸다.여기에는 4가지 메시지 유형이 있습니다. SetHighScoreRequest, SetHighScoreResponse, GetHighScoreRequest, GetHighScoreResponse.내가 유일하게 언급하고자 하는 것은 네가 본 이 재미있는 숫자 1이다.이것은 단지 미래에 우리가 더 많은 필드를 추가하거나 삭제하면, 이 숫자들은 우리가 뒤로 호환성을 저장하는 데 도움을 줄 것이다.

  • 2) 실행 명령은 자동으로 클래스를 생성합니다.
  • 내가 사용하는 것은 바둑이기 때문에 나의 명령은 다음과 같은 두 단계만 필요하다.go install google.golang.org/protobuf/cmd/protoc-gen-go
    화목하다protoc -I ./protobuf-import -I ./ ./v1/*.proto --go_out=plugins=grpc:./
    너는 나의 Makefile에서 그것을 볼 수 있다.나는 Makefile에 대해 깊이 있게 토론하지 않을 것이다. 그것은 매우 간단하다. .sh 스크립트도 매우 간단하다. 그러나 만약 당신이 그것에 대해 흥미를 가지고 경험이 없다면, 나를 클릭하십시오. 나는 그것을 설명할 것이다🙂
  • 3) gRPC 서버 만들기
  • 네, 두 번째 단계에서 이 멋진 highscore.pb.go 파일을 만들었습니다.이제 그것을 사용합시다.
    나는 아래 구조 internal_usage/server/grpc/grpc.go을 만들었다.그것이 내부에서 사용되는 이유는 일단 실현되면 우리는 정말 그것을 걱정해서는 안 되기 때문이다.그것은 시종 유효해서 우리는 코드의 다른 부분을 처리하기 시작할 수 있다.
    하지만 이 grpc.go 파일에 무엇이 있는지 봅시다.
    package grpc
    
    import (
        "context"
        v1highscore "github.com/fvukojevic/grpc_test/m-apis/m-highscore/v1"
        "github.com/pkg/errors"
        "github.com/rs/zerolog/log"
        "google.golang.org/grpc"
        "net"
    )
    
    type Grpc struct {
        address string //address where the gRPC will listen at
        srv     *grpc.Server
    }
    
    func NewServer(address string) *Grpc {
        return &Grpc{
            address: address,
        }
    }
    
    var HighScore = 999999.0
    
    func (g *Grpc) SetHighScore(ctx context.Context, input *v1highscore.SetHighScoreRequest) (*v1highscore.SetHighScoreResponse, error) {
        log.Info().Msg("SetHighscore in m-highscore is called")
    
        HighScore = input.HighScore
        return &v1highscore.SetHighScoreResponse{
            Set: true,
        }, nil
    }
    
    func (g *Grpc) GetHighScore(ctx context.Context, input *v1highscore.GetHighScoreRequest) (*v1highscore.GetHighScoreResponse, error) {
        log.Info().Msg("GetHighscore in m-highscore is called")
    
        return &v1highscore.GetHighScoreResponse{
            HighScore: HighScore,
        }, nil
    }
    
    func (g *Grpc) ListenAndServe() error {
        listener, err := net.Listen("tcp", g.address)
    
        if err != nil {
            return errors.Wrap(err, "Failed to open tcp port")
        }
    
        var serverOpts []grpc.ServerOption
    
        g.srv = grpc.NewServer(serverOpts...)
    
        v1highscore.RegisterGameServer(g.srv, g)
    
        log.Info().Str("Address", g.address).Msg("Starting gRPC server for highscore microservice")
    
        if err := g.srv.Serve(listener); err != nil {
            return errors.Wrap(err, "Failed to start gRPC server")
        }
    
        return nil
    }
    
    보시다시피, 비록 그것은 매우 복잡해 보이지만, 그것이 진정으로 대표하는 것은 무엇입니까?GetHighscore와 SetHighScore 함수는 여기 있습니다. 기억하신다면 .proto 파일에 정의되어 있습니다.gRPC 서버를 수용할 수 있는 구조도 만들었습니다.
    마지막으로, 우리는 이 ListenAndServe 방법을 가지고 있다. 왜냐하면 모든 gRPC는 특정한 주소(포트)를 감청하고 서비스를 받아야 그것을 사용할 수 있기 때문이다.
  • 4) 주
  • 에서 서버 호출
    만약 네가 바둑에 익숙하다면, 너는 모든 입구점이 포메인과main이라는 것을 안다.파일로 이동합니다.여기서 주로가자, 우리 정말 뭘 해야 돼?우리는 서버를 초기화하고 서비스를 제공하기만 하면 된다.main.go
    package main
    
    import (
        "flag"
        grpcSetup "github.com/fvukojevic/grpc_test/m-apis/m-highscore/internal_usage/server/grpc"
        "github.com/rs/zerolog/log"
    )
    
    func main() {
        var addressPtr = flag.String("address", ":50051", "address where you can connect to gRPC m-highscore service")
    
        flag.Parse()
    
        s := grpcSetup.NewServer(*addressPtr)
    
        if err := s.ListenAndServe(); err != nil {
            log.Fatal().Err(err).Msg("Failed to start grpc server")
        }
    }
    
    이렇게

    gRPC 게임 엔진 마이크로서비스


    비록 이 이름은 매우 멋있게 들리지만, 이것은 highscore microservice와 같기 때문에, 나는 너 스스로 코드를 복습하라고 한다.다시 한 번 말하지만, 기본적으로 같다

    REST는 프런트엔드와 백엔드 간 통신에 사용됩니다.


    마지막으로 나는 확실히 REST를 사용했다.왜?javascript에서 gRPC를 직접 호출하는 것은 의미가 없습니다.적어도 나한텐 아니야.그래서 저는 작은 스위치를 만들었습니다. 아주 적은 루트를 제공할 것입니다. 클릭하는 모든 루트는 내부에서 gRPC를 호출하고 필요한 작업을 수행합니다.gin gonic을 사용하여rest를 진행하고 있습니다. 이것은 매우 멋지고 빠른 소프트웨어 패키지로 설정이 상당히 간단합니다.
    하지만 제 REST 마이크로서비스는 gRPC가 영원히 실행되고 있다는 것을 알아야 합니다.따라서 clients.go 파일이 생성되었습니다.
    그래서 우리는 우리의 서버, highscore와 게임 엔진을 가지고 있다.그런데 뭐라고 불러요?그게 고객이야.그것들은 기본적으로 서버의 포트에 연결되어 그것과 통신한다.
    다음은 clients.go 파일의 간단한 모양입니다.
    package domain
    
    import (
        v1gameengine "github.com/fvukojevic/grpc_test/m-apis/m-game-engine/v1"
        v1highscore "github.com/fvukojevic/grpc_test/m-apis/m-highscore/v1"
        "github.com/rs/zerolog/log"
        "google.golang.org/grpc"
    )
    
    func NewGRPCGameServiceClient(serverAddr string) (v1highscore.GameClient, error) {
        conn, err := grpc.Dial(serverAddr, grpc.WithInsecure())
    
        if err != nil {
            log.Fatal().Msgf("Failed to dial: %v", err)
            return nil, err
        }
    
        log.Info().Msgf("Successfully connected to [%s]", serverAddr)
    
        if conn == nil {
            log.Info().Msg("m-highscore connection is nil")
        }
    
        client := v1highscore.NewGameClient(conn)
    
        return client, nil
    }
    
    func NewGRPCGameEngineServiceClient(serverAddr string) (v1gameengine.GameEngineClient, error) {
        conn, err := grpc.Dial(serverAddr, grpc.WithInsecure())
    
        if err != nil {
            log.Fatal().Msgf("Failed to dial: %v", err)
            return nil, err
        }
    
        log.Info().Msgf("Successfully connected to [%s]", serverAddr)
    
        if conn == nil {
            log.Info().Msg("m-game-engine connection is nil")
        }
    
        client := v1gameengine.NewGameEngineClient(conn)
    
        return client, nil
    }
    
    연결만 하면 오류가 있는지 확인해 보세요. (포트나 뭔가를 놓치지 않는 한 정말 안 돼요.) 이렇게.
    이제 엔딩에서 우리는 다음과 같은 코드로 우리의 휴식 노선을 공개한다.
    package main
    
    import (
        "flag"
        grpcSetup "github.com/fvukojevic/grpc_test/m-apis/m-highscore/internal_usage/server/grpc"
        "github.com/rs/zerolog/log"
    )
    
    func main() {
        var addressPtr = flag.String("address", ":50051", "address where you can connect to gRPC m-highscore service")
    
        flag.Parse()
    
        s := grpcSetup.NewServer(*addressPtr)
    
        if err := s.ListenAndServe(); err != nil {
            log.Fatal().Err(err).Msg("Failed to start grpc server")
        }
    }
    

    최종 결과


    마지막으로 최종 결과는 다음과 같다. 단지 간단한 응용 프로그램으로 사용자의 속도를 클릭하고 추적하는 데 쓰일 뿐이다.

    프로젝트 리소스


    Github:https://github.com/fvukojevic/grpc_test
    마이크로서비스가 없어도 이 프로그램은 작동할 수 있지만, 그것들은 여전히 멋있다.
    다시 한 번 말하지만, 나는 이것이 매우 어려울 수 있다는 것을 알고 있기 때문에, 만약 당신에게 어떤 문제가 있다면, 언제든지 이메일과/또는linkedIn을 통해 저에게 연락하십시오. 만약 당신이 gRPC에 대한 더 많은 정보를 알고 싶다면, 우리는 채팅을 할 수 있습니다!
    내 LinkedIn 프로필:
    다음까지!🚀🚀

    좋은 웹페이지 즐겨찾기