首页 > 其他分享 >Spring Boot 集成 GRPC

Spring Boot 集成 GRPC

时间:2023-04-01 23:31:55浏览次数:42  
标签:SpringBoot GRPC Spring Boot HelloWorld class grpc Grpc public

技术:SpringBoot 2.0.5.RELEASE + Grpc 1.15.0    运行环境:JDK 1.8 

概述:SpringBoot框架中集成Grpc服务

详细

一.背景

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。

Grpc 由 google 开发,是一款语言中立、平台中立、开源的远程过程调用(RPC)系统。

项目定位是电商平台和WMS系统中间的插件服务,wms采用.net语言开发,电商平台采用java开发,所以出现了多语言间的数据交换,开始考虑使用json协议,方便快捷,但是考虑到效率和系统发展的问题,考虑使用RPC框架,斟酌之后敲定为GRPC。

但是,我们拓展服务使用的SpringBoot,Grpc和SpringBoot集成的文章不是很多,大部分都是采用github上*-springboot.grpc.starter的项目,看了一下,并不是很感兴趣,所以自己根据官网的demo,尝试与SpringBoot集成,所以在这和大家分享下

二. 准备工作

开发环境

Spring Boot 2.0.5.RELEASE
Grpc 1.15.0
Inteliji Idea 2018.3

项目截图

Spring Boot 集成 GRPC_Grpc

三.实现过程

1. 配置SpringBoot项目
  • Pom文件增加
<parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.0.5.RELEASE</version>
  </parent>

  <dependencies>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-test</artifactId>
      </dependency>
  </dependencies>
  • 编写启动类
public static void main(String[] args) {
       // 启动SpringBoot web
      SpringApplication.run(Launcher.class, args);
}
2. 增加GRPC支持和GRPC代码生成工具,集成GrpcServer端
  • 增加POM文件
<dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty-shaded</artifactId>
            <version>1.15.0</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
            <version>1.15.0</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
            <version>1.15.0</version>
        </dependency>
  • 增加maven工具
<build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.5.0.Final</version>
            </extension>
        </extensions>
        <plugins>
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.5.1</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:3.5.1-1:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.15.0:exe:${os.detected.classifier}</pluginArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
  • 编写Server端实现类
public class HelloWorldService extends HelloWorldServiceGrpc.HelloWorldServiceImplBase {

    @Override
    public void welcome(HelloWorld.NameRequest request, StreamObserver<HelloWorld.EchoResponse> responseObserver) {
        HelloWorld.EchoResponseOrBuilder echoResponseOrBuilder = HelloWorld.EchoResponse.newBuilder();
        ((HelloWorld.EchoResponse.Builder) echoResponseOrBuilder).setMergename("welcome " + request.getName());
        responseObserver.onNext(((HelloWorld.EchoResponse.Builder) echoResponseOrBuilder).build());
        responseObserver.onCompleted();
    }
}
  • 增加Grpc启动器
@Component("grpcLauncher")
public class GrpcLauncher {

    private Logger logger = LoggerFactory.getLogger(Launcher.class);


    /**
     * 定义Grpc Server
     */
    private Server server;


    @Value("${grpc.server.port}")
    private Integer grpcServerPort;
    /**
     * GRPC 服务启动方法
     * @param grpcServiceBeanMap
     */
    public void grpcStart(Map<String, Object> grpcServiceBeanMap) {
        try{
            SelfSignedCertificate ssc = new SelfSignedCertificate();
            ServerBuilder serverBuilder = ServerBuilder.forPort(grpcServerPort).useTransportSecurity(ssc.certificate(), ssc.privateKey());
            for (Object bean : grpcServiceBeanMap.values()){
                serverBuilder.addService((BindableService) bean);
                logger.info(bean.getClass().getSimpleName() + " is regist in Spring Boot");
            }
            server = serverBuilder.build().start();
            logger.info("grpc server is started at " +  grpcServerPort);
            server.awaitTermination();
            Runtime.getRuntime().addShutdownHook(new Thread(()->{grpcStop();}));
        } catch (IOException e){
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * GRPC 服务Stop方法
     */
    private void grpcStop(){
        if (server != null){
            server.shutdownNow();
        }
    }
}
  • 添加自定义注解用于扫描Grpc服务
/**
 * 自定义注解,用于获取Spring扫描到的类
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface GrpcService {
}
  • 在SpringBoot中增加Grpc启动器,并将Spring管理的类,添加到Grpc服务中
/**
 * Spring Boot 启动器
 */
@SpringBootApplication
public class Launcher {

    public static void main(String[] args) {
        // 启动SpringBoot web
        ConfigurableApplicationContext configurableApplicationContext = SpringApplication.run(Launcher.class, args);
        Map<String, Object> grpcServiceBeanMap =  configurableApplicationContext.getBeansWithAnnotation(GrpcService.class);
        GrpcLauncher grpcLauncher = configurableApplicationContext.getBean("grpcLauncher",GrpcLauncher.class);
        grpcLauncher.grpcStart(grpcServiceBeanMap);
    }
}

至此Server端,集成完毕

Spring Boot 集成 GRPC_spring_02

3. 增加Client端
  • 获取Chanel
@Component
public class GrpcClientMananer {
    @Value("${grpc.client.host}")
    private String host;
    @Value("${grpc.client.port}")
    private Integer port;

    public ManagedChannel getChannel(){
        NettyChannelBuilder ncb = NettyChannelBuilder.forAddress(host, port).sslContext(SslContextBuilder.forClient()
                        .sslProvider(OpenSsl.isAlpnSupported() ? SslProvider.OPENSSL : SslProvider.JDK)
                        .ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE)
                        .trustManager(InsecureTrustManagerFactory.INSTANCE)
                        .applicationProtocolConfig(
                                new ApplicationProtocolConfig(
                                        ApplicationProtocolConfig.Protocol.ALPN,
                                        ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE,
                                        ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT,
                                        ApplicationProtocolNames.HTTP_2,
                                        ApplicationProtocolNames.HTTP_1_1))
                        .build());
        return ncb.build();                
    }
}
  • 调用方式
@Component
public class HelloWorldClient {

