导航:首页 > 配服务器 > 服务器怎么查看gc日志

服务器怎么查看gc日志

发布时间:2022-12-30 14:05:37

‘壹’ 查看linuxgc日志,求助,GC和GC有什么区别啊GC和GC有什么区

java虽然是自动回收内存,但是应用程序,尤其服务器程序最好根据业务情况指明内存分配限制。否则可能导致应用程序宕掉。 举例说明含义: -Xms128m 表示JVM Heap(堆内存)最小尺寸128MB,初始分配 -Xmx512m 表示JVM Heap(堆内存)最大允许的尺寸256

‘贰’ Tomcat假死排查

最近在重启生产环境项目后偶尔会出现这个情况:浏览器访问页面,无报错一直处于加载状态,服务器上tomcat日志没有访问记录输出,也没有异常日志输出,再次重启tomcat后才正常运行。

后续经过网上一番查找才得知这是tomcat假死的情况,由于当时情况紧急没有时间排查原因,只忙着重启解决(小型项目,没有做集群),这里就记录一下排查思路,防止下次遇到后再这样暴力解决。

1.项目虽然没有做集群,但是有nginx做反向代理,所以第一步应该是查看nginx上的access.log日志。倘若有访问记录日志打印,则表示前端到nginx无问题。

2.接着排查nginx到tomcat的情况。
查看tomcat的访问日志localhost_acess.log有没有本次请求记录,没有记录先怀疑是否网络有问题。从该台nginx ping 了一下tomcat server ,正常,没有发现问题。既然网络貌似没有问题,开始怀疑是tomcat本身的问题,在tomcat本机直接curl 调用该条请求,发现仍然没有响应。到此基本可以断定网络没有问题,tomcat 本身出现了假死的情况。

基于tomcat 假死的情况,开始分析有可能的原因。造成tomcat假死有可能的情况大概有以下几种:
1.内存溢出
分析当时的gc.log 是否有内存溢出的情况,或者直接 grep OutOfMemoryException catalina.sh 查看是否有内存溢出异常。

2.jvm GC 时间过长,导致应用暂停
查看gc.log回收时间,以下为例子:

最近的一次full gc 显示,也不应该会暂停几分钟的情况,这种假死可能可以排除。

3.load 太高,已经超出服务的极限
当时top一下linux

load 并不是高,这种假死可能可以排除。

4.应用程序出现死锁,需要使用jstack进行线程分析

5.大量tcp 连接 CLOSE_WAIT
使用命令 netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

6.tomcat长连接数超过最大连接数
tomcat默认最大连接数(线程数)200个,默认每一个连接的生命周期2小时(7200秒),tomcat使用http 1.1协议,而http1.1默认是长连接。tomcat接受处理完请求后,socket没有主动关闭,因此如果在2小时内,请求数超过200个,服务器就会出现上述假死现象。解决办法:

1.修改tomcat server.xml配置文件,增大最大连接数

2.修改linux的TCP超时时间(socket生命周期)限制

‘叁’ 记一次服务Full GC背后的内存泄漏问题,真是匪夷所思

最近所负责的服务略频繁地收到4xx告警

1、查业务日志,没发现相关错误的日志
2、查nginx access log,发现返回的状态码都是499,从request_uri查了一遍发现不是集中在某一个请求上,说明应该不是某个接口的问题了,有可能进程层面问题了。

通过对upstream_addr 分类,可以看到问题基本都是集中在 某一台这台机器上

3、网上资料了解到,499 是 nginx 扩展的 4xx 错误,代表客户端请求还未返回时,客户端主动断开连接。原因有几种,不过大部分原因都说到有可能服务器upstream处理过慢,导致用户提前关闭连接。那就先往这个方向排查,登录机器查看实际的access.log

发现upstream response都是10s以上。这就证明了上游服务器处理10秒还没有响应,因此nginx提前关闭链接,返回499

4、为什么进程响应如此慢,10秒太不正常了。考虑到那段时间就只有一台机器有问题,而且是进程层面的问题,首先想到的是GC,于是再次登录到机器上查看gc log。发现有Full GC,时间点和告警的时间也吻合。 惊呆的是,这次FullGC耗时长达19.07秒,由于我们的服务使用的是jdk8默认的ParallelGC,FullGC期间,整个应用Stop The World的。这是非常恐怖的一件事

