目录

运维相关复盘

OOM内存溢出问题

java程序内存溢出问题

jstat—–查看GC情况

jstat -gc 1 https://raw.githubusercontent.com/kengerlwl/kengerlwl.github.io/refs/heads/master/image/6a942e0fbd78bbacf026b27ac02bef3b/35a73b67618fcc08f48b44f8b8fa741a.png#pic_center

由于我是进入docker 容器中执行的top命令, 所以我的java的进程id是1

其中参数简单说明下: S0C:第一个幸存区的大小 S1C:第二个幸存区的大小 S0U:第一个幸存区的使用大小 S1U:第二个幸存区的使用大小 EC:伊甸园区的大小 EU:伊甸园区的使用大小 OC:老年代大小 OU:老年代使用大小 MC:方法区大小 MU:方法区使用大小 CCSC:压缩类空间大小 CCSU:压缩类空间使用大小 YGC:年轻代垃圾回收次数 YGCT:年轻代垃圾回收消耗时间 FGC:老年代垃圾回收次数 FGCT:老年代垃圾回收消耗时间 GCT:垃圾回收消耗总时间

jmat——工具内存堆dump

5.使用 jmap -dump:format=b,file=heap.log pid 保存了堆现场,然后重启了应用服务

堆文件都是一些二进制数据,在命令行查看非常麻烦,Java 为我们提供的工具都是可视化的,Linux 服务器上又没法查看,那么首先要把文件下载到本地。

由于我们设置的堆内存为 4G,所以 dump 出来的堆文件也很大,下载它确实非常费事,不过我们可以先对它进行一次压缩。

然后,借助内存分析工具MAT(Memory Analyzer Tool):可以查看到是哪个对象导致了大量的堆占用

CPU占用飙高问题JSTACK

java程序高占用

1
2
3
4
5
6
7
8
9
public class JStackDemo {

    public static void main(String[] args) {
        int a = 10;
        while (true) {
            a = 100;
        }
    }
}

第一步先查询PID和计算PID的16进制

第二步使用jstack得到线程堆栈信息

使用jstack pid |grep tid查看线程堆栈信息,并且输出到jstack.log文件中

1
jstack 2552 |grep 9f9 -A 30 > jstack.log

分析线程堆栈信息

此时应该得到了一个jstack.log的堆栈日志文件.

分析具体代码逻辑,溯源

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
cat jstack.log

"main" #1 prio=5 os_prio=0 tid=0x00007f3f8004b800 nid=0xa50 runnable [0x00007f3f86ee8000]
   java.lang.Thread.State: RUNNABLE
	at JStackDemo.main(JStackDemo.java:6)

"VM Thread" os_prio=0 tid=0x00007f3f800cb800 nid=0xa51 runnable 

"VM Periodic Task Thread" os_prio=0 tid=0x00007f3f8011d000 nid=0xa58 waiting on condition 

JNI global references: 5

第三步然后再使用 top 命令查看进程中线程(shift +h)的占用情况,找到占用 CPU 较高的线程 ID。

第四步在日志中检索相关进程的信息,找到对应的堆栈信息

实际上,遇到CPU高的问题,也是要看业务的,毕竟很多时候,只是因为请求变多了!!!!!

一个程序基本的内存结构

一个程序的基本内存结构通常包括堆(Heap)、栈(Stack)以及代码区(Code Area)和静态区(Static Area)。

  1. 堆(Heap):堆是程序运行时动态分配内存的区域,用于存储对象实例和数组等动态分配的数据。堆是由垃圾收集器(Garbage Collector)管理的,它负责在不再需要时回收对象的内存空间。在Java中,所有通过 new 关键字创建的对象都存储在堆中。
  2. 栈(Stack):栈是程序运行时的一种数据结构,用于存储方法的调用栈和局部变量。每当调用一个方法时,都会在栈上创建一个对应的栈帧(Stack Frame),栈帧包含了方法的参数、局部变量以及方法返回的地址等信息。当方法执行完毕时,对应的栈帧会被弹出栈。栈是线程私有的,每个线程都有自己的栈。
  3. 代码区(Code Area):代码区存储程序执行的字节码指令,包括所有的方法和函数代码。在Java中,字节码被加载到代码区,并由JVM执行。
  4. 静态区(Static Area):静态区存储类的静态变量、常量、类信息等。静态区在程序启动时被分配,并且在整个程序生命周期内存在。

