IDEA中自定义外部工具external tool

1. javap工具使用说明

我们会使用javap工具来反汇编class字节码文件,查看编译后的字节码命令。其用法如下:

2. 将javap工具集成到IDEA中

为了方便我们分析反汇编的内容,我们可以把该功能集成到IDEA中。打开IDEA的设置,选择external tools。然后创建两个外部工具,称为show byte code和compile java code,分别用来查看反汇编内容和编译JAVA代码生成字节码文件。设置的时候可以使用一些有......

metaspace OOM问题解决

1. 什么是metaspace

JDK8中去掉了原来的永久代,而用metaspace来替代。并且metaspace现在是使用了netive memory。

原来放在永久代里面的东西也全部放到元数据区了。元数据区主要包含以下内容:

name and fields of the class: 存放类名字、成员变量相关的元数据

methods of a class with the bytecode of the methods: 存放类方法的元数据

const......

使用prometheus来监控docker swarm集群

1. 开启docker metrics API特性

注意使用的docker版本必须为1.13

# 编辑docker daemon启动选项

vim /etc/docker/daemon.json

该文件修改内容如下:

{

"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"],

"insecure-registries":["10.45.10.31:5000"],

"experimental": true,

"metrics-addr": "0.0.0.0:4999"

}

解释:

第一行指明了第三方doc......

使用rancher管理docker

1. 介绍

Rancher 是一个容器管理的完整解决方案,并且即将成为一个完整的容器管理平台。了解rancher的功能可以看下官方的提供的介绍视频Rancher Overview。注意看该视频需要科学上网。

详细的rancher使用建议查看rancher官方文档

2. 安装

2.1 下载镜像

# server

docker pull rancher/server

2.2 部署mysql

因为rancher需要使用mysql,所以需要启动mysql容器

docker pull mysql

docker run -d --name mysqldb -e MYSQL_ROOT_PAS......

swarm mode使用

1. 介绍

docker 1.12版本以后就将docker swarm这个工具集成到了docker当中了。老版本使用docker swarm可以参考我的文章docker swarm安装使用

本文对于swarm mode的使用说明主要参考官方文档:Swarm mode overview

swarm mode相比原来的docker swarm在使用上方便了很多。未来肯定是取代docker swarm了,毕竟都内置在docker了。

2. 准备工作

2.1 开启docker node的2375端口

确保开启Docker的TCP连接端口。

PS: 需要被swarm管理的节点上的dock......

docker swarm安装使用

1. 介绍

1.1 简介

Docker Swarm 是 Docker 官方编排(Orchestration)项目之一,负责对 Docker 集群进行管理。

Docker Swarm 是 Docker公司官方在 2014 年 12月初发布的一套管理 Docker 集群的工具。它将一群 Docker 宿主机变成一个单一的,虚拟的主Swarm 使用标准的 Docker API 接口作为其前端访问入口,换言之,各种形式的Docker 工具比如 Dokku,Compose,Krane,Deis,docker-py,Docker 本身等都可以很容易的与 Swarm 进行集成。

注意: docker......

使用Portainer管理docker

1. 介绍

portainer是一款docker容器管理工具,基于swarmkit提供了图形化的管理界面。功能主要包含:

镜像管理

网络管理

数据卷管理

应用模板

状态面板

类似工具还有crane、 rancher和docker datacenter(ddc,收费的)。 这里面portainer和rancher相对比较成熟,而且也是免费和开源的。本文先对portainer做介绍。对rancher感兴趣的可以查看我的另外一篇博客:使用rancher管理docker。

2. 安装和启动

详情可以参考官方部署文档,这里我仅仅做简单说明。

2.1 安装

docker pull port......

docker构建java、tomcat、mysql生产环境镜像

1. 构建带基本环境的centos镜像

这里我们基于centos构建基本的操作系统镜像。

1.1 编辑dockerfile

创建文件centos.dockerfile用于构建镜像

############################################

# version : kami/centos

# desc : 构建包含supervisor、ssh环境的centos

############################################

# 设置继承centos官方镜像

FROM centos

# 下面是一些创建者的基本信息

MAINTAINE......

利用docker数据卷容器进行备份恢复

1. 共享数据卷容器

数据卷容器里面的数据可以在各个容器间进行共享。下面演示下操作。

1.1 创建数据卷容器

数据卷容器,顾名思义,就是将一个正常的容器作为数据卷,让其他容器通过挂载这个容器实现数据共享.可是值得注意的是,数据卷容器会降低I/O性能。