由此看来,4xx告警的初步原因已经定位到,就是FullGC导致的。

那么究竟为什么会发生FullGC呢?需要深入分析一下。
借助服务治理平台的JVM监控观察了几天。期间不同机器不同时间也发生了几次FullGC。从监控发现,基本每台机器隔两天就会发生一次FullGC,每次FullGC后年老代回收的垃圾不算多,使用比例还是挺高的。

为什么年老代空间占用这么多?

继续分析上面那条full gc log,
1、发生full gc时,年老代内存已经占用了99.98%了(1048397/1048576)。看起来因为年老代满了而触发的FullGC了。
2、full gc回收了年老代大约302M的垃圾,回收后年老代占用70.4%(738282/1048576)。这占用率还是比较高的。

1、首先jmap简单打印一下所有对象的信息。发现有ClassPathList和ClassClassPath两个类的对象数量高达1000多万,并且这两个数量是一样的。仿佛嗅到了内存泄漏的味道。

2、只依靠对象统计信息,不足以定位问题,需要使用完整HeapDump,通过MAT进一步分析

jmap把完整堆heapDump下来

隔一段时间后,继续jmap,这次只取存活对象的mp(实际效果是先执行一次FULL GC)

可以看到,经过Full GC后,ClassPathList对象没有被回收,数量反而继续增加。到这里,基本可以确定,ClassPathList是存在泄漏了。

那么,ClassPathList究竟被谁引用着,导致回收不掉呢?
通过MAT的OQL过滤出老生代的ClassPathList对象,从对象的关联关系上继续深入分析。

首先需要知道老生代的地址区间,可以使用vjtools

通过vjmap的address命令,快速打印各代地址。

可以得知,oldGen的下界是0x80000000,上界是0xc0000000(注意OQL中使用时要把数值前的那串0去掉)。

执行OQL只查询年老代中的ClassPathList对象:执行OQL只查询年老代中的ClassPathList对象:

抽取其中一个对象分析,可以发现这个ClassPathList对象被一连串不同ClassPathList对象的next属性引用着。看起来是个链表的结构

再看看GCRoot,发现是被AppClassLoader也就是我们的应用类加载器引用着。除非这个加载器卸载了,否则ClassPathList对象是不会被GC掉了。

分析到这里,似乎离真相越来越近了。到底这个ClassPathList在项目中哪里使用到了?
通过前面的分析知道了ClassPathList的整体引用关系链:
AppClassLoader -> ClassPool类的defaultPool字段 -> ClassPoolTail类的source字段 -> ClassPathList类的pathList

可以看到,ClassPathList有两个属性,一个是next,结合之前MAT的分析,ClassPathList的确就是一个链表的结构。随着时间的增长,ClassPathList不断新增,链表也随之变得越来越大,最后内存占用逐渐上升。
另一个path字段属于ClassPath类型,ClassPath是个接口,查看它的实现类,发现一个似曾相识的名称ClassClassPath,之前分析对象统计信息时,还有一个类的对象数量是和ClassPathList一样的,正是这个ClassClassPath。每新增一个ClassPathList,都会伴随着新增对应的ClassPath对象,这也解释了为什么两者数量是一致的了。

通过注释知道,这个ClassClassPath的作用大概就是,利用一个叫ClassPool的对象,可以调用其insertClassPath方法来新增一个ClassClassPath对象,insertClassPath方法内部通过头插法将ClassClassPath添加到ClassPathList链表,从而形成一个search-path,然后通过这个search-path能够获取到某一个Class类的信息。

于是尝试着搜了一下,看看项目中有没有调用到insertClassPath方法的地方。意外发现一个类,

这不就是我们项目用来打印方法入参、执行耗时、上报metrics的@AutoLog的实现类吗。

可以看到getParams方法中调用了insertClassPath,注解@AutoLog的printParams默认为true,也就是每次调用都需要打印方法入参,每次打印前都要调用getParams先获取参数名称。因此每次都会insertClassPath,从而导致ClassPathList链表越来越大。

至此,内存泄漏的元兇已经找到。解决方法也就简单了。
因为目标只是想得到方法的参数名称,通过JoinPoint其实能直接获取到,因此可以改成JoinPoint获取的方式。

