当前位置: 首页 > news >正文

K8S系列文章之 自动化运维利器 Fabric

Fabric 主要用在应用部署与系统管理等任务的自动化,简单轻量级,提供有丰富的 SSH 扩展接口。在 Fabric 1.x 版本中,它混杂了本地及远程两类功能;但自 Fabric 2.x 版本起,它分离出了独立的 Invoke 库,来处理本地的自动化任务,而 Fabric 则聚焦于远程与网络层面的任务。

为了做到这点,Fabric 主要依赖另一大核心组件 Paramiko,它是基于 SSH 协议的远程控制模块,Fabric 在其基础上封装出了更加友好的接口,可以远程执行 Shell 命令、传输文件、批量操作服务器、身份认证、多种配置与设置代理,等等。

 

一、Fabric 的版本区分

Fabric 自身存在着 2 个大版本:Fabric 1 和 Fabric 2,而在这个库的基础上,还有两个很容易混淆的相关库:Fabric2 和 Fabric3(注意这里的数字是库名的一部分)。

它们的区分如下:

Fabric 1.x:支持 Python 2.5-2.7,但不支持 Python 3
Fabric 2.x:支持 Python 2.7 与 3.4+,但不兼容 Fabric 1.x 的 fabfile
Fabric2:等同于 Fabric 2.x,为了使不同版本共存(装一个 1.x 旧版本,再装它作为新版本)
Fabric3:一个基于 Fabric 1.x 的 fork(非官方),兼容 Python 2&3,兼容 Fabric1.x 的 fabfile
综上可见,我们推荐使用官方的 Fabric 2.x 系列版本,但同时要注意,某些过时的教程可能是基于早期版本的(或非官方的 Fabric3,也是基于 Fabric 1.x),需要注意识别。

例如,在 Fabric 1.x 系列中这么写导入:from fabric.api import run;在新版本中将报错:“ImportError: No module named api”(PS:可根据是否有 fabric.api 来判断 Fabric 的版本,就像在 Python 中根据 print 语句或 print 函数来判断版本一样)。同时,由于新版本不支持老版本的 fabfile,在使用时就可能报错:“No idea what 'xxx' is!”

Fabric 2 是非兼容性版本,相比于前个版本,它主要改进的点有:

支持 Python 2.7 与 3.4+
线程安全,取消了多进程的并发实现
API 围绕 fabric.connection.Connection 进行了重组
全面修改了命令行解析器,允许在每个任务的基础上使用规则的 GNU/POSIX 风格的标志和选项(不再需要 fab mytask:weird = custom,arg = format)
可以声明前置任务与后置任务
……(官方列了​ ​10几条​​ [1],本文不一一罗列)
之前介绍过的 invoke,就是在开发 Fabric 2 时被分离出来的,具体的原因可参见​ ​这个回答​​ [2]。总而言之,在使用 Fabric 时,应该注意版本差异的问题。

二、Fabric 的基本用法

安装PIP

pip是Python包管理工具 可以安装各类软件

yum -y install python-pip
升级PIP

pip install --upgrade pip
检查PIP版本

pip --versionpip 19.3.1 from /usr/lib/python2.7/site-packages/pip (python 2.7)

安装docker compose,自行更改版本号.

pip install -U docker-compose==1.24.1
检查docker compose版本

docker-compose version
 

安装fabric


1、安装
首先是安装:​​pip intall fabric​​ ,安装后,可在命令行窗口查看版本信息:

>>> fab -V
Fabric 2.5.0
Paramiko 2.7.1
Invoke 1.4.0



执行“fab -V”,以上结果可看出我安装的是 Fabric 2.5.0 版本,同时可看到它的两个核心依赖库 Paramiko 及 Invoke 的版本信息。

2、一个简单的例子
Fabric 主要用于远程任务,即要对远程服务器进行操作,下面是一个简单的例子:# 可使用任意的文件名

from fabric import Connectionhost_ip = '47.xx.xx.xx'  # 服务器地址
user_name = 'root' # 服务器用户名
password = '****'  # 服务器密码
cmd = 'date'  # shell 命令,查询服务器上的时间con = Connection(host_ip, user_name, connect_kwargs={'password': password})
result = con.run(cmd, hide=True)print(result)



以上代码,通过账号+密码登录到远程服务器,然后执行​​date​​命令,查看服务器的时间,执行结果:

Command exited with status 0.
=== stdout ===
Fri Feb 14 15:33:05 CST 2020(no stderr)



现在打印的结果中,除了服务器时间,还有一些无关的信息。这是因为它打印的“result”是一个"fabric.runners.Result"类,我们可以把其中的信息解析出来:

print(result.stdout)  # Fri Feb 14 15:33:05 CST 2020
print(result.exited)  # 0
print(result.ok)      # True
print(result.failed)  # False
print(result.command) # date
print(result.connection.host) # 47.xx.xx.xx



上述代码使用了 Connection 类及其 run() 方法,可在连接的服务器上运行 shell 命令。如果需要用管理员权限,则需替换成 sudo() 方法。如果要在本地执行 shell 命令,则需替换成 local() 方法。

除此之外,还有 get()、put() 等方法,详见下文介绍。

3、命令行用法


上例代码可写在任意的 .py 脚本中,然后运行该脚本,或者稍微封装下再导入到其它脚本中使用。

另外,Fabric 还是个命令行工具,可以通过​​fab​​命令来执行任务。我们稍微改造一下上例的代码:# 文件名:fabfile.py

from fabric import Connection
from fabric import taskhost_ip = '47.xx.xx.xx'  # 服务器地址
user_name = 'root' # 服务器用户名
password = '****'  # 服务器密码
cmd = 'date'  # shell 命令,查询服务器上的时间@task
def test(c):"""Get date from remote host."""con = Connection(host_ip, user_name, connect_kwargs={'password': password})result = con.run(cmd, hide=True)print(result.stdout)  # 只打印时间



解释一下,主要的改动点有:

fabfile.py 文件名:入口代码的脚本名必须用这个名字
@task 装饰器:需要从 fabric 中引入这个装饰器,它是对 invoke 的 @task 装饰器的封装,实际用法跟 invoke 一样(注意:它也需要有上下文参数“c”,但实际上它并没有在代码块中使用,而是用了 Connection 类的实例)
然后,在该脚本同级目录的命令行窗口中,可以查看和执行相应的任务:

>>> fab -l
Available tasks:test   Get date from remote host.>>> fab test
Fri Feb 14 16:10:24 CST 2020



fab 是 Invoke 的扩展实现,继承了很多原有功能,所以执行“fab --help”,与之前介绍的“inv --help”相比,你会发现它们的很多参数与解释都是一模一样的。

fab 针对远程服务的场景,添加了几个命令行选项(已标蓝),其中:

--prompt-for-login-password:令程序在命令行中输入 SSH 登录密码(上例在代码中指定了 connect_kwargs.password 参数,若用此选项,可要求在执行时再手工输入密码)
--prompt-for-passphrase:令程序在命令行中输入 SSH 私钥加密文件的路径
-H 或 --hosts:指定要连接的 host 名
-i 或 --identity:指定 SSH 连接所用的私钥文件
-S 或 --ssh-config:指定运行时要加载的 SSH 配置文件
关于 Fabric 的命令行接口,更多内容可查看​ ​文档​​ [3]。

4、交互式操作
远程服务器上若有交互式提示,要求输入密码或“yes”之类的信息,这就要求 Fabric 能够监听并作出回应。

以下是一个简单示例。引入 invoke 的 Responder,初始化内容是一个正则字符串和回应信息,最后赋值给 watchers 参数:

from invoke import Responder
from fabric import Connection
c = Connection('host')
sudopass = Responder(pattern=r'\[sudo\] password:',response='mypassword\n')
c.run('sudo whoami', pty=True, watchers=[sudopass])



5、传输文件
本地与服务器间的文件传输是常见用法。Fabric 在这方面做了很好的封装,Connection 类中有以下两个方法可用:

get(*args, **kwargs):拉取远端文件到本地文件系统或类文件(file-like)对象
put(*args, **kwargs):推送本地文件或类文件对象到远端文件系统
在已建立连接的情况下,示例:

# (略)
con.get('/opt/123.txt', '123.txt')
con.put('test.txt', '/opt/test.txt')

第一个参数指的是要传输的源文件,第二个参数是要传输的目的地,可以指定成文件名或者文件夹(为空或 None 时,使用默认路径):

# (略)
con.get('/opt/123.txt', '')  # 为空时,使用默认路径
con.put('test.txt', '/opt/') # 指定路径 /opt/