首先创建一个数据卷容器,挂载到容器的/data目录。

# 这里我们把ubuntu镜像生成的容器作为数据卷容器

docker run -it -v /data --name data ubuntu

# 在data目录下随便生成点内容

echo data >> data.txt

# 退出数据卷容器

exit

1.2 共享数据卷......

docker registry v2构建私有仓库

1. 介绍

现在registry已经使用v2了,注意是和旧版v1不兼容的。两者的区别可以参考文章:Docker Registry V1 与 V2 的区别解析以及灵雀云的实时同步迁移实践

我采用的docker版本为:1.12.3

2. 安装docker-registry v2

2.1 安装镜像启动容器

docker run -d -p 5000:5000 --restart=always --name registry registry:2

......

简单回顾hbase

本文对部分hbase的知识点做个简单的文章索引。通过一些不错的博客来回顾一下hbase的相关知识。

1. hbase原理回顾

Hbase基础原理

HBase 深入浅出

这两个关于Hbase的博客重点推荐下:

有态度的HBase

HBase 深入浅出

这里再放一些引用的图,方便回顾,重点搞清楚其存储结构和数据模型就行啦。

1.1 基本存储结构

1.2 数据模型

正向代理和反向代理理解

1. 正向代理

正向代理:隐藏了真实的请求客户端,服务端不知道真实的客户端是谁,客户端请求的服务都被代理服务器代替来请求。一般正向代理都需要客户端做一些额外的配置,指定需要将请求发送给哪个代理服务器。这个过程中注意,客户端是知道请求发送给了代理,由代理再去负责使用该请求访问特定的服务器。

例子:科学上网工具SS就可以理解为正向代理。客户端都要安装SS配置后才能使用正向代理。

作用:

通过代理服务器可以访问一些原本受限无法访问的服务器。

缓存,加速资源访问

客户端访问授权,上网认证

代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息

2. 反向代理

反向代理:隐藏了真实的......

第6章:锁

本章是mysql技术内幕这本书的读书笔记。可以点击超链接查看所有的读书笔记。

1. Innodb存储引擎中的锁

1.1 数据库锁分类(latch和lock)

latch:轻量级锁,要求锁定时间非常短。如果持续时间长,则应用的性能会非常差。在InnoDB存储引擎中,latch可以分为mutex(互斥量)和rwlock(读写锁)

lock: 锁的对象是事务。用来锁定的是数据库中的表、页、行对象。

关于两者的比较可以参考下图:

查看锁信息的方式;

# 查看latch信息

......

第5章:索引和算法

本章是mysql技术内幕这本书的读书笔记。可以点击超链接查看所有的读书笔记。

1. B+树与索引

B+树就是指一个多路平衡树,只不过记录都存放在叶子节点,其他节点都是索引节点。

1.1 B+树插入

扇出的值是固定的。在数据库里面B+树索引的层数一般都比较低,位2-4层,这样经过2-4次IO就可以取到数据。

推荐看下书上p188-p199的例子,演示了B+树上插入操作的进行过程。B+树插入操作分情况主要依据叶子节点和索引节点是否插满了数据。

对于插入操作注意以下知识点:

优先进行树的旋转避免插入时的页拆分。在某个叶子节点满,但是其兄弟节点没有满的情况下优先进行树的旋转(其实就是移......

JAVA的堆内存储VS堆外存储

1. 介绍

在很多JAVA实现的产品中我们都可以看到JVM的off heap内存空间的使用。例如kafka、ignite、alluxio等等。这说明OS管理内存是有好处的,例如可以利用os page cache来改进IO性能。

今天看到一篇PPT似乎不错,打算学习下。PPT原文见:On heap cache vs off-heap cache

2. heap上对象的开销

3. JAVA中分配堆外空间的方法

3.1 java.nio.ByteBuffer

......

分布式全局自增ID

1. 全局自增ID啥用?

MQ有序消费

MVCC实现

分表分库场景

more...

2. 生产全局唯一ID方法

2.1 数据库自增ID

当服务使用的数据库只有单库单表时,可以利用数据库的auto_increment来生成全局唯一递增ID.

优势:

简单,无需程序任何附加操作

保持定长的增量

在单表中能保持唯一性

劣势:

高并发下性能不佳,主键产生的性能上限是数据库服务器单机的上限。

水平扩展困难,在分布式数据库环境下,无法保证唯一性。

2.2 UUID

一般的语言中会自带UUID的实现,比如Java中UUID方式UUID.randomUUID().toStri......

BlockingQueue浅析

1. Queue分类

1.1 BlockingQueue

BlockingQueue是并发包里阻塞队列的一个接口。主要有(针对JDK1.8版本)如下几种(下面的ConcurrentLinkedQueue和LinkedTransferQueue不是阻塞队列哦。):

队列

有界性

数据结构

ArrayBlockingQueue

bounded

加锁

array list

LinkedBlockingQueue

optionally-bounded

加锁

linked list

PriorityBlockingQueue

unbounded

加锁

heap

Delay......

聊聊JAVA的线程池

1. 介绍

并发包提供了几种不同类型的线程池。今天我们来更加仔细地看看其实现原理。下面的分析适用于JDK1.7

2. 类分析

类的结构如下:

2.1 池分类

通过ThreadPoolExecutor创建的池: 例如Fixed pool 、Cached pool和singleThread等线程池。在1.8中还引入了WorkStealingPool这个基于ForkJoinPool里面窃取工作算法的线程池,可以关注下。

通过ScheduledThreadPoolExecuto......

Kafka和RocketMQ的一点对比总结

1. 介绍

Kafka和RcoketMQ是市面上比较主流的分布式消息队列。本文对他们做一番对比。如果对MQ还不是很熟悉的,可以先看看他们的文档,再来看本文。

2. MQ系统的关键问题——如何处理消息有序、消息重复

2.1 消息有序

Kafka和RocketMQ都不支持严格的消息有序。他们都仅仅保证在一个topic分区(队列)中是有序的。当然如果只使用一个分区或者队列来提供消费,性能肯定是比较差的了。

十分钟入门RocketMQ里面说RocketMQ支持严格消息有序。我觉得可能是指的生产者把消息发往一个队列中。 如果是这样的话,不能算是MQ的严格有序,因为牺牲了太多性能。后续再看看源码......

canal设计上的一些小分析

1. 介绍

canal是阿里开源的一个binlog解析工具。本文对其设计上的一些小细节进行一番琢磨。

如果还不熟悉canal可以看看canal官方wiki和我写的canal源码解析系列。然后再看我现在这篇文章,可能会有更多的共鸣。

2. binlog解析原理的小思考

按照wiki所说,从上层来看,复制分成三步:

master将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events,可以通过show binlog events进行查看);

