一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - SpringBoot集成gRPC微服務(wù)工程搭建實(shí)踐的方法

SpringBoot集成gRPC微服務(wù)工程搭建實(shí)踐的方法

2021-07-10 14:37驚天霸戈 Java教程

這篇文章主要介紹了SpringBoot集成gRPC微服務(wù)工程搭建實(shí)踐的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

前言

本文將使用maven、grpc、protocol buffers、docker、envoy等工具構(gòu)建一個簡單微服務(wù)工程,筆者所使用的示例工程是以前寫的一個java后端工程,因為最近都在 學(xué)習(xí)微服務(wù)相關(guān)的知識,所以利用起來慢慢的把這個工程做成微服務(wù)化應(yīng)用。在實(shí)踐過程踩過很多坑,主要是經(jīng)驗不足對微服務(wù)還是停留在萌新階段,通過本文 記錄創(chuàng)建微服務(wù)工程碰到一些問題,此次實(shí)踐主要是解決以下問題:

  • 如何解決、統(tǒng)一服務(wù)工程依賴管理
  • springboot集成grpc
  • 管理protocol buffers文件
  • 使用envoy代理訪問grpc
  • 部署到docker

本文假設(shè)讀者已經(jīng)了解以下相關(guān)知識:

  • maven
  • envoy
  • grpc
  • protocol buffers
  • springboot
  • docker

由于是初步實(shí)現(xiàn)微服務(wù),不會考慮過多的細(xì)節(jié),現(xiàn)階段只需要能夠使用grpc正常通信,后續(xù)計劃會發(fā)布到k8s中,使用istio實(shí)現(xiàn)來服務(wù)網(wǎng)格。

使用maven

現(xiàn)在比較流行的構(gòu)建工具有maven和gradle,現(xiàn)階段后端開發(fā)大多數(shù)都是用的maven所以本工程也使用maven來構(gòu)建項目,當(dāng)然使用gradle也可以兩者概念大都想通,不同的地方大多是實(shí)現(xiàn)和配置方式不一致。

使用項目繼承

