良许Linux教程网 Linux教程 Linux内核调优

Linux内核调优

一、内核文件系统

操作系统运行起来后,我们还有很多工作需要跟内核交互,那么如何实现用户和Linux内核的交互呢,这就用到了内核参数,Linux提供了/proc这样一个虚拟文件系统,通过它来完成linux内核空间和用户间之间进行通信,在/proc文件系统中,我们可以将对虚拟文件的读写作为与内核中实体进行通信的一种手段,但是与普通文件不同的是,这些虚拟文件的内容都是动态创建的。并且,这些文件虽然使用查看命令查看时会返回大量信息,但文件本身的大小却显示为0字节,因为这些都是驻留在内存中的文件。

为了查看及使用上的方便,这些文件通常会按照相关性进行分类存储于不同的目录甚至子目录中,例如:

/proc/sys/net是跟网络相关的内核参数
/proc/sys/kernel是跟内核相关的内核参数
/proc/sys/vm是跟内存相关的内核参数
/proc/sys/fs是跟文件系统相关的内核参数

此外,/sys下主要存放硬件设备的驱动程序信息,可以通过/sys/block优化磁盘I/O。

下面将分类介绍下linux服务器中常见的内核参数优化策略和技巧。

二、如何优化内核参数

要观察当前内核参数的配置,例如要查看/proc/sys/目录中某个内核参数文件,可以使用cat命令查看内容。这里我们要开启linux代理转发功能,可以直接修改内核参数ip_forward对应在/proc下的文件/proc/sys/net/ipv4/ip_forward。用下面命令查看ip_forward文件内容:

[root@liangxu ~]

该虚拟文件默认值0是禁止ip转发,修改为1即开启ip转发功能。修改命令如下:

[root@liangxu ~]

修改后马上生效,即内核已经打开ip转发功能。

从上面的操作中可以看到,使用echo和cat可以很方便修改内核参数,几乎在所有带/proc文件系统的操作系统上都可以使用,但是有两个明显的问题。
echo命令不能检查参数的一致性。

在重启系统之后,所有的内核修改都会丢失。

为了解决上面的问题,运维人员应该使用sysctl来修改内核参数。sysctl使用/proc/sys目录树中的文件名作为参数。例如,msgmnb内核参数保存在/proc/sys/kernel/msgmnb中,我们可以使用cat来读取、echo来修改:

[root@liangxul]16384[root@liangxu]
[root@liangxu]32768

然而,使用echo很容易出错,所以我们推荐使用sysctl命令,因为它会修改前检查数据一致性,例如:

[root@liangxu]
kernel.msgmnb = 32768[root@liangxu]
kernel.msgmnb = 40960[root@liangxu]
kernel.msgmnb = 40960

可以看出,sysctl后面跟上内核参数,就可以查看该内核参数的当前值,要修改此内核参数,执行“sysctl -w”后面跟上内核参数以及新的赋值即可完成,看似完美了,但是还有问题,那就是上面这些sysctl操作,让系统重启后,就丢失了,那么,如果想做永久修改,就应该编辑/etc/sysctl.conf文件,在此文件中添加如下内容:

sysctl kernel.msgmnb = 40960

这样,下次重启系统的时候系统会自动读取/etc/sysctl.conf文件,当然,也可以通过如下的命令,不用重启系统就让配置立刻生效:

[root@liangxu]

三、网络内核参数的优化

网络内核参数优化在Linux作为web服务器时,是必须要优化的一个环节,linux上关于网络内核参数有非常多,合理的内核参数设置,可以最大限度的发挥web服务器的网络连接性能,下面我们总结了一些web服务器中最常见的内核参数,这些参数的含义以及优化规则都会做一个深入详细的介绍。

1、/proc/sys/net/ipv4/tcp_syn_retries
此参数表示对于一个新建连接,内核要发送多少个SYN连接请求才决定放弃,此值不应该大于255,默认值是5,建议设置为2。
设置方法:

echo 2 > /proc/sys/net/ipv4/tcp_syn_retries

