zero's Blog

持续迭代

[toc]
javapoet可以更加快捷地生成字节码,实现原理其实也就是对JavaAPT的封装,然而Javapoet有一个局限性,就是只能生成新的.class文件,却无法修改原有的类,这也是它的一大局限性所在。接下来就让我们看看它的使用方法把。

01 简单使用

使用之前要先引入这个库

1
compile 'com.squareup:javapoet:1.7.0'

javapoet是用来生成代码的,需要借助如下几个常用类

类名 作用
MethodSpec 代表一个构造函数或方法声明
TypeSpec 代表一个类,接口,或者枚举声明
FieldSpec 代表一个成员变量,一个字段声明
JavaFile 包含一个顶级类的Java文件
ParameterSpec 用来创建参数
AnnotationSpec 用来创建注解
ClassName 用来包装一个类
TypeName 类型,如在添加返回值类型是使用 TypeName.VOID

除此之外 JavaPoet提供了一套自定义的字符串格式化规则,常用的有

格式化规则 表示含义
$L 字面量
$S 字符串
$T 类、接口
$N 变量
Read more »

[toc]

Selector 简介

Selector(选择器)是 Channel 的多路复用器,它可以同时监控多个 Channel 的 IO 状况,允许单个线程来操作多个 Channel。如下:

img

Selector 的作用是什么?

Selector 提供选择执行已经就绪的任务的能力。从底层来看,Selector 提供了询问 Channel 是否已经准备好执行每个 I/O 操作的能力。Selector 允许单线程处理多个 Channel。仅用单个线程来处理多个 Channels 的好处是,只需要更少的线程来处理 Channel 。事实上,可以只用一个线程处理所有的通道,这样会大量的减少线程之间上下文切换的开销。

Read more »

内置锁ObjectMonitor类
Monitor可以理解为一个同步工具或一种同步机制,通常被描述为一个对象。每一个Java对象就有一把看不见的锁,称为内部锁或者Monitor锁。

通常所说的对象的内置锁,是对象头Mark Word中的重量级锁指针指向的monitor对象,每个对象都存在着一个 Monitor对象与之关联。执行 monitorenter 指令就是线程试图去获取 Monitor 的所有权,抢到了就是成功获取锁了;执行 monitorexit 指令则是释放了Monitor的所有权。

该对象是在HotSpot底层C++语言编写的(openjdk里面看),简单看一下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//结构体如下
ObjectMonitor::ObjectMonitor() {
_header = NULL;
_count = 0;
_waiters = 0,
_recursions = 0; //线程的重入次数
_object = NULL;
_owner = NULL; //标识拥有该monitor的线程
_WaitSet = NULL; //等待线程组成的双向循环链表,_WaitSet是第一个节点
_WaitSetLock = 0 ;
_Responsible = NULL ;
_succ = NULL ;
_cxq = NULL ; //多线程竞争锁进入时的单向链表
FreeNext = NULL ;
_EntryList = NULL ; //_owner从该双向循环链表中唤醒线程结点,_EntryList是第一个节点
_SpinFreq = 0 ;
_SpinClock = 0 ;
OwnerIsThread = 0 ;
}
Read more »

[toc]

前言

ZGC(The Z Garbage Collector)是JDK 11中推出的一款低延迟垃圾回收器,它的设计目标包括:

  • 停顿时间不超过10ms;

  • 停顿时间不会随着堆的大小,或者活跃对象的大小而增加;

  • 支持8MB~4TB级别的堆(未来支持16TB)。

从设计目标来看,我们知道ZGC适用于大内存低延迟服务的内存管理和回收。本文主要介绍ZGC在低延时场景中的应用和卓越表现,文章内容主要分为四部分:

  • GC之痛:介绍实际业务中遇到的GC痛点,并分析CMS收集器和G1收集器停顿时间瓶颈;

  • ZGC原理:分析ZGC停顿时间比G1或CMS更短的本质原因,以及背后的技术原理;

  • ZGC调优实践:重点分享对ZGC调优的理解,并分析若干个实际调优案例;

  • 升级ZGC效果:展示在生产环境应用ZGC取得的效果。

Read more »

[toc]

一、为什么需要 Pod

容器的基本概念

Pod 是 Kubernetes 项目里面一个非常重要的概念,也是非常重要的一个原子调度单位,但是为什么我们会需要这样一个概念呢?在使用容器 Docker 的时候,也没有这个说法。其实,如果想要理解 Pod,首先要理解容器,所以来回顾一下容器的概念:

容器的本质实际上是一个进程,是一个视图被隔离,资源受限的进程。

