由一次kafka消费端消息阻塞问题分析kafka消费端线程模型

最近线上有个需求希望能停止kafka消费某个topic一段时间,结果导致将该系统消费的所有topic都阻塞掉了。

背景介绍

首先介绍下该系统consumer的配置,该系统启动了一个ConsumerConnector,使用1个group同时消费3个topic,每个topic分配了一定数量的消费线程。改造的方案是在消费线程每次调用hasNext方法获取消息前,通过一个动态配置控制线程sleep一段时间。发布上线后推送配置关闭其中1个topic的时候,通过监控发现,其他所有的3个topic全部都停止了消息消费,回滚了配置后,所有topic才又开始继续消费。为什么一个topic的消费线程sleep,会影响所有topic的消息消费呢?

阅读全文

事务消息实现原理

消息队列是日常开发中经常使用的中间件之一,使用得当可以起到很好的解耦、异步、削峰的效果。使用时一般会在完成某一事物的同时发送一条MQ消息来通知其他业务系统进行处理,在一些可靠性要求比较高的场景下我们需要保证本地事物完成那么MQ就必须成功发送,然后由MQ保证消息到达消费方至少一次的投递,消息从MQ到达消费方至少一次投递这个特性市面上常见的MQ组件基本都提供了支持,但是本地事物完成那么MQ就必须成功发送的特性也就是事务消息的特性就较少有MQ组件能够直接支持了。

阅读全文

分布式事务

分布式事务一般是指涉及到操作多个数据库,甚至是操作多个分布式服务的事务,可以看做是多个分布式的操作序列组成的一个逻辑单元。分布式事务的目的是为了保证分布式系统中的数据一致性,作为保证分布式一致性的一种解决方案。

阅读全文

Java的强引用,软引用,弱引用,虚引用及其使用场景

Java中有如下四种类型的引用:

  • 强引用(Strong Reference)
  • 软引用(SoftReference)
  • 弱引用(WeakReference)
  • 虚引用(PhantomReference)

四种引用的级别由高到低依次为:

Strong Reference > SoftReference > WeakReference > PhantomReference

阅读全文

InternalResourceViewResolver引起的内存泄漏问题排查

上午突然收到某项目服务器load,GC报警,通过监控发现FullGC频繁,遂登录服务器排查问题。

首先看到GC日志如下:

1
2
3
4
2017-06-27T11:32:04.208+0800: 517665.833: [Full GC [PSYoungGen: 647168K->8382K(672256K)] [ParOldGen: 1398268K->1398141K(1398272K)] 2045436K->1406524K(2070528K) [PSPermGen: 118009K->118009K(118272K)], 1.6281840 secs] [Times: user=5.83 sys=0.00, real=1.63 secs]
2017-06-27T11:32:12.038+0800: 517673.664: [Full GC [PSYoungGen: 647168K->7685K(672256K)] [ParOldGen: 1398141K->1397889K(1398272K)] 2045309K->1405575K(2070528K) [PSPermGen: 118009K->118009K(118272K)], 1.6880830 secs] [Times: user=5.73 sys=0.00, real=1.69 secs]
2017-06-27T11:32:20.318+0800: 517681.943: [Full GC [PSYoungGen: 647168K->7419K(672256K)] [ParOldGen: 1397889K->1398270K(1398272K)] 2045057K->1405690K(2070528K) [PSPermGen: 118009K->118009K(118272K)], 1.7475230 secs] [Times: user=6.38 sys=0.00, real=1.75 secs]
2017-06-27T11:32:28.477+0800: 517690.103: [Full GC [PSYoungGen: 647168K->7429K(672256K)] [ParOldGen: 1398270K->1397884K(1398272K)] 2045438K->1405314K(2070528K) [PSPermGen: 118009K->118009K(118272K)], 1.5409620 secs] [Times: user=5.34 sys=0.00, real=1.54 secs]

阅读全文

基于空间的架构实践及思考

什么是基于空间的架构