slave将master的binary log events拷贝到它的中继日志(relay......

再来理解下ThreadLocal类

1. 什么是ThreadLocal类

JDK官方文档对其定义如下:

This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable. ThreadLocal instances are typically pri......

缓存雪崩和缓存击穿

1. 缓存击穿(穿透)

1.1 定义

缓存穿透: 查询一个在缓存内必然不存在的数据。例如查询一篇文章的ID,这个ID在缓存和DB里面都是必然不存在的。如果类似这样的查询请求特别多,就会给DB带来很大的压力。

1.2 解决

使用BITMAP来过滤:最常见的则是采用布隆过滤器(bloom filter),将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。在JAVA里面使用布隆过滤器,可以使用guava里面的bloomFilter。如果需要基本的bitmap数据结构,可以使用util下面的BitSe......

mysql性能分析方法、工具、经验总结

1. 介绍

MYSQL的性能瓶颈分析一般从两个维度去排查:

操作系统层面: 这个可以利用vmstat、iostat等工具查看OS本身在CPU、磁盘、内存上的瓶颈。提前利用一些mysqlslap这种工具做一些benchmark避免硬件资源设计部合理。

MySQL本身使用不当导致的性能瓶颈(索引问题、SQL语句问题、配置问题等等)。

PS: 我这里实验用的都是5.7版本的

2. 查询与索引优化

2.1 状态检查

我们可以通过show命令查看MySQL状态及变量,找到系统的瓶颈:

#显示状态信息(扩展show status like ‘XXX’)

Mysql> show sta......

ForkJoinPool解读

1. 介绍

JDK1.7在并发包里面引入了这个玩意儿。根据 Doug Lea 的论文——《A Java Fork/Join Framework》而来。主要通过分而治之(把大任务分割成若干个小任务)然后合并结果这种思想来实现的线程池。有更加好的并发性能。之所以有更好的并发性能,是因为其充分利用了所有线程的工作能力,避免空闲线程,充分发挥多核并行的处理能力。这个关键是后面的working stealing算法。

此外强烈推荐下Java7中的ForkJoin并发框架初探(中)这个系列的文章,作为我这篇文章的补充阅读吧。写的很好。

PS: 本文的介绍主要以JDK1.7版本为例

2. Fork......

从Runnable到Callable谈到ExecutorServer的submit方法和execute方法

1. 介绍Runnable和Callable

创建线程类一般使用的方式有三种:

继承Thread调用start方法

实现Runnable接口调用run方法

实现Callable接口调用call方法

如今,第一种方式肯定是差不多淘汰了。因为用继承约束很大。

关于使用Runnable和Callable接口的异同在StackoverFlow的一篇帖子The difference between the Runnable and Callable interfaces in Java中说的比较清楚。

主要区别就是:

Runnable能做得,Callable都能做。但是Callable......

第五章:调优案例分析与实战

本文是深入理解Java虚拟机-读书笔记系列的文章,查看所有文章目录可以点击该超链接查看。

1. 高性能硬件上的程序部署策略

一个PV比较大的网站,有时候长时间失去响应,这是由于GC造成。JVM默认使用PS这种吞吐量优先收集器,一次full GC停顿高达14秒。程序设计导致大量较大的文档数据驻留在内存。

心得:如果full GC比较少、绝大多数对象的存活时间都比较短,才建议使用较大的堆。否则GC的开销会比较大,有较长的时间停顿。

2. 集群间同步导致的内存溢出

由于集群同步大量数据,导致数据过多,而超过内存限制。

心得:

发生OOM的时候自动生成堆dump文件可以加参数: -XX......

第四章:虚拟机性能监控与故障处理工具

本文是深入理解Java虚拟机-读书笔记系列的文章,查看所有文章目录可以点击该超链接查看。

这部分的内容之前我有文章写过了,具体可以查看:

JVM调优排错工具jps、jstack、jmap、jhat、jstat、jvisualvm等的使用

PS: jhat在JAVA9中要被移除,该命令的功能可以用其他命令代替,所以可以不用看了。

关于《深入理解Java虚拟机》的书中第四章,以下内容可以了解下:

HSDIS反汇编插件: 工具下载的话可以去HLLVM看看,具体用法可以参考书上的P112-P114的内容

书上没有详细写thread dump和heap dump如何操作分析,不过这个自己还是要......

谈谈kafka的exactly once

1. 介绍

今天在复习kafka的一些知识。然后又对消息分发的语义进行了一番思考,还与小伙伴好好讨论了一番。这里小做总结。

2. mq如何做exactly once

要满足exactly once需要同时满足:

发送消息阶段,不允许发送重复的消息。

消费消息阶段,不允许消费重复的消息。

这个是文章十分钟入门RocketMQ里面写到的。

2.1 发送者如何保证不发送重复消息

在mq系统中,不采用重发策略(前提网络是完美的。。否则会丢消息,不符合整个系统是exactly once)

业务本身确保不发送重复的消息

2.2 消费者如何保证不重复消费

这里的不重复消费,主要指处......

kafka压力测试

1. 介绍

最近kafka集群要换机房了。为了确保新环境正常,我们来做一些压力测试。这次压力测试重点会关注一些异常情况下,kafka收发消息的状况。

2. 基本信息

3台broker,使用kafka0.10.1版本,每台broker使用6T硬盘,内存100G。broker配置按照官方文档推荐的生产配置来配置。

3. broker挂掉的情况

3.1 整个broker集群挂掉

这个同事做过测试,所以这里直接放结论了:

即使设置了acks=all,但是如果整个集群都连接不上了,也是不能避免消息丢失的(重发次数到了设定的值,或者发送请求超时了都会导致生产者丢弃该条消息,发送下一条消息)。重......

JAVA后端问题定位和排错

1. 介绍

原本打算自己总结一下的。但是觉得人家总结的很好,我这里就不浪费笔墨了,给大家推荐一下文章即可。

linux后端诊断与调试技术

PPT-JVM问题定位和排错

下面我对文章中可以重点关注的一些点做一下强调。大家看的时候可以留意下。

2. 查找JAVA进程中消耗CPU最多的线程

这个问题大家可能经常碰到。传统的做法是:

top命令找出有问题Java进程及线程id:

a. 开启线程显示模式(shift+h)

b. 按CPU使用率排序(shift+p,如果按照内存排就shift+m)

c. 记下Java进程id及其CPU高的线程id

用进程id作为参数,jstack有问题的......