GRPC 학습 의 길 (3) - protobuf 의 역할

6714 단어 rpc
지난 글 은 nginx 가 부하 균형 과 백 엔 드 grpc 의 통합 으로 계속 깊이 들 어가 지 않 았 다 는 것 을 소개 했다. 이 는 온라인 에서 진정 으로 실천 해 야 더 많은 깨 달 음 을 얻 을 수 있 기 때문에 입사 후에 경험 이 있 으 면 계속 쓰 자.
마침 저도 protobuf 가 도대체 grpc 와 어떤 관계 인지 궁금 합 니 다. protobuf 가 전체 rpc 과정 에서 어떤 역할 을 하 는 지 궁금 합 니 다. 그래서 제 다음 글 은 protobuf 에 관 한 것 입 니 다.
나 는 인터넷 에서 몇 개의 인터넷 자 료 를 찾 아 선인 들 의 연구 성 과 를 보 았 다.
proto 3 홈 페이지 홈 페이지 추천 글
Google Protocol Buffer 의 사용 과 원리 이 글 은 좀 낡 아서 proto 3 를 소개 하 는 것 이 아니 지만 작 가 는 매우 깊이 연구 했다.
proto 3 언어 가이드 이것 은 약간 홈 페이지 영어 의 번역 과 작가 자신의 총 결 과 같 기도 하고 아주 좋 습 니 다.
ProtoBuf 가 뭐야?
다른 사람의 설명 을 발췌 합 니 다. Protocol Buffers 는 가 볍 고 효율 적 인 구조 화 된 데이터 저장 형식 으로 구조 화 된 데이터 직렬 화 또는 직렬 화 에 사용 할 수 있 습 니 다.그것 은 데이터 저장 이나 RPC 데이터 교환 형식 으로 적합 하 다.통신 프로 토 콜, 데이터 저장 등 분야 의 언어 와 무관 하고 플랫폼 과 무관 하 며 확장 가능 한 직렬 화 구조 데이터 형식 에 사용 할 수 있 습 니 다.이 묘 사 를 보면 첫 번 째 느낌 은 구름 과 안개 속 에 있다. 연구 한 후에 protobuf 의 다음 과 같은 몇 가 지 를 요약 한다.
  • grpc 는 rpc 의 하나 로 서 서비스 간 의 네트워크 호출 이 있 을 것 입 니 다. 호출 하면 반드시 데이터 의 전송 이 있 을 것 입 니 다. 이 데이터 의 전송 은 protobuf 로 직렬 화 되 고 반 직렬 화 된 것 입 니 다. 요청 한 내용 이 호출 자 직렬 화 되 어 네트워크 를 통 해 서비스 측 에 전송 되면 서비스 측은 protobuf 로 반 직렬 화 될 수 있 습 니 다. 뒤의 글 은 세부 사항 을 설명 할 것 입 니 다.
  • protobuf 는 thrift 와 유사 한 IDL (인터페이스 설명 언어) 이 있 습 니 다. 즉, 대상 이 어떤 필드 를 포함 하 는 지, 서비스 가 어떤 인 터 페 이 스 를 포함 하 는 지 설명 하 는 것 입 니 다. 간단 한 것 은 다음 과 같 습 니 다.
  • message Person { string name = 1; int32 id = 2; string email = 3; }
  • protobuf 는 전문 적 인 도구 로 대상 코드 를 생 성 할 수 있 습 니 다. 이 코드 를 사용 하면 대상 을 파일 이나 흐름 에 서열 화 할 수 있 습 니 다. 물론 반 서열 화 대상 이 될 수도 있 습 니 다. 뒤의 예 는 구체 적 으로 소개 할 것 입 니 다.
  • protobuf 는 다양한 언어 를 지원 합 니 다. 흔히 볼 수 있 는 것 은 go, c +, 자바, phop 등 입 니 다. 구체 적 으로 홈 페이지
  • 를 참고 할 수 있 습 니 다.
    ProtoBuf 를 어떻게 사용 합 니까?
    준비 작업
    앞에서 grpc 사용 절 차 를 소개 한 것 과 마찬가지 로 지금. proto 파일 을 준비 합 니 다.
    syntax = "proto3";
    
    package tutorial;
    
    option java_package = "com.example.tutorial";
    option java_outer_classname = "AddressBookProtos";
    
    message Person {
      string name = 1;
      int32 id = 2;
      string email = 3;
    
      enum PhoneType {
        MOBILE = 0;
        HOME = 1;
        WORK = 2;
      }
    
      message PhoneNumber {
        string number = 1;
        PhoneType type = 2;
      }
    
      repeated PhoneNumber phones = 4;
    }
    
    message AddressBook {
      repeated Person people = 1;
    }

    앞에서 소개 한 maven plugin 을 사용 하여 코드 를 생 성 합 니 다.
    복사 코드
    생 성 된 코드 Address Bookprotos. java 를 새 프로젝트 에 복사 합 니 다. 다음 과 같은 구조 입 니 다.
    서열 화 대상
    홈 페이지 설명 을 참고 하여 Write Object. java 를 새로 만 듭 니 다. 코드 는 다음 과 같 습 니 다. Person 대상 을 점차적으로 구성 하고 파일 을 기록 합 니 다. 시작 매개 변수 에 파일 을 추가 하 는 경 로 를 기억 하 십시오.
    static Person PromptForAddress(BufferedReader stdin,
        PrintStream stdout) throws IOException {
        Person.Builder person = Person.newBuilder();
    
        stdout.print("Enter person ID: ");
        person.setId(Integer.valueOf(stdin.readLine()));
    
        stdout.print("Enter name: ");
        person.setName(stdin.readLine());
    
        stdout.print("Enter email address (blank for none): ");
        String email = stdin.readLine();
        if (email.length() > 0) {
            person.setEmail(email);
        }
    
        while (true) {
            stdout.print("Enter a phone number (or leave blank to finish): ");
            String number = stdin.readLine();
            if (number.length() == 0) {
                break;
            }
    
            Person.PhoneNumber.Builder phoneNumber =
                Person.PhoneNumber.newBuilder().setNumber(number);
    
            stdout.print("Is this a mobile, home, or work phone? ");
            String type = stdin.readLine();
            if (type.equals("mobile")) {
                phoneNumber.setType(Person.PhoneType.MOBILE);
            } else if (type.equals("home")) {
                phoneNumber.setType(Person.PhoneType.HOME);
            } else if (type.equals("work")) {
                phoneNumber.setType(Person.PhoneType.WORK);
            } else {
                stdout.println("Unknown phone type.  Using default.");
            }
    
            person.addPhones(phoneNumber);
        }
    
        return person.build();
    }
    
    public static void main(String[] args) throws IOException {
        if (args.length != 1) {
            System.err.println("Usage:  AddPerson ADDRESS_BOOK_FILE");
            System.exit(-1);
        }
    
        AddressBook.Builder addressBook = AddressBook.newBuilder();
    
        // Read the existing address book.
        try {
            addressBook.mergeFrom(CodedInputStream.newInstance(new FileInputStream(args[0])));
        } catch (FileNotFoundException e) {
            System.out.println(args[0] + ": File not found.  Creating a new file.");
        }
    
        // Add an address.
        addressBook.addPeople(
            PromptForAddress(new BufferedReader(new InputStreamReader(System.in)),
                System.out));
    
        // Write the new address book back to disk.
        FileOutputStream output = new FileOutputStream(args[0]);
        addressBook.build().writeTo(output);
        output.close();
    }

    실행 후 sublime 으로 작성 한 파일 을 열 면 다음 과 같 습 니 다. 왜 그런 지 구체 적 으로 연구 하 겠 습 니 다. 지금 알 고 싶 은 것 은 이러한 직렬 화 방식 이 일반 xml 와 json 보다 공간 을 절약 할 것 입 니 다.
    역 직렬 화 대상
    홈 페이지 의 새로운 ReadObject. java 를 참고 하 십시오. 코드 는 다음 과 같 습 니 다. 같은 파일 을 읽 고 역 직렬 화 되면 해당 하 는 필드 값 을 추출 할 수 있 습 니 다.
    static void Print(AddressBook addressBook) {
        for (Person person: addressBook.getPeopleList()) {
            System.out.println("Person ID: " + person.getId());
            System.out.println("  Name: " + person.getName());
    
            for (Person.PhoneNumber phoneNumber : person.getPhonesList()) {
                switch (phoneNumber.getType()) {
                    case MOBILE:
                        System.out.print("  Mobile phone #: ");
                        break;
                    case HOME:
                        System.out.print("  Home phone #: ");
                        break;
                    case WORK:
                        System.out.print("  Work phone #: ");
                        break;
                }
                System.out.println(phoneNumber.getNumber());
            }
        }
    }
    
    public static void main(String[] args) throws IOException {
        if (args.length != 1) {
            System.err.println("Usage:  ListPeople ADDRESS_BOOK_FILE");
            System.exit(-1);
        }
    
        // Read the existing address book.
        AddressBook addressBook =
            AddressBook.parseFrom(new FileInputStream(args[0]));
    
        Print(addressBook);
    }

    실행 결 과 는 다음 과 같 습 니 다.
    Person ID: 1 Name: zack
    총결산
    이로써 protobuf 와 grpc 에서 의 역할 을 어떻게 단독으로 사용 하 는 지 알 게 되 었 습 니 다. 그 다음 에 저 는 protobuf 3 의 문법 디 테 일과 직렬 화 디 테 일 을 계속 연구 하 겠 습 니 다.
    글 에서 언급 한 프로젝트 파일 을 첨부 합 니 다:
    Proto3Tutorial
    저의 개인 블 로그 www. zhijianliu. cn 에 관심 을 가 져 주 셔 서 감사합니다.
    저작권 성명: 본 고 는 지 건 의 오리지널 글 에서 나 온 것 으로 블 로 거들 의 허락 없 이 전재 할 수 없다.

    좋은 웹페이지 즐겨찾기