前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Protobuf介绍和整合SpringBoot

Protobuf介绍和整合SpringBoot

作者头像
阿泽
发布2019-09-11 20:10:21
8.1K0
发布2019-09-11 20:10:21
举报

•概要

1.服务之间的调用,协议部分,我们统一采用二进制协议protobuf over HTTP,协议版本统一采用protobuf3,接口定义语言教材:

代码语言:javascript
复制
https://developers.google.cn/protocol-buffers/docs/proto3

2、Protobuf即Protocol Buffers,是Google公司开发的一种跨语言和平台的序列化数据结构的方式,是一个灵活的、高效的用于序列化数据的协议。

与XML和JSON格式相比,protobuf更小、更快、更便捷。protobuf是跨语言的,并且自带一个编译器(protoc),只需要用protoc进行编译,就可以编译成Java、Python、C++、C#、Go等多种语言代码,然后可以直接使用,不需要再写其它代码,自带有解析的代码。只需要将要被序列化的结构化数据定义一次(在.proto文件定义),便可以使用特别生成的源代码(使用protobuf提供的生成工具)轻松的使用不同的数据流完成对结构数据的读写操作。甚至可以更新.proto文件中对数据结构的定义而不会破坏依赖旧格式编译出来的程序。

3、GitHub地址:

代码语言:javascript
复制
https://github.com/protocolbuffers/protobuf

4、不同语言源码版本下载地址:

代码语言:javascript
复制
https://github.com/protocolbuffers/protobuf/releases/latest

•协议优点

1、性能好,效率高,序列化后字节占用空间比XML少3-10倍,序列化的时间效率比XML快20-100倍。

2、有代码自动生成机制,将对结构化数据的操作封装成一个类,便于使用,服务开发人员和服务使用人员只需要使用统一的IDL作为统一的接口定义标准,避免漏字段,误用字段。

3、.支持向后和向前兼容,当客户端和服务器同时使用一块协议的时候, 当客户端在协议中增加一个字节,并不会影响客户端的使用。

4、该协议的代码自动生成,已经支持的语言有:Java,C++,Python、Go、Ruby等。

•IDL接口定义语言

1、统一采用protobuf3,教材地址:

代码语言:javascript
复制
https://developers.google.cn/protocol-buffers/docs/proto3

2、接口版本维护,我们将编写好的IDL文件,维护到git上,服务生产者和消费者共享同一份协议文件。请将各个服务的IDL文件GIT地址维护到这里:中台服务接口定义规范

3、安装protobuf

在这里下载编译好的版本:

代码语言:javascript
复制
https://github.com/protocolbuffers/protobuf/releases/latest

将protoc二进制文件加入到PATH环境变量,便于使用。

•构建工程

•工程案例

1、构建项目

2、与SpringBoot集成

a.定义IDL文件

代码语言:javascript
复制
syntax = "proto3";
package com.hs.user.base.proto;
message UserInfoRequest {
    int64 userId = 1;
}
message UserInfoResponse {
    int32 userType = 1;
    string mobile = 2;
}

b.使用protobuf工具生成sdk

代码语言:javascript
复制
protoc --java_out=src/main/java src/main/resources/*.proto

c.服务提供方需要增加protobuf库的引用,以gradle为例子

代码语言:javascript
复制
compile('com.google.protobuf:protobuf-java:3.6.1')
compile('com.googlecode.protobuf-java-format:protobuf-java-format:1.4')

d.服务提供方需要提供协议自动转换器,代码如下,直接使用即可:

代码语言:javascript
复制
package com.hs.user.base.util;
import java.util.Collections;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
@Configuration
public class UserBaseServiceProtoConvertor {
   @Bean
    public ProtobufHttpMessageConverter protobufHttpMessageConverter() {
        return new ProtobufHttpMessageConverter();
    }
    @Bean
    public RestTemplate restTemplate(ProtobufHttpMessageConverter protobufHttpMessageConverter) {
        return new RestTemplate(Collections.singletonList(protobufHttpMessageConverter));
    }
}

e.在服务提供方的Controller层,进行RequestMapping,代码如下,请注意@RequestMapping注解的使用,尤其是produces:

代码语言:javascript
复制
package com.hs.user.base.controller;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.hs.user.base.entity.UserInfoEntity;
import com.hs.user.base.proto.UserBaseServiceProto.UserInfoRequest;
import com.hs.user.base.proto.UserBaseServiceProto.UserInfoResponse;
import com.hs.user.base.proto.UserBaseServiceProto.UserInfoResponse.Builder;
import com.hs.user.base.service.UserInfoService;

@Controller
public class UserInfoServiceController {
  private static Logger logger = LoggerFactory.getLogger(UserInfoServiceController.class);  
  @Autowired
  private UserInfoService userInfoService;
  
  @RequestMapping(value="/getUserInfo" , method=RequestMethod.POST , produces = "application/x-protobuf")
  public @ResponseBody UserInfoResponse getUserInfo(@RequestBody UserInfoRequest request) throws Exception {
    logger.info("请求:{}" , request.toString());
    
    UserInfoEntity user = userInfoService.getUserInfo(request.getUserId());
    
    Builder builder = UserInfoResponse.newBuilder();
    if (user != null) {
      builder.setMobile(user.getMobile());
      builder.setUserType(user.getUserType());
    }   
    return builder.build();
  }
}

f.服务调用方代码示例:

代码语言:javascript
复制
package com.hs.user.base.test;


import java.io.IOException;
import java.net.URI;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import com.hs.user.base.proto.UserBaseServiceProto.UserInfoRequest;
import com.hs.user.base.proto.UserBaseServiceProto.UserInfoResponse;

public class UserBaseServiceTest {
  public static void main(String [] args) throws IOException {
    CloseableHttpClient httpClient = HttpClients.createDefault();
    try {
      URI uri = new URI("http", null, "127.0.0.1", 8080, "/getUserInfo", "", null);
      HttpPost post = new HttpPost(uri);
      UserInfoRequest.Builder builder = UserInfoRequest.newBuilder();
      builder.setUserId(178624L);     
            post.setEntity(new ByteArrayEntity(builder.build().toByteArray()));
            post.setHeader("Content-Type", "application/x-protobuf");
            
      HttpResponse response = httpClient.execute(post);
      
      if (response.getStatusLine().getStatusCode() == 200) {

        UserInfoResponse resp = UserInfoResponse.parseFrom(response.getEntity().getContent());
        
        System.out.println("result:" + resp.getMobile() + " " + resp.getUserType());
      } else {
        System.out.println(response.getStatusLine().getStatusCode());
      }
    } catch (Exception e) {
      System.out.println(e);
    } finally {
      httpClient.close();
    }    
  }
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Flink实战应用指南 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档