    @Autowired
    private GrpcClientMananer grpcClientMananer;

    public void call(){
        ManagedChannel channel = grpcClientMananer.getChannel();
        HelloWorld.NameRequestOrBuilder nameRequestOrBuilder = HelloWorld.NameRequest.newBuilder();
        ((HelloWorld.NameRequest.Builder) nameRequestOrBuilder).setName("Geek");
        HelloWorldServiceGrpc.HelloWorldServiceBlockingStub stub = HelloWorldServiceGrpc.newBlockingStub(channel);
        HelloWorld.EchoResponse echoResponse = stub.welcome(((HelloWorld.NameRequest.Builder) nameRequestOrBuilder).build());
        System.out.println(echoResponse.getMergename());
    }

}

`

标签:SpringBoot,GRPC,Spring,Boot,HelloWorld,class,grpc,Grpc,public
From: https://blog.51cto.com/u_10956218/6164087

相关文章

  • 【SpringBoot】关闭SpringBoot启动图标(banner)
    SpringBoot启动的时候会有如下图标如果想去掉此图标在配置文件添加一下内容配置文件:application.yml添加内容:spring:main:banner-mode:off#关闭SpringBoot启动图标(banner) ......
  • 常用注解-SpringBoot请求
    SpringBoot请求常用注解及作用范围:@Controller:【类】需要返回一个视图(themleaf),加注解4@ResponseBody等于注解2@RestController:【类】返回字符串等,与注解1都属于控制器,@RequestMapping:【方法/类】设置方法或者类的请求地址,@ResponseBody:【方法】支持将返回值放在response......
  • Spring 项目运行提示错误 Not a managed type
    在启动Spring项目的时候提示下面的错误信息。  问题和原因这个问题的原因是你的类没有在Spring管理的容器中注册。主要原因是上面的包的路径不正确。  修改上面的包的路径后重启服务就可以解决启动的时候对象没有注册的问题。 https://www.ossez.com/t/sprin......
  • SpringBoot进阶教程(七十五)数据脱敏
    无论对于什么业务来说,用户数据信息的安全性无疑都是非常重要的。尤其是在数字经济大火背景下,数据的安全性就显得更加重要。数据脱敏可以分为两个部分,一个是DB层面,防止DB数据泄露,暴露用户信息;一个是接口层面,有些UI展示需要数据脱敏,防止用户信息被人刷走了。v需求背景DB层面的......
  • 什么是 Spring Batch?
    SpringBootBatch提供可重用的函数,这些函数在处理大量记录时非常重要,包括日志/跟踪,事务管理,作业处理统计信息,作业重新启动,跳过和资源管理。它还提供了更先进的技术服务和功能,通过优化和分区技术,可以实现极高批量和高性能批处理作业。简单以及复杂的大批量批处理作业可以高度可扩......
  • Spring MVC是什么
    SpringMVC是Spring提供的一个基于MVC设计模式的轻量级Web开发框架,本质上相当于Servlet。SpringMVC是结构最清晰的Servlet+JSP+JavaBean的实现,是一个典型的教科书式的MVC构架,不像Struts等其它框架都是变种或者不是完全基于MVC系统的框架。SpringMVC角色划分清......
  • Spring MVC是什么
    SpringMVC是Spring提供的一个基于MVC设计模式的轻量级Web开发框架,本质上相当于Servlet。SpringMVC是结构最清晰的Servlet+JSP+JavaBean的实现,是一个典型的教科书式的MVC构架,不像Struts等其它框架都是变种或者不是完全基于MVC系统的框架。SpringMVC角色划分清......
  • 谈谈Spring中都用到了哪些设计模式?
    ​ 控制反转(IOC)和依赖注入(DI)IoC(InversionofControl,控制翻转) 是Spring中一个非常非常重要的概念,它不是什么技术,而是一种解耦的设计思想。它的主要目的是借助于“第三方”(即Spring中的IOC容器)实现具有依赖关系的对象之间的解耦(IOC容易管理对象,你只管使用即可),从而......
  • 谈谈Spring中都用到了哪些设计模式?
    ​ 控制反转(IOC)和依赖注入(DI)IoC(InversionofControl,控制翻转) 是Spring中一个非常非常重要的概念,它不是什么技术,而是一种解耦的设计思想。它的主要目的是借助于“第三方”(即Spring中的IOC容器)实现具有依赖关系的对象之间的解耦(IOC容易管理对象,你只管使用即可),从而......
  • java 中required_通过实例学习Spring @Required注释原理
    @Required注释应用于bean属性的setter方法,它表明受影响的bean属性在配置时必须放在XML配置文件中,否则容器就会抛出一个BeanInitializationException异常。下面显示的是一个使用@Required注释的示例。示例:让我们使EclipseIDE处于工作状态,请按照下列步骤创建一个......