基于空间的架构模型(有时也称为云架构模型)旨在减少限制应用伸缩的因素。模型的名字来源于分布式共享内存中的 tuple space (元组空间)概念。伸缩性是通过去除中心数据库的限制,并使用从内存中复制的数据框架来获得的。保存在内存的应用数据被复制给所有运行的进程。进程可以动态的随着请求数量增减而启动或结束,以此来解决伸缩性问题。这样因为没有了中心数据库,数据库瓶颈就此解决,此后可以近乎无限制的扩展了。

阅读全文

Netty源码分析 解决TCP粘包拆包问题

本文使用netty-4.1.5.Final版本源码进行分析

客户端或者服务端在进行消息发送和接收的时候,需要考虑TCP底层的粘包拆包机制。一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。一般需要上层的应用协议栈设计上,来在应用层,识别出单个完整的数据包。

阅读全文

IntelliJ IDEA下使用JRebel远程热部署

JRebel是一个热部署工具,当在开发环境中对任何一个类或者资源作出修改的时候,它使得应用能在不进行重部署的情况下将变化直接反应在部署好的应用程序上,从而跳过了构建和部署的过程,支持本地热部署和远程热部署。通过Jrebel快速实现热部署,节省了大量重启时间,提高了个人开发效率。

阅读全文

Netty源码分析 Bootstrap客户端启动

本文使用netty-4.1.5.Final版本源码进行分析

Bootstrap是Socket客户端创建工具类,用户通过Bootstrap可以方便的创建Netty的客户端并发起异步TCP连接操作。下面我们看一下客户端Bootstrap如何启动并对启动过程的源码进行分析。

阅读全文

Netty源码分析 ServerBootstrap服务端启动

本文使用netty-4.1.5.Final版本源码进行分析

ServerBootstrap是Socket服务端的启动辅助类,用户通过ServerBootstrap可以方便的创建Netty的服务端,并加以定制。下面我们看一下服务端ServerBootstrap如何启动并对启动过程的源码进行分析。

阅读全文

Netty源码分析 解决NIO的epoll死循环bug

本文使用netty-4.1.5.Final版本源码进行分析

JDK的NIO类库有一个epoll死循环bug,它会导致Selector空轮询,IO线程CPU达到100%,严重影响系统运行。netty从api使用层面对该bug进行了规避解决,下面看下netty的解决策略并从源码了解其具体实现。

阅读全文

Netty源码分析 I/O线程NioEventLoop

本文使用netty-4.1.5.Final版本源码进行分析

NioEvnetLoop作为Netty的I/O线程,主要负责轮询多路复用器,获取就绪的通道,执行网络的连接、客户端请求接入、读和写相关操作。EventLoop的职责不仅仅是处理网络I/O事件,用户自定义的Task和定时任务Task也统一由EventLoop负责处理,这样所有I/O操作都在I/O线程内部串行操作,从而实现了线程模型的统一,避免了多线程并发操作和锁竞争,提升了I/O线程的处理和调度性能。

阅读全文

Netty 线程模型

Reactor模型

Reactor模式:是一个事件驱动模型,有一个或多个并发输入源,有一个Service Handler,有多个Request Handlers;这个Service Handler会同步的将输入的请求(Event)多路复用的分发给相应的Request Handler。

Reactor模式使用的是异步非阻塞模式,对应到Java的NIO上,通过Selector接收客户端的TCP连接请求消息,当链路建立成功或者消息到达后,通过Dispatcher将对应的请求派发到指定的Handler上进行处理。

阅读全文

Java NIO 文件IO-内存映射文件MappedByteBuffer与zerocopy技术

JavaNIO内存映射文件 MappedByteBuffer

JAVA处理大文件,一般用BufferedReader,BufferedInputStream这类带缓冲的IO类,不过如果文件超大的话,更快的方式是采用MappedByteBuffer。

阅读全文

Java NIO Selector详解

Selector选择器

Selector(选择器)选择器提供了选择已经就绪的任务的能力。Selector会不断的轮询注册在上面的所有channel,如果某个channel为读写等事件做好准备,那么就处于就绪状态,通过Selector可以不断轮询发现出就绪的channel,进行后续的IO操作。一个Selector能够同时轮询多个channel。这样,一个单独的线程就可以管理多个channel,从而管理多个网络连接。

阅读全文