Java云托管服务的开支削减策略
\\摘要
\
- 随着项目不断扩大,你需要将其迁移到更大的虚拟机上。但如果新虚拟机环境超出了你的需求则会产生额外开支。\
- 相比虚拟机,容器具有更小的粒度,并且无需重启运行中的实例即可垂直扩展。\
- 单体应用和历史遗留应用无需更改配置,即可从虚拟机迁移至容器中。\
- Java的垂直扩展需要适当配置JVM和清理垃圾回收器。\
- “即用即付”和“按需付费”这两种云收费模型的对比,及提高效率的正确选择。
云服务会很昂贵,而当你为不需要的资源付费时尤其如此;另一方面,资源不足又会导致宕机。身为程序员该如何应对?这篇文章将会讨论一些技术,来帮助你恰到好处地只支付实际消耗的资源,且不受应用体量增长的限制。\
认清现实:你在虚拟机上多花钱了
\任何解决方案的第一步当然都是要承认问题的存在。以下详述大部分云用户都在面对的问题:\
几乎所有的云服务供应商都提供一系列不同体量的虚拟机供选择。而如何选择合适的体量往往让人左右为难:选小了会有性能问题,负载上去搞不好还会挂。选多了?那常规负载和空闲时的资源就都浪费了。你自己的云托管应用是不是经历过类似的情形?\
当项目开始横向扩展,资源使用低效的问题会重复出现在每个新加入的实例上。所以,这个问题也会相应地增长。\
进一步说,如果你想在同一个虚拟机中增加一点点服务,目前大部分云服务供应商能提供的唯一方案是更换双倍体量的虚拟机。参考AWS的方案:\
更糟糕的是,迁移过程会导致服务中断:需要停掉现在的虚拟机,一步步重新部署或迁移应用,其中不可避免会有相关的棘手问题需要解决。\
可见虚拟机在资源使用方面不够灵活高效,并且针对动态负载的调整能力很有限。这种缺乏弹性的方式导致了额外的开支。\
如何高效地进行双向扩展
\如果横向扩展无助于资源的高效利用,我们就需要深入虚拟机内部,理解垂直扩展是如何实现的。\
垂直扩展可以在现有基础上优化任何应用实例的内存和CPU使用。如果配置得当,这种方法对单体应用和微服务都同样有效。\
在虚拟机内通过动态增加或减少资源来进行垂直扩展同时又不中断服务是一项艰巨的任务。虚拟机提供了内存膨胀(memory balloning)的技术,但它并不是自动化的,需要用工具监控宿主系统和客户系统中的内存压力,然后进行相应的向上或向下扩展。而实际情况是这个方法并不太好用,自动化的内存共享才更实用。\
得益于开创性的同宿主内容器间资源自动分享,基于cgroups的容器技术拥有更高级别的灵活性。在设定范围内,空闲的资源会自动分配给相同硬件节点内的其他容器。\
不同于虚拟机,容器内的资源无需重启应用实例即可轻松实现扩展。\
结果就是,同一容器实时更改体量大小要比迁移至更大的虚拟机更加容易、经济和迅速。\
从虚拟机迁移至容器
\容器分为两种:应用容器和系统容器。应用容器(如Docker或rkt)一般运行在单个进程中,而系统容器(LXD、OpenVZ)则更像是完整的操作系统,可以运行全功能的初始化系统如systemd、SysVinit和openrc,这些初始化系统允许在单一容器中的进程孵化出其他进程如openssh、crond或syslogd等。这两种容器都支持垂直扩展来让资源分配更有效率。\
理想情况下,在一个新项目中你可能想基于应用容器开始从头设计,因为应用容器可以使用Docker公开的模板较为容易地创建所需镜像。但关于容器的一个普遍存在的认知误区就是容器只适用于全新的应用(微服务和原生云)。已有的经验和用例可以证实,将已有的工作从虚拟机迁移至容器,而不重写或重新设计应用也是完全可能的。\
对于单体应用和遗留应用来说,使用系统容器会更合适,因为你可以重用之前为虚拟机设计的架构和配置等:使用标准网络配置,如组播;在容器内运行多个进程,避免因不恰当的内存限制决策导致的问题;确保在容器重启过程写入本地文件系统是安全的;依照现有的方法排查问题和分析日志;使用大量基于SSH的配置工具;对其他老旧但重要的任务有较好兼容性。\
为了从虚拟机中迁移出来,单体应用的拓扑结构需要拆解成更小的逻辑块,分布于互联的容器内。下图简单示意了拆解过程:\
每个应用组件被置于隔离的容器内。通常这样可以简化应用的拓扑结构,因为项目中的某些部分可能在新架构中不是必需的。\
例如,Jave EE WebLogic Server在虚拟机环境中运行大致需要包含三种实例:管理服务器、节点管理(进程)和被管理服务器。拆解之后,我们可以去掉节点管理,因为它是作为虚拟机代理来添加或删除被管理服务器实例的。而现在,利用容器的编排(orchestration)平台以及一系列WLST(WebLogic Server Scriting Tool)脚本,容器可以自动添加被管理服务器实例并将其直连到管理服务器上。\
为继续迁移,你需要准备所需的容器镜像。对系统容器来说,这个过程比应用容器要复杂一点。你可以自己编译生成,或者使用像Jelastic之类的包含系统容器预设模板的编排工具来完成。\
最后,部署项目并配置所需的互联接。\
现在每个容器都可以动态向上向下扩展而无需停机。相比于虚拟机,容器更加轻量,所以扩展花费的时间比起虚拟机也要少得多。因为容器很容易从头再分配或克隆,所以横向扩展同样变得很顺畅。\
启用带有内存收缩机制的垃圾回收器
\对y于Java的垂直扩展来说,只用容器是不够的;JVM同样需要合理配置。尤其值得注意的是,你所选择的垃圾收集器需要在运行时提供内存收缩机制。\
这种垃圾收回收会将所有存活对象打包,去除垃圾对象,撤回(uncommit)和释放空闲内存。相较而言,如果是不支持内存紧缩的垃圾收集器或未经优化配置的JVM,Java应用会占用所有提交的内存,不能实现按应用负载变化的垂直扩展。很不幸,JDK 8的默认并行垃圾收集器(-XX:+UseParallelGC)就不支持内存收缩,且没能解决JVM低效使用内存的问题。幸运的是,将垃圾收集器更换为Garbage-First(-XX:+UseG1GC)可以很容易地解决这个问题。\
请看下面的例子:即使你的应用内存占用很低(图中蓝色部分),未使用的资源还是不能分配给其他进程或其他容器,因为它们全部分给了JVM(桔红色部分)。\
(点击看大图)\
好消息是,JDK 9会默认启用支持内存收缩的G1垃圾回收器。主要的好处之一就是可以减少空闲内存碎片,同时缩短垃圾回收的停顿时间,且无需撤回未使用的堆内存。\
如果你的JDK版本低于9,可以使用以下参数启用G1垃圾收集器:\
-XX:+UseG1GC\
后面这两个参数用来配置内存资源的垂直扩展:\
- Xms——设置扩展的步长
- Xmx——设置扩展的上限
并且,在低负载或空闲期,应用应该定期调用Full GC,如System.gc()。此过程可在应用逻辑内部实现,或借助外部工具Jelastic垃圾回收代理实现。\
在下图中,我们展示了启用以下JVM启动参数后300秒内的内存使用情况:\
-XX:+UseG1GC -Xmx2g -Xms32m\
(点击看大图)\
如图所示,资源使用方面对比之前的例子有了巨大的提升。保留内存部分(桔红色)随着真实使用的部分(蓝色)缓慢增长,且空闲期内的资源没有浪费,所有最大堆内未使用的资源都可以被同一宿主内的其他容器或进程利用。\
由此可证,容器技术和G1垃圾回收器的结合为Java云服务提供了最高效的资源利用。\
选择按需付费的云服务
\最后(但很重要)的一步是选择“按需付费”收费模型的云服务,这样我们的花销就完全基于所消耗的部分。\
云计算经常被拿来和电力使用相比较,(电力公司)按需求提供资源,属于“即用即付”。但他们之间有一个主要的区别——当你只多用了一点电时,电费账单并不会翻倍!\
大部分云服务供应商采用“即用即付”的收费模型,这意味着可以一开始选一个小一点的服务器,然后随着项目增长再逐步增加服务器。但就像我之前描述的那样,你不可能简单地选择刚好适合你现在需求的服务体量,然后不用额外的人工操作,不用停止服务,就能按你的需求扩展。所以你会一直为这些限制买单——一开始是小机器,然后体量加倍,最后扩展为许多虚拟机,但每个都未被充分使用。\
对比而言,得益于容器技术,“按需付费”的收费模型考虑的是当前应用实例的负载,并且实时供应或回收必需的资源。结果就是,你只需支付实际使用的那部分资源,并且不需要复杂的重新配置就可以扩展。\
(点击看大图)\
但如果你已经受制于某个供应商,虚拟机已经在工作了,你正在为那些限制买单,且没准备好改变它,那是否还有机会缓解状况,提高效率,节省开支?答案是,你可以用一个大一点的虚拟机,在上面安装一个容器引擎,然后把工作负载从那堆小虚拟机上迁移过来。这样你的应用就会运行在虚拟机中的容器内——像夹心蛋糕一样。但这样有助于巩固和精简已占用资源,同时释放和共享未占用资源。\
认识到垂直扩展的好处有助于快速排除一系列性能问题,避免盲目横向扩展带来的不必要的复杂性,以及减少云端应用的开销——无论是单体应用还是微服务。\
关于作者
\Ruslan Synytsky是Jelastic的CEO和联合创始人。Jelastic向开发者提供多云平台即服务(multi-cloud Platform-as-a-Service)。他设计了平台的核心技术,可在全世界范围内的数据中心部署和运行上百万个容器。Synytsky致力于搭建高可用集群方案,为云端遗留应用和微服务应用的自动垂直扩展和水平扩展提供改进和增强方案。他在技术和商业方面都有丰富经验,并热衷参与各种程序员、主机提供商、集成商和企业相关的交流会议。
查看英文原文:Cost Reduction Strategies on Java Cloud Hosting Services\\\
感谢薛命灯对本文的审校。
\给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ,@丁晓昀),微信(微信号:InfoQChina)关注我们。
相关文章:

