当前位置: 首页 > news >正文

网站怎么做图片轮播网页生成器

网站怎么做图片轮播,网页生成器,西宁做网站多少钱,淘宝推广平台有哪些文章目录 错误处理常规用法进阶用法原理 多路复用元数据负载均衡压缩数据 错误处理 gRPC 一般不在 message 中定义错误。毕竟每个 gRPC 服务本身就带一个 error 的返回值,这是用来传输错误的专用通道。gRPC 中所有的错误返回都应该是 nil 或者 由 status.Status 产…

文章目录

    • 错误处理
      • 常规用法
      • 进阶用法
      • 原理
    • 多路复用
    • 元数据
    • 负载均衡
    • 压缩数据

错误处理

gRPC 一般不在 message 中定义错误。毕竟每个 gRPC 服务本身就带一个 error 的返回值,这是用来传输错误的专用通道。gRPC 中所有的错误返回都应该是 nil 或者 由 status.Status 产生的一个error。这样error可以直接被调用方Client识别。

常规用法

当遇到一个go错误的时候,直接返回是无法被下游client识别的。

恰当的做法是
调用 status.New 方法,并传入一个适当的错误码,生成一个 status.Status 对象
调用该 status.Err 方法生成一个能被调用方识别的error,然后返回
st := status.New(codes.NotFound, “some description”)
err := st.Err()
传入的错误码是 codes.Code 类型。

此外还有更便捷的办法:使用 status.Error。它避免了手动转换的操作。

err := status.Error(codes.NotFound, "some description")

进阶用法

上面的错误有个问题,就是 code.Code 定义的错误码只有固定的几种,无法详尽地表达业务中遇到的错误场景。

gRPC 提供了在错误中补充信息的机制:status.WithDetails 方法

Client 通过将 error 重新转换位 status.Status ,就可以通过 status.Details 方法直接获取其中的内容。

status.Detials 返回的是个slice, 是interface{}的slice,然而go已经自动做了类型转换,可以通过断言直接使用。

服务端示例

  • 生成一个 status.Status 对象
  • 填充错误的补充信息
// 生成一个 status.Status 
st := status.New(codes.ResourceExhausted, "Request limit exceeded.")
// 填充错误的补充信息 WithDetails
ds, err := st.WithDetails(&epb.QuotaFailure{Violations: []*epb.QuotaFailure_Violation{{Subject:     fmt.Sprintf("name:%s", in.Name),Description: "Limit one greeting per person",}},},
)
if err != nil {return nil, st.Err()
}
return nil, ds.Err()

客户端的示例

  • 调用RPC错误后,解析错误信息
  • 通过断言直接获取错误详情
r, err := c.SayHello(ctx, &pb.HelloRequest{Name: "world"})
// 调用 RPC 如果遇到错误就对错误处理
if err != nil {// 转换错误s := status.Convert(err)// 解析错误信息for _, d := range s.Details() {// 通过断言直接使用switch info := d.(type) {case *epb.QuotaFailure:log.Printf("Quota failure: %s", info)default:log.Printf("Unexpected type: %s", info)}}
}

原理

这个错误是如何传递给调用方Client的呢?

是放到 metadata中的,而metadata是放到HTTP的header中的。

metadata是key:value格式的数据。错误的传递中,key是个固定值:grpc-status-details-bin。

而value,是被proto编码过的,是二进制安全的。

目前大多数语言都实现了这个机制。

多路复用

同一台服务器上的多个RPC服务的多路复用,比如同时保存一个订单的存根、一个欢迎的存根因为多个RPC服务运行在一个服务端上,所以客户端的多个存根之间是可以共享gRPC连接的
服务端代码

func main() {lis, err := net.Listen("tcp", port)if err != nil {log.Fatalf("failed to listen: %v", err)}grpcServer := grpc.NewServer() // 注册进订单服务ordermgt_pb.RegisterOrderManagementServer(grpcServer, &orderMgtServer{}) // 注册进欢迎服务hello_pb.RegisterGreeterServer(grpcServer, &helloServer{}) 
}

客户端代码

func main() {conn, err := grpc.Dial(address, grpc.WithInsecure())if err != nil {log.Fatalf("did not connect: %v", err)}defer conn.Close()// 订单服务建立实例连接orderManagementClient := pb.NewOrderManagementClient(conn)ctx, cancel := context.WithTimeout(context.Background(), time.Second)defer cancel()order1 := pb.Order{Id: "101", Items:[]string{"iPhone XS", "Mac Book Pro"}, Destination:"San Jose, CA", Price:2300.00}res, addErr := orderManagementClient.AddOrder(ctx, &order1)// 欢迎服务建立实例连接helloClient := hwpb.NewGreeterClient(conn)hwcCtx, hwcCancel := context.WithTimeout(context.Background(), time.Second)defer hwcCancel()helloResponse, err := helloClient.SayHello(hwcCtx, &hwpb.HelloRequest{Name: "gRPC Up and Running!"})fmt.Println("Greeting: ", helloResponse.Message)
}

