go grpc 深入笔记

为什么80%的码农都做不了架构师?>>>   hot3.png

grpc 深入

生命周期

grpc 的生命周期由4种请求的方式不同而不同:(详细查看router示例)

  • 普通rpc: 客户端发送请求,通知服务端调用rpc服务,服务端返回请求,如果状态"ok",则客户机将获得响应,从而在客户端完成该呼叫。
  • 服务端流rpc: 服务器在获取客户端的请求消息之后发送回响应流。 在发回所有响应后,服务器端的状态信息(状态码和可选状态消息)和可选的尾随元数据将被发送回完成。 客户端完成所有服务器响应后即可完成。
  • 客户端流rpc: 客户端将请求流发送到服务器,而不是单个请求。 服务器发回单个响应,通常但不一定在收到所有客户端的请求后将其其状态详细信息和可选元数据返回。
  • 双向流rpc: 发生的事情取决于应用程序,因为客户端和服务器可以以任何顺序读取和写入, 流完全独立运行。

截止/超时时间(Deadlines/Timeouts)

gprc 设置超时时间:

  • 客户端指定调用rpc的超时时间,超时返回错误 "DEADLINE_EXCEEDED"
  • 在服务器端,服务器可以查询特定的RPC是否超时,还是剩下多少时间来完成RPC。

指定的截止日期或超时时间因语言而异,并不是所有语言都有默认的最后期限。

某些语言时间是截止时间(固定时间点),而某些语言超时时间是范围 (持续时间)。

取消rpc不会回滚操作

取消RPC客户端或服务器可以随时取消调用。 取消立即终止RPC。 它不是一个“撤消”:取消之前所做的更改将不会被回滚。

身份验证

Authentication

具有或不具有基于Google token身份验证的SSL/TLS,或者您可以通过扩展提供的代码来插入自己的身份验证系统。

  • SSL/TLS:gRPC具有SSL/TLS集成,并促进使用SSL/TLS对服务器进行身份验证,并对客户端和服务器之间交换的所有数据进行加密。
  • Token (google): 通过gRPC访问Google API时获得token(通常是OAuth2 tokens)的额外支持是为某些验证流提供的: 一般情况下,此机制必须使用SSL/TLS,Google不会允许没有SSL/TLS的连接,大多数gRPC语言实现不会让您在未加密的频道上发送凭据。

google的token值能用于连接google服务,将这个token发给非google服务看能会发生被盗用的情况,并用于将客户端模拟为Google服务。

凭证

  • 通道凭据,附加到通道,如SSL凭据。
  • 调用凭据,它们附加到调用(或C ++中的ClientContext)中。

route_guide

gRPC Basics - Go

这个例子演示了客户端和服务端的集中通讯方式

  • 普通rpc: 客户端向服务端发起请求,并等待响应回来,就像普通的函数调用一样。
  • 服务器端流式RPC: 客户端向服务器发送请求并获取流来读取一系列消息。 客户端从返回的流中读取,直到没有更多的消息。
  • 客户端流RPC:客户端使用流写入一系列消息并将其发送到服务器。 一旦客户端完成了消息的写入,它等待服务器读取所有消息并返回其响应。
  • 双向流RPC:其中双方使用读写流发送消息序列。 两个流独立运行,所以客户端和服务器可以按照他们喜欢的顺序进行读取和写入:例如,服务器可能在写入响应之前等待接收所有客户端消息,或者可以交替地读取消息然后写入消息, 或读取和写入的其他组合。 每个流中的消息顺序被保留。

stream关键字放在响应类型之前指定服务端或客户端的方法使用流的方法。

下面是4中方式的定义:

service RouteGuide {rpc GetFeature(Point) returns (Feature) {}rpc ListFeatures(Rectangle) returns (stream Feature) {}rpc RecordRoute(stream Point) returns (RouteSummary) {}rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
}

pb文件

完整定义:


syntax = "proto3";option java_multiple_files = true;
option java_package = "io.grpc.examples.routeguide";
option java_outer_classname = "RouteGuideProto";package pb;// Interface exported by the server.
service RouteGuide {// A simple RPC.//// Obtains the feature at a given position.//// A feature with an empty name is returned if there's no feature at the given// position.rpc GetFeature(Point) returns (Feature) {}// A server-to-client streaming RPC.//// Obtains the Features available within the given Rectangle.  Results are// streamed rather than returned at once (e.g. in a response message with a// repeated field), as the rectangle may cover a large area and contain a// huge number of features.rpc ListFeatures(Rectangle) returns (stream Feature) {}// A client-to-server streaming RPC.//// Accepts a stream of Points on a route being traversed, returning a// RouteSummary when traversal is completed.rpc RecordRoute(stream Point) returns (RouteSummary) {}// A Bidirectional streaming RPC.//// Accepts a stream of RouteNotes sent while a route is being traversed,// while receiving other RouteNotes (e.g. from other users).rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
}// Points are represented as latitude-longitude pairs in the E7 representation
// (degrees multiplied by 10**7 and rounded to the nearest integer).
// Latitudes should be in the range +/- 90 degrees and longitude should be in
// the range +/- 180 degrees (inclusive).
message Point {int32 latitude = 1;int32 longitude = 2;
}// A latitude-longitude rectangle, represented as two diagonally opposite
// points "lo" and "hi".
message Rectangle {// One corner of the rectangle.Point lo = 1;// The other corner of the rectangle.Point hi = 2;
}// A feature names something at a given point.
//
// If a feature could not be named, the name is empty.
message Feature {// The name of the feature.string name = 1;// The point where the feature is detected.Point location = 2;
}// A RouteNote is a message sent while at a given point.
message RouteNote {// The location from which the message is sent.Point location = 1;// The message to be sent.string message = 2;
}// A RouteSummary is received in response to a RecordRoute rpc.
//
// It contains the number of individual points received, the number of
// detected features, and the total distance covered as the cumulative sum of
// the distance between each point.
message RouteSummary {// The number of points received.int32 point_count = 1;// The number of known features passed while traversing the route.int32 feature_count = 2;// The distance covered in metres.int32 distance = 3;// The duration of the traversal in seconds.int32 elapsed_time = 4;
}

使用上面的文件,然后在对应文件夹下生产xx.pb.go文件

protoc -I ./  route_guide.proto  --go_out=plugins=grpc:.

server 实现


// Package main implements a simple gRPC server that demonstrates how to use gRPC-Go libraries
// to perform unary, client streaming, server streaming and full duplex RPCs.
//
// It implements the route guide service whose definition can be found in proto/route_guide.proto.
package mainimport ("encoding/json""flag""fmt""io""io/ioutil""math""net""time""golang.org/x/net/context""google.golang.org/grpc""google.golang.org/grpc/credentials""google.golang.org/grpc/grpclog""github.com/golang/protobuf/proto""git.oschina.net/solate/test/other/grpc/router/pb"
)var (tls        = flag.Bool("tls", false, "Connection uses TLS if true, else plain TCP")certFile   = flag.String("cert_file", "testdata/server1.pem", "The TLS cert file")keyFile    = flag.String("key_file", "testdata/server1.key", "The TLS key file")jsonDBFile = flag.String("json_db_file", "testdata/route_guide_db.json", "A json file containing a list of features")port       = flag.Int("port", 10000, "The server port")
)type routeGuideServer struct {savedFeatures []*pb.FeaturerouteNotes    map[string][]*pb.RouteNote
}// GetFeature returns the feature at the given point.
func (s *routeGuideServer) GetFeature(ctx context.Context, point *pb.Point) (*pb.Feature, error) {for _, feature := range s.savedFeatures {if proto.Equal(feature.Location, point) {return feature, nil}}// No feature was found, return an unnamed featurereturn &pb.Feature{Location: point}, nil
}// ListFeatures lists all features contained within the given bounding Rectangle.
func (s *routeGuideServer) ListFeatures(rect *pb.Rectangle, stream pb.RouteGuide_ListFeaturesServer) error {for _, feature := range s.savedFeatures {if inRange(feature.Location, rect) {if err := stream.Send(feature); err != nil {return err}}}return nil
}// RecordRoute records a route composited of a sequence of points.
//
// It gets a stream of points, and responds with statistics about the "trip":
// number of points,  number of known features visited, total distance traveled, and
// total time spent.
func (s *routeGuideServer) RecordRoute(stream pb.RouteGuide_RecordRouteServer) error {var pointCount, featureCount, distance int32var lastPoint *pb.PointstartTime := time.Now()for {point, err := stream.Recv()if err == io.EOF {endTime := time.Now()return stream.SendAndClose(&pb.RouteSummary{PointCount:   pointCount,FeatureCount: featureCount,Distance:     distance,ElapsedTime:  int32(endTime.Sub(startTime).Seconds()),})}if err != nil {return err}pointCount++for _, feature := range s.savedFeatures {if proto.Equal(feature.Location, point) {featureCount++}}if lastPoint != nil {distance += calcDistance(lastPoint, point)}lastPoint = point}
}// RouteChat receives a stream of message/location pairs, and responds with a stream of all
// previous messages at each of those locations.
func (s *routeGuideServer) RouteChat(stream pb.RouteGuide_RouteChatServer) error {for {in, err := stream.Recv()if err == io.EOF {return nil}if err != nil {return err}key := serialize(in.Location)if _, present := s.routeNotes[key]; !present {s.routeNotes[key] = []*pb.RouteNote{in}} else {s.routeNotes[key] = append(s.routeNotes[key], in)}for _, note := range s.routeNotes[key] {if err := stream.Send(note); err != nil {return err}}}
}// loadFeatures loads features from a JSON file.
func (s *routeGuideServer) loadFeatures(filePath string) {file, err := ioutil.ReadFile(filePath)if err != nil {grpclog.Fatalf("Failed to load default features: %v", err)}if err := json.Unmarshal(file, &s.savedFeatures); err != nil {grpclog.Fatalf("Failed to load default features: %v", err)}
}func toRadians(num float64) float64 {return num * math.Pi / float64(180)
}// calcDistance calculates the distance between two points using the "haversine" formula.
// This code was taken from http://www.movable-type.co.uk/scripts/latlong.html.
func calcDistance(p1 *pb.Point, p2 *pb.Point) int32 {const CordFactor float64 = 1e7const R float64 = float64(6371000) // metreslat1 := float64(p1.Latitude) / CordFactorlat2 := float64(p2.Latitude) / CordFactorlng1 := float64(p1.Longitude) / CordFactorlng2 := float64(p2.Longitude) / CordFactorφ1 := toRadians(lat1)φ2 := toRadians(lat2)Δφ := toRadians(lat2 - lat1)Δλ := toRadians(lng2 - lng1)a := math.Sin(Δφ/2)*math.Sin(Δφ/2) +math.Cos(φ1)*math.Cos(φ2)*math.Sin(Δλ/2)*math.Sin(Δλ/2)c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))distance := R * creturn int32(distance)
}func inRange(point *pb.Point, rect *pb.Rectangle) bool {left := math.Min(float64(rect.Lo.Longitude), float64(rect.Hi.Longitude))right := math.Max(float64(rect.Lo.Longitude), float64(rect.Hi.Longitude))top := math.Max(float64(rect.Lo.Latitude), float64(rect.Hi.Latitude))bottom := math.Min(float64(rect.Lo.Latitude), float64(rect.Hi.Latitude))if float64(point.Longitude) >= left &&float64(point.Longitude) <= right &&float64(point.Latitude) >= bottom &&float64(point.Latitude) <= top {return true}return false
}func serialize(point *pb.Point) string {return fmt.Sprintf("%d %d", point.Latitude, point.Longitude)
}func newServer() *routeGuideServer {s := new(routeGuideServer)s.loadFeatures(*jsonDBFile)s.routeNotes = make(map[string][]*pb.RouteNote)return s
}func main() {flag.Parse()lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))if err != nil {grpclog.Fatalf("failed to listen: %v", err)}var opts []grpc.ServerOptionif *tls {creds, err := credentials.NewServerTLSFromFile(*certFile, *keyFile)if err != nil {grpclog.Fatalf("Failed to generate credentials %v", err)}opts = []grpc.ServerOption{grpc.Creds(creds)}}grpcServer := grpc.NewServer(opts...)pb.RegisterRouteGuideServer(grpcServer, newServer())grpcServer.Serve(lis)
}

