zoukankan      html  css  js  c++  java
  • 用jdk命令定位java应用问题

    linux环境,JAVA_HOME/bin目录中有很多有用的命令:jps、jstat、jinfo、jmap、jhat、jstack。本文以监听2181端口的zookeeper应用为例讲解。

    特别提醒下,在windows平台,这些命令以.exe结尾,也都可以在cmd命令行窗口执行。

    jps:虚拟机进程状况工具

    jps -mlv

    如下:

    [root@centos4 bin]# jps -mlv
    1366 org.apache.zookeeper.server.quorum.QuorumPeerMain ../config/zookeeper.properties -Xmx512M -Xms512M -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:+DisableExplicitGC -Djava.awt.headless=true -Xloggc:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../logs/zookeeper-gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dkafka.logs.dir=/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../logs -Dlog4j.configuration=file:./../config/log4j.properties
    2839 kafka.Kafka ../config/server.properties -Xmx1G -Xms1G -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:+DisableExplicitGC -Djava.awt.headless=true -Xloggc:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../logs/kafkaServer-gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dkafka.logs.dir=/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../logs -Dlog4j.configuration=file:./../config/log4j.properties
    6167 sun.tools.jps.Jps -mlv -Dapplication.home=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-1.el7_6.x86_64 -Xms8m

    jstat:虚拟机统计信息监视工具

    [root@centos4 bin]# jstat
    invalid argument count
    Usage: jstat -help|-options
           jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
    
    Definitions:
      <option>      An option reported by the -options option
      <vmid>        Virtual Machine Identifier. A vmid takes the following form:
                         <lvmid>[@<hostname>[:<port>]]
                    Where <lvmid> is the local vm identifier for the target
                    Java virtual machine, typically a process id; <hostname> is
                    the name of the host running the target Java virtual machine;
                    and <port> is the port number for the rmiregistry on the
                    target host. See the jvmstat documentation for a more complete
                    description of the Virtual Machine Identifier.
      <lines>       Number of samples between header lines.
      <interval>    Sampling interval. The following forms are allowed:
                        <n>["ms"|"s"]
                    Where <n> is an integer and the suffix specifies the units as 
                    milliseconds("ms") or seconds("s"). The default units are "ms".
      <count>       Number of samples to take before terminating.
      -J<flag>      Pass <flag> directly to the runtime system.

    可选的option可通过jstat options查看,如下:

    [root@centos4 bin]# jstat -options
    -class
    -compiler
    -gc
    -gccapacity
    -gccause
    -gcmetacapacity
    -gcnew
    -gcnewcapacity
    -gcold
    -gcoldcapacity
    -gcutil
    -printcompilation

    最常用的是-gcutil。

    jinfo:Java配置信息工具

    [root@centos4 app]# jinfo 
    Usage:
        jinfo [option] <pid>
            (to connect to running process)
        jinfo [option] <executable <core>
            (to connect to a core file)
        jinfo [option] [server_id@]<remote server IP or hostname>
            (to connect to remote debug server)
    
    where <option> is one of:
        -flag <name>         to print the value of the named VM flag
        -flag [+|-]<name>    to enable or disable the named VM flag
        -flag <name>=<value> to set the named VM flag to the given value
        -flags               to print VM flags
        -sysprops            to print Java system properties
        <no option>          to print both of the above
        -h | -help           to print this help message

    jinfo后面如果不跟任何option,直接跟pid的话,会打印出VM信息和系统信息,最全。如下:

    [root@centos4 app]# jinfo 1366
    Attaching to process ID 1366, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 25.191-b12
    Java System Properties:
    
    com.sun.management.jmxremote.authenticate = false
    java.runtime.name = OpenJDK Runtime Environment
    java.vm.version = 25.191-b12
    sun.boot.library.path = /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-1.el7_6.x86_64/jre/lib/amd64
    java.vendor.url = http://java.oracle.com/
    java.vm.vendor = Oracle Corporation
    path.separator = :
    java.rmi.server.randomIDs = true
    file.encoding.pkg = sun.io
    java.vm.name = OpenJDK 64-Bit Server VM
    sun.java.launcher = SUN_STANDARD
    user.country = US
    user.dir = /home/koushengrui/app/kafka_2.11-0.10.2.0/bin
    java.vm.specification.name = Java Virtual Machine Specification
    java.runtime.version = 1.8.0_191-b12
    os.arch = amd64
    java.endorsed.dirs = /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-1.el7_6.x86_64/jre/lib/endorsed
    line.separator = 
    java.vm.specification.vendor = Oracle Corporation
    os.name = Linux
    log4j.configuration = file:./../config/log4j.properties
    sun.jnu.encoding = UTF-8
    java.library.path = /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
    java.specification.name = Java Platform API Specification
    java.class.version = 52.0
    sun.management.compiler = HotSpot 64-Bit Tiered Compilers
    os.version = 3.10.0-693.el7.x86_64
    user.home = /root
    user.timezone = Asia/Shanghai
    java.awt.printerjob = sun.print.PSPrinterJob
    file.encoding = UTF-8
    java.specification.version = 1.8
    user.name = root
    java.class.path = :/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/aopalliance-repackaged-2.5.0-b05.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/argparse4j-0.7.0.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/connect-api-0.10.2.0.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/connect-file-0.10.2.0.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/connect-json-0.10.2.0.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/connect-runtime-0.10.2.0.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/connect-transforms-0.10.2.0.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/guava-18.0.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/hk2-api-2.5.0-b05.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/hk2-locator-2.5.0-b05.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/hk2-utils-2.5.0-b05.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jackson-annotations-2.8.0.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jackson-annotations-2.8.5.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jackson-core-2.8.5.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jackson-databind-2.8.5.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jackson-jaxrs-base-2.8.5.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jackson-jaxrs-json-provider-2.8.5.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jackson-module-jaxb-annotations-2.8.5.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/javassist-3.20.0-GA.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/javax.annotation-api-1.2.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/javax.inject-1.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/javax.inject-2.5.0-b05.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/javax.servlet-api-3.1.0.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/javax.ws.rs-api-2.0.1.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jersey-client-2.24.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jersey-common-2.24.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jersey-container-servlet-2.24.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jersey-container-servlet-core-2.24.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jersey-guava-2.24.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jersey-media-jaxb-2.24.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jersey-server-2.24.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jetty-continuation-9.2.15.v20160210.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jetty-http-9.2.15.v20160210.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jetty-io-9.2.15.v20160210.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jetty-security-9.2.15.v20160210.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jetty-server-9.2.15.v20160210.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jetty-servlet-9.2.15.v20160210.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jetty-servlets-9.2.15.v20160210.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jetty-util-9.2.15.v20160210.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/jopt-simple-5.0.3.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/kafka_2.11-0.10.2.0.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/kafka_2.11-0.10.2.0-sources.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/kafka_2.11-0.10.2.0-test-sources.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/kafka-clients-0.10.2.0.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/kafka-log4j-appender-0.10.2.0.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/kafka-streams-0.10.2.0.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/kafka-streams-examples-0.10.2.0.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/kafka-tools-0.10.2.0.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/log4j-1.2.17.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/lz4-1.3.0.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/metrics-core-2.2.0.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/osgi-resource-locator-1.0.1.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/reflections-0.9.10.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/rocksdbjni-5.0.1.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/scala-library-2.11.8.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/scala-parser-combinators_2.11-1.0.4.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/slf4j-api-1.7.21.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/slf4j-log4j12-1.7.21.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/snappy-java-1.1.2.6.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/validation-api-1.1.0.Final.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/zkclient-0.10.jar:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../libs/zookeeper-3.4.9.jar
    kafka.logs.dir = /home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../logs
    java.vm.specification.version = 1.8
    sun.java.command = org.apache.zookeeper.server.quorum.QuorumPeerMain ../config/zookeeper.properties
    java.home = /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-1.el7_6.x86_64/jre
    user.language = en
    java.vm.info = mixed mode
    java.version = 1.8.0_191
    file.separator = /
     
    VM Flags:
    Non-default VM flags: -XX:CICompilerCount=4 -XX:ConcGCThreads=2 -XX:+DisableExplicitGC -XX:G1HeapRegionSize=1048576 -XX:InitialHeapSize=536870912 -XX:InitiatingHeapOccupancyPercent=35 -XX:+ManagementServer -XX:MarkStackSize=4194304 -XX:MaxGCPauseMillis=20 -XX:MaxHeapSize=536870912 -XX:MaxNewSize=321912832 -XX:MinHeapDeltaBytes=1048576 -XX:+PrintGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC 
    Command line:  -Xmx512M -Xms512M -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:+DisableExplicitGC -Djava.awt.headless=true -Xloggc:/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../logs/zookeeper-gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dkafka.logs.dir=/home/koushengrui/app/kafka_2.11-0.10.2.0/bin/../logs -Dlog4j.configuration=file:./../config/log4j.properties

    jmap:Java堆内存映射工具

    [root@centos4 bin]# jmap 
    Usage:
        jmap [option] <pid>
            (to connect to running process)
        jmap [option] <executable <core>
            (to connect to a core file)
        jmap [option] [server_id@]<remote server IP or hostname>
            (to connect to remote debug server)
    
    where <option> is one of:
        <none>               to print same info as Solaris pmap
        -heap                to print java heap summary
        -histo[:live]        to print histogram of java object heap; if the "live"
                             suboption is specified, only count live objects
        -clstats             to print class loader statistics
        -finalizerinfo       to print information on objects awaiting finalization
        -dump:<dump-options> to dump java heap in hprof binary format
                             dump-options:
                               live         dump only live objects; if not specified,
                                            all objects in the heap are dumped.
                               format=b     binary format
                               file=<file>  dump heap to <file>
                             Example: jmap -dump:live,format=b,file=heap.bin <pid>
        -F                   force. Use with -dump:<dump-options> <pid> or -histo
                             to force a heap dump or histogram when <pid> does not
                             respond. The "live" suboption is not supported
                             in this mode.
        -h | -help           to print this help message
        -J<flag>             to pass <flag> directly to the runtime system

    jmap -heap pid:打印堆信息。从中可以看出使用的垃圾收集器、堆的配置及其使用情况。如下:

    [root@centos4 bin]# jmap -heap 1366
    Attaching to process ID 1366, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 25.191-b12
    
    using thread-local object allocation.
    Garbage-First (G1) GC with 8 thread(s)
    
    Heap Configuration:
       MinHeapFreeRatio         = 40
       MaxHeapFreeRatio         = 70
       MaxHeapSize              = 536870912 (512.0MB)
       NewSize                  = 1363144 (1.2999954223632812MB)
       MaxNewSize               = 321912832 (307.0MB)
       OldSize                  = 5452592 (5.1999969482421875MB)
       NewRatio                 = 2
       SurvivorRatio            = 8
       MetaspaceSize            = 21807104 (20.796875MB)
       CompressedClassSpaceSize = 1073741824 (1024.0MB)
       MaxMetaspaceSize         = 17592186044415 MB
       G1HeapRegionSize         = 1048576 (1.0MB)
    
    Heap Usage:
    G1 Heap:
       regions  = 512
       capacity = 536870912 (512.0MB)
       used     = 1856512 (1.7705078125MB)
       free     = 535014400 (510.2294921875MB)
       0.34580230712890625% used
    G1 Young Generation:
    Eden Space:
       regions  = 0
       capacity = 28311552 (27.0MB)
       used     = 0 (0.0MB)
       free     = 28311552 (27.0MB)
       0.0% used
    Survivor Space:
       regions  = 0
       capacity = 0 (0.0MB)
       used     = 0 (0.0MB)
       free     = 0 (0.0MB)
       0.0% used
    G1 Old Generation:
       regions  = 2
       capacity = 508559360 (485.0MB)
       used     = 1856512 (1.7705078125MB)
       free     = 506702848 (483.2294921875MB)
       0.36505315721649484% used
    
    3009 interned Strings occupying 242720 bytes.

    jmap -histo pid:打印堆中的对象信息。jmap -histo:live:打印堆中存活的对象信息。如下:

    [root@centos4 bin]# jmap -histo 1366
    
     num     #instances         #bytes  class name
    ----------------------------------------------
       1:          6703         509448  [C
       2:           910         452864  [I
       3:          1889         214352  java.lang.Class
       4:           525         207248  [B
       5:          6665         159960  java.lang.String
       6:          2816         110784  [Ljava.lang.Object;
      ........................................................
     725:             1             16  sun.util.resources.LocaleData
     726:             1             16  sun.util.resources.LocaleData$LocaleDataResourceBundleControl
    Total         39669        2380888

    num是根据bytes由大到小排列的排名。instances表示同一个class name的对象的个数。bytes是同一个class name的对象的总大小。class name是全类名。

    jmap -finalizerinfo pid:打印待回收的对象信息。如下:

    [root@centos4 bin]# jmap -finalizerinfo 1366
    Attaching to process ID 1366, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 25.191-b12
    Number of objects pending for finalization: 0

    jmap -dump:<dump-options>:dump堆信息,生成二进制的heap dump文件,俗称堆转储文件。dump是转储的意思。dump文件名可以自定义。如:

    [root@centos4 bin]# jmap -dump:format=b,file=zookeeper_201907112135.dump 1366
    Dumping heap to /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-1.el7_6.x86_64/bin/zookeeper_201907112135.dump ...
    Heap dump file created

    heap dump文件怎么用呢?由于heap dump文件是二进制文件,所以不能直接用文本编辑器打开。把heap dump文件从服务器down下来后,常用打开方式有两种:

    用VisualVM打开或者用MAT打开。

    用VisualVM打开步骤:双击JAVA_HOME/bin目录中的jvisualvm.exe打开Java VisualVM工具,点击左上角打开,装入,文件类型选择堆 Dump,然后选择刚刚的堆转储文件,就打开了。然后在概要处就可以看到基本信息、环境、系统属性以及堆转储上的线程信息,在类处可以看到所有的类以及每个类的实例数以及各类实例大小和占堆空间的比例。

    如果dump文件特别大,就需要用MAT打开了。MAT全称是Eclipse Memory Analyzer,是eclipse官方出的一个独立插件。从官网下载好后,解压,直接双击MemoryAnalyzer.exe即可运行,不用依赖eclipse。左上角File,Open Heap Dump,选择刚刚的堆转储文件,打开。在Overview中可以看到有Actions、Reports、Step By Step,Actions下面有Histogram(列出了各类实例数量及占用内存大小)、Dominator Tree(列出了最大的对象)、Top Consumers(根据类名和包名分组,打印出最昂贵的对象)。Reports下面有Leak Suspects(列出了可能的内存泄露点)。

    jstack:java堆栈跟踪工具

    [root@centos4 bin]# jstack
    Usage:
        jstack [-l] <pid>
            (to connect to running process)
        jstack -F [-m] [-l] <pid>
            (to connect to a hung process)
        jstack [-m] [-l] <executable> <core>
            (to connect to a core file)
        jstack [-m] [-l] [server_id@]<remote server IP or hostname>
            (to connect to a remote debug server)
    
    Options:
        -F  to force a thread dump. Use when jstack <pid> does not respond (process is hung)
        -m  to print both java and native frames (mixed mode)
        -l  long listing. Prints additional information about locks
        -h or -help to print this help message

    jstack pid:dump运行的进程的线程信息。如果进程hung住了,需要加-F参数来强制dump。jstack -F pid:dump hung住进程的线程信息。这两个命令都默认把信息输出到当前命令行,我们一般都会输出到指定文件,jstack pid > thread201907121424.dump。这样就会在当前目录中生成thread201907121424.dump文件。down下来分析即可。dump线程生成的文件一般称为线程转储文件。线程转储文件可以直接用文本编辑器如notepad++打开,打开后可以看到dump瞬间所有的线程及其状态。由此可知,当我们自己创建线程或者线程池时,给线程命名是多么好的习惯啊,可以快速在大量的线程中找到自己命名的线程。从中还可以看到大量的Unsafe、LockSupport、AQS、CountDownLatch的API,所以学好这些类是必需的。

  • 相关阅读:
    企业级Nginx负载均衡与keepalived高可用实战(一)Nginx篇
    Elasticsearch由浅入深(十一)内核原理
    Elasticsearch由浅入深(十一)索引管理
    Elasticsearch由浅入深(十)搜索引擎:相关度评分 TF&IDF算法、doc value正排索引、解密query、fetch phrase原理、Bouncing Results问题、基于scoll技术滚动搜索大量数据
    Elasticsearch由浅入深(九)搜索引擎:query DSL、filter与query、query搜索实战
    Elasticsearch由浅入深(八)搜索引擎:mapping、精确匹配与全文搜索、分词器、mapping总结
    Elasticsearch由浅入深(七)搜索引擎:_search含义、_multi-index搜索模式、分页搜索以及深分页性能问题、query string search语法以及_all metadata原理
    Elasticsearch由浅入深(六)批量操作:mget批量查询、bulk批量增删改、路由原理、增删改内部原理、document查询内部原理、bulk api的奇特json格式
    Elasticsearch由浅入深(五)_version乐观锁、external version乐观锁、partial update、groovy脚本实现partial update
    Elasticsearch由浅入深(四)ES并发冲突、悲观锁与乐观锁、_version乐观锁并发
  • 原文地址:https://www.cnblogs.com/koushr/p/5873402.html
Copyright © 2011-2022 走看看