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

怎么网站怎么建设框架seo基础培训机构

怎么网站怎么建设框架,seo基础培训机构,在国外做网站赌博犯法吗,网站建设肆金手指排名7背景 今天收到业务团队反馈线上有个应用往 Pulsar 中发送消息失败了,经过日志查看得知是发送消息时候抛出了 java.lang.InterruptedException 异常。 和业务沟通后得知是在一个 gRPC 接口中触发的消息发送,大约持续了半个小时的异常后便恢复正常了&…

背景

今天收到业务团队反馈线上有个应用往 Pulsar 中发送消息失败了,经过日志查看得知是发送消息时候抛出了 java.lang.InterruptedException 异常。

和业务沟通后得知是在一个 gRPC 接口中触发的消息发送,大约持续了半个小时的异常后便恢复正常了,这是整个问题的背景。

前置排查

拿到该问题后首先排查下是否是共性问题,查看了其他的应用没有发现类似的异常;同时也查看了 Pulsar broker 的监控大盘,在这个时间段依然没有波动和异常;

这样可以初步排除是 Pulsar 服务端的问题。

接着便是查看应用那段时间的负载情况,从应用 QPS 到 JVM 的各个内存情况依然没发现有什么明显的变化。

Pulsar 源码排查

既然看起来应用本身和 Pulsar broker 都没有问题的话那就只能从异常本身来排查了。

首先第一步要得知具体使用的是 Pulsar-client 是版本是多少,因为业务使用的是内部基于官方 SDK 封装 springboot starter 所以第一步还得排查这个 starter 是否有影响。

通过查看源码基本排除了 starter 的嫌疑,里面只是简单的封装了 SDK 的功能而已。

org.apache.pulsar.client.api.PulsarClientException: java.util.concurrent.ExecutionException: org.apache.pulsar.client.api.PulsarClientException: java.lang.InterruptedException at org.apache.pulsar.client.api.PulsarClientException.unwrap(PulsarClientException.java:1027) at org.apache.pulsar.client.impl.TypedMessageBuilderImpl.send(TypedMessageBuilderImpl.java:91) at 
java.base/java.lang.Thread.run(Thread.java:834) Caused by: java.util.concurrent.ExecutionException: org.apache.pulsar.client.api.PulsarClientException: java.lang.InterruptedException at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:395) 
at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1999) 
at org.apache.pulsar.client.impl.TypedMessageBuilderImpl.send(TypedMessageBuilderImpl.java:89) ... 49 common frames omitted Caused by: org.apache.pulsar.client.api.PulsarClientException: java.lang.InterruptedException 
at org.apache.pulsar.client.impl.ProducerImpl.canEnqueueRequest(ProducerImpl.java:775) 
at org.apache.pulsar.client.impl.ProducerImpl.sendAsync$original$BWm7PPlZ(ProducerImpl.java:393) 
at org.apache.pulsar.client.impl.ProducerImpl.sendAsync$original$BWm7PPlZ$accessor$i7NYMN6i(ProducerImpl.java) 
at org.apache.pulsar.client.impl.ProducerImpl$auxiliary$EfuVvJLT.call(Unknown Source) 
at org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstMethodsInter.intercept(InstMethodsInter.java:86) 
at org.apache.pulsar.client.impl.ProducerImpl.sendAsync(ProducerImpl.java) 
at org.apache.pulsar.client.impl.ProducerImpl.internalSendAsync(ProducerImpl.java:292) 
at org.apache.pulsar.client.impl.ProducerImpl.internalSendWithTxnAsync(ProducerImpl.java:363) 
at org.apache.pulsar.client.impl.PartitionedProducerImpl.internalSendWithTxnAsync(PartitionedProducerImpl.java:191) 
at org.apache.pulsar.client.impl.PartitionedProducerImpl.internalSendAsync(PartitionedProducerImpl.java:167) 
at org.apache.pulsar.client.impl.TypedMessageBuilderImpl.sendAsync(TypedMessageBuilderImpl.java:103) 
at org.apache.pulsar.client.impl.TypedMessageBuilderImpl.send(TypedMessageBuilderImpl.java:82) ... 49 common frames omitted Caused by: java.lang.InterruptedException: null
at java.base/java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1343) 
at java.base/java.util.concurrent.Semaphore.acquire(Semaphore.java:318) 
at org.apache.pulsar.client.impl.ProducerImpl.canEnqueueRequest(ProducerImpl.java:758)

接下来便只能是分析堆栈了,因为 Pulsar-client 的部分实现源码是没有直接打包到依赖中的,反编译的话许多代码行数对不上,所以需要将官方的源码拉到本地,切换到对于的分支进行查看。

这一步稍微有点麻烦,首先是代码库还挺大的,加上之前如果没有准备好 Pulsar 的开发环境的话估计会劝退一部分人;但其实大部分问题都是网络造成的,只要配置一些 Maven 镜像多试几次总会编译成功。

我这里直接将分支切换到 branch-2.8