业内常用的分布式数据库

  1. MongoDB:一种文档型数据库,可水平扩展,适用于大规模应用和复杂的数据结构。
  2. Cassandra:一个高度可扩展的分布式数据库,适用于大规模数据的分布式存储和处理。
  3. Redis:一个支持多种数据结构的内存数据库,可以用作缓存和消息传递系统。
  4. Apache HBase:基于Hadoop的分布式数据库,适用于大规模结构化数据的存储和实时查询。
  5. Amazon DynamoDB:一种托管的NoSQL数据库服务,具有高可用性和可伸缩性。
  6. Google Cloud Spanner:一种全球分布式的关系型数据库服务,提供了ACID事务和水平扩展的能力。
  7. Apache Kafka:一种分布式流处理平台和消息队列系统,用于实时数据流处理。
  8. Apache CouchDB:一种面向文档的NoSQL数据库,具有分布式特性和支持数据同步。
  9. TiDB:一个开源的分布式SQL数据库,兼容MySQL协议,适用于OLTP和OLAP场景。
  10. Neo4j:一个图形数据库,用于存储和处理具有复杂关系的数据,例如社交网络和推荐系统。

常用运维命令

  1. iftopiftop 是一个命令行工具,用于实时显示网络接口上的带宽使用情况。它以类似于 “top” 的方式显示网络连接的实时更新列表。这对于监控网络使用情况并确定哪些主机正在消耗大量带宽非常有用。

  2. iotopiotop 是一个类似于 top 命令的工具,但是它专注于显示磁盘 I/O 活动。它可以实时显示系统上每个进程的磁盘 I/O 使用情况,包括读取和写入速率,以及累计的总量。

  3. netstatnetstat 是一个用于显示网络连接、路由表和网络接口等网络相关信息的命令。它可以显示当前系统的网络连接状态,包括正在进行的连接、监听端口和路由表等。

  4. lsoflsof 是 “list open files” 的缩写,用于列出当前系统上已打开的文件。它可以显示哪些进程正在使用哪些文件、目录或网络套接字等资源。

  5. pstreepstree 是一个用于显示进程树的命令。它以树状结构显示当前系统中运行的进程及其关系,以便于理解进程之间的父子关系和衍生关系。

  6. stat 是一个命令行实用程序,用于在类Unix操作系统中显示文件或文件系统的详细信息。当您运行 stat 命令,后面跟着文件或目录的名称时,它会提供诸如以下信息:

    1. 文件类型
    2. 权限
    3. inode 号
    4. UID 和 GID(用户和组标识符)
    5. 大小
    6. 时间戳(最后访问时间、最后修改时间和最后状态更改时间)
    7. 文件系统类型

虚拟机和docker区别

  • 虚拟机提供了完整的虚拟化环境,每个虚拟机都运行独立的操作系统实例,而 Docker 则共享主机操作系统内核,容器之间相互隔离。
  • Docker 容器更加轻量级和高效,启动速度更快,资源占用更少,而虚拟机则较为笨重。
  • Docker 适用于轻量级的应用容器化和快速部署,而虚拟机适用于需要完全隔离和独立的应用场景。

docker底层

Docker 的底层是基于 Linux 内核的核心特性,主要是利用了 Linux 的容器技术。具体来说,Docker 使用了 Linux 内核的以下特性来实现容器化:

  1. Linux 容器(LXC): Docker 最初是建立在 LXC 上的,LXC 是 Linux 提供的一种基于内核的容器化技术,允许在单个 Linux 实例上运行多个隔离的 Linux 系统容器。
  2. 命名空间(Namespaces)(执行隔离): Linux 内核提供了多种命名空间,包括PID(进程)、UTS(主机名)、IPC(进程间通信)、网络和挂载。Docker 使用这些命名空间来实现容器之间的隔离,使得每个容器都拥有自己独立的进程、网络和文件系统等资源。
  3. 控制组(cgroups)(资源隔离): 控制组是 Linux 内核提供的一种资源限制和优先级控制机制,它允许对系统资源(如 CPU、内存、网络带宽等)进行分组和限制。Docker 使用控制组来限制容器的资源使用,以确保它们不会互相干扰。
  4. 联合文件系统(UnionFS): Docker 使用联合文件系统来实现容器镜像的分层和共享。联合文件系统允许将多个文件系统挂载为单个文件系统,使得容器镜像可以由多个层次组成,每个层次都可以添加、修改或删除文件,而不会影响到其他层次,从而实现镜像的轻量化和高效共享。