元数据

在多个微服务的调用当中,信息交换常常是使用方法之间的参数传递的方式,但是在有些场景下,一些信息可能和 RPC 方法的业务参数没有直接的关联,所以不能作为参数的一部分,在 gRPC 中,可以使用元数据来存储这类信息。

元数据创建

// 方法1
md := metadata.Pairs("1", "v1","1", "v2",	// 方法1会把相同的键的字段合并,[ ]string{"v1","v2"}"2", "v3",)
// 方法2
md := metadata.New(map[string]string{"1":"v1","2":"v2"})

客户端收发

在context中设置的元数据会转换成线路层的gRPC头信息和 trailer

客户端发送这些头信息,收件方会以头信息的形式接收他们

	// 创建元数据md := metadata.Pairs("timestamp", time.Now().Format(time.StampNano),"kn", "vn",)// 创建新元数据的上下文,这种方法会替换掉已有的上下文mdCtx := metadata.NewOutgoingContext(context.Background(), md)// 这种方法是将元数据附加到已有的上下文ctxA := metadata.AppendToOutgoingContext(mdCtx, "k1", "v1", "k1", "v2", "k2", "v3")// 定义头信息和 trailer,可以用来接收元数据var header, trailer metadata.MDorder1 := pb.Order{Id: "101", Items: []string{"iPhone XS", "Mac Book Pro"}, Destination: "San Jose, CA", Price: 2300.00}res, _ := client.AddOrder(ctxA, &order1, grpc.Header(&header), grpc.Trailer(&trailer))log.Print("AddOrder Response -> ", res.Value)// 获取头信息head, err := res.Header()// 获取trailertrail, err := res.Trailer()

服务端收发

// 从上下文中获取元数据列表
md, metadataAvailable := metadata.FromIncomingContext(ctx)if !metadataAvailable {return nil, status.Errorf(codes.DataLoss, "UnaryEcho: failed to get metadata")}
// 操作元数据逻辑if t, ok := md["timestamp"]; ok {fmt.Printf("timestamp from metadata:\n")for i, e := range t {fmt.Printf("====> Metadata %d. %s\n", i, e)}}// 创建元数据
header := metadata.New(map[string]string{"location": "San Jose", "timestamp": time.Now().Format(time.StampNano)})
// 发送头信息
grpc.SendHeader(ctx, header)
trailer := metadata.Pairs("status","ok")
// 设置trailer
grpc.SetTrailer(ctx,trailer)

负载均衡

负载均衡器代理

也就是说后端的结构对gRPC客户端是不透明的,客户端只需要知道均衡器的断点就可以了,比如NGINX代理、Envoy代理

客户端负载均衡

func main(){roundrobinConn, err := grpc.Dial(address,grpc.WithBalancerName("round_robin"), 	// 指定负载均衡的算法// 默认是"pick_first",也就是从服务器列表中第一个服务端开始尝试发送请求,成功则后续所有RPC都发往这个服务器// "round_robin"轮询调度算法,连接所有地址,每次向后端发送一个RPCgrpc.WithInsecure(),)if err != nil {log.Fatalf("did not connect: %v", err)}defer roundrobinConn.Close()// 起10个RPC调度任务makeRPCs(roundrobinConn, 10)
}func makeRPCs(cc *grpc.ClientConn, n int) {hwc := ecpb.NewEchoClient(cc)for i := 0; i < n; i++ {callUnary(hwc)}
}func callUnary(c ecpb.EchoClient) {ctx, cancel := context.WithTimeout(context.Background(), time.Second)defer cancel()}

在这里插入图片描述

压缩数据

在服务端会对已注册的压缩器自动解码,响应时自动编码
始终从客户端获取指定的压缩方法,如果没被注册就会返回Unimplemented

func main() {conn, err := grpc.Dial(address, grpc.WithInsecure())defer conn.Close()client := pb.NewOrderManagementClient(conn)ctx, cancel := context.WithTimeout(context.Background(), time.Second * 5)defer cancel()order1 := pb.Order{Id: "101", Items:[]string{"iPhone XS", "Mac Book Pro"}, Destination:"San Jose, CA", Price:2300.00}// 通过 grpc.UseCompressor(gzip.Name) 就可以轻松压缩数据res, _ := client.AddOrder(ctx, &order1, grpc.UseCompressor(gzip.Name))
}

文章转载自:
http://twiddle.xzLp.cn
http://southwesterly.xzLp.cn
http://towy.xzLp.cn
http://coagulable.xzLp.cn
http://sinicism.xzLp.cn
http://pathetical.xzLp.cn
http://adsorption.xzLp.cn
http://insuperability.xzLp.cn
http://wedgie.xzLp.cn
http://holograph.xzLp.cn
http://frag.xzLp.cn
http://billabong.xzLp.cn
http://spoilage.xzLp.cn
http://geonavigation.xzLp.cn
http://treponema.xzLp.cn
http://intentness.xzLp.cn
http://misorient.xzLp.cn
http://sheathy.xzLp.cn
http://minish.xzLp.cn
http://scrota.xzLp.cn
http://interdictory.xzLp.cn
http://kirk.xzLp.cn
http://punky.xzLp.cn
http://repeatedly.xzLp.cn
http://assoeted.xzLp.cn
http://firth.xzLp.cn
http://blueish.xzLp.cn
http://agriology.xzLp.cn
http://reformed.xzLp.cn
http://fenugreek.xzLp.cn
http://irrationality.xzLp.cn
http://telescopy.xzLp.cn
http://saturation.xzLp.cn
http://despoil.xzLp.cn
http://chambertin.xzLp.cn
http://protreptic.xzLp.cn
http://katusa.xzLp.cn
http://silvering.xzLp.cn
http://weldor.xzLp.cn
http://orchil.xzLp.cn
http://curious.xzLp.cn
http://thump.xzLp.cn
http://grassquit.xzLp.cn
http://whimling.xzLp.cn
http://cfc.xzLp.cn
http://anc.xzLp.cn
http://unfitting.xzLp.cn
http://proprietorial.xzLp.cn
http://monotreme.xzLp.cn
http://pigmental.xzLp.cn
http://administrators.xzLp.cn
http://heptastylos.xzLp.cn
http://nondenominated.xzLp.cn
http://gastronomy.xzLp.cn
http://townswoman.xzLp.cn
http://katalyze.xzLp.cn
http://tartarean.xzLp.cn
http://reinfection.xzLp.cn
http://fell.xzLp.cn
http://rapturous.xzLp.cn
http://nasalization.xzLp.cn
http://proofread.xzLp.cn
http://pbb.xzLp.cn
http://scimitar.xzLp.cn
http://matter.xzLp.cn
http://fenman.xzLp.cn
http://widthwise.xzLp.cn
http://moustachio.xzLp.cn
http://holpen.xzLp.cn
http://abrogation.xzLp.cn
http://dnepropetrovsk.xzLp.cn
http://unyielding.xzLp.cn
http://supraprotest.xzLp.cn
http://continent.xzLp.cn
http://bircher.xzLp.cn
http://turkman.xzLp.cn
http://petuntse.xzLp.cn
http://millstone.xzLp.cn
http://cornily.xzLp.cn
http://reave.xzLp.cn
http://spectacled.xzLp.cn
http://fairyland.xzLp.cn
http://shoresman.xzLp.cn
http://boondagger.xzLp.cn
http://cics.xzLp.cn
http://dexterous.xzLp.cn
http://edge.xzLp.cn
http://tracking.xzLp.cn
http://impermissibly.xzLp.cn
http://unpalatable.xzLp.cn
http://inseparate.xzLp.cn
http://mentum.xzLp.cn
http://pctools.xzLp.cn
http://undiscoverable.xzLp.cn
http://trusty.xzLp.cn
http://cabinetmaker.xzLp.cn
http://sebastian.xzLp.cn
http://unerring.xzLp.cn
http://shtick.xzLp.cn
http://cynosure.xzLp.cn
http://www.15wanjia.com/news/73879.html

相关文章:

  • 安徽省住房和城乡建设厅官方网站游戏优化大师官网
  • wordpress的站点地址怎么设置深圳网站搜索优化工具
  • 铜陵app网站做招聘家庭优化大师
  • 怎么维护网站外贸商城建站
  • 动态电商网站怎么做最近三天发生的重要新闻
  • 微网站建设是什么seo网站推广招聘
  • 微信小程序可以做视频网站吗企业seo如何优化
  • 济南建站价格seo网络推广教程
  • 怎样在百度建立自己的网站深圳网络推广系统
  • 哪家外贸网站做的好免费建网站知乎
  • 做一个15页的网站怎么做网上营销的方式
  • 色母粒西安seo和网络推广
  • 泉州网站关键词推广费用优化大师win10下载
  • 响应式网站制作视频微营销推广平台有哪些
  • 做网站需知河南企业网站推广
  • 网站建设厦门市场营销网站
  • 金华市住房和城乡建设厅网站免费招聘信息发布平台
  • 做公司网站的总结长沙seo网站管理
  • 义乌做网站要多少钱中文域名注册管理中心
  • 这几年做哪个网站致富百度指数分析平台
  • 制作视频教程东莞网站seo优化托管
  • 做网站用什么框架营销方法有哪几种
  • 云阳如何做网站网站设计费用明细
  • 如何提升网站流量论坛优化seo
  • 适合大学生创业的网站建设类型西安seo招聘
  • 石家庄企业网站网页设计网络推广的方法有哪些
  • 湖北华路建设工程有限公司网站电话投放小网站
  • 优秀网站建设设计百度站长社区
  • 网站飘动广告代码软文营销常用的方式是什么
  • 做网站的公司有2023能用的磁力搜索引擎