2、/proc/sys/net/ipv4/tcp_keepalive_time
此参数表示当keepalive启用的时候,TCP发送keepalive消息的频度。缺省是7200秒,建议修改为300秒。
普通web服务器建议设置为:

echo 300 >/proc/sys/net/ipv4/tcp_keepalive_time

3、/proc/sys/net/ipv4/tcp_orphan_retries

此参数表示孤儿socket废弃前重试的次数,重负载web服务器建议调小。
普通web服务器建议设置为“echo 1 >/proc/sys/net/ipv4/tcp_orphan_retries”

4、/proc/sys/net/ipv4/tcp_syncookies
此参数表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻 击,默认为0,表示关闭,普通web服务器建议设置为“echo 1 >/proc/sys/net/ipv4/ tcp_syncookies”。

这里提到了SYN攻 击,它是当前最流行的DoS(拒绝服务)与DDoS(分布式拒绝服务)的方式之一,这是一种利用TCP协议缺陷,发送大量伪造的TCP连接请求,常用假冒的IP或IP号段发来海量的请求连接第一个握手包(SYN包),被攻 击服务器回应第二个握手包(SYN+ACK包),因为对方是假冒IP,对方永远收不到包且不会回应第三个握手包。导致被攻 击服务器保持大量SYN_RECV状态的“半连接”,并且会重试默认5次回应第二个握手包,直到塞满TCP等待连接队列,资源耗尽(CPU满负荷或内存不足),让正常的业务请求连接不进来。

针对SYN攻 击,可以通过启用SYN Cookie、设置SYN队列最大长度以及设置SYN+ACK最大重试次数。设置tcp_syncookies为1就是启用了SYN Cookie。

SYN Cookie的作用是缓解服务器资源压力。启用之前,服务器在接到SYN数据包后,会立即分配存储空间,并随机化一个数字作为SYN号发送SYN+ACK数据包。然后保存连接的状态信息等待客户端确认。而在启用SYN Cookie之后,服务器不再马上分配存储空间,而且通过基于时间种子的随机数算法设置一个SYN号,替代完全随机的SYN号。发送完SYN+ACK确认报文之后,清空资源不保存任何状态信息。直到服务器接到客户端的最终ACK包。同时,通过Cookie检验算法鉴定是否与发出去的SYN+ACK报文序列号匹配,匹配则通过完成握手,失败则丢弃。

设置SYN队列最大长度以及设置SYN+ACK最大重试次数两个参数,下面马上介绍。

5、/proc/sys/net/ipv4/tcp_max_syn_backlog
此参数表示设置SYN队列最大长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。普通web服务器建议设置为:
“echo 8192 >/proc/sys/net/ipv4/tcp_max_syn_backlog”

tcp_max_syn_backlog是使用服务器的内存资源,换取更大的等待队列长度,让攻 击数据包不至于占满所有连接而导致正常用户无法完成握手。所以会消耗系统部分内存资源。

6、/proc/sys/net/ipv4/tcp_synack_retries
net.ipv4.tcp_synack_retries用来降低服务器SYN+ACK报文重试次数(默认是5次),尽快释放等待资源。

对于远端的连接请求SYN,内核会发送SYN+ACK数据报文,以确认收到上一个 SYN连接请求包。这是所谓的三次握手( threeway handshake)机制的第二个步骤。此参数是决定内核在放弃连接之前所送出的SYN+ACK的数目。

上面这三个参数与SYN攻 击的危害一一对应,完完全全是对症下药。但这些措施也是双刃剑,设置过大可能消耗服务器更多的内存资源,甚至影响正常用户建立TCP连接,因此,需要评估服务器硬件资源和攻 击力度谨慎设置。

7、/proc/sys/net/ipv4/ tcp_tw_recycle

此参数表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭,普通web服务器建议设置为 “echo 1 >/proc/sys/net/ipv4/ tcp_tw_recycle”

这里重点介绍一下TIME-WAIT,这个TIME_WAIT是指在TCP四次挥手过程中,首先调用关闭连接发起的一方,在发送最后一个ACK之后就会进入TIME_WAIT的状态,过多的TIME_WAIT连接,有什么坏处呢,我们来解释一下:

在高并发短连接的TCP服务器上,当服务器处理完请求后,会立刻主动正常关闭连接,此时就会出现大量socket处于TIME_WAIT状态,如果客户端的并发量持续增高,此时部分客户端就会显示连接不上服务器,为什么呢,因为服务器端资源用完了。这里的资源主要指服务器临时连接端口。

服务器可用的端口有个0~65535这么多,其实这真的很少,再刨除系统和其他服务要用的,剩下的就更少了。而高并发短连接场景可以让服务器在短时间范围内同时占用大量端口。

比如访问一个web页面,一秒钟的http短连接处理完成后,在关闭连接之后,这个业务用过的端口会停留在TIME_WAIT状态几分钟,而这几分钟,其它HTTP请求过来的时候是无法占用此端口的(典型的占着茅坑不。。。)。如果此时监控服务器的利用率会发现,服务器干正经事的时间和端口(资源)被挂着无法被使用的时间比例是1比几百,这就导致服务器资源严重浪费。

所以对于web服务器进行优化时,要特别注意这个TCP状态TIME_WAIT,要查看系统的TIME_WAIT状态,可以使用如下命令组合:

netstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn 
netstat -n |awk '/^tcp/ {print $NF}'|sort|uniq -c|sort -rn
netstat -n | awk '/^tcp/ {++S[$NF]};END {for(a in S) print a, S[a]}'
netstat -n | awk '/^tcp/ {++state[$NF]}; END {for(key in state) print key,"\t",state[key]}'netstat -n | awk '/^tcp/ {++arr[$NF]};END {for(k in arr) print k,"\t",arr[k]}'
netstat -ant | awk '{print $NF}' | grep -v '[a-z]' | sort | uniq -c

通过开启TIME-WAIT sockets的快速回收,可以在很大程度上减轻web服务器的负担,所以web服务器中关于TIME-WAIT的优化时必须要做的。

8、/proc/sys/net/ipv4/tcp_tw_reuse

此参数表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,因为重用连接,比重新建立新连接要便宜得多。此值默认为0,表示关闭;启用该resuse的同时,必须同时启用快速回收recycle(即tcp_tw_recycle为1)!

普通web服务器建议设置为“echo 1 >/proc/sys/net/ipv4/ tcp_tw_reuse”。

9、/proc/sys/net/ipv4/tcp_fin_timeout

此参数表示处于TIME_WAIT状态的连接在回收前必须等待的最小时间。改小它可以加快回收。普通web服务器建议设置为“echo 15 >/proc/sys/net/ipv4/tcp_fin_timeout”。
此参数以及上面两个参数是对TIME-WAIT优化最常用的配置组合。

10、/proc/sys/net/ipv4/tcp_keepalive_probes
此参数用来减少超时前的探测次数,普通web服务器建议设置为“echo 5>/proc/sys/net/ipv4/ tcp_keepalive_probes”

11、/proc/sys/net/core/netdev_max_backlog
此参数用来设每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。默认为1000。修改此参数可以优化网络设备接收队列,建议设置为:“echo 3000> /proc/sys/net/ipv4/ netdev_max_backlog”

12、/proc/sys/net/core/rmem_max、wmem_max

此两个参数可以提高TCP的最大缓冲区大小,其中:
rmem_max:表示接收套接字缓冲区大小的最大值(以字节为单位)。
wmem_max:表示发送套接字缓冲区大小的最大值(以字节为单位)。

作为网络参数的基础优化,建议设置为:

echo 16777216>/proc/sys/net/core/rmem_maxecho 16777216>/proc/sys/net/core/wmem_max

13、/proc/sys/net/ipv4/tcp_rmem、tcp_wmem

此两个参数可以提高Linux内核自动对socket缓冲区进行优化的能力,其中:
tcp_rmem:用来配置读缓冲的大小,第1个值为最小值,第2个值为默认值,第3个值为最大值。
tcp_wmem:用来配置写缓冲的大小,第1个值为最小值,第2个值为默认值,第3个值为最大值。