容器里面 PID=1 的进程就是应用本身,这意味着管理虚拟机等于管理基础设施,因为我们是在管理机器,但管理容器却等于直接管理应用本身。这也是之前说过的不可变基础设施的一个最佳体现,这个时候,你的应用就等于你的基础设施,它一定是不可变的。

Read more »

[toc]

容器

容器的工作原理主要依赖于操作系统层面的资源隔离和限制技术。

与传统的虚拟机不同,容器不需要运行完整的操作系统,而是直接在宿主机的操作系统上运行。容器共享宿主机的内核,但在文件系统、进程、网络和其他资源方面实现了隔离。以下是容器工作原理的关键技术:

命名空间(Namespaces)

namespaces是Linux内核提供的一种资源隔离机制,它可以将系统资源(如进程、文件系统、网络等)划分为多个独立的命名空间。容器内进程拥有独立视图:

  • PID命名空间隔离进程ID,网络命名空间提供独立网络栈。‌
  • 其他类型包括Mount(文件系统挂载点)、IPC(进程通信)、UTS(主机名)和User(用户ID)命名空间。‌

每个容器运行在自己的名字空间中,互不干扰。

Read more »

[toc]

控制器类型

  • ReplicationController 和 ReplicaSet
  • Deployment
  • DaemonSet
  • StateFulSet
  • Job/CronJob
  • Horizontal Pod Autoscaling
Read more »

[toc]

一、Docker

在介绍docker之前,先简单回顾一下操作系统是如何管理进程的。

首先,当我们登录到操作系统之后,可以通过 ps 等操作看到各式各样的进程,这些进程包括系统自带的服务和用户的应用进程。那么,这些进程都有什么样的特点?

  • 第一,这些进程可以相互看到、相互通信;
  • 第二,它们使用的是同一个文件系统,可以对同一个文件进行读写操作;
  • 第三,这些进程会使用相同的系统资源。

这样的三个特点会带来什么问题呢?

  • 因为这些进程能够相互看到并且进行通信,高级权限的进程可以攻击其他进程;
  • 因为它们使用的是同一个文件系统,因此会带来两个问题:这些进程可以对于已有的数据进行增删改查,具有高级权限的进程可能会将其他进程的数据删除掉,破坏掉其他进程的正常运行;此外,进程与进程之间的依赖可能会存在冲突,如此一来就会给运维带来很大的压力;
  • 因为这些进程使用的是同一个宿主机的资源,应用之间可能会存在资源抢占的问题,当一个应用需要消耗大量 CPU 和内存资源的时候,就可能会破坏其他应用的运行,导致其他应用无法正常地提供服务。

针对上述的三个问题,如何为进程提供一个独立的运行环境呢?

  • 针对不同进程使用同一个文件系统所造成的问题而言,Linux 和 Unix 操作系统可以通过 chroot 系统调用将子目录变成根目录,达到视图级别的隔离;进程在 chroot 的帮助下可以具有独立的文件系统,对于这样的文件系统进行增删改查不会影响到其他进程;
  • 因为进程之间相互可见并且可以相互通信,使用 Namespace 技术来实现进程在资源的视图上进行隔离。在 chroot 和 Namespace 的帮助下,进程就能够运行在一个独立的环境下了;
  • 但在独立的环境下,进程所使用的还是同一个操作系统的资源,一些进程可能会侵蚀掉整个系统的资源。为了减少进程彼此之间的影响,可以通过 Cgroup 来限制其资源使用率,设置其能够使用的 CPU 以及内存量。

容器就是一个视图隔离、资源可限制、独立文件系统的进程集合。容器就是一个进程集合,它将系统的其他资源隔离开来,具有自己独立的资源视图。Docker 就是基于上述技术实现的。

Read more »

[toc]

基于mysql最简单分布式ID实现

mysql自带自增主键功能,我们可以建一个表,主键id设置成自增,然后需要获取id,就往该表中插入一条数据,获取一下新增id即可。
这种方式优点就是简单。缺点也很明显

  • 随着时间推移,表中数据越来越多,毕竟获得一个id就要插入一条数据。
  • 所有获取id的都去请求这个数据库,很显然,高并发场景下单机会很乏力。
Read more »

  Spring boot为了自动配置,增加了注解@EnableAutoConfiguration。一般只需要配置@SpringBootApplication即可,为什么呢?

1
2
3
4
5
6
7
8
9
10
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

  很明显的,这个注解就是三个常用的注解@SpringBootConfiguration@EnableAutoConfiguration以及@ComponentScan组合在一起。

Read more »
0%