为了进行对比,分别在修改前后各进行一次压测。压测JVM参数大致与线上一致,为了尽快看到效果,只是调小了heap的大小。-Xms200m -Xmx200m

ClassPathList数量不断增长

年老代每次能回收的垃圾越来越少,每次回收过后的剩余空间也越来越小。最终整个年老代被撑满

虽然还没触发OOM,但是CPU负载飙高,从基本都在处于频繁的FULLGC状态

ClassPathList已经被消灭掉了

FullGC也趋于规律化了。每次回收的垃圾大致都相同

第一种方式是在启动参数增加 -XX:+PrintHeapAtGC,每次GC都打印地址

第二种方式是使用vjmap的命令,在-old, -sur, -address 中,都会打印出该区间的地址

第三种方式,使用vjmap的address命令,快速打印各代地址,不会造成过长时间停顿。

附: 我们服务的JVM参数

‘肆’ 几种常见GC简介

在springboot-admin当中,大概会有以下几种类型的gc出现,本文我们看看他们分别是什么意思。

本文使用的垃圾收集器是jdk1.8的PS+PO。

顾名思义,就是内存分配失败导致的GC,常见于年轻代当中。

使用JNI临界区的方式操作数组或者字符串时,为了防止GC过程中jarray或者jstring发生位移,而导致数组指针失效,需要保持它们在JVM Heap中的地址在JNI Critical过程中保持不变。于是JVM实现了GC_locker,用于JNI Critical内阻止其他GC的发生。

当GCLocker被激活且需要发生GC的时候(这里是否需要GC是各种GC发生时,调用GCLocker::check_active_before_gc()函数check并设置_needs_gc = true的),就会阻塞其他线程进入JNI临界区;并且在最后一个位于JNI临界区的线程退出临界区时,发起一次CGCause为_gc_locker的GC。这里解释了GCLocker Initiated GC发生的原委。

在JVM中的垃圾收集器中的Ergonomics就是负责自动的调解gc暂停时间和吞吐量之间的平衡,使你的虚拟机性能更好的一种做法。

简单说就是内存在进行分配的时候,会通过一些算法,预估是否会出现无法分配的问题。如果符合无法分配预估值,会提前进行一次gc。

这个gc主要发生的条件是元空间,也就是Metadata的参数设置问题。

通常根据我们学习的JVM只是,元空间使用的是本地内存,所以应该与当前服务器的最大内存有关。

但实际不是这样的,在jdk1.8中,如果不设置元空间的大小,会有一个默认值是 21M

所以需要我们启动的时候指定一个元空间大小:

GC日志如下所示:

‘伍’ 如何开启Tomcat的日志记录功能