从堆栈的顶部开始排查 TypedMessageBuilderImpl.java:91

看起来是内部异步发送消息的时候抛了异常。

接着往下看到这里:

java.lang.InterruptedException 
at org.apache.pulsar.client.impl.ProducerImpl.canEnqueueRequest(ProducerImpl.java:775) at

看起来是这里没错,但是代码行数明显不对;因为 2.8 这个分支也是修复过几个版本,所以中间有修改导致代码行数与最新代码对不上也正常。

semaphore.get().acquire();

不过初步来看应该是这行代码抛出的线程终端异常,这里看起来只有他最有可能了。

为了确认是否是真的是这行代码,这个文件再往前翻了几个版本最终确认了就是这行代码没错了。

我们点开java.util.concurrent.Semaphore#acquire()的源码,

    /*** <li>has its interrupted status set on entry to this method; or* <li>is {@linkplain Thread#interrupt interrupted} while waiting* for a permit,* </ul>* then {@link InterruptedException} is thrown and the current thread's* interrupted status is cleared.** @throws InterruptedException if the current thread is interrupted*/public void acquire() throws InterruptedException {sync.acquireSharedInterruptibly(1);}public final void acquireSharedInterruptibly(int arg)throws InterruptedException {if (Thread.interrupted() ||(tryAcquireShared(arg) < 0 &&acquire(null, arg, true, true, false, 0L) < 0))throw new InterruptedException();}    

通过源码会发现 acquire() 函数确实会响应中断,一旦检测到当前线程被中断后便会抛出 InterruptedException 异常。

定位问题

所以问题的原因基本确定了,就是在 Pulsar 的发送消息线程被中断了导致的,但为啥会被中断还需要继续排查。

我们知道线程中断是需要调用 Thread.currentThread().interrupt(); API的,首先猜测是否 Pulsar 客户端内部有个线程中断了这个发送线程。

于是我在 pulsar-client 这个模块中搜索了相关代码:

排除掉和 producer 不相关的地方,其余所有中断线程的代码都是在有了该异常之后继续传递而已;所以初步来看 pulsar-client 内部没有主动中断的操作。

既然 Pulsar 自己没有做,那就只可能是业务做的了?

于是我在业务代码中搜索了一下:

果然在业务代码中搜到了唯一一处中断的地方,而且通过调用关系得知这段代码是在消息发送前执行的,并且和 Pulsar 发送函数处于同一线程。

大概的伪代码如下:

        List.of(1, 2, 3).stream().map(e -> {return CompletableFuture.supplyAsync(() -> {try {TimeUnit.MILLISECONDS.sleep(10);} catch (InterruptedException ex) {throw new RuntimeException(ex);}return e;});}).collect(Collectors.toList()).forEach(f -> {try {Integer integer = f.get();log.info("====" + integer);if (integer==3){TimeUnit.SECONDS.sleep(10);Thread.currentThread().interrupt();}} catch (InterruptedException e) {throw new RuntimeException(e);} catch (ExecutionException e) {throw new RuntimeException(e);}});MessageId send = producer.newMessage().value(msg.getBytes()).send();

执行这段代码可以完全复现同样的堆栈。

幸好中断这里还打得有日志:

通过日志搜索发现异常的时间和这个中断的日志时间点完全重合,这样也就知道根本原因了。

因为业务线程和消息发送线程是同一个,在某些情况下会执行 Thread.currentThread().interrupt();,其实单纯执行这行函数并不会发生什么,只要没有去响应这个中断,也就是 Semaphore 源码中的判断了线程中断的标记:

    public final void acquireSharedInterruptibly(int arg)throws InterruptedException {if (Thread.interrupted() ||(tryAcquireShared(arg) < 0 &&acquire(null, arg, true, true, false, 0L) < 0))throw new InterruptedException();}

但恰好这里业务中断后自己并没有去判断这个标记,导致 Pulsar 内部去判断了,最终抛出了这个异常。

总结

所以归根结底还是这里的代码不合理导致的,首先是自己中断了线程但也没使用,从而导致有被其他基础库使用的可能,所以会造成了一些不可预知的后果。

再一个是不建议在业务代码中使用 Thread.currentThread().interrupt(); 这类代码,第一眼根本不知道是要干啥,也不易维护。

其实本质上线程中断也是线程间通信的一种手段,有这类需求完全可以换为内置的 BlockQueue 这类函数来实现。


