Dec 21, 2020 - Java 线程池配置的常见误区

4539 Word Count

前言 由于线程的创建和销毁对操作系统来说都是比较重量级的操作,所以线程的池化在各种语言内都有实践,当然在 Java 语言中线程池是也非常重要的一部分,有 Doug Lea 大神对线程池的封装,我们使用的时候是非常方便,但也可能会因为不了解其具体实现,对线程池的配置参数存在误解。 我们经常在一些技术书籍或博客上看到,向线程池提交任务时,线程池的执行逻辑如下: 当一个任务被提交后,线程池首先检查正在运行的线程数是否达到核心线程数,如果未达到则创建一个线程。 如果线程池内正在运行的线程数已经达到了核心线程数,任务将会被放到 BlockingQueue 内。 如果 Block...

Mar 17, 2020 - 如何计算服务限流的配额

4938 Word Count

问题 请求被限流 之前的文章提到过我们服务使用 Hystrix 进行服务限流,使用的是信号量方式,并根据接口的响应时间和服务的峰值 QPS 设置了限流的配额。 限流配额的计算方式为: 我们接口单机单个接口的峰值 QPS 为 1000,平均影响时长 15ms,我们认为 Hystrix 的信号量是并发量,那么一个信号量在一秒内能允许 1000ms/15ms~66 个请求通过,那么服务 1000QPS 配置 15 个信号量就足够了。 当然这是在忽略上下文切换和 GC 时间的情况下,考虑上这些因素,每个并发量每秒能服务的时长约为 900ms,用同样的公式计算所需要的信号量是 17,为了应...

Mar 10, 2020 - 使用状态机解决多状态问题

6183 Word Count

背景 接上文玩转 Java 动态编译,实现了 Java 代码的动态编译后,接下来就要填补上文中提到的坑,将原来使用注释配置的 Java 数据类型改为使用缩写替代。 为了便于缩写,能直观地看出完整类型,我设计的方案是: 对简单类型如 String、int、Double,就使用类型的首字母替代,如 i -> int / D -> Double; 对于容器类型如 List、Map,使用两个首字母分别标志容器的开始和闭合,如 LDL -> List<Double> / MDDM -> Map<Double,Double>; 由...

Dec 28, 2019 - 玩转 Java 动态编译

4018 Word Count

背景 问题 之前的文章 从 Spring 的环境到 Spring Cloud 的配置 中提到过我们在使用 Spring Cloud 进行动态化配置,它的实现步骤是先将动态配置通过 @Value 注入到一个动态配置 Bean,并将这个 Bean 用注解标记为 @RefreshScope,在配置变更后,这些动态配置 Bean 会被统一销毁,之后 Spring Cloud 的 ContextRefresher 会将变更后的配置作为一个新的 Spring Environment 加载进 ApplicationContext,由于 Scoped Bean 都是 Lazy Init 的,它们会在下...

Dec 10, 2019 - ThreadLocalRandom 安全吗

4398 Word Count

背景 前言 最近在写一些业务代码时遇到一个需要产生随机数的场景,这时自然想到 jdk 包里的 Random 类。但出于对性能的极致追求,就考虑使用 ThreadLocalRandom 类进行优化,在查看 ThreadLocalRandom 实现的过程中,又追了下 Unsafe 有部分代码,整个流程下来,学到了不少东西,也通过搜索和提问解决了很多疑惑,于是总结成本文。 转载随意,文章会持续修订,请注明来源地址:https://zhenbianshu.github.io 。 Random 的性能问题 使用 Random 类时,为了避免重复创建的开销,我们一般将实例化好的 Random ...

Nov 30, 2019 - 记一次简单的 JVM 调优

2617 Word Count

背景 最近对负责的项目进行了一次性能优化,其中包括对 JVM 参数的调整,算是进行了一次简单的 JVM 调优,JVM 参数调整之后,服务的整体性能有 5% 左右的提升,还算不错。 先介绍一下项目的基本情况: 项目是一个高 QPS 压力的 web 服务,单机 QPS 一直维持在 1.5K 以上,由于旧机器的”拖累”,配置的堆大小是 8G,其中 young 区是 4G,垃圾回收器用的是 parNew + CMS。 转载随意,文章会持续修订,请注明来源地址:https://zhenbianshu.github.io 。 旧状 首先是查看当前 GC 的情况,主要是使用 jstat 查...

Oct 27, 2019 - 理解二进制操作

2787 Word Count

引言 最近在用 shell 写一个小工具,里面要用到复杂的二进制操作,对 int 值进行位操作和与或非,而 shell 的语法里,& 是取布尔与,>> 是重定向,不支持二进制操作,为了写出只需要默认系统环境就可以运行的程序,于是只好摸出了好久不用的 C。在使用 C 实现二进制操作的过程中,对二进制的操作有了新的理解。 当然本文并不是要讲 C 语言的语法,而是对二进制操作符的梳理和代码里常用二进制操作的总结。 转载随意,文章会持续修订,请注明来源地址:https://zhenbianshu.github.io 。 移位操作 负数的二进制 在了解移位操作之前,我...

Oct 9, 2019 - 聊聊单元测试

2809 Word Count

单元测试 写的代码能一次正确执行是每个程序员的追求,但世事皆不能尽如人意,我们的代码经常会有 Bug,这就需要测试的存在。 测试有黑盒和白盒之分。黑盒测试,测试时认为被测程序就像一个漆黑的盒子,虽然不明白其中的运行原理,但知道怎么输入有对应的输出。QA (Quality assurance),也就是我们的测试部门一般负责对程序进行黑盒测试,调用接口时传确定的参数,再校验接口响应值符合某种预期。 与黑盒测试对应的是白盒测试,白盒测试要求被测试人员了解被测程序的构造,从而构造测试用例校验程序各个分支逻辑。从这一方面来说,单元测试就是一种白盒测试。 单元测试,又称为模块测试,是针对程序...

Aug 17, 2019 - SpringBoot 启动过程(下)组件初始化

4782 Word Count

前言 上篇文章介绍了 JVM 是怎么加载到 Spring 的,分别介绍了 Jar 包机制的 Spring 唤起 Tomcat 方式和 War 包时的 Tomcat 自动加载 Spring 方式,这篇文章就从内部来介绍一下 Spring 服务是如何启动起来的。 转载随意,文章会持续修订,请注明来源地址:https://zhenbianshu.github.io 。 概念和组件 在介绍 SpringBoot 启动流程之前,我们需要先了解一下 SpringBoot 启动时的重要概念和组件,它们或有着重要的意义,或在启动过程中起着举足轻重的作用。 ApplicationContext ...

Jul 27, 2019 - SpringBoot 启动过程(上)与 Web 服务器合作

4245 Word Count

前言 最近对 Spring 越来越感兴趣,却在阅读它的源码时很容易被类之间的跳转和方法的嵌套绕晕,为了避免无尽的烦恼,我决定跟它做一个了断,不再追求细节,了解其启动过程和重要组件即可,之后遇到细节问题再看对应模块的源码。 我们都知道,一个 Java Web 服务进程,Web 服务器是其必不可少的组件之一,仅有 Spring 是无法受理系统的 HTTP 请求的。而且在 Java 的 Servlet 模型里,Spring 是作为 Web 服务器里的一个 Servlet 存在的,这就更能说明 Spring 和 Web 服务器的关系之亲密了。 但每个 Java 进程都只有一个主类,进程从其...