精华内容
下载资源
问答
  • 提供:ZStack云计算 系列教程本教程为CoreOS上手指南系列九篇中的第八篇。内容简介CoreOS提供一系列强大的技术成果,能够显著简化分布式系统的构建流程。然而,新人用户们这些工具...Cloud-Config文件进行调试Cor

    提供:ZStack云计算

    系列教程

    本教程为CoreOS上手指南系列九篇中的第八篇。

    内容简介

    CoreOS提供一系列强大的技术成果,能够显著简化分布式系统的构建流程。然而,新人用户们对这些工具往往并不熟悉。由于其中存在众多抽象层,因此我们往往很难确定问题的具体根源。

    在本教程中,我们将了解与CoreOS主机、Docker容器以及各服务管理工具相关的故障排查知识。

    对Cloud-Config文件进行调试

    CoreOS新人们最常见的问题就是集群无法正确验证cloud-config文件。

    在服务器创建时,CoreOS会要求我们为其提供一个cloud-config文件。其会使用文件中的信息以引导自身并初始化或者加入现有集群。其同时亦会启动多项基本服务,并配置用户及群组等系统基本元素。

    下面是cloud-config文件的几项检查重点:

    • 其是否以“#cloud-config”开头?:每个cloud-config文件都必须以“#cloud-config”作为第一行。尽管在YAML中这经常被作为注释行而被忽略,但在本示例中这行其实代表其属于cloud init系统且包含配置数据。
    • 文件中是否包含有效YAML?:Cloud-config文件以YAML编写而成,这是一种数据排序格式且高度关注可读性。如果大家发生了问题,请将自己的cloud-config内容复制到YAML在线验证器当中。文件中不可存在任何错误。CoreOS提供一款工具以检查cloud-config中的语法,即Cloud-Config验证器
    • 是否使用了样报发现令牌?:发现地址会始终与设备数据保持一致——即使集群整体发生宕机。这意味着如果使用旧令牌进行引导,则发现注册将发生错误,特别是在我们此前已经使用同一IP地址进行过注册的情况下。确保每次启动集群时使用更新的发现令牌,从而避免这一问题。
    • 是否启动了fleet与etcd服务?:要让集群正常启动并运作,我们必须首先启动fleet与etcd两项服务。具体请参阅如何在DigitalOcean上运行CoreOS集群一文,以了解如何确保cloud-config文件满足这几项基本要求。

    大家只能在设备创建时传递cloud-config文件,因此一旦犯下错误,则只能关闭该服务器实例并重新启动(大多需要使用新令牌)。

    在保证cloud-config文件不睁大眼睛问题后,下一步是登录至主机以确保该文件得到正确处理。

    这项工作在DigitalOcean上很好实现,大家只需要在服务器创建时向其添加ssh密钥即可。这意味着我们能够ssh至服务器中以进行故障排查,而不会引起任何问题。

    通过DigitalOcean控制面板进行登录

    然而,cloud-config还有可能在服务器启动时对网络可用性造成影响。在这种情况下,大家需要通过DigitalOcean控制面板进行登录。这就引发了新的问题,因为CoreOS镜像在默认情况下并未设置密码。

    为解决这个问题,我们必须利用新的cloud-config文件重新创建该服务器,并在其中包含面向core用户的密码输入环节。由于需要重新创建,因此这种方式只适用于不断发现此问题且希望获取更多信息的情况。大家在检查时可向全部cloud-config文件添加密码信息,并在完成后以手动方式撤销密码。

    密码内容必须采用哈希格式。根据具体软件选择,大家可以通过多种方式实现。以下几种皆可,各位可选择适合自己的一种:

    mkpasswd --method=SHA-512 --rounds=4096
    openssl passwd -1
    python -c "import crypt, getpass, pwd; print crypt.crypt('password', '\$6\$SALT\$')"
    perl -e 'print crypt("password","\$6\$SALT\$") . "\n"'
    

    完成之后,向cloud-config文件中添加一个名为users的新区段(注意不要与‘coreos’区段重叠),并添加以下信息:

    #cloud-config
    users:
    - name: core
    passwd: hashed_password
    coreos:
    . . .
    

    验证YAML语法, 而后使用这一新cloud-config文件以创建服务器。这样我们就能够通过DigitalOcean控制面板利用密码完成登录了。

    检查各主机

    登录完成后,利用以下几种方式检查cloud-config是否得到正确处理。

    检查基本服务中的错误

    最简单的方式就是向fleetctl询问其已知设备。如果返回结果没有错误,则意味着fleet与etcd都已经正常启动,且能够与其它主机进行通信。

    fleetctl list-machines
    

    如果发现错误,则应该会看到对应的输出结果。常见的错误信息应如下所示:

    2014/09/18 17:10:50 INFO client.go:278: Failed getting response from http://127.0.0.1:4001/: dial tcp 127.0.0.1:4001: connection refused
    2014/09/18 17:10:50 ERROR client.go:200: Unable to get result for {Get /_coreos.com/fleet/machines}, retrying in 100ms
    2014/09/18 17:10:50 INFO client.go:278: Failed getting response from http://127.0.0.1:4001/: dial tcp 127.0.0.1:4001: connection refused
    2014/09/18 17:10:50 ERROR client.go:200: Unable to get result for {Get /_coreos.com/fleet/machines}, retrying in 200ms
    

    这意味着不同组件彼此堆叠,因此我们需要自上而下进行梳理。检查fleet服务以获取错误信息:

    systemctl status -l fleet
    
    ● fleet.service - fleet daemon
    Loaded: loaded (/usr/lib64/systemd/system/fleet.service; static)
    Drop-In: /run/systemd/system/fleet.service.d
           └─20-cloudinit.conf
    Active: active (running) since Thu 2014-09-18 17:10:50 UTC; 2min 26s ago
    Main PID: 634 (fleetd)
    CGroup: /system.slice/fleet.service
           └─634 /usr/bin/fleetd
    
    Sep 18 17:13:07 dumb1 fleetd[634]: INFO client.go:278: Failed getting response from http://localhost:4001/: dial tcp 127.0.0.1:4001: connection refused
    Sep 18 17:13:07 dumb1 fleetd[634]: ERROR client.go:200: Unable to get result for {Update /_coreos.com/fleet/machines/795de101bcd24a3a96aa698f770f0074/object}, retrying in 800ms
    Sep 18 17:13:08 dumb1 fleetd[634]: INFO client.go:278: Failed getting response from http://localhost:4001/: dial tcp 127.0.0.1:4001: connection refused
    

    如大家所见,该服务正在运行,但却无法接入端口4001,也就是etcd端口。这意味着该问题可能与etcd有关。

    我们需要逐一检查每项基本服务的状态与日志。常见的实现方式如下:

    systemctl status -l service
    journalctl -b -u service
    

    其中“status”命令负责提供该服务的状态及最后几行日志记录。而journal命令则可访问全部日志内容。

    接下来利用同样的操作检查etcd,在本示例中我们发现etcd服务并未运行:

    systemctl status -l etcd
    
    ● etcd.service - etcd
    Loaded: loaded (/usr/lib64/systemd/system/etcd.service; static)
    Drop-In: /run/systemd/system/etcd.service.d
           └─20-cloudinit.conf
    Active: activating (auto-restart) (Result: exit-code) since Thu 2014-09-18 17:17:03 UTC; 9s ago
    Process: 938 ExecStart=/usr/bin/etcd (code=exited, status=1/FAILURE)
    Main PID: 938 (code=exited, status=1/FAILURE)
    
    Sep 18 17:17:03 dumb1 systemd[1]: etcd.service: main process exited, code=exited, status=1/FAILURE
    Sep 18 17:17:03 dumb1 systemd[1]: Unit etcd.service entered failed state.
    

    如果检查etcd日志,则会看到:

    journalctl -b -u etcd
    
    Sep 18 17:21:27 dumb1 systemd[1]: Starting etcd...
    Sep 18 17:21:27 dumb1 systemd[1]: Started etcd.
    Sep 18 17:21:27 dumb1 etcd[1160]: [etcd] Sep 18 17:21:27.966 INFO      | The path /var/lib/etcd/log is in btrfs
    Sep 18 17:21:27 dumb1 etcd[1160]: [etcd] Sep 18 17:21:27.967 INFO      | Set NOCOW to path /var/lib/etcd/log succeeded
    Sep 18 17:21:27 dumb1 etcd[1160]: [etcd] Sep 18 17:21:27.967 INFO      | Discovery via https://discovery.etcd.io using prefix /.
    Sep 18 17:21:28 dumb1 etcd[1160]: [etcd] Sep 18 17:21:28.422 WARNING   | Discovery encountered an error: invalid character 'p' after top-level value
    Sep 18 17:21:28 dumb1 etcd[1160]: [etcd] Sep 18 17:21:28.423 WARNING   | 795de101bcd24a3a96aa698f770f0074 failed to connect discovery service[https://discovery.etcd.io/]: invalid character 'p' after top-level value
    Sep 18 17:21:28 dumb1 etcd[1160]: [etcd] Sep 18 17:21:28.423 CRITICAL  | 795de101bcd24a3a96aa698f770f0074, the new instance, must register itself to discovery service as required
    Sep 18 17:21:28 dumb1 systemd[1]: etcd.service: main process exited, code=exited, status=1/FAILURE
    Sep 18 17:21:28 dumb1 systemd[1]: Unit etcd.service entered failed state.
    

    其中高亮部分代表此特定示例缺少发现令牌。

    检查文件系统以查找由Cloud-Config生成的配置文件

    下面检查由cloud-config生成的各服务文件。

    CoreOS设备在处理cloud-config文件时,其会生成存根systemd单元文件,其用于启动fleet与etcd。检查由此创建的systemd配置文件同时变更其所在目录:

    cd /run/systemd/system
    ls -F
    
    etcd.service.d/  fleet.service.d/  oem-cloudinit.service
    

    这里我们可以看到生成的oem-cloudinit.service文件,其由CoreOS自动处理,外加存放服务信息的各目录。我们可以使用以下命令查看etcd服务的启动信息:

    cat etcd.servicd.d/20-cloudinit.conf
    
    [Service]
    Environment="ETCD_ADDR=10.132.247.162:4001"
    Environment="ETCD_DISCOVERY=https://discovery.etcd.io/"
    Environment="ETCD_NAME=795de101bcd24a3a96aa698f770f0074"
    Environment="ETCD_PEER_ADDR=10.132.247.162:7001"
    

    这个存根systemd单元文件用于将其它信息在启动时添加到该服务当中。如大家所见,其中ETCD_DISCOVERY地址符合我们之前在logs: there is no discovery token处发现的信息。我们需要利用包含有效发现令牌的cloud-config文件重新创建设备。

    利用以下命令获取同样的fleet信息:

    cat fleet.service.d/20-cloudinit.conf
    
    [Service]
    Environment="FLEET_METADATA=region=nyc,public_ip=104.131.1.89"
    Environment="FLEET_PUBLIC_IP=10.132.247.162"
    

    在这里,大家可以看到cloud-config向fleet提供了部分元数据信息。其可用于在创建服务单元文件时执行相关调度工作。

    检查元数据服务访问

    CoreOS服务器创建时所使用的cloud-config文件是利用一项元数据服务进行存储的。如果我们无法在服务器上找到该cloud-config,那么其也许未能从DigitalOcean元数据服务处提取相关信息。

    在主机设备上输入:

    curl -L 169.254.169.254/metadata/v1
    
    id
    hostname
    user-data
    vendor-data
    public-keys
    region
    interfaces/
    dns/
    

    注意,-L参数用于实现重新定向追踪。其中169.254.169.254地址将被用于每一台服务器,因此我们不应对其进行修改。结果所示为我们的元数据字段以及容纳服务器相关信息的各个目录。如果我们无法获取以上表单,则可能需要向技术人员求助。

    大家可以查询此URL以获取服务器相关信息。利用curl命令检查其中的每个条目,其中包含有cloud-config文件的为user-data字段:

    curl -L 169.254.169.254/metadata/v1/user-data
    
    #cloud-config
    users:
    - name: core
    passwd: $6$CeKTMyfClO/CPSHB$02scg00.FnwlEYdq/oXiXoohzvvlY6ykUck1enMod7VKJrzyGRAtZGziZh48LNcECu/mtgPZpY6aGCoj.h4bV1
    coreos:
    etcd:
    # generated token from https://discovery.etcd.io/new
    discovery: https://discovery.etcd.io/
    # multi-region and multi-cloud deployments need to use $public_ipv4
    addr: $private_ipv4:4001
    peer-addr: $private_ipv4:7001
    fleet:
    public-ip: $private_ipv4
    metadata: region=nyc,public_ip=$public_ipv4
    units:
    - name: etcd.service
      command: start
    - name: fleet.service
      command: start
    

    如果大家能够从这一位置找到cloud-config文件,则意味着我们的服务器同样有能力读取该cloud-config数据,并在服务器引导过程中执行相关指令。

    利用CoreOS主机设备对其它问题者故障排查

    如果大家需要进行进一步调试,则可将注意力转向包含最低安装库的CoreOS版本。其中包含容器中所运行的全部软件,但排除了其它大部分不必要的基础性工具程序。

    幸运的是,CoreOS开发人员们提供了另一种更为可行的解决办法。大家可以在每台主机上使用“toolbox”脚本,从而启动一套Fedora容器以访问各主机系统。在此容器当中,大家可以安装主机调试所必需的各类工具。

    利用以下toolbox命令:

    toolbox
    

    其会提取最新版本Fedora镜像并在容器中打开命令行。经过快速检查,大家会发现自己已经接入该主机系统的网络:

    ip addr show
    
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 04:01:28:7c:39:01 brd ff:ff:ff:ff:ff:ff
    inet 169.254.180.43/16 brd 169.254.255.255 scope link eth0
       valid_lft forever preferred_lft forever
    . . .
    

    大家也可以访问全部主机进程:

    ps aux
    
    USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    root         1  0.0  0.1 106024  4912 ?        Ss   17:10   0:04 /usr/lib/systemd/systemd --switched-root --system --deserialize 19
    root         2  0.0  0.0      0     0 ?        S    17:10   0:00 [kthreadd]
    root         3  0.0  0.0      0     0 ?        S    17:10   0:00 [ksoftirqd/0]
    root         5  0.0  0.0      0     0 ?        S<   17:10   0:00 [kworker/0:0H]
    root         6  0.0  0.0      0     0 ?        S    17:10   0:00 [kworker/u4:0]
    root         7  0.0  0.0      0     0 ?        S    17:10   0:00 [rcu_sched]
    root         8  0.0  0.0      0     0 ?        S    17:10   0:00 [rcu_bh]
    . . .
    

    大家可以在此环境中安装任意工具。举例来说,我们可以利用Fedora软件包管理器安装htop:

    yum install htop -y && htop
    

    该进程监控器会导入全部当前主机的已加载进程:

    要退出该容器环境,输入“exit”或者快速按三次CTRL-]。这样我们就会退出到主机的shell会话。

    立足任意主机对服务进行故障排查

    我们可能还需要对服务实际运行所在的主机进行故障排查。由于fleet与fleetctl能够管理整套集群中的全部服务,因此我们可以在集群内任意主机上执行这两款工具。

    首先要做的是了解服务的运行状态,包括fleet与被分配以执行各服务的个别主机。我们可以使用fleetctl工具提供的命令以轻松获取这部分信息。

    首先利用以下命令查看fleet中的服务状态:

    fleetctl list-unit-files
    
    UNIT                HASH    DSTATE      STATE       TARGET
    apache-discovery@4444.service   06d78fb loaded      loaded      04856ec4.../10.132.249.212
    apache-discovery@7777.service   06d78fb loaded      loaded      197a1662.../10.132.249.206
    apache-discovery@8888.service   06d78fb loaded      loaded      e3ca8fd3.../10.132.252.37
    apache@4444.service     0f7f53b launched    launched    04856ec4.../10.132.249.212
    apache@7777.service     0f7f53b launched    launched    197a1662.../10.132.249.206
    apache@8888.service     0f7f53b launched    launched    e3ca8fd3.../10.132.252.37
    nginx_lb.service        c8541af launched    launched    96ec72cf.../10.132.248.177
    

    在这里我们可以对fleet掌握的服务状态进行浏览。输出结果中包含几条重要信息,下面分别来看。

    • UNIT: 此处为该单元名称。在本示例中,前六项服务皆为实例单元(可参阅模板与实例一文),而结尾处则为静态实例。我们可以在命令中使用这些名称以影响各项服务。
    • HASH: 此处为该单元文件用于控制此服务的哈希。如大家所见,全部apache-discovery实例都源自同一模板文件。其中各apache实例拥有共同的来源,我们可以据此查看自己的服务是否由于使用了过期单元文件而发生异常。
    • DSTATE: 此处为该单元的理想状态。在向fleetctl发送命令以变更该单元状态时,此列亦会变化以反响该单元的理想状态。
    • STATE: 此处为fleet所掌握的该单元的实际状态。如果其与DSTATE有所不同,则意味着操作失败。
    • TARGET: 被调度以运行此服务的设备。这一项会在单元启动或者加载时显示可用信息。其中包含设备ID以及对应设备的IP地址。

    如大家所见,我们可以根据多种信息进行问题调试。

    然而,这并不是检查的重点所在。真正重要的是意识fleet与设备本地systemd实例之间在何时发生服务状态冲突。这种问题的发生原因多种多样,例如某单元在内部启动或者停止其它单元。

    要获取每项服务的状态信息,则可使用以下命令从运行该服务的主机systemd实例中提取:

    fleetctl list-units
    
    UNIT                MACHINE             ACTIVE  SUB
    apache-discovery@4444.service   04856ec4.../10.132.249.212  active  running
    apache-discovery@7777.service   197a1662.../10.132.249.206  active  running
    apache-discovery@8888.service   e3ca8fd3.../10.132.252.37   active  running
    apache@4444.service     04856ec4.../10.132.249.212  active  running
    apache@7777.service     197a1662.../10.132.249.206  active  running
    apache@8888.service     e3ca8fd3.../10.132.252.37   active  running
    nginx_lb.service        96ec72cf.../10.132.248.177  active  running
    

    这里,我们可以看到全部列出服务皆处于运行状态。这显然与list-unit-files的显示结果不同。这是因为其中每项apache service都会启动相关apache-discovery服务,而不会单独通知fleet。这并不是错误,但却可能导致服务的实际状态发生冲突。

    为了获取更多与服务相关的信息,大家可以使用fleetctl访问目标主机系统的systemctl状态及journalctl -u信息。命令如下:

    fleetctl status service_name
    
    ● apache@4444.service - Apache web server service on port 4444
    Loaded: loaded (/run/fleet/units/apache@4444.service; linked-runtime)
    Active: active (running) since Thu 2014-09-18 18:50:00 UTC; 7min ago
    Process: 3535 ExecStartPre=/usr/bin/docker pull imchairmanm/apache (code=exited, status=0/SUCCESS)
    Process: 3526 ExecStartPre=/usr/bin/docker rm apache.%i (code=exited, status=0/SUCCESS)
    Process: 3518 ExecStartPre=/usr/bin/docker kill apache.%i (code=exited, status=0/SUCCESS)
    Main PID: 3543 (docker)
    CGroup: /system.slice/system-apache.slice/apache@4444.service
           └─3543 /usr/bin/docker run -t --name apache.4444 -p 10.132.249.212:4444:80 imchairmanm/apache /usr/sbin/apache2ctl -D FOREGROUND
    

    或者使用以下命令查阅journal:

    fleetctl journal service_name
    
    -- Logs begin at Mon 2014-09-15 14:54:12 UTC, end at Thu 2014-09-18 18:57:51 UTC. --
    Sep 17 14:33:20 lala2 systemd[1]: Started Apache web server service on port 4444.
    Sep 17 14:33:20 lala2 docker[21045]: AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.10. Set the 'ServerName' directive globally to suppress this message
    Sep 18 18:49:29 lala2 systemd[1]: Stopping Apache web server service on port 4444...
    Sep 18 18:49:39 lala2 docker[3500]: apache.4444
    Sep 18 18:49:39 lala2 systemd[1]: Stopped Apache web server service on port 4444.
    Sep 18 18:49:58 lala2 systemd[1]: Starting Apache web server service on port 4444...
    Sep 18 18:49:58 lala2 docker[3518]: apache.4444
    Sep 18 18:49:58 lala2 docker[3526]: apache.4444
    Sep 18 18:49:58 lala2 docker[3535]: Pulling repository imchairmanm/apache
    Sep 18 18:50:00 lala2 systemd[1]: Started Apache web server service on port 4444.
    

    我们可以借此了解服务的失败原因。例如,如果我们的单元文件声明了一项不可用的关联性,则其将被显示于此(这可能是因为该关联未被加载至fleet当中)。

    使用上述命令的一类常见错误如下:

    Error running remote command: SSH_ AUTH _SOCK environment variable is not set. Verify ssh-agent is running. See https://github.com/coreos/fleet/blob/master/Documentation/using-the-client.md for help.
    

    这意味着我们在接入该主机时,并没有转发自己的ssh用户代理。为了让fleet获取集群内其它设备的信息,其会利用我们保存在本地计算机上的SSH证书进行接入。

    这时,大家需要在本地计算机上运行一套ssh代理并添加自己的专有密钥。本地计算机上的ssh代理运行方式如下:

    eval $(ssh-agent)
    ssh-add
    
    Identity added: /home/username/.ssh/id_rsa (/home/username/.ssh/id_rsa)
    

    完成之后,我们应当利用-A选项接入自己的CoreOS主机并转发此信息:

    ssh -A core@coreos_host
    

    这样设备就能够利用ssh证书接入集群内的其它设备了,我们亦可以立足于远程集群成员读取systemd信息。

    立足于运行该服务的主机进行容器故障排查

    尽管我们单纯利用fleetctl即可获得大量重要信息,但有时候也必须前往运行该服务的主机以完成排查工作。

    如上所述,我们可以通过转发SSH信息以轻松实现接入。在接入的主机上,我们可以利用fleetctl “hop”至其它设备。我们也可以指定一个设备ID或者直接使用服务名称。Fleetctl进程非常智能,足以了解我们所指的具体主机:

    fleetctl ssh service_name
    

    运行后,我们将获得被分配运行该服务的主机的ssh连接。当然,查询的服务必须处于“已载入”或者“已启动”状态。

    在这里,大家需要访问全部本地故障排查工具。例如,大家可以通过journalctl标记那些可能并未显示在fleetctl journal命令中的条目:

    journalctl -b --no-pager -u apache@4444
    

    现在,大家可能希望对Docker问题进行故障排查。利用以下命令查看当前正在运行的容器列表:

    docker ps
    
    CONTAINER ID        IMAGE                       COMMAND                CREATED             STATUS              PORTS                         NAMES
    b68139630337        imchairmanm/apache:latest   "/usr/sbin/apache2ct   30 minutes ago      Up 30 minutes       10.132.249.212:4444->80/tcp   apache.4444
    

    可以看到,目前只有一套容器正在运行。其中高亮部分的容器ID可用于更多Docker操作。

    如果我们的服务未能启动,则容器自然也无法运行。要查看全部容器列表,其中包含现有及未能运行的容器,则可添加-a标记:

    docker ps -a
    
    CONTAINER ID        IMAGE                       COMMAND                CREATED             STATUS                     PORTS                         NAMES
    b68139630337        imchairmanm/apache:latest   "/usr/sbin/apache2ct   31 minutes ago      Up 31 minutes              10.132.249.212:4444->80/tcp   apache.4444         
    4389108bff1a        imchairmanm/apache:latest   "/usr/sbin/apache2ct   28 hours ago        Exited (-1) 28 hours ago                                 apache.8888         
    5af6e4f95642        imchairmanm/lalala:latest   "/usr/sbin/apache2ct   3 days ago          Exited (-1) 3 days ago                                   apache.7777
    

    而要查看新近启动的容器,而不管其具体状态,则可使用-l标记:

    docker ps -l
    
    CONTAINER ID        IMAGE                       COMMAND                CREATED             STATUS              PORTS                         NAMES
    b68139630337        imchairmanm/apache:latest   "/usr/sbin/apache2ct   33 minutes ago      Up 33 minutes       10.132.249.212:4444->80/tcp   apache.4444
    

    在找到了目标容器的ID之后,则可立足于Docker层面进行调查了。首先,查看相关日志:

    docker logs container_id
    

    由此可获得收集自该容器的日志信息,无论该容器当前是否处于运行状态。如果该容器以交互方式运行(包含-i与-t标记及一套shell会话),则可在此日志中对该会话进行操作。

    大家也可以利用以下命令获取任意活动容器的运行进程列表:

    docker top container_id
    

    在容器内生成Shell会话

    在运行中容器内开启一套shell会话的作法非常常见,而CoreOS则专门提供nsenter工具来实现这一效果。

    Docker容器需要设置内核命名空间才能正常运行,而此工具能够在此类环境下启动该工具。第一步是获得该容器的PID,命令如下:

    PID=$(docker inspect --format {{.State.Pid}} container_id)
    

    现在,我们可以通过以下命令在目标容器环境下开启一套shell会话:

    sudo nsenter -t $PID -m -u -i -n -p
    

    容器环境下将出现一套shell会话。在这里,我们可以查看日志或者进行各类必要的故障排查操作。

    根据容器的具体构建方式,大家可能会收到提示称无法找到bash。在这种情况下,我们可以在命令结尾处使用sh:

    sudo nsenter -t $PID -m -u -i -n -p /bin/sh
    

    总结

    当然,这些只是在CoreOS集群内实现故障排查的一小部分可行方案。通过今天的教程,大家应该已经了解了如何对cloud-config文件、集群内设备以及服务启动状态进行故障排查。顺带一提,对Docker容器及服务自身的问题进行追踪将在其它教程中另行介绍。

    作为一种前提性思路,我们掌握的系统信息越多,故障排查工作就越易于实现。我们应当清晰掌握每款组件的功能角色,各组件之间的交互作用以及对系统功能的影响。如果在追踪问题的时候发现无处下手,那么复习一下CoreOS基础知识往往能起到意料之外的良好效果。

    本文来源自DigitalOcean Community。英文原文:How To Troubleshoot Common Issues with your CoreOS Servers By Justin Ellingwood

    翻译:diradw

    展开全文
  • 该文是《Google运维解密》系列的关于问题排查的一篇分享。该文章主要是和大家聊了聊日常运维问题排查时候的一些原则与心得。希望该文章能给大家日常问题排查能有个更好的启发。前言今天我们来聊聊“问题排查”这个...
        

    0?wxfrom=5&wx_lazy=1

    该文是《Google运维解密》系列的关于问题排查的一篇分享。该文章主要是和大家聊了聊日常运维问题排查时候的一些原则与心得。希望该文章能给大家日常问题的排查能有个更好的启发。

    640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1

    前言

    今天我们来聊聊“问题排查”这个话题,本人到目前为止还在参与一线运维的工作,遇到过很多“稀奇古怪”的线上故障和问题,结合SRE中给出的一些方法,来说说“问题排查”那点事。

    排查问题不是玄学

    排查出线上问题,并找到根本原因加以解决,是一件很有成就感的事情,曾经有人问过我,“你是怎么想到问题出现在xxx的?又是怎么确认根本原因是xxx的?”,我只能淡淡的说:“靠经验”,然后感觉这个逼装的自己还算满意。

    其实这个“靠经验”说的很模糊,一直以来,大家都觉得排查问题要靠经验,但是又说不出具体通过啥经验排查出了问题,最后让排查问题逐渐变成了一门玄学。

    排查问题犹如破案

    排查线上问题,就和侦探破案一样,就是一个不停分析线索,推理的过程,在你准备破案之前,先要明确以下两点。

    系统异常是正常的,正常是特例

    时至今日,计算机系统已经变得异常复杂,一次用户请求可能要经过发送请求,DNS解析,运营商网络和IP转换,负载均衡,服务器硬件,虚拟机/容器,视业务逻辑的复杂程度,可能还要调用其它组件,存储,数据库,缓存等。每个环节都可能出现问题,有的组件又是分布式的,大大增加的排查问题的难度。

    所以出现问题后,不要着急,保持好心态,要认为“系统异常是正常的,正常是特例”。

    飞行员首要任务是保持飞机飞行

    在初级飞行员的课程中捡到,在紧急情况中,飞行员的首要任务是保持飞机飞行,相比保证乘客与飞机安全着陆,故障定位和排除是次要目标。—SRE

    所以,恢复线上系统是首要任务,而不是找到它发生的原因。

    明确案情

    先评估出这个问题的影响范围,是全网用户不可用,还是某些用户,是某条业务线出现问题,还是很多业务线都出现问题,评估出案情的大小,是普通的民事案件,还是刑事案件。

    真相只有一个

    计算机是一门科学,而且计算机是由0|1组成的世界,在这个世界里只有“是或否”,没有中间地带,所以在计算机世界“凡事都有根本原因”,“没有偶然发生,一切都是必然”。

    所以,你要坚信真相只有一个。

    理清线索

    理清目前得到的线索和信息,比如监控上有网络报警,有用户反馈无法访问,有开发人员反馈服务器有问题,不要漏掉看似无关紧要的线索,把这些线索先整理下来,后面一并分析。

    扩大信息量

    尽可能扩大你接受到的信息量,比如问询一下开发人员今天有没有做线上改动,网络组有无重大调整。获取到有价值的信息,对于排查问题至关重要。

    查看监控,细看某个监控项的变化,追踪日志和调试信息都是扩大信息量的手段。

    分析证词

    分析用户反馈的现象,数据是可信的,有时候人说的是不可信的,举个例子,之前有开发反馈我们虚拟机有问题,有些虚拟机接口返回异常,有些正常,他就让我们帮查查虚拟机的问题,但是最后是代码调用一处动态配置造成的。

    很多反馈的信息描述,是经过描述者过滤加工过的信息,他的排查和分析有可能把你“带歪了”,先要用怀疑的态度,分析每个人的证词。

    当你听到蹄子声响时,应该先想到马,而不是斑马

    排查问题不要先入为主,有时候你觉得极其简单,看似非常不可能发生的事情,可能就是原因,不要轻易的排除掉某项原因,比如“宇宙射线导致某个电路信号出错”。

    我们之前有个mysql连接异常的问题,查了很久,做了很多调优都没有解决,最后发现是网卡跑满了。

    从大到小,从上到下

    排查步骤,先“从大到小”,先看比如运营商网络,机房状态等比较宏观的地方是否有问题,逐一排除,逐步缩小问题范围。“从上到下”,先从现象发生的顶端调用链逐一排查,逐步向下深入。

    SRE给出的一些方法

    SRE给出了一些方法可以借鉴:

    • 问题排查的几个步骤:定位,检查,诊断,测试/修复,治愈。

    • 什么,哪里和为什么,找出系统正在执行“什么”,询问系统“为什么”执行这些操作,以及系统的资源都被用在了“哪里”可以帮助你了解系统为什么出错。

    • 确定“最后一个修改”发生的时间。

    • 提供丰富的诊断和监控工具。

    下次遇到问题,使用以上方法试试看,让问题排查不再是“很玄妙的东西”。

    本文转载自公众号【HULK一线技术杂谈】

    更多相关文章阅读

    携程运维自动化平台,上万服务器变更也可以很轻松

    智能运维就是 由 AI 代替运维人员?

    看腾讯运维应对“18岁照片全民怀旧”事件的方案,你一定不后悔!

    运行无间:阿里巴巴运维保障体系的一种最佳实践

    芳华永在!一个老运维的20年奋斗史

    饿了么异地双活数据库实战

    运维版《成都》,听哭了多少人...

    阿里万亿交易量级下的秒级监控

    IT 运维的救赎——顺丰运维的理想践行


    学好 Python、拿高薪、竟是如此简单

    快加入高维学院直通车成为认证运维开发工程师

    只需要5天!

    在5天内集中向你传授面向 DevOps 的运维开发工程师所需要掌握的所有精华。


    更有含金量的是,学习结束你还将拥有一张【运维开发工程师认证证书】


    这份含金量超高的证书:

    ?wx_fmt=jpeg

    ?wx_fmt=jpeg

    如能被推荐进入上述大厂,您的培训费将被退回一半!!

    更多企业直通车,正在路上。

    也欢迎企业和我们联系:

    刘琳,微信/电话:13910952502

    参与认证运维开发工程师课程报名、详情请点击阅读原文链接

    展开全文
  • Docker启动问题排查

    万次阅读 2018-06-25 14:21:08
    当docker镜像被制作之后,通过sudo docker images命令可以查看到镜像已经被制作。正常情况下已经在Dockerfile中配置启动命令,因此container容器也已经被启动...方式一:通过查看logs日志来排查问题 通过命令sudo ...

    当docker镜像被制作之后,通过sudo docker images命令可以查看到镜像已经被制作。正常情况下已经在Dockerfile中配置启动命令,因此container容器也已经被启动。但是当镜像内部发生问题时,容器是启动不成功的,可以通过sudo docker ps -a查看所有容器,其中失败容器的status是不正常的。


    方式一:通过查看logs日志来排查问题

    通过命令sudo docker logs ${container_id}来指定具体id号的日志信息。

    当发现问题需要重新制作镜像时,通过以下步骤进行排查:
    1. 需要删除之前已经创建的镜像和据此镜像未启动的容器。步骤是先删除对应的子容器,再删除父镜像。
    + 查看容器命令:sudo docker ps -a 找到失败容器ID
    $ sudo docker ps -a
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    32928ee6451a longsl/chatproxy:1.0 “/usr/app/chatprox…” 33 hours ago Exited (1) 33 hours ago KP_CHAT_PROXY

    • 删除对应容器:sudo docker rm KP_CHAT_PROXY

    • 查看镜像命令:sudo docker images
      $ sudo docker images
      REPOSITORY TAG IMAGE ID CREATED SIZE
      longsl/chatproxy 1.0 9281da534c00 33 hours ago 723 MB
      longsl/chatserver 1.0 171344fa3b34 35 hours ago 579 MB

    • 删除对应镜像:sudo docker rmi longsl/chatproxy:1.0

    当所有清除工作完成后,开始构建新的镜像及容器

    • 创建镜像:docker build -t longsl/chatproxy:1.0 .
    • 最后启动容器

    方式二:通过用初始化命令启动容来排查问题

    通过/usr/sbin/init命令替换原项目程序来启动容器命令:

    sudo docker run -d \
        --user=kpgame \
        -m=512m \
        -e "TZ=Asia/Singapore" \
        -e 'XMXSIZE=409m' \
        ...
        longsl/chatproxy:1.0 \
          /usr/sbin/init

    启动成功后,通过sudo docker container exec KP_CHAT_PROXY_90 ls -al /usr/app/chatproxy/log命令进入出错的目录进行查看,发现仍然报 ls: cannot open directory /usr/app/chatproxy/log: Permission denied

    最后发现是centos77中的安全模块selinux把权限禁掉了,通过在运行容器的时候,给容器加特权,及加上 --privileged=true参数可以解决,在文章最后的参考链接中,有更详细的说明。修改docker 容器的启动命令如下:

    sudo docker run -d \
        --user=kpgame \
        -m=512m \
        -e "TZ=Asia/Singapore" \
        -e 'XMXSIZE=409m' \
        ...
        -v /data/kpdeploy/logs/KP_CHAT_PROXY_90:/usr/app/chatproxy/log \
        --name KP_CHAT_PROXY_90 \
          --privileged=true \
        longsl/chatproxy:1.0 \
          /usr/sbin/init

    搞定! 挂载文件可以被访问了,排查完成。


    参考链接
    [1] https://blog.csdn.net/rznice/article/details/52170085

    展开全文
  • JVM问题排查

    千次阅读 2018-06-03 16:28:46
    本文将介绍JDK自带的JVM排查工具。其提供的排查工具有:(1)jps:JVM Process Status Tool,显示系统内所有的JVM进程;(2)jstat:JVM Statistics Monitoring Tool,可以收集JVM相关的运行数据;(3)jinfo:...

    本文将介绍JDK自带的JVM排查工具。其提供的排查工具有:

    (1)jps:JVM Process Status Tool,显示系统内所有的JVM进程;

    (2)jstat:JVM Statistics Monitoring Tool,可以收集JVM相关的运行数据;

    (3)jinfo:Configuration Info for Java,显示JVM配置信息;

    (4)jmap:Memory Map for Java,用于生成JVM的内存快照;

    (5)jhat:JVM Heap Dump Browser,用于分析heapdump文件,它可以建立一个http/html服务,使用者可以在浏览器上查看分析结果;

    (6)jstack:Stack Trace for Java,显示JVM的线程快照。

    (7)jconsole:一个java GUI监视工具,可以以图表化的形式显示各种数据。并可通过远程连接监视远程的服务器VM。

    一、jps

    列出正在运行的虚拟机进程,并显示虚拟机执行主类名称以及这些进程的本地虚拟机唯一id(Local Virtual Machine Identifier,简称LVMID)。相比其他命令来说,它的功能其实比较单一,但是它的使用频率确实非常高的,因为其他的JDK命令大多都需要输入虚拟机进程id。

    注:看到这里小伙伴们可能就会比较困惑了,因为在大多数使用JDK命令时,我们都用的是pid(操作系统进程id)啊,那pid和LVMID到底有什么区别呢?其实,很负责任的告诉你,对于本地虚拟机进程来说,它俩无差别,用ps命令也可以查询到,但是如果同时启动多个虚拟机进程无法根据进程名称定位时,jps命令就派上用场了,可以输出主类名称,通过主类名称来区分。

    jps命令格式:

    jps命令格式

    jps主要提供以下选项:

    • -q
      只输出LVMID,省略主类名称;

    • -m
      输出虚拟机进程启动时传给主类函数的参数;

    • -l
      输出主类的完成package名称或者jar包完整路径名;

    • -v
      输出虚拟机启动时的JVM参数

    接下来我们来看看它的实际使用:

    • 测试代码:
      测试代码
    • 使用结果:
      jps使用结果
    二、jstat

    用于监控虚拟机运行状态信息。它可以显示本地或者远程虚拟机进程的内存、垃圾收集、JIT编译等运行数据。

    jstat命令格式:

    jstat命令格式

    jstat命令稍许有些复杂,它主要有以下参数:
    1. option:选项,jstat主要提供以下选项:

      • -class
        监视类的装载/卸载数量、总空间以及类装载所耗时间;

      • -gc
        监视java heap情况,包括eden区和两个survivor区、old区、永久区等的容量,已用空间和GC时间等信息;

      • -gccapacity
        监视内容与-gc基本是一致的,-gccapacity的输出包括heap各个区域使用到的最大最小空间;

      • gcutil
        监视内容同样与-gc基本一致,-gcutil的输出主要是heap各个区域使用空间占总空间百分比;

      • gccause
        -gcutil功能一致,但是会额外输出导致上一次gc的原因;

      • gcnew
        监视young区gc情况;

      • gcnewcapacity
        监视内容与-gcnew基本相同,-gcnewcapacity的输出包括使用到的最大最小空间;

      • -gcold
        监视old区gc情况;

      • -gcoldcapacity
        监视内容与-gcold基本相同,-gcoldcapacity的输出包括使用到的最大最小空间;

      • -gcpermcapacity
        输出永久代使用到的最大最小空间;

      注:JDK 8废除了永久代,引入了Metaspace,这个命令在JDK 8的环境下就不能使用了,那要看元数据空间相关情况,使用-gcmetacapacity即可

      • -compiler
        输出JIT编译器编译过的方法以及耗时等信息;
      • -printcompilation
        输出以及被JIT编译的方法
    2. vmid:虚拟机进程id,这时候小伙伴们肯定又要开始疑惑了,这个vmid与lvmid又有什么区别?其实对于本地虚拟机进程,它俩没任何区别,但是如果是远程虚拟机进程,它俩就有区别了,远程虚拟机进程vmid格式应该是这样:
      [protocol:][//] lvmid [@hostname[:port]/servername]

    3. interval:查询时间间隔;

    4. count:查询次数。

    注:如果参数interval和count省略则代表只查询一次;如果count省略的话,就会一直查询。来个简单的例子:jstat -gcnewcapacity 41503 1000,表示输出进程41503的young区使用及gc情况,每1000ms输出一次

    接下来就部分option给出实例,同时分析下输出。

    jstat使用

    1. jstat -class <vmid>


      jstat -class输出
      • Loaded:装载的类的数量;

      • Bytes:装载类所占用的字节数;

      • Unloaded:卸载类数量;

      • Bytes:卸载类所占用的字节数;

      • Time:装载和卸载类所花时间。

    2. jstat -compiler <vmid>


      jstat -compiler输出
      • Compiled:编译任务执行数量;

      • Failed:编译任务执行失败数量;

      • Invalid:编译任务执行失效数量;

      • Time:编译任务消耗时间;

      • FailedType:最后一个编译失败任务的类型;

      • FailedMethod:最后一个编译失败任务所在的类及方法。

    3. jstat -gc <vmid>


      jstat -gc输出
      • S0C:young区中的第一个survivor区的大小;

      • S1C:young区中的第二个survivor区的大小;

      • S0U:young区中的第一个survivor区目前已使用空间;

      • S1U:young区中的第二个survivor区目前已使用空间;

      • EC:young区中的eden区的大小;

      • EU:young区中的eden区目前已使用空间;

      • OC:old区的大小;

      • OU:old区目前已使用空间;

      • MC:元数据区大小;

      • MU:元数据区使用大小;

      • CCSC:压缩类空间大小;

      • CCSU:压缩类空间使用大小;

      • YGC:young gc次数;

      • YGCT:young gc消耗时间;

      • FGC:full gc次数;

      • FGCT:full gc消耗时间;

      • GCT:gc消耗时间。

    4. jstat -gcutil <vmid>


      jstat -gcutil输出
      • S0:young区中的第一个survivor区的使用比例;

      • S1:young区中的第二个survivor区的使用比例;

      • E:young区中的eden区的使用比例;

      • O:old区使用比例;

      • M:元数据区使用比例;

      • CCS:压缩类空间使用比例;

      • YGC:young gc次数;

      • YGCT:young gc消耗时间;

      • FGC:full gc次数;

      • FGCT:full gc消耗时间;

      • GCT:gc消耗时间。

    5. jstat -gccapacity <vmid>


      jstat -gccapacity输出
      • NGCMN:young区最小容量;

      • NGCMX:young区最大容量;

      • NGC:当前young区容量;

      • S0C:young区中的第一个survivor区的大小;

      • S1C:young区中的第二个survivor区的大小;

      • EC:young区中的eden区的大小;

      • OGCMN:old区最小容量;

      • OGCMX:old区最大容量;

      • OGC:当前old区大小;

      • OC:当前old区的大小;

      • MCMN:元数据区最小容量;

      • MCMX:元数据区最大容量;

      • MC:当前元数据区大小;

      • CCSMN:压缩类空间最小容量;

      • CCSMX:压缩类空间最大容量;

      • CCSC:当前压缩类空间大小;

      • YGC:young gc次数;

      • FGC:old gc次数。

    6. jstat -gcnew <vmid>


      jstat -gcnew输出
      • S0C:young区中的第一个survivor区的大小;

      • S1C:young区中的第二个survivor区的大小;

      • S0U:young区中的第一个survivor区目前已使用空间;

      • S1U:young区中的第二个survivor区目前已使用空间;

      • TT:对象在young区存活的次数;

      • MTT:对象在young区存活的最大次数;

      • DSS:期望survivor区大小;

      • EC:young区中的eden区的大小;

      • EU:young区中的eden区目前已使用空间;

      • YGC:young gc次数;

      • YGCT:young gc消耗时间。

    7. jstat -gcold <vmid>


      jstat -gcold输出
      • MC:元数据空间大小;

      • MU:元数据空间使用大小;

      • CCSC:压缩类空间大小;

      • CCSU:压缩类空间使用大小;

      • OC:old区大小;

      • OU:old区使用大小;

      • YGC:young gc次数;

      • FGC:full gc次数;

      • FGCT:full gc消耗时间;

      • GCT:gc消耗时间。

    8. jstat -gcmetacapacity <vmid>


      jstat -gcmetacapacity输出
      • MCMN:元数据区最小容量;

      • MCMX:元数据区最大容量;

      • MC:元数据区大小;

      • CCSMN:压缩类空间最小容量;

      • CCSMX:压缩类空间最大容量;

      • CCSC:压缩类空间大小;

      • YGC:young gc次数;

      • FGC:full gc次数;

      • FGCT:full gc消耗时间;

      • GCT:gc消耗时间。

    1. jstat -printcompilation <vmid>


      jstat -printcompilation输出
      • Compiled:编译方法数量;

      • Size:编译方法的字节码数量;

      • Type:编译方法的编译类型;

      • Method:方法名称。

    针对young区和old区相关capacity命令在这里就不做详细分析了,有兴趣的小伙伴自行敲一敲命令运行下,至于输出的表格列含义在前几个命令详细介绍中基本上都包括在内了。

    注:在使用jstat命令输出的容量的单位是字节。

    三、jinfo

    用于实时查看和调整虚拟机参数。

    jinfo命令格式

    jinfo命令格式

    jinfo命令主要有以下参数:
    1. option:选项,jinfo主要提供以下选项:

      • -flag <name>
        输出指定JVM参数值;

      • -flag [+|-]<name>
        启用或禁用指定JVM参数;

      • -flag <name>=<value>
        设置指定JVM参数值;

      • -flags
        输出所有JVM参数

      • -sysprops
        输出Java系统属性;

      • <no option>
        不指定选项则输出所有的虚拟机参数和Java系统属性

    2. pid:需要查看或者调整虚拟机参数的进程id

    接下来我们来看看它的实际使用:


    jinfo使用结果
    四、jmap

    用于生成堆内存快照(heapdump或者dump文件)。当然,如果不想使用jmap命令,也可以使用JVM参数来生成:

    • -XX:+HeapDumpOnOutOfMemoryError,如果虚拟机在出现OutOfMemory异常后生成dump文件;

    • -XX:+HeapDumpOnCtrlBreak,使用ctrl + break键让虚拟机生成dump文件。

    当然,还有一种更暴力的方式就是在linux系统下,kill -3也可以让虚拟机生成dump文件。

    jmap命令格式

    jmap命令格式

    相比jstat命令,jmap命令明显就简单的多了,就两个参数:
    1. option:选项,jmap主要提供以下选项:

      • -dump
        生成Java堆内存快照,使用格式为:-dump:[live, ]format=b,file=<filename>,使用hprof二进制形式,输出jvm的heap内容到文件<filename>,live子参数是可选的,如果指定live选项,就只dump出存活的对象;

      • finalizerinfo
        显示在F-Queue中等待Finalizer线程执行finalize方法的对象;

      • -heap
        显示heap详细信息,比如使用哪种回收器、参数配置、分代状态等;

      • histo
        显示每个class的实例数目,内存占用,类全名信息。VM的内部类名字开头会加上前缀“*”.,如果带上live子参数,则只统计活的对象数量;

      • -permstat
        以ClassLoader为统计口径显示永久代内存状态,需要注意的是,JDK 8将该option替换成了-clstats

      • -F
        强制生成dump文件,当虚拟机进程对-dump选项没有响应时可以使用。

    2. pid:需要生成dump文件的进程id

    dump文件在这里我就不做演示了,给一个简单的使用吧:


    jmap -histo输出

    从输出的结果可以清晰的看出每一个class的实例数目以及内存占用情况。

    五、jstack

    用户生成虚拟机当前时刻的线程快照(threaddump/javacore文件)。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈集合,生成线程快照的目的也就是为了定位线程出现长时间卡顿的原因。

    jstack命令格式

    jstack命令格式

    跟jmap命令一样,jstack命令也只有两个参数:
    1. option:选项,jstack主要提供以下选项:

      • -F
        当线程出现长时间卡顿的时候,强制输出线程堆栈;

      • -l
        除堆栈外,显示关于锁的附加信息;

      • -m
        如果调用JNI方法,可以显示C/C++的堆栈。

    2. pid:需要生成threaddump的进程id。

    简单给一个使用吧还是:


    jstack -l输出

    从输出结果可以清晰的看到线程堆栈以及锁相关信息。具体的怎么根据threaddump分析定位问题最近暂时没有遇到,等遇到了再出文详细介绍啦~

    六、jhat

    与jmap命令搭配使用,分析jmap生成的dump文件。jhat内置一个微型的HTTP/HTML服务器,生成dump文件的分析结果后,可以在浏览器中进行查看。其实这个命令在实际生产中使用比较少,为什么不用的原因我总结下来大概有两点:第一呢,线上生产环境怎么可能允许你在线上机器直接分析dump文件啊~~~第二就是jhat的分析功能相比其他工具简直是太简陋了。

    它的使用也很简单啊,jhat <dump文件名称>,等分析完就打开浏览器访问相应的地址+端口就可以愉快的开始分析dump文件了。

    七、jconsole

    jconsole是一个用java写的GUI程序,用来监控VM,并可监控远程的VM,非常易用,而且功能非常强。使用方法:命令行里打 jconsole,选则进程就可以了。

    Console中关于内存分区的说明。
    Eden Space (heap): 内存最初从这个线程池分配给大部分对象。 
    Survivor Space (heap):用于保存在eden space内存池中经过垃圾回收后没有被回收的对象。 
    Tenured Generation (heap):用于保持已经在 survivor space内存池中存在了一段时间的对象。 
    Permanent Generation (non-heap): 保存虚拟机自己的静态(refective)数据,例如类(class)和方法(method)对象。Java虚拟机共享这些类数据。这个区域被分割为只读的和只写的, 
    Code Cache (non-heap):HotSpot Java虚拟机包括一个用于编译和保存本地代码(native code)的内存,叫做“代码缓存区”(code cache)

    展开全文
  • Java服务问题快速排查指南

    千次阅读 2018-08-27 17:21:07
    问题 收到服务内存占用过大告警,登录虚拟机使用ps -ef发现每隔几秒java进程占用的CPU就回暴增一次 排查方向一:服务日志 查看服务日志,正频繁打印连接mail服务器失败,根据错误堆栈信息定位到业务代码位置 ...
  • 文章目录前言背景问题追踪排查分析排查一:JN服务本身问题排查二:NN 服务问题排查三:JN机器硬件层面问题推论四:JN受所在机器其它服务的影响总结 前言 众所周知,在HDFS集群中,NameNode服务是其中的核心服务。...
  • airflow调度问题排查

    千次阅读 2020-02-17 10:34:39
    文章目录问题描述排查总结 问题描述 现在公司使用的airflow调度器很慢,每次clear一个task之后,这个task要过一段时间才会被调度器调度到,这个时间大约需要15-30s。 使用的airflow版本较老:v1.7.1.3 排查 参数...
  • mysql 问题排查

    千次阅读 2018-10-17 10:23:44
    1、当sql操作数据库的时候过慢需要sql执行的语句进行分析具体分析方向有两个方向 1.1、分析sql是否属于慢查询通过是数据库的关键在EXPLAIN进行分析sql语句的性能  (1、是否使用索引,2、是否查询的字段内容过...
  • jvm问题排查总结

    千次阅读 2018-07-26 18:57:46
    一: 问题背景与现象 1、健康检查失败 2、接口测试反应慢 3、系统多次CPU或内存使用率飙升,且是java进程引起 二: 解决问题思路 1.确定服务已部署成功且没有被回收,健康状态检查成功,打开终端控制面板,...
  • java在生产中出现问题怎么进行跟踪排查解决 https://blog.csdn.net/GitChat/article/details/79019454
  • IIS 503问题排查思路

    千次阅读 2018-09-22 12:12:09
    对于IIS报503的问题相信大家都很熟悉了,博客园以前也经常503,但这个问题不好排查,前几天我也为503问题烦恼,总结了一些排查思路和大家分享,但最终还没有解决问题,请大家有懂的也赶紧指点指点。
  • Java OOM问题如何排查

    千次阅读 2020-06-15 12:07:40
    文章目录OOM 问题什么是OOM导致OOM问题的原因排查手段实战MAT分析 OOM 问题 什么是OOM OOM为out of memory的简称,来源于java.lang.OutOfMemoryError,指程序需要的内存空间大于系统分配的内存空间,OOM后果就是程序...
  • JVM线上问题排查

    千次阅读 2017-08-24 14:22:41
    作为一个合格的开发人员,不仅要能写得一手还代码,还有一项很重要的技能就是排查问题。这里提到的排查问题不仅仅是在coding的过程中debug等,还包括的就是线上问题排查。由于在生产环境中,一般没办法debug(其实...
  • 线上问题排查实战

    千次阅读 2018-06-30 22:47:17
    我们团队组织了线上问题排查实战演练,都是经典题目,在此记录下来方面后续遇到问题使用题目一:某服务器的sshd的监听端口是22,如何统计这台服务器的sshd服务各种状态(TIME_WAIT/CLOSE_WAIT/ESTABLISHED)的连接数...
  • 线上java JVM问题排查

    千次阅读 多人点赞 2020-01-10 10:42:35
    下面是一个老系统,代码写的有点问题导致出现这样一个JVM占比过高的问题,正常情况下也就是CPU负载不高的时候21:00左右的,也有30万,但是再多一点30几万就是阈值,就会出现堆积。 这个队列一直是增长的快。 这...
  • 一次线上OOM问题排查

    千次阅读 2019-08-05 21:29:22
    二、问题排查 1、出现OOM问题了,脑袋里第一反应就是项目中出现内存泄露或者内存溢出了。先登录ELK,根据关键词 “java.lang.OutOfMemoryError” 进行搜索,果然发现有OOM错误日志。 org.springframework.scheduling...
  • JVM经典问题排查系列

    2020-03-21 18:00:26
    JVM进行简单的性能调优和问题排查是一名Java程序员必备的技能,也是Java工程师面试中经常考到的知识模块。 本系列中会针对一些常见的JVM问题排查进行总结,帮助大家进行初步入门。 在学习经典案例之前,我们首先要...
  • 由于EasyNVR的受众越来越多,时长会遇到很类似的问题咨询,之前虽然有写过很多的博文进行技术的或者使用问题的解答,随着客户询问的增多,我发现,要想然客户了解问题和解决问题,往往引导和给一个思路比直接给与...
  • CPU占用过高问题排查及解决

    千次阅读 2020-03-03 11:12:17
    CPU占用过高问题排查及解决 排查步骤 1.使用top 定位到占用CPU高的进程PID 然后按shift+p按照CPU排序 top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务...
  • 这篇文章以Metrics Server部署时碰到的问题为例,介绍如何结合使用kubectl get event命令进行问题排查
  • 这篇文章以一个多容器Pod启动问题排查为例,介绍一下多容器Pod排查时使用到的方法。
  • 服务器问题排查的思路

    千次阅读 2018-04-11 19:35:53
    不要一下子就扎到服务器前面,你需要先搞明白这台服务器有多少已知的情况,还有故障的具体情况。不然你很可能就是在无的放矢 必须搞清楚的问题有: 故障的表现是什么?无响应?报错? 故障是什么时候发现的? ...
  • JVM堆外内存问题排查

    万次阅读 2018-07-15 11:35:07
    JVM 堆内存一般分析的比较多,本篇谈谈堆外内存问题排查,通常我们需要排查堆外内存的原因是系统整个内存使用飙高,但是堆内内存使用正常。这时候就需要分析堆外内存了 堆外内存组成 通常JVM的参数我们会配置 -...
  • kafka问题排查之 Java代码不进行消费

    万次阅读 2018-12-14 15:51:52
    发现问题 使用 kafka 在linux系统,通过命令测试消费正常, 但在Java 代码无法正常接收队列消息 控制台提示信息: 15:21:33.804 [main] INFO org.apache.coyote....
  • PHPStorm+Xdebug进行emote Debug时无法进入断点问题排查

    万次阅读 热门讨论 2017-08-22 21:34:27
    最近一直在研究Xdebug的用法,主要是因为XdebugPHP的开发效率提升确实很大,而却能帮我们解决很多问题。所以这里就总结下我在配置PHPStorm+Xdebug环境中遇到的坑,给遇到进不去断点的朋友一些排查的建议。
  • JVM线程、内存问题排查

    千次阅读 2018-06-01 16:11:22
    一、高CUP排查排查思路1)找出占用高的进程 2)找出占用高的线程 3)找出具体的代码工具jstack + top 命令排查步骤 1、找出占用高的进程,执行“top -c”命令,显示进程运行信息列表,键入大写P,按CPU使用率降序...
  • 服务器问题 排查思路

    千次阅读 2018-11-11 16:34:33
    一.尽可能搞清楚问题的前因后果 ...最后一次整个平台进行更新的内容是什么(代码、服务器等) 二.当前有谁在,做过什么操作 1. w/who 2. last 3. history 三.现在运行的进程有什么 ...
  • 关于网站504问题排查

    万次阅读 2014-12-09 11:42:25
    公司每周会.net web网站进行更新,而我这边每天会该web网站进行定时压测,周二更新好后,周三的定时压测抛出大量的504错误,开始进行排查。如图: 公司的服务器环境使用阿里云,入口机器为一台linux,进行...
  • 由于EasyNVR的受众越来越多,时长会遇到很类似的问题咨询,之前虽然有写过很多的博文进行技术的或者使用问题的解答,随着客户询问的增多,我发现,要想然客户了解问题和解决问题,往往引导和给一个思路比直接给与...
  • 两起变量初始化问题排查过程

    千次阅读 2014-09-24 16:24:09
     本文基于作者的实际项目经验,近期遇到的两起变量初始化问题进行了详细的分析,为相关软件问题的分析及解决提供了有益的参考。【关键词】 C语言 变量 初始化 开发 一、问题1的排查过程 在某程序版本进行...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 120,359
精华内容 48,143
关键字:

对问题进行了排查