正文
Head-of-line blocking,新请求的发起必须等待服务器对前一个请求的回应,无法同时发起多个请求,导致很难充分利用TCP连接。
● 头部冗余
HTTP头部包含大量重复数据,比如cookies,多个请求的cookie可能完全一样
● 二进制协议、分帧(Frame)
● 双向流,多路复用
● 头部压缩
● 服务器推送(Server Push)
● 优先级
● 流量控制
● 流重置
HTTP/2-帧
●HTTP/2抛弃HTTP/1的文本协议改为二进制协议。HTTP/2的基本传输单元为帧。每个帧都从属于某个流。
● Length: Payload 长度
● Type: 帧类型
● Stream identifier:流ID
● Frame Payload: 依帧类型而不同
HTTP/2-帧的类型
● HEADERS 对应HTTP/1的 Headers
● DATA 对应HTTP/1的 Body
● CONTINUATION 头部太大,分多个帧传输(一个HEADERS+若干CONTINUATION)
● SETTINGS 连接设置
● WINDOW_UPDATE 流量控制
● PUSH_PROMISE 服务端推送
● PRIORITY 流优先级更改
● PING 心跳或计算RTT
● RST_STREAM 马上中止一个流
● GOAWAY 关闭连接并且发送错误信息
HTTP/2-流
HTTP/2连接上传输的每个帧都关联到一个流,一个连接上可以同时有多个流。同一个流的帧按序传输,不同流的帧交错混合传输。客户端、服务端双方都可以建立流,流也可以被任意一方关闭。客户端发起的流使用奇数流ID,服务端发起的使用偶数。
Protocol Buffers是什么
一个语言无关,平台无关,可扩展的结构化数据序列化方案,用于协议通讯,数据存储和其他更多用途。
一个灵活,高效,自动化的结构化数据序列化机制(想象xml),但是更小,更快并且更简单,一旦定义好数据如何构造, 就可以使用特殊的生成的源代码来轻易的读写你的结构化数据到和从不同的数据流,用不同的语言。你甚至可以更新你的数据结构而不打破已部署的使用"旧有"格式编译的程序。
将移动和HTTP/2放在首位的通用的RPC框架,
● 网络基础设施设计良好的支持HTTP,比如防火墙, 负载, 加密, 认证, 压缩, ...
第1步. 定义 hello-dto.proto 文件
syntax = "proto3";
option java_package = "com.jd.jsf.grpc.dto";
option java_multiple_files = true;
option java_outer_classname = "HelloServiceDTO";
package grpc;
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
第2步. 定义hello-service.proto文件(可以和第一步合并)
syntax = "proto3";
import "hello-dto.proto";
option java_package = "com.jd.jsf.grpc.service";
option java_multiple_files = true;
option java_outer_classname = "IHelloService";
package grpc;
// The greeting service definition.
service HelloService {
// Sends a greeting
rpc SayHello (grpc.HelloRequest) returns (grpc.HelloReply) {}
}
第3步. 生成 源代码 文件
#! /bin/bash
PROTOC3="/grpc/
protoc
-3.1.0"
PROJECT_HOME="./"
echo "gen dto"
${PROTOC3}/bin/protoc \
-I=${PROJECT_HOME}/src/main/proto/ \
--java_out=${PROJECT_HOME}/src/main/java \
${PROJECT_HOME}/src/main/proto/hello-dto.proto
echo "gen service"
${PROTOC3}/bin/protoc \
-I=${PROJECT_HOME}/src/main/proto/ \
--java_out=${PROJECT_HOME}/src/main/java \
${PROJECT_HOME}/src/main/proto/hello-service.proto
echo "gen grpc service"
${PROTOC3}/bin/protoc \
--plugin=protoc-gen-grpc-java=${PROTOC3}/bin/
protoc-gen-grpc-java
-1.1.1-linux-x86_64.exe \
--grpc-java_out=${PROJECT_HOME}/src/main/java \
-I=${PROJECT_HOME}/src/main/proto/ \
${PROJECT_HOME}/src/main/proto/hello-service.proto
echo "over!"
第4步. 编写Server端
int port = 50051;
server = ServerBuilder.forPort(port).addService(new GreeterImpl()).build() .start();
server.awaitTermination();
class GreeterImpl extends HelloServiceGrpc.HelloServiceImplBase {
@Override
public void sayHello(HelloRequest req, StreamObserver
responseObserver) {
HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
}