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.pswp.cn/news/396192.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/396192.shtml
英文地址,請注明出處:http://en.pswp.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…