java

容器及java oom

容器oom 原因 当容器设置 memory limit 过小时,并且容器进程需要的memory大于 容器limit内存时,会报出容器oom,即进程可申请的内存小于系统分配给该进程的内存时oom 结果 linux内核会kill掉该进程,即容器会因为oom重启 解决方案 调大memory limit或限制进程使用内存大小 java.lang.OutOfMemoryError: Java heap space 原因 在启动java程序时,可设置堆内存大小xmx,如果该值设置的过小,导致jvm gc回收空间过小,并且堆无空间分配新的对象,即会报出java.lang.OutOfMemoryError: Java

  • 刘凯
1 min read
java

tomcat网络模型

Tomcat启动流程 tomcat中基本所有的组件均通过LifecycleMBeanBase管理,在启动时,依次调用该LifecycleMBeanBase实现类所管理的其它组件的start方法,实际调用为startInternal()方法 其中tomcat中的容器实现的是LifecycleMBeanBase的子类ContainerBase,在ContainerBase.startInternal()方法中会依次启动 Cluster,Realm,子容器,Pipleline等 selector.select(1000)。当 Poller 启动后因为 selector 中并没有已注册的 Channel,所以当执行到该方法时只能阻塞。所有的 Poller 共用一个 Selector,其实现类是 sun.nio.ch.EPollSelectorImpl

  • 凯文
6 min read
java

apollo使用及实现

apollo功能 配置功能 namespace config key 灰度 自定义字段,如uid 配置灰度百分比 在执行方法时传入该uid 端 服务端 agent监听zk,将该服务订阅的配置下载到本地,保存为文件 sdk监听文件,修改内存中的配置 app 将配置按服务端过程下载至服务器本地 app通过http接口,在返回前台时调用 小程序 同app 配置链路 修改或新增配置后,发布给distributor distributor分发给各机房独立的zk notifier服务通知agent监听指定的zk节点,agent为容器内部的apollo agent 业务服务集成sdk,初始访问时sdk在本地文件找不到开关配置,发请求给agent,

  • 凯文
4 min read
java

20220720-记录一次生产导出问题

问题 线上导出订单时,节点未重启,但是调接口不通,原因是调用三方接口超时错误,查看gc、cpu&内存监控,发现 cpu idle 40% mem.used 3730m,容器是4g 堆大小为3g gc time 大幅增加 故问题原因是由于频繁gc导致 stw,故无法在timeout时间内处理请求 导出订单数量3w+ 临时方案 修改网关接口路由配置,导出接口路由至单独的小流量集群 模拟环境 由于sim环境数据较少,故通过模拟的方式导出,即调整代码逻辑,一直导出第一页订单,

  • 凯文
10 min read
java

sentinel介绍及原理