SpringBoot培训教程--史前文明之Spring简介
一. Spring之起源 1.你知道J2EE吗? 要说到Spring的历史起源,首先咱们要说说J2EE这个玩意儿。 J2EE在1999年和2000年的时候开始得到广泛实现,在J2EE中提出了”事务管理“等核心中间层标准化的概念,但是在实践中出现了各种问题,尤其…

利用外部命令Oralce数据库导入导出
1--数据库导出(exp) 首先进入命令行 导出数据库 在命令行中输入如下命令: exp c2j/c2jc2j filec:/table.dmp tablesjbitaku,jbitakum grantsy 然后按回车键 说明: c2j/c2jc2j 分别表示用户名,密码和服务名 file:输出文件的位置和文…

LeetCode实战:子集
题目英文 Given a set of distinct integers, nums, return all possible subsets (the power set). Note: The solution set must not contain duplicate subsets. Example: Input: nums [1,2,3] Output: [[3],[1],[2],[1,2,3],[1,3],[2,3],[1,2],[] ]题目中文 给定一组…

linux的挂载命令
在linux中所有的存储设备都必须挂载后才能使用,相当于windows的分配盘符 挂载命令 mount #查看系统中已经挂载好的设备 mount -a #根据/etc/fstab中的内容,自动挂载 /etc/fstab是系统开机的自动挂载文件 系统挂载时要自动检车测这个文件,如果…

