java三个层_手机故障说说图片大全

java三个层_手机故障说说图片大全从一个故障说说 Java 的三个 BlockingQueue http://click.aliyun.com/m/7884/

java三个层_手机故障说说图片大全

最近出了个故障,排查的时候耗费了很长的时间,回顾整个排查过程,经验主义在这里起了不好的作用,直接导致了整个故障排查的时间非常长,这个故障的根本原因在于BlockingQueue用的有问题,顺带展开说说Java中常用的几个BlockingQueue:ArrayBlockingQueue、LinkedBlockingQueue和SynchronousQueue。

当时故障的现象是应用处理请求的线程池满了,导致请求处理不了,于是dump线程,看线程都在做什么,结果发现线程都Block在写日志的地方,以前出现过很多次问题,去线程dump的时候看到也是一堆的block在写日志,但通常是别的原因引发的,所以这次也是按照这样的经验,认为肯定不会是写日志这个地方的问题,于是各种排查…折腾了N久后,回过头看发现持有那把日志锁的地方是自己人写的代码,那段代码在拿到了这个日志锁后,从线程堆栈上看,block在了ArrayBlockingQueue.put这个地方,于是翻看这段代码,结果发现这是个1024长度的BlockingQueue,那就意味着如果这个Queue被放了1024个对象的话,put就一定会被block住,而且其实翻代码的时候能看出写代码的同学是考虑到了BlockingQueue如果满了应该要处理的,代码里写着:
if (blockingQueue.remainingCapacity() < 1) { //todo } blockingQueue.put
这里两个悲催的问题,一是这个if判断完还是直接会走到put,而不是else,二是竟然关键的满了后的处理逻辑还在//todo…
另外我觉得这段代码还反应了同学对BlockingQueue的接口不太熟,要达到这个效果,不需要这样先去判断,更合适的做法是用blockingQueue.offer,返回false再做相应的异常处理。

BlockingQueue是在生产/消费者模式下经常会用到的数据结构,通常常用的主要会是ArrayBlockingQueue、LinkedBlockingQueue和SynchronousQueue。

ArrayBlockingQeue/LinkedBlockingQueue两者的最大不同主要在于存放Queue中对象方式,一个是数组,一个是链表,代码注释里也写到了两者的不同:
Linked queues typically have higher throughput than array-based queues but less predictable performance in most concurrent applications.

SynchronousQueue是一个非常特殊的BlockingQueue,它的模式是在offer的时候,如果没有另外一个线程正在take或poll的话,那么offer就会失败;在take的时候,如果没有另外的线程正好并发在offer,也会失败,这种特殊的模式非常适合用来做要求高响应并且线程出不固定的线程池的Queue。

对于在线业务场景而言,所有的并发,外部访问阻塞的地方的一个真理就是一定要有超时机制,我不知道见过多少次由于没有超时造成的在线业务的严重故障,在线业务最强调的是快速处理掉一次请求,所以fail fast是在线业务系统设计,代码编写中的最重要原则,按照这个原则上面的代码最起码明显犯的错误就是用put而不是带超时机制的offer,或者说如果是不重要的场景,完全就应该直接用offer,false了直接抛异常或记录下异常即可。

对于BlockingQueue这种场景呢,除了超时机制外,还有一个是队列长度一定要做限制,否则默认的是Integer.MAX_VALUE,万一代码出点bug的话,内存就被玩挂了。

说到BlockingQueue,就还是要提下BlockingQueue被用的最多的地方:线程池,Java的ThreadPoolExecutor中有个参数是BlockingQueue,如果这个地方用的是ArrayBlockingQueue或LinkedBlockingQueue,而线程池的coreSize和poolSize不一样的话,在coreSize线程满了后,这个时候线程池首先会做的是offer到BlockingQueue,成功的话就结束,这种场景同样不符合在线业务的需求,在线业务更希望的是快速处理,而不是先排队,而且其实在线业务最好是不要让请求堆在排队队列里,在线业务这样做很容易引发雪崩,超出处理能力范围直接拒绝抛错是相对比较好的做法,至于在前面页面上排队什么这个是可以的,那是另外一种限流机制。

所以说在写高并发、分布式的代码时,除了系统设计外,代码细节的功力是非常非常重要的。

转载自:
http://hellojava.info/

作者:阿里毕玄

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/13922.html

(0)

相关推荐

  • 如果有一个特别大的访问量到数据库上,怎么做优化?主从复制、读写分离「终于解决」

    如果有一个特别大的访问量到数据库上,怎么做优化?主从复制、读写分离「终于解决」第一个就是使用优化查询的方法。这个在前期的内容中有具体说明,这里不再做说明。 第二、这里简要说明一个以下几个方法: 主从复制、读写分离、负载均衡 目前,大部分的主流关系型数据库都提供了主从复制的功能,

    2023-02-09
    161
  • Python工程师

    Python工程师Python是一种简单易学、功能强大的编程语言,在人工智能、数据分析、Web开发等领域有着广泛的应用。Python工程师是指掌握Python语言,具有一定计算机编程基础,能够运用Python语言进行软件开发、数据处理等工作的工程师。

    2024-06-11
    62
  • 5大步骤+10个案例,堪称SQL优化万能公式[亲测有效]

    5大步骤+10个案例,堪称SQL优化万能公式[亲测有效]在应用开发的早期,数据量少,开发人员开发功能时更重视功能上的实现,随着生产数据的增长,很多SQL语句开始暴露出性能问题,对生产的影响也越来越大,有时可能这些有问题的SQL就是整个系统性能的瓶颈。

    2023-06-09
    144
  • 数据库(mysql)基础操作「建议收藏」

    数据库(mysql)基础操作「建议收藏」声明: 1)仅作为个人学习,如有冒犯,告知速删! 2)不想误导,如有错误,不吝指教! 分隔符 DDL(数据定义语言) >建库,建表 DML(数据操作语言) >对表中的记录操作增删改查 DQ

    2023-03-12
    162
  • Delgue语言:帮助人们快速上手的低代码语言

    Delgue语言:帮助人们快速上手的低代码语言大部分的人接触低代码平台,可能是被它的简单操作、短时间的开发周期、性价比等特点所吸引。其中,简单操作易上手是低代码平台最为突出的特点。应用程序开

    2022-12-14
    213
  • 使用conda删除包的方法

    使用conda删除包的方法Python众所周知是一门非常流行的编程语言。它有许多供应商提供的不同发行版,其中的Anaconda是最受欢迎的发行版之一。Anaconda提供了众多内置的包和巨大的包管理系统,使得使用Python变得更加容易。Anaconda提供的conda包管理器可以轻松安装和解除安装各种Python包。在本文中,我们将详细介绍如何使用conda删除包。

    2024-07-18
    41
  • log4j2注解_log4j日志配置

    log4j2注解_log4j日志配置最新爆发的Log4j2安全远程漏洞,又称“Log4Shell”,让整个互联网陷入了威胁之中,大量企业和Java项目都在紧锣密鼓的升级更新补丁,还

    2023-07-13
    144
  • Python String长度函数:计算字符串长度

    Python String长度函数:计算字符串长度在Python中,字符串是一种很常用的数据类型,它是由一系列字符组成的序列。Python给我们提供了一个内置函数len(),用于计算字符串的长度。根据官方文档的介绍:len(s)函数返回对象(字符、字节、列表、字典等)的长度或元素个数。在本文中,我们聚焦在字符串上。

    2024-04-12
    82

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注