Grpc系列学习(二)
写在前面:因为1024CSDN写博客会有徽章,本人多少带点收集控,故正好整理出第二篇关于Grpc的学习文章.
这次照例宣传一下我的个人博客:
demo:
制作证书
在服务端支持Rpc
和Restful Api
,需要用到TLS
,因此我们要先制作证书
进入certs
目录,生成TLS
所需的公钥密钥文件
openssl genrsa -out server.key 2048
openssl ecparam -genkey -name secp384r1 -out server.key
openssl genrsa
:生成RSA
私钥,命令的最后一个参数,将指定生成密钥的位数,如果没有指定,默认512openssl ecparam
:生成ECC
私钥,命令为椭圆曲线密钥参数生成及操作,本文中ECC
曲线选择的是secp384r1
自签名公钥
openssl req -new -x509 -sha256 -key server.key -out server.pem -days 3650
openssl req
:生成自签名证书,-new
指生成证书请求、-sha256
指使用sha256
加密、-key
指定私钥文件、-x509
指输出证书、-days 3650
为有效期,此后则输入证书拥有者信息
填写信息
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:grpc server name
Email Address []:
Proto
编写
1.google.api
我们看到proto
目录中有google/api
目录,它用到了google
官方提供的两个api
描述文件,主要是针对grpc-gateway
的http
转换提供支持,定义了Protocol Buffer
所扩展的HTTP Option
annotations.proto
文件:
// Copyright (c) 2015, Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
package google.api;
import "google/api/http.proto";
import "google/protobuf/descriptor.proto";
option java_multiple_files = true;
option java_outer_classname = "AnnotationsProto";
option java_package = "com.google.api";
extend google.protobuf.MethodOptions {
// See `HttpRule`.
HttpRule http = 72295728;
}
http.proto
文件:
// Copyright 2016 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
package google.api;
option cc_enable_arenas = true;
option java_multiple_files = true;
option java_outer_classname = "HttpProto";
option java_package = "com.google.api";
// Defines the HTTP configuration for a service. It contains a list of
// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method
// to one or more HTTP REST API methods.
message Http {
// A list of HTTP rules for configuring the HTTP REST API methods.
repeated HttpRule rules = 1;
}
// Use CustomHttpPattern to specify any HTTP method that is not included in the
// `pattern` field, such as HEAD, or "*" to leave the HTTP method unspecified for
// a given URL path rule. The wild-card rule is useful for services that provide
// content to Web (HTML) clients.
message HttpRule {
// Selects methods to which this rule applies.
//
// Refer to [selector][google.api.DocumentationRule.selector] for syntax details.
string selector = 1;
// Determines the URL pattern is matched by this rules. This pattern can be
// used with any of the {get|put|post|delete|patch} methods. A custom method
// can be defined using the 'custom' field.
oneof pattern {
// Used for listing and getting information about resources.
string get = 2;
// Used for updating a resource.
string put = 3;
// Used for creating a resource.
string post = 4;
// Used for deleting a resource.
string delete = 5;
// Used for updating a resource.
string patch = 6;
// Custom pattern is used for defining custom verbs.
CustomHttpPattern custom = 8;
}
// The name of the request field whose value is mapped to the HTTP body, or
// `*` for mapping all fields not captured by the path pattern to the HTTP
// body. NOTE: the referred field must not be a repeated field.
string body = 7;
// Additional HTTP bindings for the selector. Nested bindings must
// not contain an `additional_bindings` field themselves (that is,
// the nesting may only be one level deep).
repeated HttpRule additional_bindings = 11;
}
// A custom pattern is used for defining custom HTTP verb.
message CustomHttpPattern {
// The name of this custom HTTP verb.
string kind = 1;
// The path matched by this custom verb.
string path = 2;
}
hello.proto
这一小节将编写Demo
的.proto
文件,我们在proto
目录下新建hello.proto
文件,写入文件内容:
syntax = "proto3";
package proto;
import "google/api/annotations.proto";
service HelloWorld {
rpc SayHelloWorld(HelloWorldRequest) returns (HelloWorldResponse) {
option (google.api.http) = {
post: "/hello_world"
body: "*"
};
}
}
message HelloWorldRequest {
string referer = 1;
}
message HelloWorldResponse {
string message = 1;
}
在hello.proto
文件中,引用了google/api/annotations.proto
,达到支持HTTP Option
的效果
- 定义了一个
service
RPC服务HelloWorld
,在其内部定义了一个HTTP Option
的POST
方法,HTTP
响应路径为/hello_world
- 定义
message
类型HelloWorldRequest
、HelloWorldResponse
,用于响应请求和返回结果
编译
在编写完.proto
文件后,我们需要对其进行编译,就能够在server
中使用
进入proto
目录,执行以下命令
# 编译google.api
protoc -I . --go_out=plugins=grpc,Mgoogle/protobuf/descriptor.proto=github.com/golang/protobuf/protoc-gen-go/descriptor:. google/api/*.proto
#编译hello_http.proto为hello_http.pb.proto
protoc -I . --go_out=plugins=grpc,Mgoogle/api/annotations.proto=grpc-hello-world/proto/google/api:. ./hello.proto
#编译hello_http.proto为hello_http.pb.gw.proto
protoc --grpc-gateway_out=logtostderr=true:. ./hello.proto
执行完毕后将生成hello.pb.go
和hello.gw.pb.go
,分别针对grpc
和grpc-gateway
的功能支持
命令行模块 cmd
介绍
这一小节我们编写命令行模块,为什么要独立出来呢,是为了将cmd
和server
两者解耦,避免混淆在一起。
我们采用 Cobra 来完成这项功能,Cobra
既是创建强大的现代CLI应用程序的库,也是生成应用程序和命令文件的程序。提供了以下功能:
- 简易的子命令行模式
- 完全兼容posix的命令行模式(包括短和长版本)
- 嵌套的子命令
- 全局、本地和级联
flags
- 使用
Cobra
很容易的生成应用程序和命令,使用cobra create appname
和cobra add cmdname
- 智能提示
- 自动生成commands和flags的帮助信息
- 自动生成详细的help信息
-h
,--help
等等 - 自动生成的bash自动完成功能
- 为应用程序自动生成手册
- 命令别名
- 定义您自己的帮助、用法等的灵活性。
- 可选与viper紧密集成的apps
—选自某百科
编写server
在编写cmd
时需要先用server
进行测试关联,因此这一步我们先写server.go
用于测试
在server
模块下 新建server.go
文件,写入测试内容:
package server
import (
"log"
)
var (
ServerPort string
CertName string
CertPemPath string
CertKeyPath string
)
func Serve() (err error){
log.Println(ServerPort)
log.Println(CertName)
log.Println(CertPemPath)
log.Println(CertKeyPath)
return nil
}
编写cmd
在cmd
模块下 新建root.go
文件,写入内容:
package cmd
import (
"fmt"
"os"
"github.com/spf13/cobra"
)
var rootCmd = &cobra.Command{
Use: "grpc",
Short: "Run the gRPC hello-world server",
}
func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(-1)
}
}
emmm…这个官网的Hello World还是有点多的,今天就不写了~~
@copyright ------------baijianruoliorz@Github--------------------------------