软件测试需要学习什么技术
软件测试在近几年被很多企业都重视起来,互联网时代,APP种类越来越多,软件测试这一行业的发展前景是非常大的,那么想要学习软件测试需要学习什么技术呢?来看看下面的详细介绍。 软件测试需要学习什么技术? 每个软件在上线之前都离…

silverlight4.0 写文件不能设置默认文件名
Silverlight4.0 不提供SaveFileDialog的SafeFileName的写属性 Weve not exposed the "DefaultFileName" property on SaveFileDialog due to time constraints.Moe Elshall | Silverlight Development TeamMicrosoft Corporation等待5.0解决问题。转载于:https://www…

我是如何组织“算法刻意练习活动”的?
背景 在上个学期末,我们组织了一次团队的招新活动 – 如何加入 LSGO 软件技术团队?。 我们让预加入团队的同学在假期中完成以下两个任务之一: 学习 C# 语言: https://www.bilibili.com/video/av2357992/?p1学习 Python 语言&a…

[Ubuntu] ubuntu10.04系统维护之Wine的安装
在介绍安装wine之前,我想是有必要先介绍一下Wine的。当然,如果是Liunx的高手,我想是没必要看的,但是对于笔者这样的菜鸟级人物还是需要看一下的。 Wine是一款Liunx下的模拟器软件,但是Wine又不仅仅是一个模拟器软件&am…