客户端实现


// Package main implements a simple gRPC client that demonstrates how to use gRPC-Go libraries
// to perform unary, client streaming, server streaming and full duplex RPCs.
//
// It interacts with the route guide service whose definition can be found in proto/route_guide.proto.
package mainimport ("flag""io""math/rand""time""golang.org/x/net/context""google.golang.org/grpc""google.golang.org/grpc/credentials""google.golang.org/grpc/grpclog""git.oschina.net/solate/test/other/grpc/router/pb"
)var (tls                = flag.Bool("tls", false, "Connection uses TLS if true, else plain TCP")caFile             = flag.String("ca_file", "testdata/ca.pem", "The file containning the CA root cert file")serverAddr         = flag.String("server_addr", "127.0.0.1:10000", "The server address in the format of host:port")serverHostOverride = flag.String("server_host_override", "x.test.youtube.com", "The server name use to verify the hostname returned by TLS handshake")
)// printFeature gets the feature for the given point.
func printFeature(client pb.RouteGuideClient, point *pb.Point) {grpclog.Printf("Getting feature for point (%d, %d)", point.Latitude, point.Longitude)feature, err := client.GetFeature(context.Background(), point)if err != nil {grpclog.Fatalf("%v.GetFeatures(_) = _, %v: ", client, err)}grpclog.Println(feature)
}// printFeatures lists all the features within the given bounding Rectangle.
func printFeatures(client pb.RouteGuideClient, rect *pb.Rectangle) {grpclog.Printf("Looking for features within %v", rect)stream, err := client.ListFeatures(context.Background(), rect)if err != nil {grpclog.Fatalf("%v.ListFeatures(_) = _, %v", client, err)}for {feature, err := stream.Recv()if err == io.EOF {break}if err != nil {grpclog.Fatalf("%v.ListFeatures(_) = _, %v", client, err)}grpclog.Println(feature)}
}// runRecordRoute sends a sequence of points to server and expects to get a RouteSummary from server.
func runRecordRoute(client pb.RouteGuideClient) {// Create a random number of random pointsr := rand.New(rand.NewSource(time.Now().UnixNano()))pointCount := int(r.Int31n(100)) + 2 // Traverse at least two pointsvar points []*pb.Pointfor i := 0; i < pointCount; i++ {points = append(points, randomPoint(r))}grpclog.Printf("Traversing %d points.", len(points))stream, err := client.RecordRoute(context.Background())if err != nil {grpclog.Fatalf("%v.RecordRoute(_) = _, %v", client, err)}for _, point := range points {if err := stream.Send(point); err != nil {grpclog.Fatalf("%v.Send(%v) = %v", stream, point, err)}}reply, err := stream.CloseAndRecv()if err != nil {grpclog.Fatalf("%v.CloseAndRecv() got error %v, want %v", stream, err, nil)}grpclog.Printf("Route summary: %v", reply)
}// runRouteChat receives a sequence of route notes, while sending notes for various locations.
func runRouteChat(client pb.RouteGuideClient) {notes := []*pb.RouteNote{{&pb.Point{Latitude: 0, Longitude: 1}, "First message"},{&pb.Point{Latitude: 0, Longitude: 2}, "Second message"},{&pb.Point{Latitude: 0, Longitude: 3}, "Third message"},{&pb.Point{Latitude: 0, Longitude: 1}, "Fourth message"},{&pb.Point{Latitude: 0, Longitude: 2}, "Fifth message"},{&pb.Point{Latitude: 0, Longitude: 3}, "Sixth message"},}stream, err := client.RouteChat(context.Background())if err != nil {grpclog.Fatalf("%v.RouteChat(_) = _, %v", client, err)}waitc := make(chan struct{})go func() {for {in, err := stream.Recv()if err == io.EOF {// read done.close(waitc)return}if err != nil {grpclog.Fatalf("Failed to receive a note : %v", err)}grpclog.Printf("Got message %s at point(%d, %d)", in.Message, in.Location.Latitude, in.Location.Longitude)}}()for _, note := range notes {if err := stream.Send(note); err != nil {grpclog.Fatalf("Failed to send a note: %v", err)}}stream.CloseSend()<-waitc
}func randomPoint(r *rand.Rand) *pb.Point {lat := (r.Int31n(180) - 90) * 1e7long := (r.Int31n(360) - 180) * 1e7return &pb.Point{Latitude: lat, Longitude: long}
}func main() {flag.Parse()var opts []grpc.DialOptionif *tls {var sn stringif *serverHostOverride != "" {sn = *serverHostOverride}var creds credentials.TransportCredentialsif *caFile != "" {var err errorcreds, err = credentials.NewClientTLSFromFile(*caFile, sn)if err != nil {grpclog.Fatalf("Failed to create TLS credentials %v", err)}} else {creds = credentials.NewClientTLSFromCert(nil, sn)}opts = append(opts, grpc.WithTransportCredentials(creds))} else {opts = append(opts, grpc.WithInsecure())}conn, err := grpc.Dial(*serverAddr, opts...)if err != nil {grpclog.Fatalf("fail to dial: %v", err)}defer conn.Close()client := pb.NewRouteGuideClient(conn)// Looking for a valid featureprintFeature(client, &pb.Point{Latitude: 409146138, Longitude: -746188906})// Feature missing.printFeature(client, &pb.Point{Latitude: 0, Longitude: 0})// Looking for features between 40, -75 and 42, -73.printFeatures(client, &pb.Rectangle{Lo: &pb.Point{Latitude: 400000000, Longitude: -750000000},Hi: &pb.Point{Latitude: 420000000, Longitude: -730000000},})// RecordRouterunRecordRoute(client)// RouteChatrunRouteChat(client)
}

testdata

route_guide_db.json 在调用的时候是会用到的

tls 如果没有的话默认会使用tcp。

route_guide_db.json 数据

[{"location": {"latitude": 407838351,"longitude": -746143763},"name": "Patriots Path, Mendham, NJ 07945, USA"
}, {"location": {"latitude": 408122808,"longitude": -743999179},"name": "101 New Jersey 10, Whippany, NJ 07981, USA"
}, {"location": {"latitude": 413628156,"longitude": -749015468},"name": "U.S. 6, Shohola, PA 18458, USA"
}, {"location": {"latitude": 419999544,"longitude": -740371136},"name": "5 Conners Road, Kingston, NY 12401, USA"
}, {"location": {"latitude": 414008389,"longitude": -743951297},"name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA"
}, {"location": {"latitude": 419611318,"longitude": -746524769},"name": "287 Flugertown Road, Livingston Manor, NY 12758, USA"
}, {"location": {"latitude": 406109563,"longitude": -742186778},"name": "4001 Tremley Point Road, Linden, NJ 07036, USA"
}, {"location": {"latitude": 416802456,"longitude": -742370183},"name": "352 South Mountain Road, Wallkill, NY 12589, USA"
}, {"location": {"latitude": 412950425,"longitude": -741077389},"name": "Bailey Turn Road, Harriman, NY 10926, USA"
}, {"location": {"latitude": 412144655,"longitude": -743949739},"name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA"
}, {"location": {"latitude": 415736605,"longitude": -742847522},"name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA"
}, {"location": {"latitude": 413843930,"longitude": -740501726},"name": "162 Merrill Road, Highland Mills, NY 10930, USA"
}, {"location": {"latitude": 410873075,"longitude": -744459023},"name": "Clinton Road, West Milford, NJ 07480, USA"
}, {"location": {"latitude": 412346009,"longitude": -744026814},"name": "16 Old Brook Lane, Warwick, NY 10990, USA"
}, {"location": {"latitude": 402948455,"longitude": -747903913},"name": "3 Drake Lane, Pennington, NJ 08534, USA"
}, {"location": {"latitude": 406337092,"longitude": -740122226},"name": "6324 8th Avenue, Brooklyn, NY 11220, USA"
}, {"location": {"latitude": 406421967,"longitude": -747727624},"name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA"
}, {"location": {"latitude": 416318082,"longitude": -749677716},"name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA"
}, {"location": {"latitude": 415301720,"longitude": -748416257},"name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA"
}, {"location": {"latitude": 402647019,"longitude": -747071791},"name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA"
}, {"location": {"latitude": 412567807,"longitude": -741058078},"name": "New York State Reference Route 987E, Southfields, NY 10975, USA"
}, {"location": {"latitude": 416855156,"longitude": -744420597},"name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA"
}, {"location": {"latitude": 404663628,"longitude": -744820157},"name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA"
}, {"location": {"latitude": 407113723,"longitude": -749746483},"name": ""
}, {"location": {"latitude": 402133926,"longitude": -743613249},"name": ""
}, {"location": {"latitude": 400273442,"longitude": -741220915},"name": ""
}, {"location": {"latitude": 411236786,"longitude": -744070769},"name": ""
}, {"location": {"latitude": 411633782,"longitude": -746784970},"name": "211-225 Plains Road, Augusta, NJ 07822, USA"
}, {"location": {"latitude": 415830701,"longitude": -742952812},"name": ""
}, {"location": {"latitude": 413447164,"longitude": -748712898},"name": "165 Pedersen Ridge Road, Milford, PA 18337, USA"
}, {"location": {"latitude": 405047245,"longitude": -749800722},"name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA"
}, {"location": {"latitude": 418858923,"longitude": -746156790},"name": ""
}, {"location": {"latitude": 417951888,"longitude": -748484944},"name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA"
}, {"location": {"latitude": 407033786,"longitude": -743977337},"name": "26 East 3rd Street, New Providence, NJ 07974, USA"
}, {"location": {"latitude": 417548014,"longitude": -740075041},"name": ""
}, {"location": {"latitude": 410395868,"longitude": -744972325},"name": ""
}, {"location": {"latitude": 404615353,"longitude": -745129803},"name": ""
}, {"location": {"latitude": 406589790,"longitude": -743560121},"name": "611 Lawrence Avenue, Westfield, NJ 07090, USA"
}, {"location": {"latitude": 414653148,"longitude": -740477477},"name": "18 Lannis Avenue, New Windsor, NY 12553, USA"
}, {"location": {"latitude": 405957808,"longitude": -743255336},"name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA"
}, {"location": {"latitude": 411733589,"longitude": -741648093},"name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA"
}, {"location": {"latitude": 412676291,"longitude": -742606606},"name": "1270 Lakes Road, Monroe, NY 10950, USA"
}, {"location": {"latitude": 409224445,"longitude": -748286738},"name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA"
}, {"location": {"latitude": 406523420,"longitude": -742135517},"name": "652 Garden Street, Elizabeth, NJ 07202, USA"
}, {"location": {"latitude": 401827388,"longitude": -740294537},"name": "349 Sea Spray Court, Neptune City, NJ 07753, USA"
}, {"location": {"latitude": 410564152,"longitude": -743685054},"name": "13-17 Stanley Street, West Milford, NJ 07480, USA"
}, {"location": {"latitude": 408472324,"longitude": -740726046},"name": "47 Industrial Avenue, Teterboro, NJ 07608, USA"
}, {"location": {"latitude": 412452168,"longitude": -740214052},"name": "5 White Oak Lane, Stony Point, NY 10980, USA"
}, {"location": {"latitude": 409146138,"longitude": -746188906},"name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA"
}, {"location": {"latitude": 404701380,"longitude": -744781745},"name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA"
}, {"location": {"latitude": 409642566,"longitude": -746017679},"name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA"
}, {"location": {"latitude": 408031728,"longitude": -748645385},"name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA"
}, {"location": {"latitude": 413700272,"longitude": -742135189},"name": "367 Prospect Road, Chester, NY 10918, USA"
}, {"location": {"latitude": 404310607,"longitude": -740282632},"name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA"
}, {"location": {"latitude": 409319800,"longitude": -746201391},"name": "11 Ward Street, Mount Arlington, NJ 07856, USA"
}, {"location": {"latitude": 406685311,"longitude": -742108603},"name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA"
}, {"location": {"latitude": 419018117,"longitude": -749142781},"name": "43 Dreher Road, Roscoe, NY 12776, USA"
}, {"location": {"latitude": 412856162,"longitude": -745148837},"name": "Swan Street, Pine Island, NY 10969, USA"
}, {"location": {"latitude": 416560744,"longitude": -746721964},"name": "66 Pleasantview Avenue, Monticello, NY 12701, USA"
}, {"location": {"latitude": 405314270,"longitude": -749836354},"name": ""
}, {"location": {"latitude": 414219548,"longitude": -743327440},"name": ""
}, {"location": {"latitude": 415534177,"longitude": -742900616},"name": "565 Winding Hills Road, Montgomery, NY 12549, USA"
}, {"location": {"latitude": 406898530,"longitude": -749127080},"name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA"
}, {"location": {"latitude": 407586880,"longitude": -741670168},"name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA"
}, {"location": {"latitude": 400106455,"longitude": -742870190},"name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA"
}, {"location": {"latitude": 400066188,"longitude": -746793294},"name": ""
}, {"location": {"latitude": 418803880,"longitude": -744102673},"name": "40 Mountain Road, Napanoch, NY 12458, USA"
}, {"location": {"latitude": 414204288,"longitude": -747895140},"name": ""
}, {"location": {"latitude": 414777405,"longitude": -740615601},"name": ""
}, {"location": {"latitude": 415464475,"longitude": -747175374},"name": "48 North Road, Forestburgh, NY 12777, USA"
}, {"location": {"latitude": 404062378,"longitude": -746376177},"name": ""
}, {"location": {"latitude": 405688272,"longitude": -749285130},"name": ""
}, {"location": {"latitude": 400342070,"longitude": -748788996},"name": ""
}, {"location": {"latitude": 401809022,"longitude": -744157964},"name": ""
}, {"location": {"latitude": 404226644,"longitude": -740517141},"name": "9 Thompson Avenue, Leonardo, NJ 07737, USA"
}, {"location": {"latitude": 410322033,"longitude": -747871659},"name": ""
}, {"location": {"latitude": 407100674,"longitude": -747742727},"name": ""
}, {"location": {"latitude": 418811433,"longitude": -741718005},"name": "213 Bush Road, Stone Ridge, NY 12484, USA"
}, {"location": {"latitude": 415034302,"longitude": -743850945},"name": ""
}, {"location": {"latitude": 411349992,"longitude": -743694161},"name": ""
}, {"location": {"latitude": 404839914,"longitude": -744759616},"name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA"
}, {"location": {"latitude": 414638017,"longitude": -745957854},"name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA"
}, {"location": {"latitude": 412127800,"longitude": -740173578},"name": ""
}, {"location": {"latitude": 401263460,"longitude": -747964303},"name": ""
}, {"location": {"latitude": 412843391,"longitude": -749086026},"name": ""
}, {"location": {"latitude": 418512773,"longitude": -743067823},"name": ""
}, {"location": {"latitude": 404318328,"longitude": -740835638},"name": "42-102 Main Street, Belford, NJ 07718, USA"
}, {"location": {"latitude": 419020746,"longitude": -741172328},"name": ""
}, {"location": {"latitude": 404080723,"longitude": -746119569},"name": ""
}, {"location": {"latitude": 401012643,"longitude": -744035134},"name": ""
}, {"location": {"latitude": 404306372,"longitude": -741079661},"name": ""
}, {"location": {"latitude": 403966326,"longitude": -748519297},"name": ""
}, {"location": {"latitude": 405002031,"longitude": -748407866},"name": ""
}, {"location": {"latitude": 409532885,"longitude": -742200683},"name": ""
}, {"location": {"latitude": 416851321,"longitude": -742674555},"name": ""
}, {"location": {"latitude": 406411633,"longitude": -741722051},"name": "3387 Richmond Terrace, Staten Island, NY 10303, USA"
}, {"location": {"latitude": 413069058,"longitude": -744597778},"name": "261 Van Sickle Road, Goshen, NY 10924, USA"
}, {"location": {"latitude": 418465462,"longitude": -746859398},"name": ""
}, {"location": {"latitude": 411733222,"longitude": -744228360},"name": ""
}, {"location": {"latitude": 410248224,"longitude": -747127767},"name": "3 Hasta Way, Newton, NJ 07860, USA"
}]

tls协议使用文件

ca.pem
-----BEGIN CERTIFICATE-----
MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla
Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0
YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT
BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7
+L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu
g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd
Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau
sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m
oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG
Dfcog5wrJytaQ6UA0wE=
-----END CERTIFICATE-----
server1.key
-----BEGIN PRIVATE KEY-----
MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOHDFScoLCVJpYDD
M4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1BgzkWF+slf
3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd9N8YwbBY
AckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAECgYAn7qGnM2vbjJNBm0VZCkOkTIWm
V10okw7EPJrdL2mkre9NasghNXbE1y5zDshx5Nt3KsazKOxTT8d0Jwh/3KbaN+YY
tTCbKGW0pXDRBhwUHRcuRzScjli8Rih5UOCiZkhefUTcRb6xIhZJuQy71tjaSy0p
dHZRmYyBYO2YEQ8xoQJBAPrJPhMBkzmEYFtyIEqAxQ/o/A6E+E4w8i+KM7nQCK7q
K4JXzyXVAjLfyBZWHGM2uro/fjqPggGD6QH1qXCkI4MCQQDmdKeb2TrKRh5BY1LR
81aJGKcJ2XbcDu6wMZK4oqWbTX2KiYn9GB0woM6nSr/Y6iy1u145YzYxEV/iMwff
DJULAkB8B2MnyzOg0pNFJqBJuH29bKCcHa8gHJzqXhNO5lAlEbMK95p/P2Wi+4Hd
aiEIAF1BF326QJcvYKmwSmrORp85AkAlSNxRJ50OWrfMZnBgzVjDx3xG6KsFQVk2
ol6VhqL6dFgKUORFUWBvnKSyhjJxurlPEahV6oo6+A+mPhFY8eUvAkAZQyTdupP3
XEFQKctGz+9+gKkemDp7LBBMEMBXrGTLPhpEfcjv/7KPdnFHYmhYeBTBnuVmTVWe
F98XJ7tIFfJq
-----END PRIVATE KEY-----
server1.pem
-----BEGIN CERTIFICATE-----
MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET
MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ
dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx
MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV
BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50
ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco
LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg
zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd
9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw
CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy
em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G
CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6
hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh
y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8
-----END CERTIFICATE-----

参考

grpc Authentication

PS: 觉得不错的请点个赞吧!! (ง •̀_•́)ง

转载于:https://my.oschina.net/solate/blog/876688

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/396192.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

messagedigest 图片加密_MessageDigest 加密和解密2

-------------------解密---------------------------package com.drawthink.platform.util;import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;import java…

34个省市自治区排序_freeCodeCamp的1,000多个学习小组现已完全自治

34个省市自治区排序by Justin Sane贾斯汀桑恩(Justin Sane) freeCodeCamp的1,000多个学习小组现已完全自治 (freeCodeCamp’s 1,000 study groups are now fully autonomous) When the first local freeCodeCamp (fCC) study group popped up, we had no idea that within les…

oracle rac alter日志,ORACLE 11G RAC 增加日志组及增大日志文件

1、查看目前日志组和日志文件情况SQL> select * from v$logfile order by 1;GROUP# STATUS TYPE MEMBER IS_---------- ------- ------- -------------------------------------------------- ---1 ONLINE FRA/st…

RSA加密算法简单分析

预备知识 1&#xff09;RSA是第一个比较完善的公开密钥算法&#xff0c;它既能用于加密&#xff0c;也能用于数字签名。RSA以它的三个发明者Ron Rivest, Adi Shamir, Leonard Adleman的名字首字母命名&#xff0c;这个算法经受住了多年深入的密码分析&#xff0c;虽然密码分析者…

C#字符串变量使用

string由于是引用类型&#xff0c;所以&#xff0c;声明的字符串变量会存储到堆上&#xff0c;而且该变量是不可变的&#xff0c;一旦初始化了该变量&#xff0c;该内存区域中存储的内容将不能更改。在对字符串操作时&#xff0c;是在堆上创建了一个新的字符串变量&#xff0c;…

c语输入单引号_C语言的printf不能用单引号?

多年没用C语言了。近日用R语言编程时因有太多循环&#xff0c;只好用C写个扩展模块&#xff0c;一时竟不知怎么动手了。在多种语言中&#xff0c;单引号和双引号是可以等同使用的。因键入双引号要比单引号多按一SHIFT键&#xff0c;我偏好单引号。在用printf显示字符串&#xf…

css flexbox模型_CSS Flexbox在全国范围内的公路旅行中得到了解释

css flexbox模型by Kevin Kononenko凯文科诺年科(Kevin Kononenko) CSS Flexbox在全国范围内的公路旅行中得到了解释 (CSS Flexbox Explained by Road Tripping Across the Country) 如果您旅行很长&#xff0c;那么您可以了解CSS Flexbox&#xff01; (If you have ever been…

oracle 10g 白皮书,Oracle 10g标准版与企业版

beautiful 于 2007-03-06 00:43:37发表:最后还有一些关于oracle产品的FAQ&#xff1a;1. Oracle数据库软件目前在售的版本号&#xff1f;A&#xff1a;目前在售的是Oracle 9i 和Oracle 10g2. 10g是不是比9i更好&#xff1f;A&#xff1a;一个新版本的软件推出以后&#xff0c;总…

Linux 小笔记

1、查看linux 版本 按ctrlshiftt 快捷键&#xff0c;打开终端&#xff0c;输入sudo uname --m &#xff0c;按下enter 如果显示i686,你安装了32位操作系统 如果显示 x86_64&#xff0c;你安装了64位操作系统 转载于:https://www.cnblogs.com/1995hxt/p/5436683.html

不会发布npm包?进来看看?

前言 npm(Node Package Manager)&#xff0c;一个Node的包管理器&#xff0c;平时我们常用的公共模块&#xff08;插件&#xff09;或者叫做包大多都放在上面&#xff0c;所以接下来要封装的插件&#xff0c;我们就简单称它为npm包&#xff0c;本文从就从这个简单的例子开始&am…

如何让帝国CMS7.2搜索模板支持动态标签调用

帝国cms站内搜索一般不支持动态标签调用&#xff0c;如果要调用如何实现呢&#xff1f;修改两个地方就可以实现了。打开 /e/search/result/index.php 文件&#xff0c;找到&#xff08;文件改了&#xff0c;不会调用也是徒劳&#xff01;看看这个帝国cms搜索关键字调用标签(sho…

access字体变为斜体_Linux折腾记(四):Linux桌面系统字体配置详解

字体显示效果测试文字&#xff1a;复制代码代码如下:这一段是为了测试宋体字的显示效果&#xff0c;包括宋体里面自带的英文字体&#xff0c;“This is english,how does it look like?”。这一行是小字。后面几个字是加粗的宋体。标点符号“&#xff0c;。&#xff1a;&#…

oracle between and monday,oracle——时间

时间数据1. 插入时间数据插入语法命令&#xff1a;insert into floor values (to_date(年-月-日 时:分:秒,YYYY-MM-DD HH24:MI:SS));完整的时间插入insert into floor values (to_date(2010-07-12 09:10:12,YYYY-MM-DD HH24:MI:SS));查询显示&#xff1a;2010-07-12 09:10:12.0…

Nova 组件详解 - 每天5分钟玩转 OpenStack(26)

本节开始&#xff0c;我们将详细讲解 Nova 的各个子服务。 前面架构概览一节知道 Nova 有若干 nova-* 的子服务&#xff0c;下面我们将依次学习最重要的几个。今天先讨论 nova-api 和 nova-conductor。 nova-api Nova-api 是整个 Nova 组件的门户&#xff0c;所有对 Nova 的请…

肯德基圣代中间空心_建造冰淇淋圣代解释CSS位置

肯德基圣代中间空心by Kevin Kononenko凯文科诺年科(Kevin Kononenko) 建造冰淇淋圣代解释CSS位置 (CSS Positioning Explained By Building An Ice Cream Sundae) 如果您之前做过冰淇淋圣代&#xff0c;那么您可以了解CSS的位置。 (If you’ve made an ice cream sundae befo…

00

&#xff08;1&#xff09;设置gcc 把所有gcc版本解压到/home/flinn/tools/目录下&#xff0c;以免切换编译器export PATHPATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/flinn/tools/4.4.3/bin &#xff08;2&#xff09;编译&#xff1…

12_04_Linux软件管理之四yum

2019独角兽企业重金招聘Python工程师标准>>> RPM安装&#xff1a; 二进制格式&#xff1a; 源程序--》编译--》二进制格式 有些特性是编译时选定的&#xff0c;如果编译时未选定此特性&#xff0c;将无法使用&#xff1b; rpm包的版本会落后于源码包&#xff0c;甚至…

datastage 函数_DataStage常用函数大全

1/38DataStage常用函数大全DATASTAGE常用函数大全.................................................................................................1一、类型转换函数................................................................................................…

linux 解析elf文件格式,Linux下ELF文件解析

1. windows PE文件与Linux ELF文件概述在windows中可执行文件是pe文件格式&#xff0c;Linux中可执行文件是ELF文件&#xff0c;其文件格式是ELF文件格式&#xff0c;在Linux下的ELF文件除了可执行文件(Excutable File),可重定位目标文件(RellocatableObject File)、共享目标文…

富爸爸穷爸爸害了我_这是我必须告诉爸爸的-在我们的时间用完之前

富爸爸穷爸爸害了我by Bram Bos通过Bram Bos 这是我必须告诉爸爸的-在我们的时间用完之前 (This is what I must tell my dad — before our time runs out) I was a young boy in the 1980s. Like the typical Generation-X kid, I grew up in the days of the home computer…