grpc簡介:
官網地址:https://grpc.io/
gRPC 是一個高性能、開源、通用的RPC框架,由Google推出,基於HTTP2協議標準設計開發,默認採用Protocol Buffers數據序列化協議,支持多種開發語言。gRPC提供了一種簡單的方法來精確的定義服務,並且爲客戶端和服務端自動生成可靠的功能庫。
在gRPC客戶端可以直接調用不同服務器上的遠程程序,使用姿勢看起來就像調用本地程序一樣,很容易去構建分佈式應用和服務。和很多RPC系統一樣,服務端負責實現定義好的接口並處理客戶端的請求,客戶端根據接口描述直接調用需要的服務。客戶端和服務端可以分別使用gRPC支持的不同語言實現。
特性:
-
強大的IDL
gRPC使用ProtoBuf來定義服務,ProtoBuf是由Google開發的一種數據序列化協議(類似於XML、JSON、hessian)。ProtoBuf能夠將數據進行序列化,並廣泛應用在數據存儲、通信協議等方面。
-
多語言支持
gRPC支持多種語言,並能夠基於語言自動生成客戶端和服務端功能庫。目前已提供了C版本grpc、Java版本grpc-java 和 Go版本grpc-go,其它語言的版本正在積極開發中,其中,grpc支持C、C++、Node.js、Python、Ruby、Objective-C、PHP和C#等語言,grpc-java已經支持Android開發。
-
HTTP2
gRPC基於HTTP2標準設計,所以相對於其他RPC框架,gRPC帶來了更多強大功能,如雙向流、頭部壓縮、多複用請求等。這些功能給移動設備帶來重大益處,如節省帶寬、降低TCP鏈接次數、節省CPU使用和延長電池壽命等。同時,gRPC還能夠提高了雲端服務和Web應用的性能。gRPC既能夠在客戶端應用,也能夠在服務器端應用,從而以透明的方式實現客戶端和服務器端的通信和簡化通信系統的構建。
DEMO-java
主要依賴:
<dependency>
<groupId>io.github.lognet</groupId>
<artifactId>grpc-spring-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
配置proto:
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.4.1.Final</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.0</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.16.1:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
編寫proto接口文件
syntax = "proto3";
option java_multiple_files = true;
package cc.superl.grpc.demo.hello;
message Person {
string first_name = 1;
string last_name = 2;
}
message Greeting {
string message = 1;
}
service HelloWorldService {
rpc sayHello (Person) returns (Greeting);
}
【可自行安裝protobuf工具進行生成的語言代碼】
具體查看 https://developers.google.com/protocol-buffers/docs/proto3#generating
進行編譯:
產出結果就是接口:
開始編寫簡單的demo
- Server端
import cc.superl.grpc.demo.hello.Greeting;
import cc.superl.grpc.demo.hello.HelloWorldServiceGrpc.HelloWorldServiceImplBase;
import cc.superl.grpc.demo.hello.Person;
import io.grpc.stub.StreamObserver;
import org.lognet.springboot.grpc.GRpcService;
@GRpcService
public class HelloServerImpl extends HelloWorldServiceImplBase {
@Override
public void sayHello(Person request, StreamObserver<Greeting> responseObserver) {
String message = "Hello " + request.getFirstName() + " "
+ request.getLastName() + "!";
Greeting greeting =
Greeting.newBuilder().setMessage(message).build();
responseObserver.onNext(greeting);
responseObserver.onCompleted();
}
}
- 客戶端dmeo
import cc.superl.grpc.demo.hello.Greeting;
import cc.superl.grpc.demo.hello.HelloWorldServiceGrpc;
import cc.superl.grpc.demo.hello.Person;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class HelloClient {
private HelloWorldServiceGrpc.HelloWorldServiceBlockingStub stub;
@PostConstruct
private void init() {
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost",6565).usePlaintext().build();
stub = HelloWorldServiceGrpc.newBlockingStub(channel);
}
public String sayHello(String firstName,String lastName) {
Person person = Person.newBuilder().setFirstName(firstName)
.setLastName(lastName).build();
Greeting greeting =
stub.sayHello(person);
return greeting.getMessage();
}
}
grpc-port 默認爲6565,可進行設置在application配置文件中其他端口
- 測試類
import cc.superl.grpc.demo.client.HelloClient;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {
@Autowired
private HelloClient client;
@Test
public void testSayHello() {
assertThat(client.sayHello("a","b")).isEqualTo("Hello a b!");
}
}
簡單demo就到此了
福利:
對grpc的反向代理,nginx在1.13.10版本做了支持,https://www.nginx.com/blog/nginx-1-13-10-grpc/
安裝編譯nginx時需
./configure --with-http_ssl_module --with-http_v2_module
nginx.conf配置內容爲:
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent"';
server {
listen 80 http2;
access_log logs/access.log main;
location / {
# Replace localhost:50051 with the address and port of your gRPC server
# The 'grpc://' prefix is optional; unencrypted gRPC is the default
grpc_pass grpc://localhost:50051;
}
}
}
對於TLS支持爲
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent"';
server {
listen 1443 ssl http2;
ssl_certificate ssl/cert.pem;
ssl_certificate_key ssl/key.pem;
access_log logs/access.log main;
location / {
# Use grpcs for TLS-encrypted gRPC traffic
grpc_pass grpcs://localhost:50051;
}
}
}s
參看資料:
https://www.nginx.com/blog/nginx-1-13-10-grpc/
https://www.bookstack.cn/read/go-grpc/chapter1-intro.md
https://grpc.io/docs/quickstart/java/
https://yidongnan.github.io/grpc-spring-boot-starter/en/server/getting-started.html