Windows中的tomcat开启gc日志的方法:在catlinna.bat中添加set CATALINA_OPTS=-XX:ParallelGCThreads=4 -XX:+PrintGCDetails -Xloggc:D:/work/apache-tomcat-7.0.37-windows-x64/apache-tomcat-7.0.37/logs/tomcat_gc.log,gc日志就会打印到我们指定的日志文件中。 它的格式应该是这样:
Young gc 86.188: [GC [PSYoungGen: 32896K->880K(33024K)] 98532K->66588K(99264K), 0.0041792 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

‘陆’ 弱弱的问一句 jvm full gc到底是啥意思

JVM 内置的通用垃圾回收原则,堆内存划分为 Eden、Survivor 和 Tenured/Old 空间。GC一共分三种:MinorGC,Major GC v和Full GC。Full GC是清理整个堆空间—包括年轻代和永久代。有时候系统会频繁的FullGC,这时候需要去服务器查一下原因。

当编辑并运行一个Java程序时,需要同时涉及到这四种方面。使用文字编辑软件(例如记事本、写字板、UltraEdit等)或集成开发环境(Eclipse、MyEclipse等)在Java源文件中定义不同的类 ,通过调用类(这些类实现了Java API)中的方法来访问资源系统,把源文件编译生成一种二进制中间码,存储在class文件中,然后再通过运行与操作系统平台环境相对应的Java虚拟机来运行class文件,执行编译产生的字节码,调用class文件中实现的方法来满足程序的Java API调用。

(6)服务器怎么查看gc日志扩展阅读

触发Full GC执行的情况有如下四种。旧生代空间不足

1.旧生代空间只有在新生代对象转入及创建为大对象、大数组时才会出现不足的现象,当执行Full GC后空间仍然不足,则抛出如下错误:

java.lang.OutOfMemoryError: Java heap space

为避免以上两种状况引起的FullGC,调优时应尽量做到让对象在Minor GC阶段被回收、让对象在新生代多存活一段时间及不要创建过大的对象及数组。

2. Permanet Generation空间满

PermanetGeneration中存放的为一些class的信息等,当系统中要加载的类、反射的类和调用的方法较多时,Permanet Generation可能会被占满,在未配置为采用CMS GC的情况下会执行Full GC。如果经过Full GC仍然回收不了,那么JVM会抛出如下错误信息:

java.lang.OutOfMemoryError: PermGen space

为避免Perm Gen占满造成Full GC现象,可采用的方法为增大Perm Gen空间或转为使用CMS GC。

3. CMS GC时出现promotion failed和concurrent mode failure

对于采用CMS进行旧生代GC的程序而言,尤其要注意GC日志中是否有promotion failed和concurrent mode failure两种状况,当这两种状况出现时可能会触发Full GC。

promotionfailed是在进行Minor GC时,survivor space放不下、对象只能放入旧生代,而此时旧生代也放不下造成的;concurrent mode failure是在执行CMS GC的过程中同时有对象要放入旧生代,而此时旧生代空间不足造成的。

应对措施为:增大survivorspace、旧生代空间或调低触发并发GC的比率,但在JDK 5.0+、6.0+的版本中有可能会由于JDK的bug29导致CMS在remark完毕后很久才触发sweeping动作。对于这种状况,可通过设置-XX:CMSMaxAbortablePrecleanTime=5(单位为ms)来避免。

4. 统计得到的Minor GC晋升到旧生代的平均大小大于旧生代的剩余空间

这是一个较为复杂的触发情况,Hotspot为了避免由于新生代对象晋升到旧生代导致旧生代空间不足的现象,在进行Minor GC时,做了一个判断,如果之前统计所得到的Minor GC晋升到旧生代的平均大小大于旧生代的剩余空间,那么就直接触发Full GC。

例如程序第一次触发MinorGC后,有6MB的对象晋升到旧生代,那么当下一次Minor GC发生时,首先检查旧生代的剩余空间是否大于6MB,如果小于6MB,则执行Full GC。

当新生代采用PSGC时,方式稍有不同,PS GC是在Minor GC后也会检查,例如上面的例子中第一次Minor GC后,PS GC会检查此时旧生代的剩余空间是否大于6MB,如小于,则触发对旧生代的回收。

除了以上4种状况外,对于使用RMI来进行RPC或管理的Sun JDK应用而言,默认情况下会一小时执行一次Full GC。可通过在启动时通过- java-Dsun.rmi.dgc.client.gcInterval=3600000来设置Full GC执行的间隔时间或通过-XX:+ DisableExplicitGC来禁止RMI调用System.gc。

参考资料来源:网络-JAVA

‘柒’ 配置Elasticsearch

Elasticsearch船只具有良好的默认值,并且只需要很少的配置。可以在运行的集群上使用集群更新设置API更改大多数设置。
配置文件应该包含特定于节点的设置(例如node.name和路径),或者节点为了能够加入集群而需要的设置,例如 cluster.name 和 network.host 。

Elasticsearch有三个配置文件:

这些文件位于config目录中,其默认位置取决于安装是来自存档分发版(tar.gz或zip)还是包分发版(Debian或RPM包)。
对于存档发行版,config目录位置默认为 $ES_HOME/config 。配置目录的位置可以通过 ES_PATH_CONF 环境变量改变,如下所示:

或者,您可以通过命令行或shell配置文件导出ES_PATH_CONF环境变量。

对于包分发,配置目录位置默认为 /etc/elasticsearch 。配置目录的位置也可以通过 ES_PATH_CONF 环境变量更改,但是请注意,仅在shell中设置是不够的。相反,这个变量来源于 /etc/default/elasticsearch (用于Debian包)和 /etc/sysconfig/elasticsearch (用于RPM包)。您需要相应地在其中一个文件中编辑 ES_PATH_CONF=/etc/elasticsearch 条目,以更改配置目录的位置。

配置格式为YAML。下面是更改数据和日志目录路径的示例:

设置也可以扁平化如下:

在YAML中,你可以将非标量值格式化为序列:

虽然不太常见,但你也可以将非标量值格式化为数组:

使用${…}符号将被替换为环境变量的值。例如:

环境变量的值必须是简单字符串。使用逗号分隔的字符串来提供Elasticsearch将解析为列表的值。例如,Elasticsearch将以下字符串分割为 ${HOSTNAME} 环境变量的值列表

集群和节点设置可以根据配置方式进行分类:

您可以使用 集群更新设置API 在运行的集群上配置和更新动态设置。您还可以使用 elasticsearch.yml 在未启动或关闭的节点上本地配置动态设置。

使用集群更新设置API进行的更新可以是持久的(跨集群重启应用),也可以是短暂的(在集群重启后重置)。您还可以通过使用API为临时或持久设置赋值为空来重置它们。

如果您使用多个方法配置相同的设置,Elasticsearch将按照以下优先顺序应用这些设置:

例如,您可以应用瞬变设置来覆盖持久设置或 elasticsearch.yml 设置。然而,对 elasticsearch.yml 的更改,不会覆盖已定义的瞬态或持久设置。

最好使用集群更新设置API设置动态的集群范围设置,并使用 elasticsearch.yml 仅用于本地配置。使用集群更新设置API可以确保所有节点上的设置是相同的。如果您不小心在 elasticsearch.yml 中配置了不同的设置。在不同的节点上,很难注意到差异。

静态设置只能在未启动或关闭的节点上使用 elasticsearch.yml 进行配置。

必须在集群中的每个相关节点上设置静态设置

Elasticsearch开始时只需要很少的配置,但是在生产环境中使用集群之前,有很多方面需要考虑:

Elasticsearch将创建索引的数据写入索引,将数据流写入数据目录。Elasticsearch将自己的应用程序日志(其中包含关于集群运行状况和操作的信息)写入日志目录

对于macOS .tar.gz、Linux .tar.gz和Windows .zip安装,数据和日志默认是 $ES_HOME 的子目录。但是,在升级过程中, $ES_HOME 中的文件有被删除的风险

In proction, we strongly recommend you set the path.data and path.logs in elasticsearch.yml to locations outside of $ES_HOME . Docker , Debian , RPM , macOS Homebrew , and Windows .msi installations write data and log to locations outside of $ES_HOME by default.

To avoid errors, only Elasticsearch should open files in the path.data directory. Exclude the path.data directory from other services that may open and lock its files, such as antivirus or backup programs.

Supported path.data and path.logs values vary by platform

只有当一个节点与集群中的所有其他节点共享 cluster.name 时,该节点才能加入集群。默认名称是 elasticsearch ,但是您应该将其更改为描述集群用途的适当名称。

不要在不同的环境中重用相同的集群名称。否则,节点可能会加入错误的集群

Elasticsearch使用 node.name 作为Elasticsearch特定实例的人类可读标识符。这个名称包含在许多api的响应中。当Elasticsearch启动时,节点名默认为机器的主机名,但是可以在 elasticsearch.yml 中显式配置

缺省情况下,Elasticsearch只绑定到 127.0.0.1 和 [::1] 等环回地址。这对于在单个服务器上运行一个或多个节点的集群进行开发和测试已经足够了,但是 弹性生产集群 必须包含其他服务器上的节点。有许多 网络设置 ,但通常你只需要配置 network.host :

当你为 network.host 提供值时。Elasticsearch假定您正在从开发模式转向生产模式,并将一些系统启动检查从警告升级到异常。看看 开发和生产模式 之间的区别。

在投入生产之前,配置两个重要的发现和集群形成设置,以便集群中的节点能够相互发现并选择一个主节点。

Elasticsearch可以开箱即用,无需任何网络配置,它将绑定到可用的环回地址,并扫描本地端口 9300 到 9305 ,以便与运行在同一服务器上的其他节点连接。这种行为提供了一种无需进行任何配置的自动集群体验。

当您希望与其他主机上的节点形成集群时,使用 静态 discovery.seed_hosts 设置. This setting provides a list of other nodes in the cluster that are master-eligible and likely to be live and contactable to seed the discovery process .
此设置接受集群中所有符合主节点的地址的YAML序列或数组。每个地址可以是一个IP地址,也可以是通过DNS解析为一个或多个IP地址的主机名。

当您第一次启动Elasticsearch集群时, 集群引导 步骤将确定在第一次选举中计票的符合主资格的节点集。在 开发模式 下,如果没有配置发现设置,这个步骤将由节点自己自动执行。

因为自动引导 本身就不安全 ,,所以在生产模式下启动新集群时,必须显式列出符合主资格的节点,这些节点的投票应该在第一次选举中计算。您可以使用集群设置此列表。 initial_master_nodes 设置。

在集群第一次成功形成之后,删除每个节点配置中的 Initial_master_nodes 设置。在重新启动集群或向现有集群添加新节点时,不要使用此设置。

通过节点的 node.name 标识初始主节点, 该节点默认为主节点的主机名。请确保 cluster.initial_master_nodes 值 与 node.name 完全匹配如果您使用完全限定的域名(FQDN),例如master-node-a.example.com作为您的节点名,那么您必须在此列表中使用FQDN。相反,如果node.name是没有任何尾随限定符的裸主机名,您也必须省cluster.initial_master_nodes中的尾随限定符如果您使用完全限定的域名(FQDN),例如 master-node-a.example.com 作为您的节点名, 那么您必须在此列表中使用FQDN。相反,如果f node.name 是没有任何尾随限定符的裸主机名,您也必须省略 cluster.initial_master_nodes 中的尾随限定符。

请参见 bootstrapping a cluster 以及 发现和集群形成设置 .

默认情况下,Elasticsearch会根据节点的 角色 和总内存自动设置JVM堆大小。对于大多数生产环境,我们建议使用默认大小。

自动堆大小需要 bundled JDK ,如果使用自定义JRE位置,则需要Java 14或更高版本的JRE。

如果需要,您可以通过手动 设置JVM堆大小 来覆盖默认大小

默认情况下,Elasticsearch将JVM配置为将堆内存溢出异常转储到默认数据目录。在RPM和Debian软件包中,数据目录是/var/lib/elasticsearch。在Linux、MacOS和Windows发行版上,数据目录位于Elasticsearch安装的根目录下。

如果此路径不适合接收堆转储,请修改 -XX:HeapDumpPath=… jvm.options

默认情况下,Elasticsearch启用垃圾收集(GC)日志。这些是在jvm中配置的 jvm.options 并输出到与Elasticsearch日志相同的默认位置。默认配置每64mb轮换一次日志,最多可以消耗2gb的磁盘空间。

您可以使用 JEP 158: Unified JVM Logging 中描述的命令行选项重新配置JVM日志。除非您更改了默认jvm。选项文件,Elasticsearch默认配置将应用于您自己的设置之外。要禁用默认配置,首先通过提供 -Xlog:disable 选项禁用日志记录,然后提供您自己的命令行选项。这将禁用所有JVM日志记录,因此一定要检查可用选项并启用所需的所有内容。

要查看原始JEP中未包含的其他选项,请参见使用 JVM统一日志框架启用日志记录 .

Change the default GC log output location to /opt/my-app/gc.log by creating $ES_HOME/config/jvm.options.d/gc.options with some sample options:

Configure an Elasticsearch Docker container to send GC debug logs to standard error ( stderr ). This lets the container orchestrator handle the output. If using the ES_JAVA_OPTS environment variable, specify:

默认情况下,Elasticsearch使用启动脚本直接在系统临时目录下创建的私有临时目录。

在某些Linux发行版上,如果最近没有访问过/tmp中的文件和目录,系统实用程序将清除它们。如果需要临时目录的特性长时间不使用,那么在Elasticsearch运行时,这种行为会导致私有临时目录被删除。如果随后使用需要此目录的特性,则删除私有临时目录会导致问题。

如果您使用.deb或.rpm包安装Elasticsearch,并在systemd下运行它,那么Elasticsearch使用的私有临时目录将被排除在定期清理之外。

如果您打算在Linux或MacOS上长时间运行.tar.gz发行版,请考虑为Elasticsearch创建一个专用的临时目录,该目录不在将旧文件和目录清除的路径下。这个目录应该设置权限,以便只有作为Elasticsearch运行的用户才能访问它。然后,在启动Elasticsearch之前,设置$ES_TMPDIR环境变量指向这个目录。

默认情况下,Elasticsearch将JVM配置为将致命错误日志写入默认日志目录。对于 RPM 和 Debian 软件包, 这个目录是 /var/log/elasticsearch . On Linux and MacOS and Windows 发行版, logs 目录位于Elasticsearch安装根目录下。

这些日志是JVM遇到致命错误(例如分段错误)时产生的。如果此路径不适合接收日志,请修改 -XX:ErrorFile=... 在 jvm.options 条目。

在灾难中,快照可以防止数据永久丢失。快照生命周期管理是对集群进行定期备份的最简单方法。有关更多信息,请参见备份集群。

在灾难中, 快照 可以防止数据永久丢失. 快照生命周期管理 是对集群进行定期备份的最简单方法. 有关更多信息, 请参见 备份集群 。

备份集群的唯一可靠和受支持的方法是使用快照。您不能通过复制Elasticsearch集群节点的数据目录来备份该集群。不支持从文件系统级备份恢复任何数据的方法。如果试图从这样的备份恢复集群,可能会出现损坏、丢失文件或其他数据不一致的报告,或者看起来已经成功地悄无声息地丢失了一些数据。

有些设置是敏感的,仅依靠文件系统权限来保护它们的值是不够的。对于这个用例,Elasticsearch提供了一个密钥存储库和 elasticsearch -keystore 工具 来管理密钥存储库中的设置。

只有重新启动Elasticsearch后,对keystore的所有修改才会生效。

这些设置就像elasticsearch中的常规设置一样。Yml配置文件,需要在集群中的每个节点上指定。目前,所有安全设置都是特定于节点的设置,在每个节点上必须具有相同的值。

Just like the settings values in elasticsearch.yml , 对密钥存储库内容的更改不会自动应用到运行的Elasticsearch节点。重新读取设置需要重新启动节点。但是,某些安全设置被标记为 可重新加载 。. Such settings can be re-read and applied on a running node .

所有安全设置的值(无论是否可重新加载)必须在所有集群节点上相同。在进行所需的安全设置更改后,使用 bin/elasticsearch-keystore add 命令, call:

keystore-password : 用于加密Elasticsearch密钥库的密码

此API在每个集群节点上解密并重新读取整个密钥存储库,但只应用可重新加载的安全设置。对其他设置的更改直到下次重启才会生效。一旦调用返回,重新加载就完成了,这意味着依赖于这些设置的所有内部数据结构都已更改。所有的设置都应该从一开始就具有新值。

当更改多个可重新加载的安全设置时,在每个集群节点上修改所有安全设置,然后发出 reload_secure_settings 调用,而不是在每次修改后重新加载。

有可重新加载的安全设置:

‘捌’ 如何查看 java gc 类型

Java中的GC有哪几种类型?

参数

描述

UseSerialGC

虚拟机运行在Client模式的默认值,打开此开关参数后,
使用Serial+Serial Old收集器组合进行垃圾收集。

UseParNewGC

打开此开关参数后,使用ParNew+Serial Old收集器组合进行垃圾收集。

UseConcMarkSweepGC

打开此开关参数后,使用ParNew+CMS+Serial Old收集器组合进行垃圾收集。Serial Old作为CMS收集器出现Concurrent Mode Failure的备用垃圾收集器。

UseParallelGC

虚拟机运行在Server模式的默认值,打开此开关参数后,使用Parallel Scavenge+Serial Old收集器组合进行垃圾收集。

UseParallelOldGC

打开此开关参数后,使用Parallel Scavenge+Parallel Old收集器组合进行垃圾收集。

在Java程序启动完成后,通过jps观察进程来查询到当前运行的java进程,使用
jinfo –flag UseSerialGC 进程

的方式可以定位其使用的gc策略,因为这些参数都是boolean型的常量,如果使用该种gc策略会出现+号,否则-号。

使用-XX:+上述GC策略可以开启对应的GC策略。

GC日志查看
可以通过在java命令种加入参数来指定对应的gc类型,打印gc日志信息并输出至文件等策略。

GC的日志是以替换的方式(>)写入的,而不是追加(>>),如果下次写入到同一个文件中的话,以前的GC内容会被清空。

对应的参数列表
-XX:+PrintGC 输出GC日志
-XX:+PrintGCDetails 输出GC的详细日志
-XX:+PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式)
-XX:+PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
-XX:+PrintHeapAtGC 在进行GC的前后打印出堆的信息
-Xloggc:../logs/gc.log 日志文件的输出路径

