当前位置: 首页 > news >正文

从JVM角度思考--如何预估线上环境机器资源大小

(一)概述

如何给JVM虚拟机巧妙地设计参数对大部分开发来说一直是个随缘的事情,可能是去网上拷贝一套参数,可能是沿用公司其他应用的参数。但是这个随缘的操作可能就会给未来留下隐患。给JVM分配的内存过大倒是没什么问题,无非浪费点资源,但是如果分配的内存过小,就有可能导致频繁的Full GC,给人一种系统一直很卡的感觉。这篇文章就通过一个实例分析一下如何结合场景设置JVM虚拟机参数。

当然,本文更重要的是希望能通过预估参数的这个过程,让你更加了解虚拟机内部的一些东西,要想最准确的参数设置,用一些工具记录下JVM各个区域的变化会更有效。

(二)前置准备

系统基于JDK1.8,堆结构如下。

在这里插入图片描述

为了方便理解业务,本文以电商的交易系统为例进行讲解。在微服务架构下,目前主流的互联网公司都会把自己的业务拆分成多个服务架构,比如电商系统会分为交易微服务、购物车微服务、商品微服务等等,可能这个粒度会更细。一个底层架构会将这些微服务集成起来。实际上就是一个大的容器里放了一个个jar包。

(三)通常业务场景下的预估流程

一个交易微服务中会涉及到订单对象、优惠券对象、用户对象、交易记录对象等一系列对象,我们可以简单预估在一次交易中这些对象会占用的空间。预估的方式也很简单,八种基本类型直接带入字节大小,对象类型以基本类型为基础预估大小。只需要一个大致的值就行。

比如每次交易中一个订单对象大约是1kb,优惠券对象2kb,用户对象4kb,交易记录对象4kb,除此之外还可能会存在的List集合、数组等等。大约一次交易中产生的对象大约在25kb左右

一个每日交易量在100万的系统,交易量主要集中在6个小时中,平均每秒最大会有40笔订单的产生。也就意味着每秒产生对象大小是1M。这些产生的对象在一次交易结束后都会被当成垃圾,也就意味着每秒会产生1M的垃圾。

假设我们只有一台2核4G的服务器,分配给堆的内存一般就1.5G左右,通过计算,可以算出堆中每个区域的大小,如下图:

通过计算可以得出,每400秒,400M的Eden区就满了,会进行一次young GC。98%的垃圾会被回收,意味着将会有8M左右的垃圾进入在survivor转移。一些对象在经过几次young GC之后会进入到老年代中,这种情况Full GC的频率会很低。虽然400秒一次youngGC略微还是快了些,但是对于系统而言基本上没有影响。

(四)特殊业务场景下的预估流程

现在公司打算开展一次一小时的补贴活动,在活动的这一个小时时间内,订单数量可能会是之前的20倍,也就意味着每秒会有800笔订单的产生,每秒会产生20M的垃圾,这下会发生什么呢?

Eden区20秒就被占满,20秒执行一次youngGC,此时由于订单过于多,可能部分接口响应会达到几秒甚至几十秒,这些对象在经过几次youngGC之后就会逐步就会进入到老年代中。一般在线上一个小时内出现2次以上FullGC就得告警了

这种情况下就意味着我们对机器资源以及JVM虚拟机内存需要重新考虑了。

首先考虑提升JVM虚拟机内存,由于硬件限制,JVM虚拟机内存的提高首先要提高机器的性能,我们从双核4G升级成4核8G。分配给堆4.5G的内存。这个时候Eden区就会有1200M的内存,同样条件下,1分钟才会执行一次youngGC。20秒提高到1分钟能保证响应慢的接口对象也能在youngGC中被消灭,而不会进入到老年代中。

同时我们可以把一台机器升级为3台机器,负载均衡后每台机器的订单压力是原来的1/3,youngGC时间提升为原来的3倍,同时接口响应时间加快。基本上3台4核8G的机器就能满足这次活动。

(五)总结

预估之后,并非意味着就完全没问题了,还需要在上线时备好更多机器,防止意外发生。实践能给你带来最好的答案。

相关文章:

  • 1到3年的Java开发工程师应该如何准备面试
  • 写了两年代码之后再来看看Spring中的Bean
  • 【Python之旅】第二篇(四):字典
  • 使用Optional更优雅地处理非空判断
  • 你能保证你的代码没有异常吗?
  • OC之NSString/NSMutableString
  • 公司CEO和我说:在系统优化的时候,不要轻易用多线程
  • phalapi-进阶篇6(解决大量数据存储数据库分表分库拓展)
  • 快速理解工厂方法模式,及其在源码中的应用
  • 线上报了内存溢出异常,又不完全是内存溢出
  • 用代码告诉你“问世间情为何物,直教人生死相许”
  • 互联网公司的完整开发流程是怎样的?
  • 如何在SpringBoot启动时执行初始化操作,两个简单接口就可以实现
  • BZOJ4584 : [Apio2016]赛艇
  • 查准考证网站卡了整整一个小时进不去,被抢票支配的恐惧又来了
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • 【技术性】Search知识
  • Android路由框架AnnoRouter:使用Java接口来定义路由跳转
  • css系列之关于字体的事
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • es6要点
  • HTTP--网络协议分层,http历史(二)
  • k8s 面向应用开发者的基础命令
  • magento2项目上线注意事项
  • Python语法速览与机器学习开发环境搭建
  • Sublime text 3 3103 注册码
  • Twitter赢在开放,三年创造奇迹
  • Vue ES6 Jade Scss Webpack Gulp
  • vue--为什么data属性必须是一个函数
  • windows下使用nginx调试简介
  • 关于 Cirru Editor 存储格式
  • 后端_MYSQL
  • 技术攻略】php设计模式(一):简介及创建型模式
  • 蓝海存储开关机注意事项总结
  • 说说动画卡顿的解决方案
  • 用jQuery怎么做到前后端分离
  • ionic异常记录
  • Spring Batch JSON 支持
  • ​sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块​
  • $.ajax,axios,fetch三种ajax请求的区别
  • (20)目标检测算法之YOLOv5计算预选框、详解anchor计算
  • (26)4.7 字符函数和字符串函数
  • (9)目标检测_SSD的原理
  • (C#)获取字符编码的类
  • (java)关于Thread的挂起和恢复
  • (阿里云万网)-域名注册购买实名流程
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (四)模仿学习-完成后台管理页面查询
  • (提供数据集下载)基于大语言模型LangChain与ChatGLM3-6B本地知识库调优:数据集优化、参数调整、Prompt提示词优化实战
  • (学习日记)2024.01.09
  • (一)Dubbo快速入门、介绍、使用
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (转)Linux NTP配置详解 (Network Time Protocol)
  • .net core IResultFilter 的 OnResultExecuted和OnResultExecuting的区别
  • .NET Project Open Day(2011.11.13)