ing### 架构图 JumpServer 分为多个组件,大致的架构如上图所示。其中 Lina 和 Luna 为纯静态文件,最终由 nginx 整合,没有端口,core、koko、lion以服务的形式部署,有端口。 本文主要版本选择为2.15.3
组件版本
组件 | 版本 | 备注 |
---|
Python | 3.8.12 | Core组件运行解释器 | Mysql | 5.7.37 | 数据存储 本次部署为yum安装 | Redis | 6.2.5 | 数据缓存 | Core | 2.15.3 | jumpserver核心组件 | Nodejs | 12.2.0 | Lina、Luna编译 | Lina | 2.15.3 | JumpServer 的前端 UI 项目,主要使用 Vue,Element UI 完成 | Luna | 2.15.3 | JumpServer 的前端 UI 项目,主要使用 Angular CLI 完成 | Go | 1.15.1 | Koko编译 | Koko | 2.15.3 | Koko 是 Go 版本的 coco,重构了 coco 的 SSH/SFTP 服务和 Web Terminal 服务 | Lion | 2.15.3 | 实现 RDP/VNC 协议跳板机功能 | Nginx | 1.20.0 | 代理转发 |
安装包下载地址
官网地址 Python3.8.12 Redis6.2.5 Core2.15.3 Nodejs12.2.0 Lina2.15.3 Luna Go1.15 Koko2.15.3 Lion2.15.3 Nginx1.20.0 guacamole-server1.3.0 GeoLite2-City.mmdb 国内地址 Python3.8.12 Redis6.2.5 Core2.15.3 Nodejs12.2.0 Lina2.15.3 Luna2.15.3 Go1.15.1 Koko2.15.3 Lion2.15.3 Nginx1.20.0 guacamole-server1.3.0 GeoLite2-City.mmdb
本文主要搭建参考:https://docs.jumpserver.org/zh/master/dev/build/
环境介绍
服务器版本 | 内网地址 | 备注 |
---|
centos7.6 | 172.18.158.92 | mysql、redis、core、python3、nodejs、lina、luna、go、koko、lion、nginx、guacamole-server |
部署Core
一、源码安装python3
-
当前环境 -
卸载自带的python3
rpm -qa|grep python3 |xargs rpm -e --allmatches --nodeps
- 下载指定版本的python3
wget http://8.210.62.122/python/Python-3.8.12.tgz
- 安装编译工具
yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make gdbm-devel db4-devel libpcap-devel xz-devel libffi-devel
- 解压
tar xf Python-3.8.12.tgz -C /usr/local/
- 编译
cd /usr/local/Python-3.8.12
./configure --prefix=/usr/local/python3
make && make install
- 配置环境变量
cat /etc/profile.d/python3.sh
export PYTHON_HOME=/usr/local/python3
export PATH=$PYTHON_HOME/bin:$PATH
python3 -V
Python 3.8.12
参考文章:https://blog.csdn.net/weixin_45717886/article/details/123992330 二、yum安装mysql 8. 配置mysql yum仓库 官网地址 国内地址
wget https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm
rpm -ivh mysql80-community-release-el7-1.noarch.rpm
- 修改安装mysql的yum源文件
[root@mysql ~]
把安装5.7的源打开, 关闭安装8.0的源 1是开启 0是关闭
[root@mysql ~]
[root@mysql ~]
- 获取密码
grep "password" /var/log/mysqld.log
参考文章:https://blog.csdn.net/weixin_45717886/article/details/103411025
- 修改密码并创建授权用户
alter mysql.user '用户名'@'登入主机' identified by '密码';
create database jumpserver default charset utf8 collate utf8_general_ci;
grant all on jumpserver.* to 'jumpsever'@'127.0.0.1' identified by '密码';
grant all on jumpserver.* to 'jumpsever'@'localhost' identified by '密码';
grant all on jumpserver.* to 'jumpsever'@'172.18.%' identified by '密码';
flush privileges;
参考文章:https://editor.csdn.net/md/?articleId=103356082 三、安装redis
- 下载安装包
curl -O https://download.redis.io/releases/redis-6.2.5.tar.gz
- 解压
tar xf redis-6.2.5.tar.gz -C /usr/local/
- 编译
cd /usr/local/redis-6.2.5/
make PREFIX=/usr/local/redis install
- 配置环境变量
cat /etc/profile.d/redis.sh
export REDIS_HOME=/usr/local/redis
export PATH=$REDIS_HOME/bin:$PATH
source /etc/profile.d/redis.sh
redis-server --version
Redis server v=6.2.5 sha=00000000:0 malloc=jemalloc-5.1.0 bits=64 build=3ec1f34ab2699b91
- redis配置文件
mkdir /usr/local/redis/{etc,data,log,run}
cp -ar /usr/local/redis-6.2.5/redis.conf /usr/local/redis/etc/
[root@localhost etc]
75c75
< bind 0.0.0.0
---
> bind 127.0.0.1 -::1
257c257
< daemonize yes
---
> daemonize no
289c289
< pidfile /usr/local/redis/run/redis_6379.pid
---
> pidfile /var/run/redis_6379.pid
302c302
< logfile /usr/local/redis/log/redis.log
---
> logfile ""
454c454
< dir /usr/local/redis/data
---
> dir ./
902d901
```shell
cat redis.conf |grep -v -E "^#|^$"
bind 0.0.0.0
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
pidfile /usr/local/redis/run/redis_6379.pid
loglevel notice
logfile /usr/local/redis/log/redis.log
databases 16
always-show-logo no
set-proc-title yes
proc-title-template "{title} {listen-addr} {server-mode}"
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
rdb-del-sync-files no
dir /usr/local/redis/data
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled
repl-disable-tcp-nodelay no
replica-priority 100
acllog-max-len 128
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
lazyfree-lazy-user-flush no
oom-score-adj no
oom-score-adj-values 0 200 800
disable-thp yes
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes
- 内核参数调优
vim /etc/sysctl.conf
net.core.somaxconn=32768
net.ipv4.tcp_max_syn_backlog=32768
vm.overcommit_memory=1
大页内存动态分配,需要关闭让redis负责内存管理。
临时关闭
cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never
echo never > /sys/kernel/mm/transparent_hugepage/enabled
cat /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never]
永久关闭
vim /etc/default/grub
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet transparent_hugepage=never"
GRUB_DISABLE_RECOVERY="true"
grub2-mkconfig -o /boot/grub2/grub.cfg
reboot 重启机器后使得设备的参数有效
cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-3.10.0-1160.el7.x86_64 root=/dev/mapper/centos-root ro rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet transparent_hugepage=never
[root@localhost ~]
always madvise [never]
部分文章参考:https://blog.51cto.com/u_8026776/2074544
- 配置systemd管理redis服务
创建启动用户
useradd redis -M -s /sbin/nologin
chown -R redis.redis /usr/local/redis
cat /usr/lib/systemd/system/redis.service
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf
Type=forking
User=redis
Group=redis
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl restart redis
systemctl enable redis
文章参考:https://blog.csdn.net/weixin_45717886/article/details/123754781
四、Core安装
- 下载core
wget http://8.210.62.122/jumpserver/jumpserver-2.15.3.tar.gz
- 解压core
tar -xf jumpserver-2.15.3.tar.gz -C /opt
cd /opt
mv jumpserver-2.15.3 jumpserver
- 下载GeoLite2-City.mmdb文件
cd /opt/jumpserver
wget http://8.210.62.122/jumpserver/GeoLite2-City.mmdb -O apps/common/utils/geoip/GeoLite2-City.mmdb
- 安装rpm依赖
yum -y install `cat requirements/rpm_requirements.txt`
- 安装python依赖
为 JumpServer 项目单独创建 python3 虚拟环境。
python3 -m venv /opt/py3
source /opt/py3/bin/activate
每次运行项目都需要先执行 source /opt/py3/bin/activate 载入此环境。 配置python3安装模块源
[root@jumpserver jumpserver]
[global]
index-url=http://mirrors.cloud.aliyuncs.com/pypi/simple/
[install]
trusted-host=mirrors.cloud.aliyuncs.com
pip3 install -U pip
pip3 install --upgrade pip
python3 -m pip install --upgrade setuptools
文章参考:https://stackoverflow.com/posts/62500932/edit
- 修改安装模块文件
[root@jumpserver jumpserver]
注释这个模块 后面会手动安装
- 安装python项目的相关模块
pip install -r requirements/requirements.txt
- 手动安装huaweicloud-sdk-python模块
pip3 install huaweicloud-sdk-python
- 修改core配置文件
cp config_example.yml config.yml
[root@jumpserver jumpserver]
4c4
< SECRET_KEY: ******************************
---
> SECRET_KEY:
8c8
< BOOTSTRAP_TOKEN: ********************
---
> BOOTSTRAP_TOKEN:
13d12
< DEBUG: true
18d16
< LOG_LEVEL: DEBUG
25d22
< SESSION_EXPIRE_AT_BROWSER_CLOSE: true
41c38
< DB_PASSWORD: YingjiaN@123
---
> DB_PASSWORD:
完整版配置文件
SECRET_KEY: **************************
BOOTSTRAP_TOKEN: *************
DEBUG: true
LOG_LEVEL: DEBUG
SESSION_EXPIRE_AT_BROWSER_CLOSE: true
DB_ENGINE: mysql
DB_HOST: 127.0.0.1
DB_PORT: 3306
DB_USER: jumpserver
DB_PASSWORD: *****
DB_NAME: jumpserver
HTTP_BIND_HOST: 0.0.0.0
HTTP_LISTEN_PORT: 8080
WS_LISTEN_PORT: 8070
REDIS_HOST: 127.0.0.1
REDIS_PORT: 6379
- 处理国际化
rm -f apps/locale/zh/LC_MESSAGES/django.mo
python apps/manage.py compilemessages
- 启动core
后台运行可以加 -d,./jms start -d
./jms start
启动成功后效果
文章参考:https://www.pythonf.cn/read/100015 部署完core 退出venv环境 继续下面组件部署
部署Lina
- 安装、解压nodejs
wget http://8.210.62.122/jumpserver/node-v12.20.0-linux-x64.tar.xz
tar xf node-v12.20.0-linux-x64.tar.xz -C /usr/local
cd /usr/local
mv node-v12.20.0-linux-x64 node
- 配置nodejs环境变量
[root@jumpserver local]
export NODE_HOME=/usr/local/node
export PATH=$NODE_HOME/bin:$PATH
source /etc/profile.d/node.sh
- 下载Lina
wget http://8.210.62.122/jumpserver/lina-2.15.3.tar.gz
- 解压lina
tar xf lina-2.15.3.tar.gz -C /opt
- 安装依赖
cd /opt/lina-2.15.3
npm config set sass_binary_site https://npm.taobao.org/mirrors/node-sass
npm config set registry https://registry.npm.taobao.org
npm install -g yarn
yarn config set registry https://registry.npm.taobao.org
yarn install
- 修改lina的配置文件
vim .env.development
ENV = 'development'
VUE_APP_BASE_API = ''
VUE_APP_PUBLIC_PATH = '/ui/'
VUE_CLI_BABEL_TRANSPILE_MODULES = true
VUE_APP_LOGIN_PATH = '/core/auth/login/'
VUE_APP_LOGOUT_PATH = '/core/auth/logout/'
VUE_APP_CORE_HOST = 'http://localhost:8080/'
VUE_APP_CORE_WS = 'http://localhost:8070/'
VUE_APP_ENV = 'development'
如果只是调试则使用如下命令运行,运行成功后会显示临时地址和端口号进行访问lina前端
yarn serve
如果是构建lina,使用如下命令进行编译生成lina包,直接和nginx部署
yarn build:prod
mv lina /opt
编译完成后在目录下面会生成lina文件夹,配合jumpserver.conf的lina配置部分进行配置即可,配置如下
server {
listen 80;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 8;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary off;
gzip_static on;
gzip_disable "MSIE [1-6].";
location /ui/ {
try_files $uri / /ui/index.html;
alias /opt/lina/;
}
location / {
rewrite ^/(.*)$ /ui/$1 last;
}
}
部署Luna
- 下载luna
wget http://8.210.62.122/jumpserver/luna-2.15.3.tar.gz
- 解压
tar xf luna-2.15.3.tar.gz -C /opt
- 安装依赖
cd /opt/luna-2.15.3
npm install
npm install --dev
npm rebuild node-sass
- 修改配置文件
cp proxy.conf.json proxy.conf.json.bak
[root@jumpserver luna-2.15.3]
{
"/koko": {
"target": "http://localhost:5000",
"secure": false,
"ws": true
},
"/media/": {
"target": "http://localhost:8080",
"secure": false,
"changeOrigin": true
},
"/api/": {
"target": "http://localhost:8080",
"secure": false,
"changeOrigin": true
},
"/core": {
"target": "http://localhost:8080",
"secure": false,
"changeOrigin": true
},
"/static": {
"target": "http://localhost:8080",
"secure": false,
"changeOrigin": true
},
"/lion": {
"target": "http://localhost:9529",
"secure": false,
"pathRewrite": {
"^/lion/monitor": "/monitor"
},
"ws": true,
"changeOrigin": true
},
"/omnidb": {
"target": "http://localhost:8082",
"secure": false,
"ws": true,
"changeOrigin": true
}
}
同lina一样,如果只是调试运行,运行如下命令:
npm install -g @angular/cli
ng servre
如果是构建luna,则运行如下命令
ng build --prod
缺少这个模块,手动下载
npm install crypto-js
再次构建
ng build --prod
[root@jumpserver luna-2.15.3]
server {
listen 80;
location /luna/ {
try_files $uri / /index.html;
alias /opt/luna/;
}
}
部署Koko
- 安装、解压go
wget http://8.210.62.122/jumpserver/go1.15.linux-amd64.tar.gz
tar -xf go1.15.linux-amd64.tar.gz -C /usr/local/
- 配置go环境变量
[root@jumpserver luna-2.15.3]
export GO_HOME=/usr/local/go
export PATH=$GO_HOME/bin:$PATH
source /etc/profile.d/go.sh
- 下载、解压koko
wget http://8.210.62.122/jumpserver/koko-2.15.3.tar.gz
tar xf koko-2.15.3.tar.gz -C /opt
- 编译
/opt/koko-2.15.3
make
报错执行
go env -w GOPROXY=https://goproxy.cn,direct
重新编译
make clean
make
会在build目录下生成该文件
- 修改koko配置文件
tar xzf koko---linux-amd64.tar.gz
cd koko---linux-amd64
[root@jumpserver koko---linux-amd64]
/opt/koko-2.15.3/build/koko---linux-amd64
cp config_example.yml config.yml
[root@jumpserver koko---linux-amd64]
CORE_HOST: http://127.0.0.1:8080
BOOTSTRAP_TOKEN: ********
BIND_HOST: 0.0.0.0
SSHD_PORT: 2222
HTTPD_PORT: 5000
LOG_LEVEL: DEBUG
- 启动koko
后台运行可以加 -d,./koko -d
./koko
部署Lion
Lion 使用了 Apache 软件基金会的开源项目 Guacamole,JumpServer 使用 Golang 和 Vue 重构了 Guacamole 实现 RDP/VNC 协议跳板机功能。
- 下载、解压guacamole-server
wget http://8.210.62.122/jumpserver/guacamole-server-1.3.0.tar.gz
tar xf guacamole-server-1.3.0.tar.gz -C /opt
- 下载依赖
yum -y localinstall --nogpgcheck https://mirrors.aliyun.com/rpmfusion/free/el/rpmfusion-free-release-7.noarch.rpm
yum install -y cairo-devel libjpeg-turbo-devel libpng-devel libtool uuid-devel
yum install -y ffmpeg-devel freerdp-devel pango-devel libssh2-devel libtelnet-devel libvncserver-devel libwebsockets-devel pulseaudio-libs-devel openssl-devel libvorbis-devel libwebp-devel
- 构建 guacd
./configure --with-init-dir=/etc/init.d
make
make install
ldconfig
如果希望使用 systemd 管理, 可以使用 ./configure --with-systemd-dir=/etc/systemd/system/
./configure --with-systemd-dir=/etc/systemd/system/
make
make install
systemctl daemon-reload
- 下载、解压lion
wget http://8.210.62.122/jumpserver/lion-v2.15.3-linux-amd64.tar.gz
tar xf lion-v2.15.3-linux-amd64.tar.gz -C /opt
- 修改lion配置文件
cd /opt/lion-v2.15.3-linux-amd64
cp config_example.yml config.yml
CORE_HOST: http://127.0.0.1:8080
BOOTSTRAP_TOKEN: ********
BIND_HOST: 0.0.0.0
HTTPD_PORT: 8081
LOG_LEVEL: DEBUG
- 启动Guacd服务
systemctl restart guacd
systemctl enable guacd
- 启动Lion
./lion
放到后台启动
部署Nginx
- 安装nginx
wget http://8.210.62.122/nginx/scripts/install_ngix.sh
bash install_ngix.sh
[root@jumpserver lion-v2.15.3-linux-amd64]
nginx version: nginx/1.20.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --sbin-path=/usr/local/nginx/sbin/nginx --conf-path=/usr/local/nginx/conf/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/nginx.lock --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module --with-http_gzip_static_module --http-client-body-temp-path=/var/tmp/nginx/client/ --http-proxy-temp-path=/var/tmp/nginx/proxy/ --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --http-scgi-temp-path=/var/tmp/nginx/scgi --with-pcre
- 修改nginx.conf配置文件
[root@jumpserver conf]
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /tmp/nginx/nginx.pid;
events {
worker_connections 10240;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /usr/local/nginx/conf/conf.d/*.conf;
- 修改jumpserver.conf配置文件
[root@jumpserver conf]
server {
listen 80;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 8;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary off;
gzip_static on;
gzip_disable "MSIE [1-6].";
client_max_body_size 5000m;
location /luna/ {
try_files $uri / /index.html;
alias /opt/dist/;
}
location /media/replay/ {
add_header Content-Encoding gzip;
root /opt/jumpserver/data/;
}
location /media/ {
root /opt/jumpserver/data/;
}
location /static/ {
root /opt/jumpserver/data/;
}
location /koko/ {
proxy_pass http://localhost:5000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /lion/ {
proxy_pass http://localhost:8081;
proxy_buffering off;
proxy_request_buffering off;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_ignore_client_abort on;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 6000;
}
location /ws/ {
proxy_pass http://localhost:8070;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /api/ {
proxy_pass http://localhost:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /core/ {
proxy_pass http://localhost:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /ui/ {
try_files $uri / /ui/index.html;
alias /opt/lina/;
}
location / {
rewrite ^/(.*)$ /ui/$1 last;
}
}
- nginx 配置检查
[root@jumpserver conf]
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx
由于nginx.cof中pid目录不存在
mkdir /tmp/nginx
- 启动nginx
systemctl restart nginx
文章参考:https://www.jianshu.com/p/5a583c67e8aa 文章参考:https://blog.csdn.net/IT_ZRS/article/details/120587671 文章参考:https://www.jianshu.com/p/5a583c67e8aa 文章参考:https://blog.csdn.net/IT_ZRS/article/details/120587671 文章参考:https://blog.csdn.net/u013896064/article/details/122919250 文章参考:https://www.pythonf.cn/read/100015 文章参考:https://blog.csdn.net/weixin_38623994/article/details/106920048
使用文档待建
|