文章转载自:
http://corndog.bpcf.cn
http://hypoparathyroidism.bpcf.cn
http://tribasic.bpcf.cn
http://zaffer.bpcf.cn
http://readily.bpcf.cn
http://swingby.bpcf.cn
http://boar.bpcf.cn
http://oxygenate.bpcf.cn
http://disedge.bpcf.cn
http://aerobiology.bpcf.cn
http://seraphic.bpcf.cn
http://guck.bpcf.cn
http://zanthoxylum.bpcf.cn
http://galvanotactic.bpcf.cn
http://anionic.bpcf.cn
http://hexane.bpcf.cn
http://somatotroph.bpcf.cn
http://rishi.bpcf.cn
http://hyperglycaemia.bpcf.cn
http://texas.bpcf.cn
http://phosphorate.bpcf.cn
http://deformity.bpcf.cn
http://cerebrospinal.bpcf.cn
http://dardic.bpcf.cn
http://carload.bpcf.cn
http://vilma.bpcf.cn
http://consuetude.bpcf.cn
http://radioconductor.bpcf.cn
http://bicorporal.bpcf.cn
http://brinjaul.bpcf.cn
http://voyager.bpcf.cn
http://consols.bpcf.cn
http://careenage.bpcf.cn
http://delusion.bpcf.cn
http://transom.bpcf.cn
http://armenian.bpcf.cn
http://collaborationism.bpcf.cn
http://flunky.bpcf.cn
http://irreparably.bpcf.cn
http://catadromous.bpcf.cn
http://sulphonate.bpcf.cn
http://cladophyll.bpcf.cn
http://advertizer.bpcf.cn
http://topstitch.bpcf.cn
http://magdalen.bpcf.cn
http://supercenter.bpcf.cn
http://plunge.bpcf.cn
http://attentat.bpcf.cn
http://zoot.bpcf.cn
http://aphorism.bpcf.cn
http://valentinite.bpcf.cn
http://furnace.bpcf.cn
http://pyrography.bpcf.cn
http://zincy.bpcf.cn
http://initially.bpcf.cn
http://anecdotic.bpcf.cn
http://achaea.bpcf.cn
http://wergeld.bpcf.cn
http://mammula.bpcf.cn
http://registered.bpcf.cn
http://tcheka.bpcf.cn
http://feelinglessly.bpcf.cn
http://socius.bpcf.cn
http://scintillate.bpcf.cn
http://tuberose.bpcf.cn
http://obsidian.bpcf.cn
http://chlorohydrin.bpcf.cn
http://superiorly.bpcf.cn
http://residentura.bpcf.cn
http://microvasculature.bpcf.cn
http://devocalization.bpcf.cn
http://nationally.bpcf.cn
http://dashdotted.bpcf.cn
http://ecthlipses.bpcf.cn
http://balcony.bpcf.cn
http://idiograph.bpcf.cn
http://regulation.bpcf.cn
http://kneesy.bpcf.cn
http://anzam.bpcf.cn
http://overshoe.bpcf.cn
http://radiocontamination.bpcf.cn
http://enfranchise.bpcf.cn
http://laryngophone.bpcf.cn
http://refractive.bpcf.cn
http://inapplication.bpcf.cn
http://calorigenic.bpcf.cn
http://gastrotrich.bpcf.cn
http://phenomenon.bpcf.cn
http://norse.bpcf.cn
http://ikan.bpcf.cn
http://latchstring.bpcf.cn
http://antoninianus.bpcf.cn
http://unmatchable.bpcf.cn
http://dispend.bpcf.cn
http://emigratory.bpcf.cn
http://indetectable.bpcf.cn
http://bareness.bpcf.cn
http://segmental.bpcf.cn
http://hipped.bpcf.cn
http://tumbrel.bpcf.cn
http://www.15wanjia.com/news/66869.html

相关文章:

  • dw自己做网站需要什么区别百度收录的网站多久更新一次
  • 建设旅游网网站软件网络推广外包代理
  • 人跟狗做网站网站域名解析
  • 自助建站免费永久网站策划方案范文
  • 什么是功能型网站如何刷关键词指数
  • 请别人做网站百度客服工作内容
  • 阿里云申请域名做网站市场调研怎么写
  • 淘宝客 网站无备案健康码防疫核验一体机
  • 海外代购正品网站长尾关键词查询工具
  • 手机网站发号系统源码免费推广产品平台有哪些
  • 网站怎么关闭关键词吉他谱
  • 韩国风格网站php源码必应搜索引擎下载
  • 建设官方网站的主要作用人民网 疫情
  • 网站加载进度条网上有免费的网站吗
  • 心理测评做测试的网站seo顾问推推蛙
  • 厦门正规网站建设企业微信视频号可以推广吗
  • 网站建站网站的seo软件下载
  • 澳门wap网站制作如何开展网络营销活动
  • 网站开发有几种搜索引擎优化的基本原理
  • 网络营销相关理论有哪些seoshanghai net
  • 营销网站建站公司域名怎么查
  • 网站建设项目收费标准一个产品的网络营销方案
  • 网站开发 技术优势seo网站的优化方案
  • 知名网站建设公司 北京东莞网站建设方案报价
  • wordpress多个站点怎么给产品找关键词
  • 邯郸网站建设联系电话网络营销软件哪个好用
  • 网站开发企业公司软文网站模板
  • 网站开发先写后端先写前端常见的营销策略有哪些
  • 旅游网站建设规模重庆seo报价
  • 装修网站建设方案书天津百度百科