get() 方法的默认存储路径是​​os.getcwd​​ ,而 put() 方法的默认存储路径是 home 目录。

6、服务器批量操作
对于服务器集群的批量操作,最简单的实现方法是用 for 循环,然后逐一建立 connection 和执行操作,类似这样:

for host in ('web1', 'web2', 'mac1'):
  result = Connection(host).run('uname -s')

但有时候,这样的方案会存在问题:

如果存在多组不同的服务器集群,需要执行不同操作,那么需要写很多 for 循环
如果想把每组操作的结果聚合起来(例如字典形式,key-主机,value-结果),还得在 for 循环之外添加额外的操作
for 循环是顺序同步执行的,效率太低,而且缺乏异常处理机制(若中间出现异常,会导致跳出后续操作)
对于这些问题,Fabric 提出了 Group 的概念,可将一组主机定义成一个 Group,它的 API 方法跟 Connection 一样,即一个 Group 可简化地视为一个 Connection。

然后,开发者只需要简单地操作这个 Group,最后得到一个结果集即可,减少了自己在异常处理及执行顺序上的工作。

Fabric 提供了一个 fabric.group.Group 基类,并由其派生出两个子类,区别是:

SerialGroup(*hosts, **kwargs):按串行方式执行操作
ThreadingGroup(*hosts, **kwargs):按并发方式执行操作
Group 的类型决定了主机集群的操作方式,我们只需要做出选择即可。然后,它们的执行结果是一个​​fabric.group.GroupResult​​类,它是 dict 的子类,存储了每个主机 connection 及其执行结果的对应关系。

>>> from fabric import SerialGroup
>>> results = SerialGroup('web1', 'web2', 'mac1').run('uname -s')
>>> print(results)
<GroupResult: {<Connection 'web1'>: <CommandResult 'uname -s'>,<Connection 'web2'>: <CommandResult 'uname -s'>,<Connection 'mac1'>: <CommandResult 'uname -s'>,
}>



另外,GroupResult 还提供了 failed 与 succeeded 两个属性,可以取出失败/成功的子集。由此,也可以方便地批量进行二次操作。 ​ ​原文​​

三、Fabric 的进阶用法


1、身份认证
Fabric 使用 SSH 协议来建立远程会话,它是一种相对安全的基于应用层的加密传输协议。

基本来说,它有两种级别的安全认证方式:

基于口令的身份认证:使用账号与密码来登录远程主机,安全性较低,容易受到“中间人”攻击
基于密钥的身份认证:使用密钥对方式(公钥放服务端,私钥放客户端),不会受到“中间人”攻击,但登录耗时较长
前文在举例时,我们用了第一种方式,即通过指定 connect_kwargs.password 参数,使用口令来登录。

Fabric 当然也支持采用第二种方式,有三种方法来指定私钥文件的路径,优先级如下:

优先查找 connect_kwargs.key_filename 参数,找到则用作私钥
其次查找命令行用法的 --identify 选项
最后默认使用操作系统的 ssh_config 文件中的​​IdentityFile​​ 的值
如果私钥文件本身还被加密过,则需要使用 connect_kwargs.passphrase 参数。

2、配置文件
Fabric 支持把一些参数项与业务代码分离,即通过配置文件来管理它们,例如前面提到的密码和私钥文件,可写在配置文件中,避免与代码耦合。

Fabric 基本沿用了 Invoke 的配置文件体系(官方文档中列出了 9 层),同时增加了一些跟 SSH 相关的配置项。支持的文件格式有 .yaml、.yml、.json 与 .py(按此次序排优先级),推荐使用 yaml 格式(后缀可简写成 yml)。

其中,比较常用的配置文件有:

系统级的配置文件:/etc/fabric.yml
用户级的配置文件:~/.fabric.yml(Windows 在 C:\Users\xxx 下)
项目级的配置文件:/myproject/fabric.yml
以上文件的优先级递减,由于我本机是 Windows,为了方便,我在用户目录建一个".fabric.yml"文件,内容如下:

# filename:.fabric.ymluser: root
connect_kwargs:password: xxxx
# 若用密钥,则如下
#  key_filename:
#    - your_key_file



我们把用户名和密码抽离出来了,所以 fabfile 中就可以删掉这些内容:

# 文件名:fabfile.py
from fabric import Connection
from fabric import taskhost_ip = '47.xx.xx.xx'  # 服务器地址
cmd = 'date'  # shell 命令,查询服务器上的时间@task
def test(c):"""Get date from remote host."""con = Connection(host_ip)result = con.run(cmd, hide=True)print(result.stdout)



然后,在命令行中执行:

>>> fab test
Tue Feb 18 10:33:38 CST 2020



配置文件中还可以设置很多参数,详细可查看​ ​文档​​ [4]。

3、网络网关
如果远程服务是网络隔离的,无法直接被访问到(处在不同局域网),这时候需要有网关/代理/隧道,这个中间层的机器通常被称为跳板机或堡垒机。

Fabric 中有两种网关解决方案,对应到 OpenSSH 客户端的两种选项:

ProxyJump:简单,开销少,可嵌套
ProxyCommand:开销大,不可嵌套,更灵活
在创建 Fabric 的 Connection 对象时,可通过指定 gateway 参数来应用这两种方案:

ProxyJump 方式就是在一个 Connection 中嵌套一个 Connection 作为前者的网关,后者使用 SSH 协议的​​direct-tcpip​​ 为前者打开与实际远程主机的连接,而且后者还可以继续嵌套使用自己的网关。

from fabric import Connectionc = Connection('internalhost', gateway=Connection('gatewayhost'))



ProxyCommand 方式是客户端在本地用 ssh 命令(类似“ssh -W %h:%p gatewayhost”),创建一个子进程,该子进程与服务端进行通信,同时它能读取标准输入和输出。

其他参考文档

pip install Fabric # 安装

pip freeze > requirements.txt # 把安装包写入文件中

一个官网例子:

def hello(name='sitin'):print("Hello world %s!" % name)

使用fab执行一下效果如下:

image.png

这里面我们需要知道fab是fabric安装的命令行工具,我们主要是通过它进行操作。

我个人平时用的比较多的命令有:

run 远端执行命令

local 本地执行命令

cd 远端切换目录

lcd 本地切换

@task 装饰器声明函数为fab task

简单的脚本我觉得是已经够用了,复杂一点需要更多操作了,详情见后文。

部署步骤

通常情况下,作为一个Python工程师我们发布代码需要做的事儿常见的有以下几点:

  1. git pull 拉取最新代码,比如master分支(或者develop分支)
  2. tar 打包最新代码
  3. rsync增量同步到远端服务器,去掉一些不需要的本地目录
  4. 备份数据库或者备份代码
  5. supervisor指定重启远端一个或多个服务,通过交互式指令判断
  6. sentry查看日志正常与否

除了最后一步,这里面所有的操作我们都在fabfile.py就进行操作了,一般情况下fabfile.py放在项目根目录,当然你放在其他地方也没有什么问题。通过-f进行指定就行。

概要讲了,下面请参看我们的一个实战例子

一个例子

from fabric.api import (with_settings,hosts,cd,  # 远端lcd, # 本地切换目录run, # 执行env,
)
EST_ENV = '127.0.0.1'
TEST_USER = 'test'
env.forward_agent = True# 允许本地 SSH 代理连接远程终端时跳转
@hosts(TEST_ENV) # 指定远程操作的机器地址
@with_settings(user=TEST_USER) # 用来临时设定 env 变量,可以等同于 with settings
def deploy_test():# 发布测试环境local('git pull --rebase upsgream dev') # local执行本地命令拉取代码到本地,这个可以用CI自动发布,就不用拉取到本地。local('rsync -r . --exclude=tmp/ --exclude=backup/ sitin@yourip:/data/your_project') # 上传代码with cd('/data/your_project'): # 表示所有操作在这个目录下面run('docker-compose pull test')  # test镜像名backup_db() # 这里其实就是一个普通备份函数run('docker-compose stop test') # 执行远端命令同local相反run('docker-compose rm -f test')run('docker-compose run --rm test python manage.py migrate') # db同步run('docker-compose up -d test')

在终端执行命令

fab deploy_test # 就能进行发布了测试环境了

fab deploy_product # 如果有就能发布了

通常情况下测试,开发,服务器与线上操作不太一样,我们可以通过上面方式进行操作。除了上面的操作之后,如果我们测试线上完全一直或者多台服务器,可以通过指定不同角色来进行选择服务器的发布。

