How to configure services within Systemd that can be restarted outside of Systemd?

本文探讨了在Red Hat Enterprise Linux 7中使用Systemd管理服务状态的方法。通过设置RemainAfterExit选项为yes,即使进程退出,服务仍被视为活动状态,确保了外部重启后服务状态的正确性。

https://access.redhat.com/solutions/2978271

 SOLUTION 已验证 - 已更新 2017年六月22日04:24 - 

English 

环境

  • Red Hat Enterprise Linux 7
    • Custom Systemd Unit files

问题

  • I have created a systemd script for our environment which starts and stops the processes fine with a server reboot. Daily we restart some of those processes with a separate script which causes systemd to think the service status is inactive. Is there a way to force systemd to run a stop of the service even if it thinks the current status is inactive (dead)?

  • Is there a way to make systemd understand the processes are still active (running) even after a separate script has restarted the processes?

决议

The option needed within the systemd unit file [Service] definitions is RemainAfterExit=yes.

From the description in the man pages:

Raw

       RemainAfterExit=
           Takes a boolean value that specifies whether the service
           shall be considered active even when all its processes
           exited. Defaults to no.

根源

With the action of allowing systemd to start the service, but then managing it externally to systemd, systemd assumes that the service has entered a dead state. By setting the above, the end result should be that systemd will still consider the service active regardless of the actions taken in the interim.

Note: This does not avoid the issues documented in the article below. Though the shutdown scripts will be executed during system shutdown using the resolution documented, it will not isolate processes that have been externally restarted from being shutdown in the indicated manner.

When restarting a service outside of systemd, why are the processes killed in a non-graceful manner during a subsequent system shutdown and reboot?

Please see the following example:

/root/test

Raw

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>

    #include <unistd.h>

    int main() {
        int parent;
        int fd;
        int retval;
        char buffer[8];

        printf("Parent = %d\n", getpid());

        parent = fork();
        if (parent > 0) {
                printf("Forked %d\n", parent);
                retval = snprintf(buffer, sizeof(buffer), "%d\n", parent);
                fd = open("/tmp/test.pid", O_CREAT|O_CLOEXEC|O_RDWR);

                retval = write(fd, buffer, sizeof(buffer));

                close(fd);
        } else {
                while (1) {
                        sleep(1);
                }
        }
        return 0;
    }

/root/testkill.sh

Raw

    #!/bin/bash

    PID=$(cat /tmp/test.pid)

    echo "Killing $PID" >> /tmp/test.log
    kill $PID

/etc/systemd/system/test.service

Raw

    [Unit]
    Description=Testing the remainafterexit option

    [Service]
    Type=forking
    PIDFile=/tmp/test.pid
    ExecStartPre=/bin/bash -c "echo Started $MAINPID"
    ExecStart=/root/test
    ExecStop=/bin/bash /root/testkill.sh
    ExecStopPost=/bin/bash -c "echo Stopped $MAINPID"
    KillMode=none

Testing the above:

Raw

    # systemctl start test

    # systemctl status test
    ● test.service - Testing the remainafterexit option
       Loaded: loaded (/etc/systemd/system/test.service; static; vendor preset: disabled)
       Active: active (running) since Wed 2016-12-07 12:33:20 EST; 12s ago
      Process: 5673 ExecStart=/root/test (code=exited, status=0/SUCCESS)
      Process: 5672 ExecStartPre=/bin/bash -c echo Started $MAINPID (code=exited, status=0/SUCCESS)
     Main PID: 5676 (test)
       CGroup: /system.slice/test.service
           └─5676 /root/test

    Dec 07 12:33:20 example.hostname.com systemd[1]: Starting Testing the remainafterexit option...
    Dec 07 12:33:20 example.hostname.com bash[5672]: Started
    Dec 07 12:33:20 example.hostname.com test[5673]: Parent = 5673
    Dec 07 12:33:20 example.hostname.com test[5673]: Forked 5676
    Dec 07 12:33:20 example.hostname.com systemd[1]: Started Testing the remainafterexit option.

Without the RemainAfterExit option:

Raw

    # bash /root/testkill.sh 

    # systemctl status test
    ● test.service - Testing the remainafterexit option
       Loaded: loaded (/etc/systemd/system/test.service; static; vendor preset: disabled)
       Active: failed (Result: exit-code) since Wed 2016-12-07 12:34:18 EST; 2s ago
      Process: 5685 ExecStopPost=/bin/bash -c echo Stopped $MAINPID (code=exited, status=0/SUCCESS)
      Process: 5682 ExecStop=/bin/bash /root/testkill.sh (code=exited, status=1/FAILURE)
      Process: 5673 ExecStart=/root/test (code=exited, status=0/SUCCESS)
      Process: 5672 ExecStartPre=/bin/bash -c echo Started $MAINPID (code=exited, status=0/SUCCESS)
     Main PID: 5676 (code=killed, signal=TERM)

    Dec 07 12:33:20 example.hostname.com systemd[1]: Starting Testing the remainafterexit option...
    Dec 07 12:33:20 example.hostname.com bash[5672]: Started
    Dec 07 12:33:20 example.hostname.com test[5673]: Parent = 5673
    Dec 07 12:33:20 example.hostname.com test[5673]: Forked 5676
    Dec 07 12:33:20 example.hostname.com systemd[1]: Started Testing the remainafterexit option.
    Dec 07 12:34:18 example.hostname.com bash[5682]: /root/testkill.sh: line 6: kill: (5676) - No such process
    Dec 07 12:34:18 example.hostname.com systemd[1]: test.service: control process exited, code=exited status=1
    Dec 07 12:34:18 example.hostname.com bash[5685]: Stopped
    Dec 07 12:34:18 example.hostname.com systemd[1]: Unit test.service entered failed state.
    Dec 07 12:34:18 example.hostname.com systemd[1]: test.service failed.

With the RemainAfterExit option:

Raw

    # systemctl start test
    # bash /root/testkill.sh 
    # systemctl status test
    ● test.service - Testing the remainafterexit option
       Loaded: loaded (/etc/systemd/system/test.service; static; vendor preset: disabled)
       Active: active (exited) since Wed 2016-12-07 12:35:07 EST; 8s ago
      Process: 5732 ExecStart=/root/test (code=exited, status=0/SUCCESS)
      Process: 5730 ExecStartPre=/bin/bash -c echo Started $MAINPID (code=exited, status=0/SUCCESS)
     Main PID: 5735 (code=killed, signal=TERM)

    Dec 07 12:35:07 example.hostname.com systemd[1]: Starting Testing the remainafterexit option...
    Dec 07 12:35:07 example.hostname.com bash[5730]: Started
    Dec 07 12:35:07 example.hostname.com test[5732]: Parent = 5732
    Dec 07 12:35:07 example.hostname.com test[5732]: Forked 5735
    Dec 07 12:35:07 example.hostname.com systemd[1]: Started Testing the remainafterexit option.

From there, stopping the service will still fire:

Raw

    # /root/test 
    Parent = 5740
    Forked 5741
    # systemctl stop test

    # systemctl status test
    ● test.service - Testing the remainafterexit option
       Loaded: loaded (/etc/systemd/system/test.service; static; vendor preset: disabled)
       Active: inactive (dead)

    Dec 07 12:34:18 example.hostname.com systemd[1]: Unit test.service entered failed state.
    Dec 07 12:34:18 example.hostname.com systemd[1]: test.service failed.
    Dec 07 12:35:07 example.hostname.com systemd[1]: Starting Testing the remainafterexit option...
    Dec 07 12:35:07 example.hostname.com bash[5730]: Started
    Dec 07 12:35:07 example.hostname.com test[5732]: Parent = 5732
    Dec 07 12:35:07 example.hostname.com test[5732]: Forked 5735
    Dec 07 12:35:07 example.hostname.com systemd[1]: Started Testing the remainafterexit option.
    Dec 07 12:36:19 example.hostname.com systemd[1]: Stopping Testing the remainafterexit option...
    Dec 07 12:36:19 example.hostname.com bash[5749]: Stopped
    Dec 07 12:36:19 example.hostname.com systemd[1]: Stopped Testing the remainafterexit option.