这里使用如下的参数来进行日志的打印:
-XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xloggc:./gclogs

对于新生代回收的一行日志,其基本内容如下:
2014-07-18T16:02:17.606+0800: 611.633: [GC 611.633: [DefNew: 843458K->2K(948864K), 0.0059180 secs] 2186589K->1343132K(3057292K), 0.0059490 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

其含义大概如下:
2014-07-18T16:02:17.606+0800(当前时间戳): 611.633(时间戳): [GC(表示Young GC) 611.633: [DefNew(单线程Serial年轻代GC): 843458K(年轻代垃圾回收前的大小)->2K(年轻代回收后的大小)(948864K(年轻代总大小)), 0.0059180 secs(本次回收的时间)] 2186589K(整个堆回收前的大小)->1343132K(整个堆回收后的大小)(3057292K(堆总大小)), 0.0059490 secs(回收时间)] [Times: user=0.00(用户耗时) sys=0.00(系统耗时), real=0.00 secs(实际耗时)]

老年代回收的日志如下:
2014-07-18T16:19:16.794+0800: 1630.821: [GC 1630.821: [DefNew: 1005567K->111679K(1005568K), 0.9152360 secs]1631.736: [Tenured:
2573912K->1340650K(2574068K), 1.8511050 secs] 3122548K->1340650K(3579636K), [Perm : 17882K->17882K(21248K)], 2.7854350 secs] [Times: user=2.57 sys=0.22, real=2.79 secs]

gc日志中的最后貌似是系统运行完成前的快照:
Heap
def new generation total 1005568K, used 111158K [0x00000006fae00000, 0x000000073f110000, 0x0000000750350000)
eden space 893888K, 12% used [0x00000006fae00000, 0x0000000701710e90, 0x00000007316f0000)
from space 111680K, 3% used [0x0000000738400000, 0x000000073877c9b0, 0x000000073f110000)
to space 111680K, 0% used [0x00000007316f0000, 0x00000007316f0000, 0x0000000738400000)
tenured generation total 2234420K, used 1347671K [0x0000000750350000, 0x00000007d895d000, 0x00000007fae00000)
the space 2234420K, 60% used [0x0000000750350000, 0x00000007a2765cb8, 0x00000007a2765e00, 0x00000007d895d000)
compacting perm gen total 21248K, used 17994K [0x00000007fae00000, 0x00000007fc2c0000, 0x0000000800000000)
the space 21248K, 84% used [0x00000007fae00000, 0x00000007fbf92a50, 0x00000007fbf92c00, 0x00000007fc2c0000)
No shared spaces configured.

GC日志的离线分析
可以使用一些离线的工具来对GC日志进行分析,比如sun的gchisto( https://java.net/projects/gchisto),gcviewer( https://github.com/chewiebug/GCViewer ),这些都是开源的工具,用户可以直接通过版本控制工具下载其源码,进行离线分析。

下面就已gcviewer为例,简要分析一下gc日志的离线分析,gcviewer源代码工程是maven结构的,可以直接用maven进行package,这里编译的是1.34版本,本版本的快照已经上传至附件中。

需要说明的是,gcviewer支持多种参数生成的gc日志,直接通过java –jar的方式运行,加载生成的gc日志即可:

阅读全文

与服务器怎么查看gc日志相关的资料

热点内容
浦发银行app有什么优点 浏览:966
缓解压力放松心情的办法是吵架 浏览:780
pythonmap使用方法 浏览:782
旅行世界app叫什么 浏览:921
加密篦子怎么制造视频 浏览:903
电脑主服务器未运行怎么解决 浏览:328
js超级玛丽源码 浏览:308
云镜下载什么格式app 浏览:765
iosAndroidjava 浏览:402
外卖员转型做程序员 浏览:927
看房用什么app准 浏览:157
鸡蛋解压玩具测评 浏览:705
阿里云发布arm服务器芯片 浏览:756
对加密货币平台的态度 浏览:373
刺客信条pdf 浏览:453
湛江头条程序员 浏览:162
装上加密狗就死机 浏览:927
windows程序员转linux 浏览:570
androidusb驱动xp 浏览:947
单片机的数字电压表设计 浏览:792