env.roledefs = { 'test': ['test@yourip'],  # 指定多台机器 'dev': ['dev@yourip'],   'prod': ['opt@yourip2'],}def deploy(branch=master): pass

fab -R test(上面定义的角色) deploy -f fabfile.py

deploy这里还可以指定发布哪个分支的代码

这样指定某一个角色的服务器,某一个分支进行发布非常简单方便,对于经常使用的复杂命令操作我们还可以作为缩写命令来进行操作。

 

相关文章:

K8S系列文章之 自动化运维利器 Fabric

Fabric 主要用在应用部署与系统管理等任务的自动化&#xff0c;简单轻量级&#xff0c;提供有丰富的 SSH 扩展接口。在 Fabric 1.x 版本中&#xff0c;它混杂了本地及远程两类功能&#xff1b;但自 Fabric 2.x 版本起&#xff0c;它分离出了独立的 Invoke 库&#xff0c;来处理…...

flask--->CBV/模板/请求响应/session

CBV 1 cbv写法-1 写个类&#xff0c;继承MethodView-2 在类中写跟请求方式同名的方法-3 注册路由&#xff1a;app.add_url_rule(/home, view_funcHome.as_view(home)) #home是endpoint&#xff0c;就是路由别名2 cbv加装饰器-方式一&#xff1a;class Home(MethodView):decor…...

Go语言基础:运算符、文件操作、接口、Packages、if else、for循环

文章目录 1.运算符2.文件操作3.接口4.Packages5.If else6.For循环 1.运算符 func main() {// 算术运算符a, b : 3, 7c : a bd : a - be : a * bf : a / bg : a % baa--fmt.Println(c, d, e, f, g)// 关系运算符fmt.Println(a b)fmt.Println(a ! b)fmt.Println(a < b)fmt.…...

2308C++学习简单协程文档

调试 用gdb/lldb p __coro_frame p __promise试 Try有三种状态:无状态,有异常,有值. 条件变量 主要区别在简单异步中条件变量面向Lazy协程.在条件变量上阻塞协程时,不会阻塞当前线程.用于多个协程间交互协作.基于协程版条件变量,多个协程可实现典型生产者消费者模型. 通知…...

C++笔记之从数组指针到函数数组指针(使用using name和std::function)

C笔记之从数组指针到函数数组指针(使用using name和std::function) 参考笔记&#xff1a; C之指针探究(三)&#xff1a;指针数组和数组指针 C之指针探究(十三)&#xff1a;函数指针数组 C之指针探究(二)&#xff1a;一级指针和一维数组 C之指针探究(十一)&#xff1a;函数名的…...

【数据结构】常见的排序算法

常见的排序算法 常见的排序算法插入排序之直接插入排序时间复杂度特性总结 插入排序之希尔排序时间复杂度 选择排序之直接选择排序特性总结 选择排序之堆排序时间复杂度特性总结 交换排序之冒泡排序特性总结 交换排序之快速排序hoare版本挖坑法双指针法快速排序的优化1&#xf…...

CentOS 安装 Jenkins

本文目录 1. 安装 JDK2. 获取 Jenkins 安装包3. 将安装包上传到服务器4. 修改 Jenkins 配置5. 启动 Jenkins6. 打开浏览器访问7. 获取并输入 admin 账户密码8. 跳过插件安装9. 添加管理员账户 1. 安装 JDK Jenkins 需要依赖 JDK&#xff0c;所以先安装 JDK1.8。输入以下命令&a…...

前端如何设置表格边框样式和单元格间距?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 实现思路⭐ 代码演示⭐ 注意事项⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对Web开发感兴…...

Ubuntu 22.04安装搜狗输入法

Ubuntu 22.04安装搜狗输入法 ubtuntu 22.04安装搜狗输入法 1. 添加中文语言支持2. 安装fcitx输入法框架3. 设置fcitx为系统输入法4. 设置fcitx开机启动&#xff0c;并卸载ibus输入法框架5. 安装搜狗输入法6. 重启电脑&#xff0c;调出搜狗输入法 1. 添加中文语言支持 Setti…...

【C++】初阶 --- 内联函数(inline)

文章目录 &#x1f95e;内联函数&#x1f35f;1、C语言实现"宏函数"&#x1f35f;2、内联函数的概念&#x1f35f;3、内联函数的特性&#x1f35f;4、总结 &#x1f95e;内联函数 &#x1f35f;1、C语言实现"宏函数" &#x1f970;用C语言先来实现普通的…...

VGGNet剪枝实战:使用VGGNet训练、稀疏训练、剪枝、微调等,剪枝出只有3M的模型

摘要 本文讲解如何实现VGGNet的剪枝操作。剪枝的原理&#xff1a;在BN层网络中加入稀疏因子&#xff0c;训练使得BN层稀疏化&#xff0c;对稀疏训练的后的模型中所有BN层权重进行统计排序&#xff0c;获取指定保留BN层数量即取得排序后权重阈值thres。遍历模型中的BN层权重&am…...

【iOS】GCD深入学习

关于GCD和队列的简单介绍请看&#xff1a;【iOS】GCD学习 本篇主要介绍GCD中的方法。 栅栏方法:dispatch_barrier_async 我们有时候需要异步执行两组操作&#xff0c;而且第一组操作执行完之后&#xff0c;才能开始执行第二组操作&#xff0c;当然操作组里也可以包含一个或者…...

Webpack开启本地服务器;HMR热模块替换;devServer配置;开发与生成环境的区分与配置

目录 1_开启本地服务器1.1_开启本地服务器原因1.2_webpack-dev-server 2_HMR热模块替换2.1_认识2.2_开启HMR2.3_框架的HMR 3_devServer配置3.1_host配置3.2_port、open、compress 4_开发与生成环境4.1_如何区分开发环境4.2_入口文件解析4.3_区分开发和生成环境配置 1_开启本地服…...

opencv 31-图像平滑处理-方框滤波cv2.boxFilter()

方框滤波&#xff08;Box Filtering&#xff09;是一种简单的图像平滑处理方法&#xff0c;它主要用于去除图像中的噪声和减少细节&#xff0c;同时保持图像的整体亮度分布。 方框滤波的原理很简单&#xff1a;对于图像中的每个像素&#xff0c;将其周围的一个固定大小的邻域内…...

Kubernetes关于cpu资源分配的设计

kubernetes资源 在K8s中定义Pod中运行容器有两个维度的限制: 资源需求(Requests):即运行Pod的节点必须满足运行Pod的最基本需求才能运行Pod。如 Pod运行至少需要2G内存,1核CPU。(软限制)资源限额(Limits):即运行Pod期间,可能内存使用量会增加,那最多能使用多少内存,这…...

Flink读取mysql数据库(java)

代码如下: package com.weilanaoli.ruge.vlink.flink;import com.ververica.cdc.connectors.mysql.source.MySqlSource; import com.ververica.cdc.connectors.mysql.table.StartupOptions; import com.ververica.cdc.debezium.JsonDebeziumDeserializationSchema; import org…...

小程序学习(五):WXSS模板语法

1.什么是WXSS WXSS是一套样式语言,用于美化WXML的组件样式,类似于网页开发中的CSS 2.WXSS和CSS的关系 WXSS模板样式-rpx 3.什么是rpx尺寸单位 4.rpx的实现原理 5.rpx与px之间的单位换算* WXSS模板样式-样式导入 6.什么是样式导入 使用WXSS提供的import语法,可以导入外联的样式…...

注解 @JsonFormat 与 @DateTimeFormat 的使用

文章目录 JsonFormat (双端互传)DateTimeFormat &#xff08;前端传后端日期格式转化&#xff09;情况一 前端是时间组件 <el-date-picker 或其他情况二 前端未设置组件 JsonFormat (双端互传) com.fasterxml.jackson.annotation.JsonFormat; 将字符串的时间转换成Date类型…...

Python实现决策树算法:完整源码逐行解析

决策树是一种常用的机器学习算法&#xff0c;它可以用来解决分类和回归问题。决策树的优点是易于理解和解释&#xff0c;可以处理数值和类别数据&#xff0c;可以处理缺失值和异常值&#xff0c;可以进行特征选择和剪枝等操作。决策树的缺点是容易过拟合&#xff0c;对噪声和不…...

Linux文本三剑客---grep、sed、awk

目录标题 1、grep1.1 命令格式1.2命令功能1.3命令参数1.4grep实战演练 2、sed2.1 认识sed2.2命令格式2.3常用选项options2.4地址定界2.5 编辑命令command2.6用法演示2.6.1常用选项options演示2.6.2地址界定演示2.6.3编辑命令command演示 3、awk3.1认识awk3.2常用命令选项3.3awk…...

局域网VoIP网络电话测试

0. 环境 ubuntu18或者ubuntu22 - SIP服务器 win10 - SIP客户端1 ubuntu18 - SIP客户端2 1. SIP服务器搭建asterisk 1.0 环境 虚拟机ubuntu18 或者ubuntu22 1.1 直接安装 sudo apt-get install asterisk 1.2 配置用户信息 分为两个部分&#xff0c;第一部分是修改genera…...

el-table 去掉边框(修改颜色)

原始&#xff1a; 去掉表格的border属性&#xff0c;每一行下面还会有一条线&#xff0c;并且不能再拖拽表头 为了满足在隐藏表格边框的情况下还能拖动表头&#xff0c;修改相关css即可&#xff0c;如下代码 <style lang"less"> .table {//避免单元格之间出现白…...

redis与MongoDB的区别

1.Redis与MongoDB的概念 1.1 MongoDB MongoDB 是由C语言编写的&#xff0c;是一个基于分布式文件存储的开源数据库系统。 在高负载的情况下&#xff0c;添加更多的节点&#xff0c;可以保证服务器性能。 MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。 MongoDB …...

CSS设置高度

要设置 article.content 的恰当高度&#xff0c;您可以使用 CSS 来控制元素的外观。有几种方法可以设置元素的高度&#xff0c;具体取决于你的需求和布局。 以下是几种常见的方法&#xff1a; 1. 固定高度&#xff1a;你可以直接为 article.content 设置一个固定的高度值&…...

开源免费用|Apache Doris 2.0 推出跨集群数据复制功能

随着企业业务的发展&#xff0c;系统架构趋于复杂、数据规模不断增大&#xff0c;数据分布存储在不同的地域、数据中心或云平台上的现象越发普遍&#xff0c;如何保证数据的可靠性和在线服务的连续性成为人们关注的重点。在此基础上&#xff0c;跨集群复制&#xff08;Cross-Cl…...

【docker】docker-compose服务编排

目录 一、服务编排概念二、docker compose2.1 定义2.2 使用步骤2.3 docker-compose安装2.4 docker-compose卸载 三、编排示例 一、服务编排概念 1.微服务架构的应用系统中一般包含若干个微服务&#xff0c;每个微服务一般都会部署多个实例&#xff0c;如果每个微服务都要手动启…...

EdgeBox_tx1_A200 PyTorch v1.9.0 环境部署

大家好&#xff0c;我是虎哥&#xff0c;今天远程帮助几个小伙伴在A200 控制器上安装PyTorch v1.9.0 torchvision v0.10.0&#xff0c;中间也是经历了很多波折&#xff0c;当然&#xff0c;大部分是网络问题和版本适配问题&#xff0c;所以完事后&#xff0c;将自己完整可用的过…...

【雕爷学编程】MicroPython动手做(33)——物联网之天气预报

天气&#xff08;自然现象&#xff09; 是指某一个地区距离地表较近的大气层在短时间内的具体状态。而天气现象则是指发生在大气中的各种自然现象&#xff0c;即某瞬时内大气中各种气象要素&#xff08;如气温、气压、湿度、风、云、雾、雨、闪、雪、霜、雷、雹、霾等&#xff…...

分库分表之基于Shardingjdbc+docker+mysql主从架构实现读写分离 (三)

本篇主要说明&#xff1a; 1. 因为这个mysql版本是8.0&#xff0c;所以当其中一台mysql节点挂掉之后&#xff0c;主从同步&#xff0c;甚至双向数据同步都失效了&#xff0c;所以本篇主要记录下当其中的节点挂掉之后如何再次生效。另外推荐大家使用mysql5.7的版本&#xff0c;这…...

探秘企业DevOps一体化平台建设终极形态丨IDCF

笔者从事为企业提供研发效能改进解决方案相关工作十几年&#xff0c;为国内上百家企业提供过DevOps咨询及解决方案落地解决方案&#xff0c;涉及行业包括&#xff1a;金融、通信、制造、互联网、快销等多种行业。 DevOps的核心是研发效能改进&#xff0c;效能的提升离不开强大…...