zoukankan      html  css  js  c++  java
  • 聊聊Grpc使用中的坑以及怎么填

    总所周知,随着云技术的发展,和业务的复杂度的上升,越来越多的系统开始拆分成独立的子模块微服务。模块之间免不了相互通信。但是随着业务量的增多,传输量也随之增大,偶发性timeout,无响应, 传输量过大等问题。

    这时候就要对服务进行配置需要进行调优。可以从运维层面,或者代码层面,本文主要介绍从代码层面

    Grpc是一个很好的微服务框架,大部分语言都支持,之前的文章有介绍,可以看一下

     

    这次主要说一下在Grpc微服务通信间的一些问题及优化。运维层面我们就不说了,主要是代码层面的优化。主要是C#代码,其他语言可参考,Grpc框架都大差不差

     

    问题一:

     Docker Swarm 模式下 服务闲置一段时间,客户端第一次连接会提示异常。咱公网是k8s部署,不清楚为什么k8s不会出现这个问题。

    后来,通过查资料,可以大致知道是这么个流程。首先 kube-proxy 是支持 IPTABLES 和 IPVS 两种模式的,

    使用的是 IPTABLES不会出现问题。具体为啥,没做深入连接,运维层面,我们就不吹牛逼。各位看官有兴趣去查一下,告诉小弟。

     

    Grpc.Core.RpcException: Status(StatusCode=Unavailable, Detail="Connection reset by peer")
       at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at Grpc.Core.Internal.AsyncCall`2.UnaryCall(TRequest msg)
       at Grpc.Core.DefaultCallInvoker.BlockingUnaryCall[TRequest,TResponse](Method`2 method, String host, CallOptions options, TRequest request)
       at Grpc.Core.Interceptors.InterceptingCallInvoker.<BlockingUnaryCall>b__3_0[TRequest,TResponse](TRequest req, ClientInterceptorContext`2 ctx)
       at Grpc.Core.ClientBase.ClientBaseConfiguration.ClientBaseConfigurationInterceptor.BlockingUnaryCall[TRequest,TResponse](TRequest request, ClientInterceptorContext`2 context, BlockingUnaryCallContinuation`2 continuation)

    解决方案:

    1、重试机制

    .net 可通过polly 实现,当然,这种方式不太好,毕竟不算根本上解决问题。只能算取巧。可以用第二种,从根本上解决唤醒问题

      private readonly Polly.Retry.RetryPolicy RetryPolicy = Policy
               .Handle<RpcException>(t => t.Status.StatusCode == StatusCode.Unavailable)
               .Retry(1);

    2、还可以通过优化Grpc 服务端代码,新增如下配置即可

    var server = new Server(new List<ChannelOption>
    {
      new ChannelOption("grpc.keepalive_time_ms", 800000), // 发送 keepalive 探测消息的频度
      new ChannelOption("grpc.keepalive_timeout_ms", 5000), // keepalive 探测应答超时时间
      new ChannelOption("grpc.keepalive_permit_without_calls", 1) // 是否允许在没有任何调用时发送 keepalive
    })
    {
      Services = { ServiceA },
      Ports = { new ServerPort(host, port, ServerCredentials.Insecure) },
    };

    问题二:

    Grpc传输量,默认是4M,如果服务之间调用,传输数据量超过最大值,会提示 , Received message larger than max (xxxxxx vs. 4194304

    解决方案:

    1、我们通过代码配置,调大这个限制。以提高服务间吞吐量。

    当然,不建议太大,太大了对服务资源也是一种消耗。可以通过第二种方式进行优化

     var channelOptions = new List<ChannelOption>();
    // add max message length option 设最大接收数量 channelOptions.Add(new ChannelOption(ChannelOptions.MaxReceiveMessageLength, (4 * 1024 * 1024) * 7))

    2、通过Grpc流式调用

    Grpc 是基于 HTTP/2 实现的,HTTP/2 具有流的概念,流是为了实现 HTTP/2 的多路复用。流是服务器和客户端在 HTTP/2 连接内用于交换帧数据的独立双向序列,逻辑上可看做一个较为完整的交互处理单元,即表达一次完整的资源请求、响应数据交换流程。

    类型

    说明

    简单 RPC

    客户端传入一个请求对象,服务端返回一个结果对象

    客户端流式 RPC

    客户端传入多个请求对象,服务端返回一个结果对象

    服务端流式 RPC

    客户端传入一个请求对象,服务端返回多个结果对象

    双向流式 RPC

    客户端传入多个请求对象,服务端返回多个结果对象

     

    具体可以用法看一下官方文档,后面出一篇文章详细说一下流式调用,各位大侠敬请期待

     

     

    如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!

    本文版权归作者和博客园共有,来源网址:https://www.cnblogs.com/DanielYao/欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利

     
  • 相关阅读:
    推荐系统中的特征处理
    推荐系统之协同过滤
    python 对字典排序
    推荐系统资料汇总
    python print和strip
    python ConfigParse模块(转)
    01_HBase概述
    04_Storm编程上手_WordCount集群模式运行
    03_Storm编程上手-wordcount
    02_Storm集群部署
  • 原文地址:https://www.cnblogs.com/DanielYao/p/12915697.html
Copyright © 2011-2022 走看看