Memcached 集群高可用安装文档
本文参考了好几篇文档修改而来的,且目前用于生产环境。目前一年,没有出现一次问题。文档中有部门细节需要仔细看看,如有问题,可以联系我。
一、Memcache安装
192.168.200.45:11212主
192.168.200.45:11212主
192.168.200.45:11213备
安装memcache前需要先安装libevent
wget http://mirrors.hncgo.com/libevent-2.0.22-stable.tar.gz wget http://mirrors.hncgo.com/memcached-1.4.33.tar.gz
安装memcache前需要先安装libevent
查看libevent是否安装:
ls -al /usr/lib | grep libevent
未安装时应该无查询记录。
安装libevent:
tar xf libevent-2.0.22-stable.tar.gz cd libevent-2.0.22-stable ./configure -prefix=/usr make && make install
查看libevent是否安装成功:
ls -al /usr/lib |grep libevent
安装Memcache
tar -xvf tar xf memcached-1.4.33.tar.gz cd memcached-1.4.33 ./configure -with-libevent=/usr make && make install
查看Memcache是否安装成功:
ls -al /usr/local/bin/mem*
若安装失败,可根据提示的错误信息搜索解决方法即可。
将memcache加入系统服务
增加memcached 到
vim /etc/init.d/memcached
# chkconfig: 345 60 60 # description: The memcached daemon is a network memory cache service. # processname: memcached #!/bin/sh # Source function library. . /etc/rc.d/init.d/functions PORT=11211 USER=root MAXCONN=1024 CACHESIZE=5120 OPTIONS="" CACHE_HOME=/usr/local/bin # Check that networking is up. if [ "$NETWORKING" = "no" ] then exit 0 fi RETVAL=0 prog="memcached" start () { echo -n $"Starting $prog: " # insure that /var/run/memcached has proper permissions chown $USER $CACHE_HOME/memcached daemon $CACHE_HOME/memcached -d -p $PORT -u $USER -m $CACHESIZE -c $MAXCONN -P $CACHE_HOME/memcached.pid $OPTIONS RETVAL=$? echo [ $RETVAL -eq 0 ] && touch /var/lock/subsys/memcached } stop () { echo -n $"Stopping $prog: " killproc memcached RETVAL=$? echo if [ $RETVAL -eq 0 ] ; then rm -f /var/lock/subsys/memcached rm -f /var/run/memcached.pid fi } restart () { stop start } # See how we were called. case "$1" in start) start ;; stop) stop ;; status) status memcached ;; restart|reload) restart ;; condrestart) [ -f /var/lock/subsys/memcached ] && restart || : ;; *) echo $"Usage: $0 {start|stop|status|restart|reload|condrestart}" exit 1 esac exit $?
设置权限755
cd /etc/init.d/ chmod -R 755 memcached chkconfig --add memcached chkconfig memcached on service memcached start
##以上为单机安装
二、集群安装请参考以下文档
192.168.200.45:11212主
192.168.200.45:11212主
192.168.200.45:11213备
三、Memcache启动命令常用参数
-p(小写) 监听的TCP端口(默认为11211)
-U(大写) 监听的UDP端口(默认为11211,0时关闭)
-d 以守护进程方式运行
-u(小写) 运行Memcache的用户账户,非root用户
-m 分配给Memcache节点的最大的内存,单位是MB,默认为64MB
-c 最大运行的并发连接数,也称为软连接数,默认是1024
-v 输出警告和错误信息
-vv(两个v) 打印客户端的请求和返回信息
-h 打印帮助信息
-i 打印memcached和libevent的版权信息
-l(字母L的小写) 绑定地址(默认所有都允许,无论内外网或者本地IP,但有安全隐患,若设置为127.0.0.1,就只能本机访问,一般是设置内网IP,供局域网的机器访问即可)
-P(大写) 将pid写入文件,这样可以使得后边进行快速进程终止,需要与-d一起使用
-f 块大小增长因子,默认是1.25
-M(大写) 内存耗尽时返回错误,而不是删除项
示例1:打印memcached命令帮助信息
命令:/usr/local/bin/memcached -h
返回信息如截图所示:
这里写图片描述
示例2:memcached服务端通用启动命令
命令:/usr/local/bin/memcached -d -m 128 -u root -l 192.168.0.105 -p 11211 -P /tmp/memcached11211.pid
命令说明:以root用户启动memcached服务端,以守护进程方式启动,最大内存为128MB,监听IP为192.168.0.106,监听端口为11211,将进程pid写入/tmp/memcached11211.pid中。
补充:Linux监听memcached节点是否正常启动,或使用情况的几条常用命令
1)查看memcache进程,可以看到memcached的详细启动命令:ps -ef|grep memcached
看到类似的结果,说明memcache启动成功。
这里写图片描述
2)查看端口11211的进程信息,可看到进程ID:lsof -i:11211。也可以使用cat /tmp/memcached11211.pid命令查看。
为了达到演示效果,本机启动了一个telnet命令连接该memcached服务节点,如下图所示:
这里写图片描述
3)查看端口11211的网络连接信息,若有客户端程序连接,可用此命令查看:netstat -anp|grep 11211
为了达到演示效果,本机启动了一个telnet命令连接该memcached服务节点,如下图所示:
这里写图片描述
四、经典场景
1、利用memcache缓存sesssion信息,用于集群部署环境下的session共享。
2、利用memcache缓存系统用户信息,商品信息等。
3、利用memcache缓存高频访问的海量小文件等。
4、利用memcache实现锁控制。
这里只作简单的介绍,详细使用方法会在将后的章节分享。
以上内容就是memcache最基础的知识,主要是memcache服务的安装,启动。
Telnet客户端或应用程序(Java或PHP)的客户端将在下一章节介绍。
二、安装集群
在memcache主上安装集群软件
使用Magent代理组件搭建集群服务。
:
1)memcache节点宕机后,客户端能自动重连。
2)有数据备份,比如部署了memcache节点1、节点2和备份节点,当节点1宕机,set操作到节点1的时候,会失败(不会自动跳到另一个节点当中去),但备份memcache节点是会保留所有key,所有运用get命令还是能够得到正常结果的。
下载
2)编译安装
wget http://mirrors.hncgo.com/magent-0.6.tar.gz tar zxvf magent-0.6.tar.gz make
报错1:
gcc -Wall -g -O2 -I/usr/local/include -m64 -c -o magent.o magent.c
magent.c: In function 'writev_list':
magent.c:729: error: 'SSIZE_MAX' undeclared (first use in this function)
magent.c:729: error: (Each undeclared identifier is reported only once
magent.c:729: error: for each function it appears in.)
make: *** [magent.o] Error 1
解决办法:
[root@centos6 memcached]# vi ketama.h
在开头加入
#ifndef SSIZE_MAX #define SSIZE_MAX 32767 #endif
继续make
报错2:
gcc -Wall -g -O2 -I/usr/local/include -m64 -c -o magent.o magent.c
gcc -Wall -g -O2 -I/usr/local/include -m64 -c -o ketama.o ketama.c
gcc -Wall -g -O2 -I/usr/local/include -m64 -o magent magent.o ketama.o /usr/lib64/libevent.a /usr/lib64/libm.a
gcc: /usr/lib64/libevent.a: No such file or directory
gcc: /usr/lib64/libm.a: No such file or directory
解决办法:
[root@centos6 memcached]# ln -s /usr/lib/libevent* /usr/lib64/
[root@centos6 memcached]# make
报错3:
gcc -Wall -g -O2 -I/usr/local/include -m64 -o magent magent.o ketama.o /usr/lib64/libevent.a /usr/lib64/libm.a
gcc: /usr/lib64/libm.a: No such file or directory
make: *** [magent] Error 1
解决办法:
yum install glibc glibc-devel
如果是64bit的系统则不会在/usr/lib64/libm.a 生成,如果是32bit即会有。
[root@centos6 memcached]# cp /usr/lib64/libm.so /usr/lib64/libm.a
继续make
报错4:
gcc -Wall -g -O2 -I/usr/local/include -m64 -o magent magent.o ketama.o /usr/lib64/libevent.a /usr/lib64/libm.a
/usr/lib64/libevent.a(event.o): In function `detect_monotonic':
event.c:(.text+0xc79): undefined reference to `clock_gettime'
/usr/lib64/libevent.a(event.o): In function `gettime':
event.c:(.text+0xd60): undefined reference to `clock_gettime'
collect2: ld returned 1 exit status
make: *** [magent] Error 1
解决办法:
[root@centos6 memcached]# vi Makefile
CFLAGS = -Wall -g -O2 -I/usr/local/include $(M64)
改为:
CFLAGS = -lrt -Wall -g -O2 -I/usr/local/include $(M64)
成功
[root@centos6 memcached]# make
gcc -Wall -g -O2 -I/usr/local/include -m64 -o magent magent.o ketama.o -lrt /usr/lib64/libevent.a /usr/lib64/libm.a
[root@centos6 memcached]# ls
Makefile ketama.c ketama.h ketama.o magent magent-0.6.tar.gz magent.c magent.o
[root@centos6 memcached]# cp magent /usr/bin/
magent启动
[root@centos6 memcached]# magent -u root -n 51200 -l 192.168.200.45 -p 11211 -s 192.168.200.46:11212 -b 192.168.200.47:11213
分别在127.0.0.1机器的11211,11212,11213端口启动3个Memcached进程,在12000端口开启magent代理程序;(以此类推可在不同机器上启动memcached)
11211和11212为主Memcached,11213为备份Memcached;
netstat -lntup |grep 11211
http://www.cnblogs.com/breezey/p/4679702.html
安装repcache同步
wget http://mirrors.hncgo.com/repcached-master.zip
unzip repcached-master.zip
cd repcached-master
./configure --prefix=/usr/local/repcached --enable-64bit --enable-replication --with-libevent=/usr/local/libevent
make && make install
启动
ldconfig /usr/local/repcached/bin/memcached -u root -l 192.168.200.46 -p 11211 -m 2048 -x 192.168.200.47 -X 11212 -d ldconfig /usr/local/repcached/bin/memcached -u root -l 192.168.200.47 -p 11211 -m 2048 -x 192.168.200.46 -X 11212 -d
-u:指定启动memcached的用户,该用户需要事先创建
-l:指定memcached监听的本地ip地址
-p:指定memcached监听的本地的tcp端口,默认为11211
-m:指定memcached启动后占用的内存空间大小,单位为M
-x:指定repcached的master的ip地址,需要从master同步数据
-X:指定从master同步数据时的端口,默认为11212
-d:将其作为守护进程放入后台运行
测试:
在105上进行如下操作:
telnet 192.168.1.105 11211 set key1 0 60 5 hello
在106上查看:
复制代码
telnet 192.168.1.106 11211 get key1
当看到显示
VALUE key1 0 5 hello
即代表数据成功实现同步,反之测试亦然。
1、整体方案描述
6个memcache节点,使用repcached,其中4个做工作节点,2个做备份节点
3个magent节点(作为第二层),2个做工作节点,1个做备份节点
2个用户工作节点,MA-USER为工作节点,MA-MGR为备份节点
2、端口分配(拟定,各位可根据实际情况任意指定)
由于占用端口数量较多,使用表格整理方便查看。
3、启动命令
1)新建memcache repcached节点
名称 端口号 监听 复制端口号 备注
memcached节点1 46:11461 11215 工作节点
memcached节点2 47:11472 11215 工作节点
memcached节点3 46:11463 11216 工作节点
memcached节点4 47:11474 11216 工作节点
memcached节点5 45:11455 11217 备份节点
memcached节点6 45:11456 11217 备份节点
magent节点1 46:11212 - 第二层,对内可见,对外不可见
magent节点2 47:11213 - 第二层,对内可见,对外不可见
magent节点3 45:11214 - 第二层,对内可见,对外不可见
magent节点4 45:11211 - 对外访问层
magent节点5 45:11451 - 备份节点
ldconfig /usr/local/repcached/bin/memcached -u root -l 192.168.200.46 -p 11461 -m 2048 -x 192.168.200.47 -X 11215 –d #主 /usr/local/repcached/bin/memcached -u root -l 192.168.200.47 -p 11472 -m 2048 -x 192.168.200.46 -X 11215 -d #从 /usr/local/repcached/bin/memcached -u root -l 192.168.200.46 -p 11463 -m 2048 -x 192.168.200.47 -X 11216 -d #从 /usr/local/repcached/bin/memcached -u root -l 192.168.200.47 -p 11474 -m 2048 -x 192.168.200.46 -X 11216 -d #主 /usr/local/repcached/bin/memcached -u root -l 192.168.200.45 -p 11455 -m 2048 -x 192.168.200.45 -X 11217 -d #主 备 /usr/local/repcached/bin/memcached -u root -l 192.168.200.45 -p 11456 -m 2048 -x 192.168.200.45 -X 11217 -d #从
将这6条语句放在startRepcached.sh 文件中
2)新建magent节点(第二层magent)
magent -u root -n 2048 -l 192.168.200.46 -p 11212 -s 192.168.200.46:11461 -b 192.168.200.47:11472 magent -u root -n 2048 -l 192.168.200.47 -p 11213 -s 192.168.200.47:11474 -b 192.168.200.46:11463 magent -u root -n 2048 -l 192.168.200.45 -p 11214 -s 192.168.200.45:11455 -b 192.168.200.45:11456
将这3条语句放在startSecondMagent.sh 文件中
2)新建magent节点(第二层magent)
magent -u root -n 2048 -l 192.168.200.45 -p 11211 -s 192.168.200.46:11212 -b 192.168.200.45:11214 magent -u root -n 2048 -l 192.168.200.45 -p 11451 -s 192.168.200.47:11213 -b 192.168.200.45:11214
将这3条语句放在startMagent.sh 文件中
192.168.200.45.sh #!/bin/sh /usr/local/repcached/bin/memcached -u root -l 192.168.200.45 -p 11455 -m 2048 -x 192.168.200.45 -X 11217 -d /usr/local/repcached/bin/memcached -u root -l 192.168.200.45 -p 11456 -m 2048 -x 192.168.200.45 -X 11217 -d magent -u root -n 2048 -l 192.168.200.45 -p 11211 -s 192.168.200.46:11212 -b 192.168.200.45:11214 magent -u root -n 2048 -l 192.168.200.45 -p 11451 -s 192.168.200.47:11213 -b 192.168.200.45:11214 192.168.200.46.sh #!/bin/sh /usr/local/repcached/bin/memcached -u root -l 192.168.200.46 -p 11461 -m 2048 -x 192.168.200.47 -X 11215 -d /usr/local/repcached/bin/memcached -u root -l 192.168.200.46 -p 11463 -m 2048 -x 192.168.200.47 -X 11216 -d magent -u root -n 2048 -l 192.168.200.46 -p 11212 -s 192.168.200.46:11461 -b 192.168.200.47:11472 192.168.200.47.sh #!/bin/sh /usr/local/repcached/bin/memcached -u root -l 192.168.200.47 -p 11472 -m 2048 -x 192.168.200.46 -X 11215 -d /usr/local/repcached/bin/memcached -u root -l 192.168.200.47 -p 11474 -m 2048 -x 192.168.200.46 -X 11216 -d magent -u root -n 2048 -l 192.168.200.47 -p 11213 -s 192.168.200.47:11474 -b 192.168.200.46:11463
联合memcache,repcached,magent,monit四个组件搭建高可用集群方案
一、基本介绍
1、组件承担的角色
1)memcache负责缓存对象。
2)repcached负责单主单从的同步备份。
3)magent代理实现N主N备。
4)monit监听以上组件的各个实例端口,保证故障自动重启。
2、集群思路
1)利用repcached对memcache进行1对1的主备设计
2)利用magent多MA负载分担实现N主N备方案。
3)利用monit的监听机制,实例宕机后,能够快速重启。
二、Monit安装及基本使用
1、下载安装
我用的是Centos 6.8,官网上发布了rpm包,直接下载安装即可
wget http://mirrors.hncgo.com/monit-5.5-1.el6.rf.x86_64.rpm rpm -ivh monit-5.5-1.el6.rf.x86_64.rpm
安装完成后,会在/etc目录下生成monit.conf文件和monit.d文件夹
2、启动
启动命令:/etc/init.d/monit start
默认监听端口为2812,启动成功后,可以使用web浏览器打开http://localhost:2812
netstat -ntlp |grep 2812
注意两点修改:
1)/etc/monit.conf文件中,
要修改使用的IP地址,如192.168.200.45,允许访问的地址设置为局域网内可访问,如192.168.200.0/24。
若不先设置,默认启动的话,只能是本机浏览器访问才行,别的机器都不行。
set httpd port 2812 and use address 192.168.200.45 # only accept connection from localhost allow 192.168.200.0/24 # allow localhost to connect to the server and allow admin:monit # require user 'admin' with password 'monit' allow @monit # allow users of group 'monit' to connect (rw) allow @users readonly # allow users of group 'users' to connect readonly
2)因为做实验的机器是安装在虚拟机Linux机器上的,本地为Windows,若还是无法访问,请尝试关闭Linux的防火墙:
#service iptables status
#service iptables stop
3、配置文件修改
Monit是比较通用的监听组件,用得比较广泛,这里就针对目前要使用的Memcache相关组件进行监听配置的讲解(monit.conf里面已经有许多示例可以参照的)。
我们来看一个监控Apache的示例
# 监控apache # check process apache with pidfile /var/run/apache2.pid start program = "/etc/init.d/apache2 start" stop program = "/etc/init.d/apache2 stop" # apache吃cpu和内存比较厉害,额外添加一些关于这方面的监控设置 if cpu > 50% for 2 cycles then alert if cpu > 70% for 5 cycles then restart if totalmem > 1500 MB for 10 cycles then restart if children > 250 then restart if loadavg(5min) greater than 10 for 20 cycles then stop if failed host www.example.com port 8080 protocol http then restart if 3 restarts within 5 cycles then timeout group server # 可选,依赖于nginx depends on nginx
可以看出有以下几个关键点:
1、process 后面的是监控的进程名
2、start program和stop program是启动和停止的命令,注意这个命令不能是sh文件。
3、CPU占用率的监控写法还是比较简单的。
4、 if failed这一行写的是监听的IP和端口,这点很重要。
5、其他的语法,根据需要照着抄就OK。
所以说,Monit的监控进行的语法配置可以快速上手的,不过要精通就要另外下一番功夫了。
4、memcache进程监控写法
将memcache注册成服务,主要是方便start program和stop program两行命令方便书写。
check process memcache11211 with pidfile /tmp/memcached11211.pid start program = "/usr/local/bin/memcached -d -m 64 -u root -l 192.168.0.106 -p 11211 -P /tmp/memcached11211.pid" with timeout 60 seconds stop program = "/usr/bin/kill `cat /tmp/memcached11211.pid`" if failed host 192.168.0.106 port 11211 then restart if cpu is greater than 40% for 2 cycles then alert if cpu > 60% for 5 cycles then restart if 10 restarts within 10 cycles then timeout
启动命令是能够正常使用的,我们在命令行操作中使用杀进程的方式人为的停止memcache服务,过一段时间后,发现monit能够让该memcache重新启动。不过好像stop program起不到效果,在页面上点击stop service无法停止memcache服务。
有个办法是使用安装版的memcache,将这个启动文件进行裁剪,只剩下stop方法,如下:
#!/bin/sh # # memcached: MemCached Daemon # # chkconfig: - 90 25 # description: MemCached Daemon # # Source function library. . /etc/rc.d/init.d/functions . /etc/sysconfig/network #[ ${NETWORKING} = "no" ] && exit 0 #[ -r /etc/sysconfig/dund ] || exit 0 #. /etc/sysconfig/dund #[ -z "$DUNDARGS" ] && exit 0 stop() { echo -n $"Shutting down memcached: " kill -9 `cat tmp/memcached11211.pid` echo } # See how we were called. case "$1" in stop) stop ;; *) echo $"Usage: $0 {stop}" exit 1 esac exit 0
其实就是将kill命令写进这个脚本文件里,然后将该文件保存在/etc/init.d/目录下,命名为stopmemcached11211。
这样,就可以在monit里配置/sbin/service stopmemcached11211 stop命令了。
因为这个脚本文件里,pid文件的名字是写死的,如果涉及多个memcache实例,只能copy多个这样的文件,然后再改一下文件名,本来想把这个命令做成参数化的,奈何对脚本文件编写不是很专业,临时写了个案例凑数,若有精通此项技能的同学,或是有别的好方法,还望多多指点,将这个改进一下。
repcached和magent也可以使用类似的操作。
详细的进程监控信息如下:
这里写图片描述
另外,Monit本身是实用性非常强的组件之一,关于其通用的配置,各位很容易找到,在这里就不班门弄斧了。
5、注意几点
1)monit的start program和stop program要写完整路径,如/sbin/service等。
2)新增的注册服务,若出现Permission denied错误时,增加执行权限就可以了:chmod +x stopmemcached11211。
3)使用monit监控repcached进程时,由于主备切换的关系,在monit里的启动命令要写成Slave类型的,并且在启动Monit前,要先启动相关的repcached进程。
三、集群架构图
这里写图片描述
结构示意图注释:
1)M1-S为memcache工作节点,M1-B为memcache备份节点,两节点之间使用repcached复制。
2)MA-1,MA-2,MA-N表示多个magent代理节点,处于中间层,用户不可见。
3)MA-USER,MA-MGR为用户可见的代理节点
4)MA-1,M1-S,M1-B三个节点表示一个单主单备的模型,多个这样的单主单备模型组成一套N主N备方案。
这样,无论M1-S,M2-S的节点如何宕机,都不会有单点故障,也不会导致memcache节点顺序变化。
问:如果MA-1宕机,会不会导致单点故障?或是MA-USER宕机,情形又如何呢?
答:应该不会,magent代理节点是无状态的,只要memcache有数据,都应该没问题。另外MA-MGR为MA-USER的备份节点,只要MA-MGR和MA-USER不要同时宕机,一般都没问题。
四、实战演练
1、整体方案描述
6个memcache节点,使用repcached,其中4个做工作节点,2个做备份节点
3个magent节点(作为第二层),2个做工作节点,1个做备份节点
2个用户工作节点,MA-USER为工作节点,MA-MGR为备份节点
2、端口分配(拟定,各位可根据实际情况任意指定)
由于占用端口数量较多,使用表格整理方便查看。
名称 端口号 监听复制端口号 备注
memcached节点1 12211 15001 工作节点
memcached节点2 12212 15001 工作节点
memcached节点3 12311 15002 工作节点
memcached节点4 12312 15002 工作节点
memcached节点5 12411 15003 备份节点
memcached节点6 12412 15003 备份节点
magent节点1 13211 - 第二层,对内可见,对外不可见
magent节点2 13212 - 第二层,对内可见,对外不可见
magent节点3 13213 - 第二层,对内可见,对外不可见
magent节点4 14211 - 对外访问层
magent节点5 14212 - 备份节点
3、启动命令
1)新建memcache repcached节点
memcached -p 12211 -X 15001 -l 192.168.0.106 -v -d -u root memcached -p 12212 -X 15001 -x 192.168.0.106 -v -d -u root memcached -p 12311 -X 15002 -l 192.168.0.106 -v -d -u root memcached -p 12312 -X 15002 -x 192.168.0.106 -v -d -u root memcached -p 12411 -X 15003 -l 192.168.0.106 -v -d -u root memcached -p 12412 -X 15003 -x 192.168.0.106 -v -d -u root
将这6条语句放在startRepcached.sh 文件中
2)新建magent节点(第二层magent)
magent -u root -n 2048 -l 192.168.0.106 -p 13211 -s 192.168.0.106:12211 -b 192.168.0.106:12212 magent -u root -n 2048 -l 192.168.0.106 -p 13212 -s 192.168.0.106:12311 -b 192.168.0.106:12312 magent -u root -n 2048 -l 192.168.0.106 -p 13213 -s 192.168.0.106:12411 -b 192.168.0.106:12412
将这3条语句放在startSecondMagent.sh 文件中
2)新建magent节点(第二层magent)
magent -u root -n 2048 -l 192.168.0.106 -p 14211 -s 192.168.0.106:13211 -b 192.168.0.106:13213 magent -u root -n 2048 -l 192.168.0.106 -p 14212 -s 192.168.0.106:13212 -b 192.168.0.106:13213
将这3条语句放在startMagent.sh 文件中
PS:用做测试机时,我只用了一台Linux机器,各位可根据实际机器IP配置,修改相应的命令即可
北丐洪七公--Jeff
Dignity comes from strength, strength comes from struggle!
本文版权归作者和博客园共有,欢迎转载,未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步