前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >简说代码健壮性

简说代码健壮性

原创
作者头像
sansan
发布2023-03-21 20:21:21
3110
发布2023-03-21 20:21:21
举报
文章被收录于专栏:屌丝程序媛屌丝程序媛

这两周一直在优化基于sparkStream的实时流,作为一个精致的猪猪程序媛,不堪忍受天天有问题的历史债。bug终于有所收敛,通过博客的形式给各位新手程序员一点点建议吧。。。

接口失败后异常处理

针对第三方接口,例如数据库对象初始化,打开text文件,请求服务等均会存在接口请求或者连接请求失败的情况,请求失败后通用处理方式是捕获异常,然后设置一定的等待时间(避免压力过大,造成接口雪崩),给予合理的重试次数,例如下图中redis对象初始化失败,等待20ms后发起一次重试。

代码语言:javascript
复制
     var jedisClient: Jedis = null
      try {
        jedisClient = new Jedis(kvHost, kvPort.toInt)
        jedisClient.auth(kvAuth)
      } catch {
        case e: Exception => {
          println(s"error new jedisClient throw exception: ${e.getMessage} \n" + e.printStackTrace())
        }
          // 20ms后重连
          Thread.sleep(20)
          jedisClient = new Jedis(kvHost, kvPort.toInt)
          jedisClient.auth(kvAuth)
      }

资源合理关闭

涉及第三方中间件或者数据库,例如mysql、redis、kafka等,资源对象分配使用完后要记得关闭,否则持续打开不关闭会造成Caused by: java.io.IOException: Too many open files 之类的问题,例如下图中在每个worker上分配 kafka producer对象,使用完毕后及时关掉。

代码语言:javascript
复制
    outputData.foreachRDD { rdd =>
      rdd.foreachPartition { partition =>
        val producer = newProducerWithoutClose(outKafkaDesc)
        partition.foreach { record =>
          producer.send(outKafkaDesc.topic, record)
        }
        producer.close()
      }
    }

输入检查

这点写C++的人真应该深有体会,因为多年写C++,且C++中对指针的使用很频繁,所以本人一直保持,所以函数的指针入参在使用前必须检查是否为空,当然这里的输入包括:接口的返回结果,函数的参数,组件的属性等。例如下面对接口输入参数合法性检测,空指针判断等。

代码语言:javascript
复制
int32_t DataProcess::VrInfoParse(const SearchRequest& request) {
  if (request.search_ext().find("vr_info") != request.search_ext().end()) {
    std::string vr_info = request.search_ext().at("vr_info");
    // json解析, fill PageInfo
    rapidjson::Document vr_doc;
    vr_doc.Parse(vr_info);
    if (!vr_doc.HasParseError()) {
      if (vr_doc.HasMember("vrid") && vr_doc["vrid"].IsString()) {
        vr_info_.vr_id = vr_doc["vrid"].GetString();
        
    } else {
      log.error("invalid vr info:" << vr_info);
      return -1; 
    }   
  } else {
    log.error("not find vr info");
    return -1; 
  }
  return 0;
}

业务边界

这次在排查调用对象池GenericObjectPool的方法returnObject报错时发现,流量峰值较高Obejct分配达到峰值时,这种情况若设置了对象池MaxIdle,且满足对象池中的idle对象数量大于MaxIdle,则可能导致归还的对象资源被释放掉。如下图所示,所以设置MaxIdle最好结合实际的业务场景,避免过小造成程序core,也避免过大,造成资源浪费。

returnObject源码
returnObject源码

程序的边界,这点相信各位在刷leetcode题目的时候也深有体会,此处不在赘述。

最后,给大家的建议是:在排查问题的过程中,一定要深究其原因,看清楚问题的本质原理,切勿图快省事,看得多了遇到问题就能得心应手,信手拈来。同时要思考问题的解决办法是不是有多种,效率是本钱,效率是王道,用低成本修复遇到的问题,自己的人力也就释放了。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 接口失败后异常处理
  • 资源合理关闭
  • 输入检查
  • 业务边界
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档