作为网络参数的基础优化,建议设置为:

echo "4096 87380 16777216">/proc/sys/net/ipv4/tcp_rmem
echo "4096 65536 16777216">/proc/sys/net/ipv4/tcp_rmem

14、/proc/sys/net/core/somaxconn

此参数用来设置socket监听(listen)的backlog上限。什么是backlog呢?backlog就是socket的监听队列,当一个请求(request)尚未被处理或建立时,他会进入backlog。而socket server可以一次性处理backlog中的所有请求,处理后的请求不再位于监听队列中。当server处理请求较慢,以至于监听队列被填满后,新来的请求会被拒绝。默认为128。作为网络参数的基础优化,建议设置为:

echo 4096 >/proc/sys/net/core/somaxconn

四、系统kernel参数优化

1、/proc/sys/kernel/panic

此参数用来设置如果发生“内核严重错误(kernel panic)”,则内核在重新引导之前等待的时间(以秒为单位)。默认值为0,表示在发生内核严重错误时将禁止重新引导,建议设置为1,也就是内核故障后1秒后自动重启。
设置方法为:echo 1 >/proc/sys/kernel/panic

2、/proc/sys/kernel/pid_max

此参数用来设置Linux下进程数量的最大值,默认是32768,正常情况下是够用的,当我们跑重量任务时,会不够用,最终导致内存无法分配的错误,所以可以适当增加,方法如下:

[root@localhost ~]32768[root@localhost ~]
[root@localhost ~]196608

3、/proc/sys/kernel/ctrl-alt-del

该文件有一个二进制值,该值控制系统在接收到ctrl+alt+delete按键组合时如何反应。这两个值分别是:

0值,表示捕获ctrl+alt+delete,并将其送至 init 程序;这将允许系统可以安全地关闭和重启,就好象输入shutdown命令一样。
1值,表示不捕获ctrl+alt+delete。

建议设置为1,可以防止意外按下ctrl+alt+delete导致系统非正常重启。

4、/proc/sys/kernel/core_pattern

此参数用来设置core文件保存位置或文件名,只有文件名时,则保存在应用程序运行的目录下,配置方法:echo “core.%e.%p” >/proc/sys/kernel/core_pattern,其中%e表示程序名, %p表示进程id。

五、内存内核参数优化

1、 /proc/sys/vm/dirty_background_ratio

这个参数指定了当文件系统缓存脏数据数量达到系统内存百分之多少时(如10%)就会触发pdflush/flush/kdmflush等后台回写进程运行,将一定缓存的脏页异步地刷入磁盘;例如,服务器内存32G,那么有3.2G的内存可以用来缓存脏数据,超过3.2G的话就pdflush/flush/kdmflush进程就会来清理它。
缺省设置:10

2、 /proc/sys/vm/dirty_ratio

这个参数指定了当文件系统缓存脏数据数量达到系统内存百分之多少时(如15%),系统不得不开始处理缓存脏页(因为此时脏数据数量已经比较多,为了避免数据丢失需要将一定脏数据刷入磁盘);如果触发了这个设置,那么新的IO请求将会被阻挡,直到脏数据被写进磁盘。这是造成IO卡顿的重要原因,但这也是保证内存中不会存在过量脏数据的保护机制。

注意这个参数和dirty_background_ratio参数的区别,dirty_background_ratio是脏数据百分比的一个软限制,而dirty_ratio是一个脏数据百分比硬限制,在参数设置上,dirty_ratio一定要大于或等于dirty_background_ratio的值。

在磁盘写入不是很频繁的场景,适当增大此值,可以极大提高文件系统的写性能。但是,如果是持续、恒定的写入场合时,应该降低其数值。

缺省设置:20

3、 /proc/sys/vm/dirty_expire_centisecs

该文件表示如果脏数据在内存中驻留时间超过该值,pdflush进程在下一次将把这些数据写回磁盘。这个参数声明Linux内核写缓冲区里面的数据多“旧”了之后,pdflush进程就开始考虑写到磁盘中去。单位是1/100秒。缺省是 3000,也就是30秒的数据就算旧了,将会刷新磁盘。对于特别重载的写操作来说,这个值适当缩小也是好的,但也不能缩小太多,因为缩小太多也会导致IO提高太快。