Setting up libwayland-server0:amd64 (1.22.0-2.1build1) ... Setting up libx11-xcb1:amd64 (2:1.8.7-1build1) ... Setting up libpciaccess0:amd64 (0.17-3build1) ... Setting up session-migration (0.3.9build1) ... Created symlink /etc/systemd/user/graphical-session-pre.target.wants/session-migration.service → /usr/lib/systemd/user/session-migration.service. Setting up fontconfig (2.15.0-1.1ubuntu2) ... Regenerating fonts cache... done. Setting up libraw1394-11:amd64 (2.1.2-2build3) ... Setting up libgck-2-2:amd64 (4.2.0-5) ... Setting up libproxy1v5:amd64 (0.5.4-4build1) ... Setting up libdrm-nouveau2:amd64 (2.4.122-1~ubuntu0.24.04.1) ... Setting up libtag1v5-vanilla:amd64 (1.13.1-1build1) ... Setting up libxdamage1:amd64 (1:1.1.6-1build1) ... Setting up libxcb-xfixes0:amd64 (1.15-1ubuntu2) ... Setting up libogg0:amd64 (1.3.5-3build1) ... Setting up desktop-file-utils (0.27-2build1) ... Setting up libspeex1:amd64 (1.2.1-2ubuntu2.24.04.1) ... Setting up libcaca0:amd64 (0.99.beta20-4build2) ... Setting up libv4lconvert0t64:amd64 (1.26.1-4build3) ... Setting up libgcr-4-4:amd64 (4.2.0-5) ... Setting up hicolor-icon-theme (0.17-2) ... Setting up libxi6:amd64 (2:1.8.1-1build1) ... Setting up libtwolame0:amd64 (0.4.0-2build3) ... Setting up libwoff1:amd64 (1.0.2-2build1) ... Setting up libxrender1:amd64 (1:0.9.10-1.1build1) ... Setting up libvte-2.91-common (0.76.0-1ubuntu0.1) ... Setting up libhyphen0:amd64 (2.8.8-7build3) ... Setting up libdatrie1:amd64 (0.2.13-3build1) ... Setting up libvisual-0.4-0:amd64 (0.4.2-2build1) ... Setting up libxcb-render0:amd64 (1.15-1ubuntu2) ... Setting up libaspell15:amd64 (0.60.8.1-1build1) ... Setting up libdrm-radeon1:amd64 (2.4.122-1~ubuntu0.24.04.1) ... Setting up libglvnd0:amd64 (1.7.0-1build1) ... Setting up libxcb-glx0:amd64 (1.15-1ubuntu2) ... Setting up libwebpdemux2:amd64 (1.3.2-0.4build3) ... Setting up libmanette-0.2-0:amd64 (0.2.7-1build2) ... Setting up libdrm-intel1:amd64 (2.4.122-1~ubuntu0.24.04.1) ... Setting up libgdk-pixbuf2.0-common (2.42.10+dfsg-3ubuntu3.1) ... Setting up x11-common (1:7.7+23ubuntu3) ... Setting up libwebrtc-audio-processing1:amd64 (0.3.1-0ubuntu6) ... Setting up libxcb-shm0:amd64 (1.15-1ubuntu2) ... Setting up libsoup-3.0-common (3.4.4-5ubuntu0.3) ... Setting up libmpg123-0t64:amd64 (1.32.5-1ubuntu1.1) ... Setting up libcairo2:amd64 (1.18.0-3build1) ... Setting up libcolord2:amd64 (1.4.7-1build2) ... Setting up gnome-terminal-data (3.52.0-1ubuntu2) ... Setting up libxxf86vm1:amd64 (1:1.1.4-1build4) ... Setting up liborc-0.4-0t64:amd64 (1:0.4.38-1ubuntu0.1) ... Setting up libxcb-present0:amd64 (1.15-1ubuntu2) ... Setting up libdconf1:amd64 (0.40.0-4build2) ... Setting up libasound2-data (1.2.11-1build2) ... Setting up libgles2:amd64 (1.7.0-1build1) ... Setting up libasound2t64:amd64 (1.2.11-1build2) ... Setting up emacsen-common (3.0.5) ... Setting up libepoxy0:amd64 (1.5.10-1build1) ... Setting up libspa-0.2-modules:amd64 (1.0.5-1ubuntu3) ... Setting up libxfixes3:amd64 (1:6.0.0-2build1) ... Setting up libxcb-sync1:amd64 (1.15-1ubuntu2) ... Setting up libavahi-common-data:amd64 (0.8-13ubuntu6) ... Setting up libatspi2.0-0t64:amd64 (2.52.0-1build1) ... Setting up libopus0:amd64 (1.4-1build1) ... Setting up libxinerama1:amd64 (2:1.1.4-3build1) ... Setting up libxv1:amd64 (2:1.0.11-1.1build1) ... Setting up libatomic1:amd64 (14.2.0-4ubuntu2~24.04) ... Setting up libvorbis0a:amd64 (1.3.7-1build3) ... Setting up libxrandr2:amd64 (2:1.5.2-2build1) ... Setting up libnautilus-extension4:amd64 (1:46.2-0ubuntu0.3) ... Setting up libdv4t64:amd64 (1.0.0-17.1build1) ... Setting up libglapi-mesa:amd64 (24.2.8-1ubuntu1~24.04.1) ... Setting up libvulkan1:amd64 (1.3.275.0-1build1) ... Setting up libv4l-0t64:amd64 (1.26.1-4build3) ... Setting up libxcb-dri2-0:amd64 (1.15-1ubuntu2) ... Setting up xdg-dbus-proxy (0.1.5-1build2) ... Setting up libvpx9:amd64 (1.14.0-1ubuntu2.1) ... Setting up alsa-topology-conf (1.2.5.1-2) ... Setting up libtag1v5:amd64 (1.13.1-1build1) ... Setting up libasyncns0:amd64 (0.8-6build4) ... Setting up libxshmfence1:amd64 (1.3-1build5) ... Setting up at-spi2-common (2.52.0-1build1) ... Setting up libwavpack1:amd64 (5.6.0-1build1) ... Setting up libxcb-randr0:amd64 (1.15-1ubuntu2) ... Setting up libtheora0:amd64 (1.1.1+dfsg.1-16.1build3) ... Setting up libharfbuzz0b:amd64 (8.3.0-2build2) ... Setting up libthai-data (0.1.29-2build1) ... Setting up libgdk-pixbuf-2.0-0:amd64 (2.42.10+dfsg-3ubuntu3.1) ... Setting up sgml-data (2.0.11+nmu1) ... Setting up libcairo-gobject2:amd64 (1.18.0-3build1) ... Setting up libflac12t64:amd64 (1.4.3+ds-2.1ubuntu2) ... Setting up libwayland-egl1:amd64 (1.22.0-2.1build1) ... Setting up libhunspell-1.7-0:amd64 (1.7.2+really1.7.2-10build3) ... Setting up glib-networking-common (2.80.0-1build1) ... Setting up libwebpmux3:amd64 (1.3.2-0.4build3) ... Setting up gvfs-common (1.54.0-1ubuntu2) ... Setting up libxcomposite1:amd64 (1:0.4.5-1build3) ... Setting up libpipewire-0.3-0t64:amd64 (1.0.5-1ubuntu3) ... Setting up libsecret-common (0.21.4-1build3) ... Setting up yelp-xsl (42.1-2ubuntu0.24.04.1) ... Setting up libmp3lame0:amd64 (3.100-6build1) ... Setting up libgraphene-1.0-0:amd64 (1.10.8-3build2) ... Setting up libvorbisenc2:amd64 (1.3.7-1build3) ... Setting up libaa1:amd64 (1.4p5-51.1) ... Setting up libiec61883-0:amd64 (1.2.0-6build1) ... Setting up libdrm-amdgpu1:amd64 (2.4.122-1~ubuntu0.24.04.1) ... Setting up libwayland-client0:amd64 (1.22.0-2.1build1) ... Setting up libavc1394-0:amd64 (0.5.4-5build3) ... Setting up libgl1-amber-dri:amd64 (21.3.9-0ubuntu2) ... Setting up mesa-vulkan-drivers:amd64 (24.2.8-1ubuntu1~24.04.1) ... Setting up glib-networking-services (2.80.0-1build1) ... Setting up gtk-update-icon-cache (3.24.41-4ubuntu1.3) ... Setting up mesa-libgallium:amd64 (24.2.8-1ubuntu1~24.04.1) ... Setting up libharfbuzz-icu0:amd64 (8.3.0-2build2) ... Setting up xdg-desktop-portal (1.18.4-1ubuntu2.24.04.1) ... Created symlink /etc/systemd/user/graphical-session-pre.target.wants/xdg-desktop-portal-rewrite-launchers.service → /usr/lib/systemd/user/xdg-desktop-portal-rewrite-launchers.service. Setting up libatk1.0-0t64:amd64 (2.52.0-1build1) ... Setting up libgbm1:amd64 (24.2.8-1ubuntu1~24.04.1) ... Setting up dictionaries-common (1.29.7) ... Setting up alsa-ucm-conf (1.2.10-1ubuntu5.4) ... Setting up libxtst6:amd64 (2:1.2.3-1.1build1) ... Setting up libxcursor1:amd64 (1:1.2.1-1build1) ... Setting up libgl1-mesa-dri:amd64 (24.2.8-1ubuntu1~24.04.1) ... Setting up libavahi-common3:amd64 (0.8-13ubuntu6) ... Setting up libgstreamer-plugins-base1.0-0:amd64 (1.24.2-1ubuntu0.2) ... Setting up dconf-service (0.40.0-4build2) ... Setting up libthai0:amd64 (0.1.29-2build1) ... Setting up libsecret-1-0:amd64 (0.21.4-1build3) ... Setting up libgstreamer-plugins-good1.0-0:amd64 (1.24.2-1ubuntu1.1) ... Setting up libegl-mesa0:amd64 (24.2.8-1ubuntu1~24.04.1) ... Setting up libjavascriptcoregtk-4.1-0:amd64 (2.48.1-0ubuntu0.24.04.1) ... Setting up gstreamer1.0-plugins-base:amd64 (1.24.2-1ubuntu0.2) ... Setting up libshout3:amd64 (2.4.6-1build2) ... Setting up aspell (0.60.8.1-1build1) ... Setting up libgdk-pixbuf2.0-bin (2.42.10+dfsg-3ubuntu3.1) ... Setting up libwayland-cursor0:amd64 (1.22.0-2.1build1) ... Setting up libegl1:amd64 (1.7.0-1build1) ... Setting up hunspell-en-us (1:2020.12.07-2) ... Setting up libsndfile1:amd64 (1.2.2-1ubuntu5.24.04.1) ... Setting up libavahi-client3:amd64 (0.8-13ubuntu6) ... Setting up libatk-bridge2.0-0t64:amd64 (2.52.0-1build1) ... Setting up libglx-mesa0:amd64 (24.2.8-1ubuntu1~24.04.1) ... Setting up libglx0:amd64 (1.7.0-1build1) ... Setting up dconf-gsettings-backend:amd64 (0.40.0-4build2) ... Setting up libpulse0:amd64 (1:16.1+dfsg1-2ubuntu10.1) ... Setting up libenchant-2-2:amd64 (2.3.3-2build2) ... Setting up libpango-1.0-0:amd64 (1.52.1+ds-1build1) ... Setting up aspell-en (2020.12.07-0-1) ... Setting up enchant-2 (2.3.3-2build2) ... Setting up libgl1:amd64 (1.7.0-1build1) ... Setting up libpangoft2-1.0-0:amd64 (1.52.1+ds-1build1) ... Setting up libcups2t64:amd64 (2.4.7-1.2ubuntu7.3) ... Setting up libgtk-3-common (3.24.41-4ubuntu1.3) ... Setting up libpangocairo-1.0-0:amd64 (1.52.1+ds-1build1) ... Setting up gsettings-desktop-schemas (46.1-0ubuntu1) ... Setting up gstreamer1.0-x:amd64 (1.24.2-1ubuntu0.2) ... Setting up librsvg2-2:amd64 (2.58.0+dfsg-1build1) ... Setting up libgstreamer-gl1.0-0:amd64 (1.24.2-1ubuntu0.2) ... Setting up librsvg2-common:amd64 (2.58.0+dfsg-1build1) ... Setting up gstreamer1.0-gl:amd64 (1.24.2-1ubuntu0.2) ... Setting up adwaita-icon-theme (46.0-1) ... update-alternatives: using /usr/share/icons/Adwaita/cursor.theme to provide /usr/share/icons/default/index.theme (x-cursor-theme) in auto mode Setting up humanity-icon-theme (0.6.16) ... Setting up ubuntu-mono (24.04-0ubuntu1) ... Processing triggers for man-db (2.12.0-4build2) ... Processing triggers for libglib2.0-0t64:amd64 (2.80.0-6ubuntu3.4) ... Setting up libgtk-3-0t64:amd64 (3.24.41-4ubuntu1.3) ... Setting up gvfs-libs:amd64 (1.54.0-1ubuntu2) ... Setting up at-spi2-core (2.52.0-1build1) ... Processing triggers for sgml-base (1.31) ... Setting up glib-networking:amd64 (2.80.0-1build1) ... Setting up libhandy-1-0:amd64 (1.8.3-1build2) ... Setting up xdg-desktop-portal-gtk (1.15.1-1build2) ... Setting up docbook-xml (4.5-12) ... Processing triggers for libc-bin (2.39-0ubuntu8.4) ... Setting up libsoup-3.0-0:amd64 (3.4.4-5ubuntu0.3) ... Setting up libgtk-3-bin (3.24.41-4ubuntu1.3) ... Setting up libvte-2.91-0:amd64 (0.76.0-1ubuntu0.1) ... Setting up gvfs-daemons (1.54.0-1ubuntu2) ... Setting up gnome-terminal (3.52.0-1ubuntu2) ... update-alternatives: using /usr/bin/gnome-terminal.wrapper to provide /usr/bin/x-terminal-emulator (x-terminal-emulator) in auto mode Setting up gvfs:amd64 (1.54.0-1ubuntu2) ... Setting up gstreamer1.0-plugins-good:amd64 (1.24.2-1ubuntu1.1) ... Setting up nautilus-extension-gnome-terminal:amd64 (3.52.0-1ubuntu2) ... Setting up libwebkit2gtk-4.1-0:amd64 (2.48.1-0ubuntu0.24.04.1) ... Setting up libyelp0:amd64 (42.2-1ubuntu0.24.04.1) ... Setting up yelp (42.2-1ubuntu0.24.04.1) ... Processing triggers for dictionaries-common (1.29.7) ... aspell-autobuildhash: processing: en [en-common]. aspell-autobuildhash: processing: en [en-variant_0]. aspell-autobuildhash: processing: en [en-variant_1]. aspell-autobuildhash: processing: en [en-variant_2]. aspell-autobuildhash: processing: en [en-w_accents-only]. aspell-autobuildhash: processing: en [en-wo_accents-only]. aspell-autobuildhash: processing: en [en_AU-variant_0]. aspell-autobuildhash: processing: en [en_AU-variant_1]. aspell-autobuildhash: processing: en [en_AU-w_accents-only]. aspell-autobuildhash: processing: en [en_AU-wo_accents-only]. aspell-autobuildhash: processing: en [en_CA-variant_0]. aspell-autobuildhash: processing: en [en_CA-variant_1]. aspell-autobuildhash: processing: en [en_CA-w_accents-only]. aspell-autobuildhash: processing: en [en_CA-wo_accents-only]. aspell-autobuildhash: processing: en [en_GB-ise-w_accents-only]. aspell-autobuildhash: processing: en [en_GB-ise-wo_accents-only]. aspell-autobuildhash: processing: en [en_GB-ize-w_accents-only]. aspell-autobuildhash: processing: en [en_GB-ize-wo_accents-only]. aspell-autobuildhash: processing: en [en_GB-variant_0]. aspell-autobuildhash: processing: en [en_GB-variant_1]. aspell-autobuildhash: processing: en [en_US-w_accents-only]. aspell-autobuildhash: processing: en [en_US-wo_accents-only]. Processing triggers for libgdk-pixbuf-2.0-0:amd64 (2.42.10+dfsg-3ubuntu3.1) ... Processing triggers for sgml-base (1.31) ... Processing triggers for libc-bin (2.39-0ubuntu8.4) ... Scanning processes... Scanning linux images... Running kernel seems to be up-to-date. No services need to be restarted. No containers need to be restarted. No user sessions are running outdated binaries. No VM guests are running outdated hypervisor (qemu) binaries on this host. # Failed to parse arguments: Cannot open display: root@srv771# 使用虚拟控制台(按Ctrl+Alt+F1-F6进入tty终端)y终端) # 返回图形界面按Ctrl+Alt+F7 root@srv771551:~# ^C root@srv771551:~# ^C root@srv771551:~#
05-29
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值