定节点,具体来说,依赖的是lable标签的办法来指定节点。

linux目录概述

  1. /bin:基本命令二进制文件存放目录。
  2. /boot引导加载程序和内核镜像文件存放目录
  3. /dev:设备文件存放目录。
  4. /etc:系统配置文件存放目录
  5. /home:用户主目录存放目录。
  6. /lib:系统共享库文件存放目录。
  7. /media:挂载可移动设备的目录。
  8. /mnt:手动挂载临时文件系统的目录。
  9. /opt:可选软件包安装目录。
  10. /proc:虚拟文件系统,包含系统运行时信息,以及各种进程的具体信息
  11. /root:超级用户的主目录。
  12. /sbin:系统管理命令存放目录。
  13. /srv:服务相关数据存放目录。
  14. /sys:虚拟文件系统,包含与内核相关信息。
  15. /tmp:临时文件存放目录。
  16. /usr系统应用程序和文件存放目录。
  17. /var:经常变化文件存放目录。

/proc目录

Linux系统上的/proc目录是一种文件系统,即proc文件系统。与其它常见的文件系统不同的是,/proc是一种伪文件系统(也即虚拟文件系统),存储的是当前内核运行状态的一系列特殊文件,用户可以通过这些文件查看有关系统硬件及当前正在运行进程的信息,甚至可以通过更改其中某些文件来改变内核的运行状态。

/proc目录是开机后才会有的,关机就没了。具体访问是/proc/<PID>/xxx ,linux万物皆文件

linux文件系统

文件权限

chmod 777 xxx

7对应着rwx二进制111

还有一个改变权限的方法,从之前的介绍中我们可以发现,基本上就九个权限分别是:

  • user:用户
  • group:组
  • others:其他

inode 硬链接和软连接

inode是Unix和类Unix操作系统中的一个重要概念,用于存储文件或目录的元数据信息,包括文件大小、拥有者、权限、时间戳以及文件数据的存放位置等

  • 硬链接更像是原始文件的副本,与原始文件共享相同的inode和数据块,因此对硬链接的修改会影响到原始文件,反之亦然。(不可以跨不同文件系统
  • 软链接更像是一个指针,指向原始文件或目录的路径,因此对软链接的修改不会影响到原始文件,也不会影响到软链接指向的文件或目录。(可以跨不同文件系统

什么是交换空间?

  • 交换空间是Linux使用的一定空间,用于临时保存一些并发运行的程序。当RAM没有足够的内存来容纳正在执行的所有程序时,就会发生这种情况。

其他

ansible了解

Ansible是一种自动化工具,用于自动化配置管理、应用程序部署、任务自动化等。它具有简单易用、轻量级、可扩展等特点,广泛应用于IT基础设施的自动化管理领域。

脚本能直接执行,但是cron里面就不能直接执行

如果你的脚本在直接执行时正常工作,但在cron中无法正常执行,可能有几个原因导致这种情况发生:

  1. 环境变量:cron中的环境变量可能与你的交互式 shell 环境不同。在脚本中使用了依赖于特定环境变量的路径或命令时,可能会导致脚本无法执行。为了解决这个问题,你可以在cron任务中设置合适的环境变量或者使用绝对路径。
  2. 路径问题:在cron中执行脚本时,默认的工作目录可能不同于你的交互式 shell 环境。如果脚本中使用了相对路径,可能无法找到对应的文件。你可以在脚本中使用绝对路径来解决这个问题。
  3. 权限问题:cron任务可能以不同的用户身份运行。如果你的脚本需要特定的权限或者在特定的用户环境中运行,需要确保cron任务以正确的用户身份运行。
  4. 日志问题:cron任务默认不会像交互式 shell 环境那样输出到终端,因此你可能无法直接看到脚本执行时的输出。你可以在cron任务中设置输出重定向到日志文件,以便查看脚本执行时的输出。