缺省设置:3000(1/100秒)

4、  /proc/sys/vm/dirty_writeback_centisecs

这个参数控制内核的脏数据刷新进程pdflush的运行间隔。单位是1/100秒。缺省数值是500,也就是5秒。如果我们的系统是持续地写入动作,那么建议降低这个数值比较好,这样可以把尖峰的写操作削平成多次写操作,相反,如果我们的系统是短期地尖峰式的写操作,并且写入数据不大(几十M/次)且内存又比较富裕,那么应该增大此数值
缺省设置:500(1/100秒)

5、/proc/sys/vm/vfs_cache_pressure

该文件表示内核回收用于directory和inode cache内存的倾向;缺省值100表示内核将根据pagecache和swapcache,把directory和inode cache保持在一个合理的百分比;降低该值低于100,将导致内核倾向于保留directory和inode cache;增加该值超过100,将导致内核倾向于回收directory和inode cache。此参数一般情况下不需要调整,只有在极端场景下才建议进行调整。
缺省设置:100

6、 /proc/sys/vm/min_free_kbytes

该文件表示强制Linux VM最低保留多少空闲内存(Kbytes)。
缺省设置:90112(88M物理内存,centos7版本)

7、 /proc/sys/vm/nr_pdflush_threads
该文件表示当前正在运行的pdflush进程数量,在I/O负载高的情况下,内核会自动增加更多的pdflush进程。

8、 /proc/sys/vm/overcommit_memory

该文件指定了内核针对内存分配的策略,其值可以是0、1、2。

0, 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
1, 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
2, 表示内核允许分配超过所有物理内存和交换空间总和的内存。
此参数,需要根据服务器运行的具体应用来优化,比如服务器运行的是redis内存数据库,那么推荐设置为1,如果是web类应用,建议保持默认即可。

9、/proc/sys/vm/panic_on_oom

此参数表示内存不够时内核是否直接panic(恐慌),  默认为0,表示当内存耗尽时,内核会触发OOM killer杀掉最耗内存的进程。如果设置为1表示在OOM时系统会panic(恐慌),Linux Kernel panic正如其名,表示linux kernel不知道如何走了,此时它会尽可能把此时能获取的全部信息都打印出来。有时候为了不让系统自动kill掉进程,就需要设置此值为1。

下面简单介绍下OOM killer机制:

当系统物理内存和交换空间都被用完时,如果还有进程来申请内存,内核将触发OOM killer,当发生OOM时系统的行为会基于 “cat /proc/sys/vm/panic_on_oom”的值决定,

这个值为0表示在OOM时系统执行OOM Killer,那么系统是怎么选择一个进程杀掉呢,选择的标准就是杀掉最少数量的进程同时释放出最大数量的内存,要达到这个目标, Kernel维护着一份oom_score数据,它包含各个进程的oom_score,我们可以在/proc/${pid}/oom_score中查看各个进程的oom_score值(该值越大,越容易被杀掉),最终的oom_score值会参照/proc//oom_adj ,  oom_adj取值范围从-17到15,当等于-17时表示在任何时候此进程都不会被“OOM killer” kill掉。

因此,我们说,影响OOM killer机制的因素有两个:

/proc/[pid]/oom_score:当前该pid进程被kill的分数,越高的分数意味着越可能被kill,这个数值是根据oom_adj运算后的结果,是oom_killer的主要参考。
/proc/[pid]/oom_adj:表示该pid进程被oom killer杀掉的权重,介于[-17,15]之间,越高的权重,意味着更可能被oom killer选中,-17表示禁止被kill掉。

10、/proc/sys/vm/swappiness

此参数表示使用swap分区的几率。swappiness=0的时候表示最大限度使用物理内存,然后才是swap空间,swappiness=100的时候表示积极的使用swap分区,并且把内存上的数据及时的搬运到swap空间里面。linux的基本默认设置为60,表示你的物理内存在使用到100-60=40%的时候,就开始出现有交换分区的使用。此值在一些内存数据库服务器上需要设置的足够小,比如redis、hbase机器上,应该设置0-10之间,表示最大限度使用物理内存。