Python培训教程:Python内置数据结构之双向队列
经常听说Python就是一门执行速度低的语言,可能是你的程序中使用了复杂的算法与数据结构,才会导致程序执行速率低的。在Python的标准库中提供了常见的数据结构工开发者使用,不仅执行速率比较快,还可以简化开发者的编程工作。下面我…

华为hybrid-vlan
华为hybrid-vlan、三层交换、DHCP拓扑:需求:1.路由器终结vlan2.交换机间以hybrid方式透传vlan3.PC以DHCP获取IP思路:1.PC的网关在路由器上2.配置hybrid-vlan3.配置DHCP步骤:路由器AR1:<Huawei>sy[Huawei]vlan 10…

android 按住拖动gallery防止马上加载数据导致gallery卡的方法
gallery菜单滑动有一个不好的效果就是每次经过中间的菜单都默认是被选中状态,同时会加载数据 以至于切换不流畅,有一种卡卡的感觉!!其实用线程来处理这个问题,一定的时间后如果选择的index值不变,说明已经稳…

LeetCode实战:买卖股票的最佳时机
背景 为什么你要加入一个技术团队?如何加入 LSGO 软件技术团队?我是如何组织“算法刻意练习活动”的?为什么要求团队的学生们写技术Blog 题目英文 Say you have an array for which the ith element is the price of a given stock on day …

HTML5培训教程:HTML5基础介绍
HTML5发展史: HTML5草案的前身名为 Web Applications 1.0,于2004年被WHATWG提出,于2007年被W3C接纳,并成立了新的 HTML 工作团队。 • HTML 5 的第一份正式草案已于2008年1月22日公布。HTML5 仍处于完善之中。然而,大部…

LeetCode实战:买卖股票的最佳时机 II
背景 为什么你要加入一个技术团队?如何加入 LSGO 软件技术团队?我是如何组织“算法刻意练习活动”的?为什么要求团队的学生们写技术Blog 题目英文 Say you have an array for which the ith element is the price of a given stock on day …

csdn模拟登陆
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章原始出版、作者信息和本声明。否则将追究法律责任。http://blog.csdn.net/mayongzhan - 马永占,myz,mayongzhan 首先声明本模拟不稳定,有时会出现登陆不进去.模拟的原理请参考bl…

Xcode 创建.a和framework静态库(转)
最近因为项目中的聊天SDK,需要封装成静态库,所以实践了一下创建静态库的步骤,做下记录。 库介绍 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行。库分静态库和动态库两种。iOS中的静态库有 .a 和 .framework两…