根據(jù)maven的pom文件繼承特性,將工程分不同的模塊,所有的模塊都繼承父pom.xml的依賴、插件等內(nèi)容,這樣就可以實(shí)現(xiàn)統(tǒng)一管理,并方便以后管理、維護(hù)。先看一下大概的項目結(jié)構(gòu):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
appbubblebackend   (1
├── appbubblecommon
├── appbubblesmsservice  (2
├── appbubbleuserservice
├── docker-compose.yaml  (3
├── pom.xml
├── protos     (4
│ ├── sms
│ └── user
└── scripts     (5
 ├── docker
 ├── envoy
 ├── gateway
 └── sql

以下是各個目錄的用處簡述,詳細(xì)的用處文章后面都會提到,先在這里列出個大概:

  1. 工程主目錄
  2. 單個服務(wù)工程目錄(模塊)
  3. docker-compose發(fā)布文件
  4. 存放.proto文件
  5. 發(fā)布、編譯時用到的腳本文件

知道大概的項目工程結(jié)構(gòu)后我們創(chuàng)建一個父pom.xml文件,放在appbubblebackend目錄下面:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
   xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelversion>4.0.0</modelversion>
 <parent>
  <groupid>org.springframework.boot</groupid>
  <artifactid>spring-boot-starter-parent</artifactid>
  <version>2.1.2.release</version>
  <relativepath/> <!-- lookup parent from repository -->
 </parent>
 
 <groupid>com.bubble</groupid>
 <artifactid>bubble</artifactid>
 <version>0.0.1-snapshot</version>
 <packaging>pom</packaging>
 
 <modules>
  <module>appbubblesmsservice</module>
  <module>appbubblecommon</module>
  <module>appbubbleuserservice</module>
 </modules>
 
 <!-- 省略其他部分 -->
</project>

因為使用springboot構(gòu)架,所以主pom.xml文件繼承自springboot的pom文件。 有了主pom.xml后然后使每個模塊的pom.xml都繼承自 主pom.xml文件:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
 xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelversion>4.0.0</modelversion>
 <parent>
 <groupid>com.bubble</groupid>
 <artifactid>bubble</artifactid>
 <version>0.0.1-snapshot</version>
 </parent>
 <artifactid>sms</artifactid>
 <version>0.0.1-snapshot</version>
 
 <!-- 省略其他部分 -->
</project>

經(jīng)過上面的配置后,所有的模塊都會繼承appbubblebackend中的pom.xml文件,這樣可以很方便的更改依賴、配置等信息。

依賴管理

maven提供依賴中心化的管理機(jī)制,通過項目繼承特性所有對appbubblebackend/pom.xml所做的更改都會對其他模塊產(chǎn)生影響,詳細(xì)的依賴管理 內(nèi)容可查看官方文檔。

?
1
2
3
4
5
6
7
8
9
10
<dependencymanagement>
  <dependencies>
   <!-- grpc -->
   <dependency>
    <groupid>io.grpc</groupid>
    <artifactid>grpc-netty-shaded</artifactid>
    <version>${grpc.version}</version>
   </dependency>
  </dependencies>
</dependencymanagement>

通過dependencymanagement標(biāo)簽來配置依賴,這樣可以就可以實(shí)現(xiàn)統(tǒng)一依賴的管理,并且還可以添加公共依賴。

插件管理

使用pluginmanagement可以非常方便的配置插件,因為項目中使用了protocol buffers需要集成相應(yīng)的插件來生成java源文件:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<pluginmanagement>
   <plugins>
    <plugin>
     <groupid>org.xolstice.maven.plugins</groupid>
     <artifactid>protobuf-maven-plugin</artifactid>
     <version>0.5.1</version>
     <executions>
      <execution>
       <goals>
        <goal>compile</goal>
        <goal>compile-custom</goal>
       </goals>
      </execution>
     </executions>
    </plugin>
   </plugins>
</pluginmanagement>

protocol buffers插件的完整配置參數(shù),可以這找到。

profile

使用profile的目的是為了區(qū)分生成docker鏡像時的一些特殊配置,示例工程只配置了一個docker-build的profile:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<profiles>
 <profile>
  <id>docker-build</id>
  <properties>
   <jarname>app</jarname>
  </properties>
 </profile>
</profiles>
 
 <properties>
 <jarname>${project.artifactid}-${project.version}</jarname>
</properties>
 
<build>
 <finalname>${jarname}</finalname>
</build>

如果使用mvn package -p docker-build命令生成jar包時,相應(yīng)的輸出文件名是app.jar這樣可以方便在dockerfile中引用文件,而不需要使用${project.artifactid}-${project.version}的形式來查找輸出的jar這樣可以省去了解析pom.xml文件。如果還需要特殊的參數(shù)可以或者不同的行為,可以添加多個profile,這樣配置起來非常靈活。

protocol buffers文件管理

因為是使用微服務(wù)開發(fā),而且rpc通信框架是使用的grpc,所以每個服務(wù)工程都會使用.proto文件。服務(wù)工程之間又會有使用同一份.proto文件的需求,比如在進(jìn)行rpc通信時服務(wù)提供方返回的消息test定義在a.proto文件中,那么在使用方在解析消息時也同樣需要a.proto文件來將接收到的消息轉(zhuǎn)換成test消息,因此管理.proto文件也有一些小麻煩。關(guān)于protocol buffers的使用可參考 官方文檔。

protocol buffers文件管理規(guī)約

在我們的示例項目中使用集中管理的方式,即將所有的.proto文件放置在同一個目錄(appbubblebackend/protos)下并按服務(wù)名稱來劃分:

?
1
2
3
4
5
├── sms
│ ├── smsmessage.proto
│ └── smsservice.proto
└── user
 └── usermessage.proto

還可以將整個目錄放置在一個單獨(dú)的git倉庫中,然后在項目中使用git subtree來管理文件。

protocol buffers 插件配置

有了上面的目錄結(jié)構(gòu)后,就需要配置一下protocol buffers的編譯插件來支持這種.proto文件的組織結(jié)構(gòu)。在講解如何配置插件解決.proto文件的編譯問題之前,推薦讀者了解一下插件的配置文檔:xolstice maven plugins。在我們的工程中使用如下配置:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<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.17.1:exe:${os.detected.classifier}</pluginartifact>
   <additionalprotopathelements combine.children="append" combine.self="append">
    <additionalprotopathelement>${gopath}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis</additionalprotopathelement>
    <additionalprotopathelement>${gopath}/src</additionalprotopathelement>
   </additionalprotopathelements>
   <protosourceroot>${protos.basedir}</protosourceroot>
   <writedescriptorset>true</writedescriptorset>
   <includedependenciesindescriptorset>true</includedependenciesindescriptorset>
  </configuration>
  <!-- ... -->
 </plugin>

首先上面的插件配置使用protosourceroot標(biāo)簽將protocol buffers的源文件目錄更改成appbubblebackend/protos目錄,因為工程中使用了googleapis來定義服務(wù)接口,所以需要使用添加additionalprotopathelement標(biāo)簽添加額外的依賴文件。注意這個插件的配置是在appbubblebackend/pom.xml文件中的,服務(wù)工程都是繼承此文件的。在父pom文件配置好以后,再看一下服務(wù)工程的插件配置:

?
1
2
3
4
5
6
7
8
9
10
11
12
<plugins>
 <plugin>
 <groupid>org.xolstice.maven.plugins</groupid>
 <artifactid>protobuf-maven-plugin</artifactid>
 <configuration>
  <includes>
  <include>${project.artifactid}/*.proto</include>
  <include>user/*.proto</include>
  </includes>
 </configuration>
 </plugin>
 </plugins>

服務(wù)工程主要使用includes標(biāo)簽,將需要的.proto文件包含在編譯腳本中,includes標(biāo)簽中的include只是一個指定匹配.proto文件的匹配模式,<include>${project.artifactid}/*.proto</include>意思是appbubblebackend/protos/${project.artifactid}目錄下的所有以.proto文件結(jié)尾的文件,如果服務(wù)工程有多個依賴可以將需要依賴的文件也添加到編譯服務(wù)中,如上面的<include>user/*.proto</include>就將appbubblebackend/protos/user中的.proto文件添加進(jìn)來,然后進(jìn)行整體的編譯。

grpc

grpc是由google開源的rpc通信框架,grpc使用protocol buffers定義服務(wù)接口并自動生成grpc相關(guān)代碼,有了這些代碼后就可以非常方便的實(shí)現(xiàn)grpc服務(wù)端和gprc客戶端,過多的細(xì)節(jié)就不細(xì)說了先看一下如何使用在springboot中使用grpc。

運(yùn)行g(shù)rpc服務(wù)

利用applicationrunner接口,在sprintboot中運(yùn)行g(shù)rpc服非常方便,只需要像下面代碼一樣就可以運(yùn)行一個簡單的grpc服務(wù)。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.bubble.sms.grpc;
 
@component
public class grpcserverinitializer implements applicationrunner {
 
 
 @autowired
 private list<bindableservice> services;
 
 @value("${grpc.server.port:8090}")
 private int port;
 
 @override
 public void run(applicationarguments args) throws exception {
 
  serverbuilder serverbuilder = serverbuilder
    .forport(port);
 
  if (services != null && !services.isempty()) {
   for (bindableservice bindableservice : services) {
    serverbuilder.addservice(bindableservice);
   }
  }
  server server = serverbuilder.build();
  serverbuilder.intercept(transmitstatusruntimeexceptioninterceptor.instance());
  server.start();
  startdaemonawaitthread(server);
 }
 
 
 private void startdaemonawaitthread(server server) {
  thread awaitthread = new thread(() -> {
   try {
    server.awaittermination();
   } catch (interruptedexception ignore) {
    
   }
  });
  awaitthread.setdaemon(false);
  awaitthread.start();
 }
}

envoy代理

grpc服務(wù)運(yùn)行起來后就需要進(jìn)行調(diào)試了,比如使用curl、chrome等工具向grpc服務(wù)發(fā)起restful請求,實(shí)際上grpc的調(diào)試并沒有那么簡單。一開始的方案是使用了grpc-gateway,為每個服務(wù)都啟動一個網(wǎng)關(guān)將http 1.x請求轉(zhuǎn)換并發(fā)送到grpc服務(wù)。然而grpc-gateway只有g(shù)o語言的版本,并沒有java語言的版本,所有在編譯和使用中比較困難,后來發(fā)現(xiàn)了envoy提供了envoy.grpc_json_transcoder這個http過濾器,可以很方便的將restful json api轉(zhuǎn)換成grpc請求并發(fā)送給grpc服務(wù)器。

envoy的相關(guān)配置都放置在appbubblebackend/scripts/envoy目錄中,里面的envoy.yaml是一份簡單的配置文件:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
static_resources:
 listeners:
 - name: grpc-8090
 address:
  socket_address: { address: 0.0.0.0, port_value: 8090 }
 filter_chains:
 - filters:
  - name: envoy.http_connection_manager
  config:
   stat_prefix: sms_http
   codec_type: auto
   # 省略部分配置
   http_filters:
   - name: envoy.grpc_json_transcoder
   config:
    proto_descriptor: "/app/app.protobin"
    services: ["sms.smsservice"]
    match_incoming_request_route: true
    print_options:
    add_whitespace: true
    always_print_primitive_fields: true
    always_print_enums_as_ints: false
    preserve_proto_field_names: false
# 省略部分配置

使用envoy.grpc_json_transcoder過濾器的主要配置是proto_descriptor選項,該選項指向一個proto descriptor set文件。appbubblebackend/scripts/envoy/compile-descriptor.sh是編譯proto descriptor set的腳本文件, 運(yùn)行腳本文件會在腳本目錄下生成一個app.protobin的文件,將此文件設(shè)置到envoy.grpc_json_transcoder就可大致完成了envoy的代理配置。

使用docker發(fā)布

經(jīng)過上面的一系統(tǒng)準(zhǔn)備工作之后,我們就可以將服務(wù)發(fā)布到docker中了,docker相關(guān)的文件都放置中appbubblebackend/scripts/docker和一個appbubblebackend/docker-compose.yaml文件。在發(fā)布時使用單個dockerfile文件來制作服務(wù)鏡像:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from rcntech/ubuntu-grpc:v0.0.5
expose 8080
expose 8090
 
#將當(dāng)前目錄添加文件到/bubble
arg app_project_name
#復(fù)制父pom.xml
add /pom.xml /app/pom.xml
add /protos /app/protos
add $app_project_name /app/$app_project_name
add scripts/gateway /app/gateway
add scripts/docker/entrypoint.sh /app/entrypoint.sh
run chmod u+x /app/entrypoint.sh
 
entrypoint ["/app/entrypoint.sh"]

有了dockerfile文件后,在docker-compose.yaml里面做一些配置就能將服務(wù)打包成鏡像:

?
1
2
3
4
5
6
7
8
9
10
sms:
build:
context: ./
dockerfile: scripts/docker/dockerfile
args:
 app_project_name: "appbubblesmsservice"
environment:
apollo_meta: "http://apollo-configservice-dev:8080"
app_project_name: "appbubblesmsservice"
env: dev

同時編寫了一個通用的entrypoint.sh腳本文件來啟動服務(wù)器:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/bash
 
export gopath=${home}/go
export path=$path:/usr/local/go/bin:$gopath/bin
 
rootprojectdir="/app"
projectdir="${rootprojectdir}/${app_project_name}"
 
cd ${rootprojectdir}/appbubblecommon
./mvnw install
 
cd $projectdir
#打包app.jar
./mvnw package -dskiptests -p docker-build
#編譯proto文件
./mvnw protobuf:compile protobuf:compile-custom -p docker-build
 
 
# run service
java -jar ${projectdir}/target/app.jar

entrypoint.sh腳本中將服務(wù)工程編譯成app.jar包再運(yùn)行服務(wù)。還有envoy代理也要啟動起來這樣我們就可以使用curl或其他工具直接進(jìn)行測試了。

總結(jié)

搭建這個工程大概摸索了一周的時間,主要的時間是花在了protocol buffers文件的管理與使用envoy作為代理調(diào)試grpc服務(wù)上。文章中的示例工程已經(jīng)傳到了github: appbubblebackend 后面會打算慢慢的完善這個應(yīng)用,這是個簡單的短視屏應(yīng)用除了服務(wù)器還包含了android和ios端,等到將后端微服務(wù)化為開源出來供學(xué)習(xí)交流使用。

參考引用

grpc官方文檔
protocol buffers maven 插件文檔
protocol buffers官方文檔
grpc 官方文檔中文版
grpc-json transcoder

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://juejin.im/post/5c3ed5a2f265da616f703399

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久性综合亚洲精品电影网 | 欧美一卡2卡三卡4卡5卡免费观看 | 交换朋友夫妇3中文字幕 | 99视频在线免费 | 交换年轻夫妇HD中文字幕 | 香港成人社区 | 久久国产香蕉 | 久久精品视频uu | 欧美特黄视频在线观看 | 五月天婷婷网亚洲综合在线 | 国内精品视频一区二区三区八戒 | 美女脱了内裤让男桶爽 | 日本在线观看免费观看完整版 | 四虎影院精品 | 成年人视频免费在线播放 | 日本三级香港三级久久99 | 成人欧美一区二区三区白人 | 久久精品国产亚洲AV热无遮挡 | 久久久精品日本一区二区三区 | 欧洲男同直粗无套播放视频 | 毛片大全高清免费 | 日产乱码卡1卡2卡三免费 | 国产 国语对白 露脸正在播放 | 蜜桃视频一区二区三区四区 | 亚洲国产综合另类视频 | 午夜福利视频极品国产83 | 亚洲欧美久久一区二区 | 四虎影视4hu最新地址在线884 | kuaibo成人播放器| 无码中文字幕av免费放 | 久久中文字幕综合不卡一二区 | 成人一区二区丝袜美腿 | 大胸纲手被羞羞漫画网站 | 国产精品欧美亚洲韩国日本 | 国产精品视频2021 | 四虎视屏 | 亚洲视频一区在线播放 | 国产视频a区 | 91麻豆国产福利在线观看 | 国产高清在线播放免费观看 | 桃花岛在线|