缺省设置:60

六、文件系统内核参数优化

1、/proc/sys/fs/file-max

该参数指定了可以分配的文件句柄的最大数目。如果用户得到的错误消息声明由于打开文件数已经达到了最大值,从而他们不能打开更多文件,则可能需要增加该值。

设置方法为:echo “10485750”>/proc/sys/fs/file-max

2、/proc/sys/fs/inotify/max_user_watches

Linux下Rsync+inotify-tools实现数据实时同步中有一个重要的配置就是设置Inotify的max_user_watches值,如果不设置,当遇到大量文件的时候就会出现出错的情况。
可以通过如下方式增加此值:

echo “8192000”>/proc/sys/fs/inotify/max_user_watches

关于Linux系统内核基础优化参数就介绍这么多,对于一个web服务器来说,这些都是必须要做的基础优化,至于更多的优化,要结合应用环境特点,具体问题具体对待。

最后,要将设置好的内核参数永久生效,需要修改/etc/sysctl.conf文件。首先检查sysctl.conf文件,如果已经包含需要修改的参数,则修改该参数的值,如果没有需要修改的参数,在sysctl.conf文件中添加该参数即可。
线上环境建议将所有要设置的内核参数加入到/etc/sysctl.conf文件中。

下面是我们一个线上web服务器配置参考,此配置可以支撑每天1亿的请求量(服务器硬件为16核32GB内存):

net.ipv4.conf.lo.arp_ignore = 1net.ipv4.conf.lo.arp_announce = 2net.ipv4.conf.all.arp_ignore = 1net.ipv4.conf.all.arp_announce = 2net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_fin_timeout = 10net.ipv4.tcp_max_syn_backlog = 20000net.core.netdev_max_backlog =  32768net.core.somaxconn = 32768net.core.wmem_default = 8388608net.core.rmem_default = 8388608net.core.rmem_max = 16777216net.core.wmem_max = 16777216net.ipv4.tcp_timestamps = 0net.ipv4.tcp_synack_retries = 2net.ipv4.tcp_syn_retries = 2net.ipv4.tcp_syncookies = 1net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_mem = 94500000 915000000 927000000net.ipv4.tcp_max_orphans = 3276800net.ipv4.tcp_fin_timeout = 10net.ipv4.tcp_keepalive_time = 120net.ipv4.ip_local_port_range = 1024  65535net.ipv4.tcp_max_tw_buckets = 80000net.ipv4.tcp_keepalive_time = 120net.ipv4.tcp_keepalive_intvl = 15net.ipv4.tcp_keepalive_probes = 5net.ipv4.conf.lo.arp_ignore = 1net.ipv4.conf.lo.arp_announce = 2net.ipv4.conf.all.arp_ignore = 1net.ipv4.conf.all.arp_announce = 2net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_fin_timeout = 10net.ipv4.tcp_max_syn_backlog = 20000net.core.netdev_max_backlog =  32768net.core.somaxconn = 32768net.core.wmem_default = 8388608net.core.rmem_default = 8388608net.core.rmem_max = 16777216net.core.wmem_max = 16777216net.ipv4.tcp_timestamps = 0net.ipv4.tcp_synack_retries = 2net.ipv4.tcp_syn_retries = 2net.ipv4.tcp_mem = 94500000 915000000 927000000net.ipv4.tcp_max_orphans = 3276800net.ipv4.ip_local_port_range = 1024  65535net.ipv4.tcp_max_tw_buckets = 500000net.ipv4.tcp_keepalive_time = 60net.ipv4.tcp_keepalive_intvl = 15net.ipv4.tcp_keepalive_probes = 5net.nf_conntrack_max = 2097152

这个内核参数优化例子,可以作为一个web系统的优化标准,但并不保证适应任何环境。

以上就是良许教程网为各位朋友分享的Linux系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你!

本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部