likes
comments
collection
share

Springboot集成Brpc

作者站长头像
站长
· 阅读数 43

本文代码可在总结处自取。

1、为什么要写这篇文章

最近自己做的业务在和C++团队对接,双方需要指定接口与传输协议。原本是直接使用http协议传输json数据,对双方来说都比较简单可接受。但是json数据传输效率实在令人堪忧,导致我们不得不另寻其道。因此,商量过后决定使用Brpc协议传输protobuf数据。

这对对方来说轻而易举,分分钟就搞定了。咱们搞Java的如果是第一次接触的话,还是需要一些时间调研的。

最开始想的是能有一篇手把手搭建Springboot集成Brpc的文章,但是浏览了一堆就没一个靠谱的`( >﹏< )′。于是自己只能不断查阅github兄弟上的wiki、遇到问题找StackOverflow大哥,最终才成功搭建起来基于Brpc协议的C++客户端与Java服务端。

想着自己踩坑不少,有必要记录一下整个搭建过程,不仅方便日后自己查阅,也能帮助兄弟们少走弯路。

2、Java服务端搭建

由于现在Java已经差不多和Spring/SpringBoot划上等号了(bushi),因此本小节仅介绍SpringBoot集成Brpc的工程搭建。

Baidu已经为我们开源了brpc-java的项目,chrome上输入关键词brpc java,第一个搜索词条便是baidu/starlight(感谢Google)。

Springboot集成Brpc

想要搭建一个点对点对接的工程,我们可以直接看这个仓库->wiki->快速开始->2. SpringBoot场景(类似Spring MVC)这个锚点的内容。

2.1、Springboot工程搭建

这个相信大家都轻车熟路了,我就不再费太多口舌了。不过要注意的是,springboot的版本要在2.x,我们原先的工程就是1.x的Springboot,导致容器每次都启动失败。具体原因当时没有深入研究,后续有机会再给补上(主要原因还是打工人想早点干完活🤣)。

2.2、添加starlight依赖

截止写这篇文章的时候,mvnrepository仅有下面一个版本的仓库,所以可以不用去找了,就用下面的吧。

<dependency>
    <groupId>com.baidu.cloud</groupId>
    <artifactId>spring-cloud-starter-baidu-starlight</artifactId>
    <version>2022.2.0</version>
</dependency>

记得还要添加一个httpclient依赖,这里就添加apache httpclient了。

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.3</version>
</dependency>

2.3、工程代码

因为是搭建启动demo,代码量非常少,这里就一起说完了。

整个工程的组织结构如下所示:

  • Application:Springboot启动类,没啥好说的
  • domain包:这个包下的类主要是brpc服务的请求和响应,设计这些请求和响应是为了C++侧更好的设计proto数据。
  • service包:暴露出去的服务接口和服务实现。
  • application.yaml:starlight配置

Springboot集成Brpc

domain包下的类:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class EchoRequest {
    private String message;
}

@Data
@NoArgsConstructor
@AllArgsConstructor
public class EchoResponse {
    private String message;
}

service包下的类:

public interface EchoService {
    EchoResponse echo(EchoRequest request);
}

// @RpcService注解指定了该service以brpc协议暴露出去,starlight支持一个接口同时暴露brpc和http协议,具体可以参考wiki
@RpcService
public class EchoServiceImpl implements EchoService {
    @Override
    public EchoResponse echo(EchoRequest request) {
        System.out.println(request.getMessage());
        return new EchoResponse("Success");
    }
}

Application类:

@SpringBootApplication
@StarlightScan // 扫描@RpcService注解暴露的服务
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

application.yaml:brpc服务将被暴露再8777端口

starlight:
  server:
    enable: true
    port: 8777

启动Application,如果没有问题就表示Java服务端已经搭建完成了。

3、C++客户端搭建

其实这一小节没有太大必要,我们搭建好了服务后直接让C++侧的同学对接你的服务进行测试就行了。

但想着为了搭建一个可靠的服务,咱们可以现在本地搭建一个C++ brpc client进行测试下,确保咱们的服务端没问题后再和C++客户端侧对接,这样不显得你更加靠谱么。

3.1、安装、编译brpc

在安装brpc之前需要安装依赖的环境:

  • 安装git、g++、make、libssl-dev。(还是喜欢一个一个安装,在安装失败的时候就不用到处找日志了)
sudo apt-get install git 
sudo apt-get install g++ 
sudo apt-get install make 
sudo apt-get install libssl-dev
  • 安装gflags、protobuf、leveldb
sudo apt-get install realpath 
sudo apt-get install libgflags-dev 
sudo apt-get install libprotobuf-dev 
sudo apt-get install libprotoc-dev 
sudo apt-get install protobuf-compiler 
sudo apt-get install libleveldb-dev
  • 下载brpc源码
git clone https://github.com/brpc/brpc.git
  • 使用config_brpc.sh编译brpc
cd brpc
sh config_brpc.sh --headers=/usr/include --libs=/usr/lib
make
  • 测试是否编译成功
cd example/echo_c++
make
./echo_server & ./echo_client
  • 访问localhost:8080,如果能够出现如下页面,说明使用已经没问题了。

Springboot集成Brpc

3.2、与Java服务端联调测试

为了简单起见,我们直接使用EchoClient进行测试。

首先我们需要修改echo.proto文件,我们需要把C++客户端的数据协议与Java服务端对齐,修改后的文件如下所示,主要有两点修改:

  • package,包改成了EchoService所在包名路径
  • EchoService.echo,方法首字母改成小写,与Java端对齐。当然也可以改成大写,让Java端与C++端对齐。
syntax="proto2";
package org.chubxu.brpc.service;

option cc_generic_services = true;

message EchoRequest {
      required string message = 1;
};

message EchoResponse {
      required string message = 1;
};

service EchoService {
      rpc echo(EchoRequest) returns (EchoResponse);
};

改完后需要重新编译proto文件。

protoc --cpp_out=./ echo.proto

因为proto文件改变,客户端源码也必须做出相应改变,有以下几点需要改变

  • EchoService_Stub的名称空间
  • EchoRequestEchoResponse的名称空间
  • stub的方法名

其实改变的地方就是对应proto文件改变的地方。

org::chubxu::brpc::service::EchoService_Stub stub(&channel);
org::chubxu::brpc::service::EchoRequest request;
org::chubxu::brpc::service::EchoResponse response;
stub.echo(&cntl, &request, &response, NULL);

改完后重新编译一下。

make

之后就可以发起请求了,观察client.cpp源码,可知客户端使用gflag接收了几个命令行参数,其中就有server参数指定brpc服务端的ip和port,因此我们执行下面的命令就可以成功发起请求了。

./echo_client --server=host:8777

服务端日志

Springboot集成Brpc

客户端日志

Springboot集成Brpc

4、总结

到这里,整个搭建和联调过程就结束了,还算是比较详细吧。其中对接的数据只是非常简单的message,且只有一个。如果是复杂数据的话,proto文件和Java bean需要设计的非常规范,否则非常容易出现protostuff反序列化异常问题。这个有机会就下次再说啦。

ps:本文全部代码在 👉 springboot04-brpc,有需要的可以自取哈。

转载自:https://juejin.cn/post/7177191380194689080
评论
请登录