软件测试培训需要学习什么
软件测试在近几年引起了很多人的关注,不少人都想要学习软件测试,零基础的学员都会选择报软件测试培训机构学习,那么软件测试需要学习什么呢?来看看下面的详细介绍。 软件测试培训需要学习什么? 软件测试需要学测试环境(网络环境,…

IL,Emit之OpCodes说明(备查)
名称说明Add将两个值相加并将结果推送到计算堆栈上。Add_Ovf将两个整数相加,执行溢出检查,并且将结果推送到计算堆栈上。Add_Ovf_Un将两个无符号整数值相加,执行溢出检查,并且将结果推送到计算堆栈上。And计算两个值的按位“与”并…

LeetCode实战:只出现一次的数字
背景 为什么你要加入一个技术团队?如何加入 LSGO 软件技术团队?我是如何组织“算法刻意练习活动”的?为什么要求团队的学生们写技术Blog 题目英文 Given a non-empty array of integers, every element appears twice except for one. Find…

610D - Vika and Segments(线段树+扫描线+离散化)
扫描线:http://www.cnblogs.com/scau20110726/archive/2013/04/12/3016765.html 看图,图中的数字是横坐标离散后对应的下标,计算时左端点不变,右端点加1,所以总的更新的区间是l到r-1。 也可以理解为1代表的是ÿ…

UI设计比较流行的插画类型和运用
在当代平面设计中,插画是颇为经常使用的展现性元素,是视觉转达的紧张对象。插画在设计作品中,每每用来指导、开导和出现消息,更有针对性地、视觉化地同用户举行交换。真正高效的插画必然是有针对性的,易于辨认的&#…

poj 2362 Square
#include <iostream> //参照poj 1011 sticks#include <algorithm>using namespace std;int sticks[20],visited[20];int flag,total;int t,seg;int cmp(const void* a,const void* b){return (*(const int*)b)-(*(const int *)a);}void solve(int k,int…

Java BIO、NIO、AIO
同步与异步 同步与异步的概念, 关注的是 消息通信机制 同步是指发出一个请求, 在没有得到结果之前该请求就不返回结果, 请求返回时, 也就得到结果了.比如洗衣服, 把衣服放在洗衣机里, 没有洗好之前我们一直看着, 直到洗好了才拿出来晾晒. 异步是指发出一个请求后, 立刻得到了回…

LeetCode实战:数组中的第K个最大元素
背景 为什么你要加入一个技术团队?如何加入 LSGO 软件技术团队?我是如何组织“算法刻意练习活动”的?为什么要求团队的学生们写技术Blog 题目英文 Find the kth largest element in an unsorted array. Note that it is the kth largest el…

热修复测试过程注意事项
软件测试行是近几年比较火热的技术岗位,想要学习软件测试的同学有很多,今天小编给你分析一下关于热修复测试过程注意事项的相关内容,如果你在一次测试中脱颖而出那将来的你一定很精彩! 基于tinker实际测试过程中遇到的问题,小编简…

LeetCode实战:存在重复元素
背景 为什么你要加入一个技术团队?如何加入 LSGO 软件技术团队?我是如何组织“算法刻意练习活动”的?为什么要求团队的学生们写技术Blog 题目英文 Given an array of integers, find if the array contains any duplicates. Your function…

oracle exec 和 call 区别
转自:http://helloaq.iteye.com/blog/221614 exec 和 call 执行一个procedure时, exec是sqlplus的命令,只能在sqlplus中使用。 call是sql命令,任何工具都可以使用转载于:https://www.cnblogs.com/zerocc/archive/2011/07/27/21189…

html简单响应式滚动条置顶
简单响应式滚动条置顶 一般的,让页面出现滚动条的常见方法有: overflow:auto||overflow:scroll 或者overflow-x水平滚动条和overflow-y垂直滚动条那么现在要实现这样的一个效果: 直接在body中给一个header,后面一个Group盒子&…

UI设计培训之:5个小技巧快速学会PS抠图
一听到PS抠图,我们大家心里是不是产生了退却心理,害怕它过于复杂的操作。 那么现在有一种简单方法教给大家,如何在10分钟内快速学会ps抠图。 而你所需要准备的就是给自己10分钟的尝试时间。 你没有尝试过某件事情,就不要轻易说它难…

AIX VNC setup
1. 下载VNC for AIX虽然标明是for AIX51的,但AIX53和AIX61仍可用。 2. 安装RPM: rpm -Uhv vnc-3.3.3r2-3.aix5.1.ppc.rpm 3.编辑配置文件: # which vncserver/usr/bin/X11/vncserver #chmod 777 /usr/binX11/vncserver vi /usr/bin/X11/vncserver 更改前…