sentinel作用 Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。 sentinel整体设计的很精巧,只需要一个sentinel-core便可以运行,它提供了诸如服务降级、黑白名单校验、QPS、线程数、系统负载、CPU负载、流控等功能,可谓是功能非常的强大。 sentinel使用 SphU.entry 手动执行限流逻辑 sentinel使用SphU或者SphO标示一个被保护的资源,比如: Entry entry = SphU.entry("HelloWorld", EntryType.

  • 凯文
11 min read
java

生产问题之CaffeineCache使用中的坑

问题描述 服务缓存中使用CaffeineCache时,通过CaffeineCache在数据更新并且超过refreshAfterWrite时间后首次获取缓存时,偶发性的获取不到最新的缓存 实现 public class CaffeineCacheTest { public static void main(String[] args) throws Exception { CaffeineCacheTest test = new CaffeineCacheTest(); Cache cache = test.caffeineCacheManager().getCache("test"); CacheObject cacheObject = (CacheObject) cache.get(

  • 凯文
3 min read
java

响应式编程RxJava之Single

简单入门 Single.just(T value); 通常使用RxJava,主要是为了异步处理一些任务。即传入一些值,经过逻辑处理之后返回结果。 以上代码中的just(T value),可以看作是传入参数。 有了输入,如何输出呢?我们讲到了异步处理,那自然得有一个异步回调才行吧,这简直理所应当吧。所以这里介绍最重要的"subscribe"概念。 Single.just(T value).subscribe(); 例如: int addValue(int a,

  • 凯文
8 min read
java

reactor响应式编程之 Mono & flux

Publisher 由于响应流的特点,我们不能再返回一个简单的POJO对象来表示结果了。必须返回一个类似Java中的Future的概念,在有结果可用时通知消费者进行消费响应。 Reactive Stream规范中这种被定义为Publisher<T> ,Publisher<T>是一个可以提供0-N个序列元素的提供者,并根据其订阅者Subscriber<? super T>的需求推送元素。一个Publisher<T>可以支持多个订阅者,并可以根据订阅者的逻辑进行推送序列元素。下面这个Excel计算就能说明一些Publisher<T>的特点。 Publisher&

  • 凯文
5 min read
java

响应式编程之RxJava VS Reactor

目前市场上比较流行的有几种,RxJava,Akka,Vert.x,Reactor。最常使用的两种框架,并且实现了响应式编程规范的是RxJava和Reactor。 两者之间有什么区别呢? API Flowable和FluxAPI很相似都支持,ReactiveX常见的那些操作符。map,filter,flatmap等等,具体操作符列表:http://reactivex.io/documentation/operators.html 在Java版本上: RxJava2.x必须至此Java 6,因为它Rxjava在安卓中用的很多 Reactor则至少要求Java 8. 其内部利用了很多新版Java的特性。并且还可以方便的转换为:CompletableFuture,java.

  • 凯文
4 min read
java

jvm类的加载及方法调用过程

类的加载过程 加载 加载是指查找字节流,并且据此创建类的过程。 加载需要借助类加载器,在 Java 虚拟机中,类加载器使用了双亲委派模型,即接收到加载请求时,会先将请求转发给父类加载器。 链接 验证:确保被加载类能够满足 Java 虚拟机的约束条件 准备:为被加载类的静态字段分配内存;部分 Java 虚拟机还会在此阶段构造其他跟类层次相关的数据结构,比如说用来实现虚方法的动态绑定的方法表 解析:将符号引用解析成为实际引用;如果符号引用指向一个未被加载的类,或者未被加载类的字段或方法,那么解析将触发这个类的加载(但未必触发这个类的链接以及初始化。) 初始化 常量值(ConstantValue)初始化直接由 Java

  • 凯文
7 min read
java

Java 虚拟机执行Java 字节码过程

Java 虚拟机具体是怎样运行 Java 字节码的 java类加载 从虚拟机视角来看,执行 Java 代码首先需要将它编译而成的 class 文件加载到 Java 虚拟机中。加载后的 Java 类会被存放于方法区(Method Area)中。实际运行时,虚拟机会执行方法区内的代码。 如果你熟悉 X86 的话,你会发现这和段式内存管理中的代码段类似。而且,Java 虚拟机同样也在内存中划分出堆和栈来存储运行时数据。 不同的是,Java 虚拟机会将栈细分为面向 Java 方法的

  • 凯文
5 min read
java

java-mysql时区问题

问题 数据库时间展示正常,但是web页面时间与数据库时间差 13/14 个小时 原因 mysql采用的是CST时区,而java使用的是北京时间,两个时区有时差13个小时有时差14个小时,故从数据库查出数据后,如果直接展示无问题,但是如果通过java程序 SimpleDateFormat转换,就会出现问题 解决方案 在通过SimpleDateFormat转换时间时,设置时区为 CST 此方案,后续所有使用SimpleDateFormat转换数据库时间时,都需要指定TimeZone 但是通过SimpleDateFormat转换非数据库date(如 当前date)时,不需要指定TimeZone format.setTimeZone(TimeZone.getTimeZone("CST&

  • 凯文
1 min read
java

spring bean factory介绍

问题 singletonObjects与earlySingletonObjects的作用 如果singletonFactories中存放的内容 如何解决循环引用问题 aop对应的代理类如何保存实例 spring 缓存 singletonObjects-一级缓存 private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); spring 单例对象集合,所有的实例实例化完成后均需要保存在该变量中,该变量的key为bean name,value为spring管理的实例 在spring 创建实例完成后,添加至该缓存中,并且将该实例从earlySingletonObjects中移除,且将该实例对应的factory从singletonFactories中移除 singletonFactories-三级缓存

  • 刘凯
2 min read
java

synchronized详解

问题 某实例未执行过锁代码块,该实例的标识位是101还是001? 轻量级锁和重量级锁执行完成锁代码块后的标识位分别是什么? 轻量级锁执行完锁代码块后,出现其他线程竞争锁,该线程竞争成功后是什么锁? synchronized是否可降级? java对象Mark Word 32位Header Mark Word 即32bit,4个字节 64位Header Mark Word |------------------------------------------------------------------------------|--------------------| | Mark Word (64 bits) | State | |------------------------------------------------------------------------------|--------------------| | unused:25 | identity_hashcode:31 | unused:

  • 凯文
9 min read
java

java基础之二进制存储

原码、反码和补码 在计算机内,定点数有3种表示法:原码、反码和补码 原码 二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。 反码 正数的反码与其原码相同; 负数的反码是对其原码逐位取反,但符号位除外;即对其原码的绝对值取反,如 10001010的反码为11110101 补码 正数的补码与其原码相同;负数的补码是在其反码的末位加1。 byte jvm byte存储方式 Java中用补码表示二进制数,补码的最高位是符号位,最高位为“0”表示正数,最高位为“

  • 凯文
3 min read