Spring Boot 集成 GRPC
Spring Boot 集成 GRPC
http://www.demodashi.com/demo/14110.html
概述
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
项目截图

三.实现过程
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>
- 编写启动类
publicstaticvoid main(String[] args){// 启动SpringBoot webSpringApplication.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端实现类
publicclassHelloWorldServiceextendsHelloWorldServiceGrpc.HelloWorldServiceImplBase{@Overridepublicvoid 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")publicclassGrpcLauncher{privateLogger logger =LoggerFactory.getLogger(Launcher.class);/*** 定义Grpc Server*/privateServer server;@Value("${grpc.server.port}")privateInteger grpcServerPort;/*** GRPC 服务启动方法* @param grpcServiceBeanMap*/publicvoid grpcStart(Map<String,Object> grpcServiceBeanMap){try{SelfSignedCertificate ssc =newSelfSignedCertificate();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(newThread(()->{grpcStop();}));}catch(IOException e){e.printStackTrace();}catch(InterruptedException e){e.printStackTrace();}}/*** GRPC 服务Stop方法*/privatevoid grpcStop(){if(server !=null){server.shutdownNow();}}}
- 添加自定义注解用于扫描Grpc服务
/*** 自定义注解,用于获取Spring扫描到的类*/@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic@interfaceGrpcService{}
- 在SpringBoot中增加Grpc启动器,并将Spring管理的类,添加到Grpc服务中
/*** Spring Boot 启动器*/@SpringBootApplicationpublicclassLauncher{publicstaticvoid main(String[] args){// 启动SpringBoot webConfigurableApplicationContext 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端,集成完毕

3. 增加Client端
- 获取Chanel
@ComponentpublicclassGrpcClientMananer{@Value("${grpc.client.host}")privateString host;@Value("${grpc.client.port}")privateInteger port;publicManagedChannel 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(newApplicationProtocolConfig(ApplicationProtocolConfig.Protocol.ALPN,ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE,ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT,ApplicationProtocolNames.HTTP_2,ApplicationProtocolNames.HTTP_1_1)).build());return ncb.build();}}
- 调用方式
@ComponentpublicclassHelloWorldClient{@AutowiredprivateGrpcClientMananer grpcClientMananer;publicvoid 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());}}`
四.其他补充
暂没

浙公网安备 33010602011771号