一、简介 一个 Rust 编写的现代化包管理器 —— uv，它比 pip 快 10 倍以上，还原生支持虚拟环境、锁文件、缓存优化等功能。 uv 是由 Astral 开发的 Python 包管理工具，目标是替代： pip（安装依赖） virtualenv/venv（创建虚拟环境） pip-tools（生成 requirements.txt） 二、安装 2.1、方法一：使用 PowerShell 一键安装（推荐） 步骤： 打开 PowerShell 可以在“开始菜单”中搜索 PowerShell 右键 → 以管理员身份运行（推荐） 执行以下命令安装 uv： powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/uv/releases/download/0.7.12/uv-installer.ps1 | iex" 这个脚本将自动完成以下操作： 下载预构建的 uv 可执行文件。 放入用户目录下（如：C:\Users\你的用户名\.cargo\bin）。 尝试自动添加环境变量。 验证是否安装成功： 关闭并重新打开命令行，输入： uv --version 2.2、方法二：手动下载安装包 访问下载地址：uv 0.7.12 Releases 找到你的平台对应版本，Windows 64 位一般下载这个：uv-x86_64-pc-windows-msvc.zip 解压后会得到一个 uv.exe 文件。 将 uv.exe 放入某个路径，并把该路径加入系统环境变量 Path，例如放入： 三、使用 创建虚拟环境并安装依赖，速度飞快： # 创建虚拟环境 uv venv # 启动虚拟环境 .\.venv\Scripts\activate # 安装 requests uv pip install requests
一、概述 1.1、概述 LangChain4J 即 LangChain For Java。 随着人工智能（AI）技术的迅猛发展，越来越多的开发者开始将目光投向AI应用的开发。然而，目前市场上大多数AI框架和工具如LangChain、PyTorch等主要支持Python，而Java开发者常常面临工具缺乏和学习门槛较高的问题。 LangChain4J 官方文档 1.2、作用 LLM 大模型应用技术架构： 大模型开发分类：超级个体+智能体、行业垂直大模型、基础通用大模型。 产品定位： 二、起步 2.1、前置约定 2.1.1、langchain4j 执行的各种大语言模型(LLMS) Comparison Table of all supported Language Models 2.1.2、模型约定 2.1.3、配置及关键点 所有调用均基于 OpenAI 协议标准或者 SrpingBoot 官方推荐整合规则，实现一致的接口设计与规范，确保多模型切换的便利性，提供高度可扩展的开发支持。 2.2、入门 2.2.1、接入按理百炼平台的通义模型 https://bailian.console.aliyun.com 2.2.2、大模型调用 1、获得 API-key 2、获得模型名 3、获得 baseUrl 开发地址
一、简介 Ansible 是一个 IT 自动化工具，他能配置系统，部署软件，编排更复杂的 IT 任务，如连续部署或零停机时间滚动更新。 Ansible 用 Python 编写，Ansible 允许不需要在每个节点上安装自己的组件，可以在不止一个地方控制整个基础架构。 二、工作原理 Inventory：被管理节点的列表，资源池。 PlayBook：类似于 Shell 脚本，通过一系列命令执行自动化操作。 Module。 在 Ansible 管理体系中，存在 管理节点 和 被管理节点 两种角色。 被管理节点通常被成为资产。 在管理节点上，Ansible 将 AdHoc 或 PlayBook 转换为 python 脚本，并通过 SSH 传输到被管理节点上。 在被管理节点上依次执行 Python 脚本。 三、Ansible 安装 3.1、先决条件 3.2、安装 Ansible yum 方式： [root@localhost ~]# yum install epel-release [root@localhost ~]# yum install ansible pip 方式： [root@localhost ~]# yum install epel-release [root@localhost ~]# yum install python2-pip [root@localhost ~]# pip install ansible 查看 Ansible 版本： [root@localhost ~]# ansible --version ansible 2.9.27 config file = /etc/ansible/ansible.cfg configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules'] ansible python module location = /usr/lib/python2.7/site-packages/ansible executable location = /usr/bin/ansible python version = 2.7.5 (default, Oct 14 2020, 14:45:30) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] 四、Ansible 简单部署 4.1、管理节点与被管理节点建立 SSH 信任关系 管理节点 (ansible) 中创建密钥对： [root@localhost ~]# ssh-keygen -t rsa 将本地的公钥传输到被管理节点： [root@localhost .ssh]# ssh-copy-id root@192.168.200.135 [root@localhost .ssh]# ssh-copy-id root@192.168.200.136 4.2、场景 4.2.1、检测所有被管理主机在线状态 [root@manager ~]# ansible all -i 192.168.19.135,192.168.19.136 -m ping 192.168.19.135 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } 192.168.19.136 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } -i : 参数后面是一个列表 (List) , 因此当为一个被管理节点时，我们后面一定要加一个英文逗号 (,) , 告知是 List。 4.2.2、确保 /tmp/a.conf 发布到所有被管理节点上 [root@manager ~]# touch /tmp/a.conf [root@manager ~]# ansible all -i 192.168.19.135,192.168.19.136 -m copy -a "src=/tmp/a.conf dest=/tmp/a.conf" 192.168.19.136 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", "dest": "/tmp/a.conf", "gid": 0, "group": "root", "md5sum": "d41d8cd98f00b204e9800998ecf8427e", "mode": "0644", "owner": "root", "secontext": "unconfined_u:object_r:admin_home_t:s0", "size": 0, "src": "/root/.ansible/tmp/ansible-tmp-1702535672.46-6415-225212235428808/source", "state": "file", "uid": 0 } 192.168.19.135 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", "dest": "/tmp/a.conf", "gid": 0, "group": "root", "md5sum": "d41d8cd98f00b204e9800998ecf8427e", "mode": "0644", "owner": "root", "secontext": "unconfined_u:object_r:admin_home_t:s0", "size": 0, "src": "/root/.ansible/tmp/ansible-tmp-1702535672.44-6413-170350629067151/source", "state": "file", "uid": 0 } all: 在 Ansible 中，叫做 pattern , 即匹配，用来在 -i 参数的资产中匹配一部分，all 代表匹配所有 -i: 指定 Ansible 的资产，即被管理主机 (也可以是文件名) -m: 指定要运行的模板，比如这里的 ping 模块 和 copy 模块 -a: 指定模块的参数，这里 ping 模块没有指定参数，copy 模块指定了 src 和 dest 参数 五、Ansible 资产 实际场景中，被管理的服务器肯定不止 2 台，因此我们可以将被管理服务器写入一个文件或脚本中。 5.1、静态资产 顾名思义，静态资产本身是一个文本文件，一个类似 INI 的文件 默认情况下，Ansible 的资产文件 位于 /etc/ansible/hosts.pip 安装的可能没有这个文件，创建一个即可。 示例： # This is the default ansible 'hosts' file. # # It should live in /etc/ansible/hosts # # - Comments begin with the '#' character # - Blank lines are ignored # - Groups of hosts are delimited by [header] elements # - You can enter hostnames or ip addresses # - A hostname/ip can be a member of multiple groups `Ex 1: 不属于任何组的单独主机，必须放在所有主机组的前面，也就是必须位于文件最前方 green.example.com blue.example.com 192.168.100.1 192.168.100.10 `Ex 2: 主机组 webservers 包含 4 个主机，调用时可以通过组名匹配主机 [webservers] alpha.example.org beta.example.org 192.168.1.100 192.168.1.110 ` 有规律的主机可以使用这总方法显示，这代表 www001.example.com , www002.example.com , ... www [001:006].example.com `Ex 3: 主机组可以在 组和主机中间添加空格以便阅读 [dbservers] db01.intranet.mydomain.net db02.intranet.mydomain.net 10.25.1.56 10.25.1.57 # Here's another example of host ranges, this time there are no # leading 0s: ## db-[99:101]-node.example.com 5.1.1、自定义资产 vim /etc/ansible/inventory.ini # 没有组名的属于 all 组 1.1.1.1 2.2.2.2 3.3.3.[1:15] test01.lml.com test03.lml.com test [05:09].lml.com [web_servers] 192.168.1.2 192.168.1.3 192.168.1.5 [db_servers] 192.168.2.2 192.168.2.3 192.168.2.5 192.168.1.5 # 创建 all_server 组，并将 db_servers 和 web_servers 添加为自己的子组 # 选择 all_server 组时，则代表选中了 web_servers 和 db_servers 组下的所有主机 [all_servers] [all_servers:children] db_servers web_servers 1、Ansible 的资产文件中，可以以 IP 地址的形式或者主机名的形式存在。 2、Ansible 的资产若连续，可以使用 [start:end] 的形式去表达。 3、可以将服务器按照业务场景定义成组，比如 db_servers 和 web_servers。 4、组合组之间可以存在继承关系，比如 db_servers 和 web_servers 同时继承 all_servers 组。 5.1.2、如何使用自定义资产 通过 -i 参数指定自定义资产的位置即可 (可以是全路径，也可以是相对路径)。 # ansible all -i inventory.ini .........// 伪命令，不可执行 5.1.3、验证自定义资产 列举出所有资产： ansible all -i inventory.ini --list-hosts hosts (19) : 1.1.1.1 2.2.2.2 3.3.3.1 ...... 列举出选定资产 (比如 db_servers)： ansible db_servers -i inventory.ini --list-hosts 5.2、资产选择器 5.2.1、基本语法格式 ansible PATTERN -i inventory -m moudle -a argument PATTERN：可以是 IP 列表，也可以是组名，值得注意的是，资产中写的什么就要写什么，不能通过域名解析 -i：资产列表，从哪里进行筛选 -m：使用哪一个模块 -a：模块所对应的参数 1、选择一台或几台服务器 [root@localhost ansible]# ansible 1.1.1.1 -i inventory.ini --list-host hosts (1): 1.1.1.1 [root@localhost ansible]# ansible test01.lml.com -i inventory.ini --list-host hosts (1): test01.lml.com [root@localhost ansible]# ansible 1.1.1.1,2.2.2.2 -i inventory.ini --list-host hosts (2): 1.1.1.1 2.2.2.2 2、选择一组服务器 [root@localhost ~]# ansible all_servers -i inventory.ini --list-host hosts (6): 192.168.2.2 192.168.2.3 192.168.2.5 192.168.1.2 192.168.1.3 192.168.1.5 # 两个子组的重复部分会被去重 3、使用 * 匹配 [root@localhost ansible]# ansible 3.3.3.1* -i inventory.ini --list-host hosts (7): 3.3.3.10 3.3.3.11 3.3.3.12 3.3.3.13 3.3.3.14 3.3.3.15 3.3.3.1 4、使用逻辑进行匹配 1）并集 (两个组中所有主机，去重) # 显示两个组中所有的主机 [root@localhost ansible]# ansible 'web_servers:db_servers' -i inventory.ini --list-host hosts (6): 192.168.1.2 192.168.1.3 192.168.1.5 192.168.2.2 192.168.2.3 192.168.2.5 2）交集 (两个组中共有主机) # 显示同时承担 web_server 和 db_server 的主机 [root@localhost ansible]# ansible 'web_servers:&db_servers' -i inventory.ini --list-host hosts (1): 192.168.1.5 3）差集 (A 有 B 没有，或 B 有 A 没有) # 在 web_servers 中，但是不在 db_servers 中 [root@localhost ansible]# ansible 'web_servers:!db_servers' -i inventory.ini --list-host hosts (2): 192.168.1.2 192.168.1.3 # 在 db_servers 中，但是不再 web_servers 中 [root@localhost ansible]# ansible 'db_servers:!web_servers' -i inventory.ini --list-host hosts (3): 192.168.2.2 192.168.2.3 192.168.2.5 六、Ansible Ad-Hoc Command Ad-hoc 命令是一个概念性的名字，是相对于 Ansible playbook 来说的，类似于在命令行敲入 shell 和写 shell scripts 两者之间的关系，可以用于执行一些临时命令。 如果我们敲入一些命令去比较快的完成一些事情，而不需要将这些执行的命令特别保存下载，这样的命令就叫做 ad-hoc 命令。 Ansible 提供两种方式去完成任务，一是 ad-hoc , 一是写 Ansible playbook, 前者可以解决一些简单的任务，后者解决较复杂的任务，比如做配置管理或部署。 6.1、命令格式 命令格式语法如下 : ansible pattern [-i inventory] -m moudule -a argument pattern: 资产选择器 -i: 指定资产清单文件的位置。 -m: 指定本次 Ansible ad-hoc 要执行的模块，可以类别成 shell 中的命令。 -a: 模块的参数，可以类比成 SHELL 中的命令参数。 6.3、联机帮助 Ansible 的核心模块和附加模块，数量有 1000+ , 很难一次性掌握，因此我们可以使用 Ansible 的帮助文档，它本身提供的命令就是由 Ansible-doc 实现 列出所有的核心模块和附加模块： ansible-doc -l 查询某个模块的使用方法： ansible-doc modulename 6.4、常用模块 为方便演示，我们使用如下配置文件： 管理机 : 192.168.200.132 被管理机 1 : 192.168.200.133 被管理机 2 : 192.168.200.134 编写如下配置文件到 /etc/ansible/hosts： [dbservers] 192.168.200.133 [webservers] 192.168.200.134 6.4.1、command & shell 模块 两个模块都是在远程服务器上执行命令 command 模块：是 ad-hoc 的默认模块，在执行 ad-hoc 时，若不指定模块的名字则默认使用此模块 [root@localhost ansible]# ansible all -i hosts -a "echo 'hello world'" 192.168.200.133 | CHANGED | rc=0 >> hello world 192.168.200.134 | CHANGED | rc=0 >> hello world [root@localhost ansible]# ansible all -i hosts -m shell -a "echo 'hello world'" 192.168.200.133 | CHANGED | rc=0 >> hello world 192.168.200.134 | CHANGED | rc=0 >> hello world command 模块 和 shell 模块的差异： shell 模块：可以执行 SHELL 的内置命令和特性 (比如管道符)。 command 模块：无法执行 SHELL 的内置命令和特性。 实例： [root@localhost ansible]# ansible all -i hosts -m shell -a "echo 'hello' | grep -o 'e'" 192.168.200.133 | CHANGED | rc=0 >> e 192.168.200.134 | CHANGED | rc=0 >> e [root@localhost ansible]# ansible all -i hosts -m command -a "echo 'hello' | grep -o 'e'" 192.168.200.133 | CHANGED | rc=0 >> hello | grep -o e 192.168.200.134 | CHANGED | rc=0 >> hello | grep -o e 6.4.2、script 模块 将管理节点上的脚本传到被管理节点 (远程服务器) 上进行执行，理论上此模块的执行完全不需要被管理服务器上有 Python。 示例： [root@localhost ansible]# echo "touch /tmp/testfile" > /root/a.sh [root@localhost ansible]# ansible webservers -i hosts -m script -a "/root/a.sh" 192.168.200.134 | CHANGED => { "changed": true, "rc": 0, "stderr": "Shared connection to 192.168.200.134 closed.\r\n", "stderr_lines": [ "Shared connection to 192.168.200.134 closed." ], "stdout": "", "stdout_lines": [] } [root@localhost ansible]# ansible webservers -i hosts -m shell -a "ls -l /tmp" 192.168.200.134 | CHANGED | rc=0 >> -rw-r--r-- 1 root root 0 Dec 18 21:23 testfile 6.4.5、yum 模块 等同于 Linux 上的 yum 命令，对远程服务器上 RPM 包进行管理，常用参数如下： name 要安装的软件包名，多个软件包以 ( , ) 隔开。 state 对当前指定的软件安装，移除操作 (present installed latest absent removed)。 present 确认已经安装，但不升级。 installed 确认已经安装。 latest 确保安装，且升级为最新。 absent 和 removed 确认已删除。 6.4.5.1、安装一个软件包 [root@localhost ansible]# ansible webservers -i hosts -m yum -a "name=nginx state=present" [root@localhost ansible]# ansible webservers -i hosts -m yum -a "name=nginx state=installed" [root@localhost ansible]# ansible webservers -i hosts -m yum -a "name=nginx state=latest" # 检查是否安装 [root@manager ~]# ansible webservers -i /etc/ansible/hosts -m shell -a "nginx -version" 192.168.200.134 | CHANGED | rc=0 >> nginx version: nginx/1.20.1 6.4.5.2、移除一个软件包 [root@manager ~]# ansible webservers -i /etc/ansible/hosts -m yum -a "name=nginx state=absent" [root@manager ~]# ansible webservers -i /etc/ansible/hosts -m yum -a "name=nginx state=removed" [root@manager ~]# ansible webservers -i /etc/ansible/hosts -m shell -a "nginx -version" 192.168.200.134 | FAILED | rc=127 >> /bin/sh: nginx: command not foundnon-zero return code 6.4.5.3、安装一个软件包组 [root@manager ~]# ansible all -i /etc/ansible/hosts -m yum -a "name='@Developmenttools' state=present" 6.4.6、systemd 模块 CentOS6 之前的版本使用 service 模块，使用 ansible-doc service 命令查看帮助信息。 管理远程节点上的 systemd 服务，就是由 systemd 所管理的服务，常用参数如下 daemon_reload：重新载入 systemd , 扫描新的或有变动的单元，值为 yes。 enabled：是否开机自启动 yes | no。 name：必选项，服务名称，比如 httpd , vsftpd 等。 state：对当前服务执行启动，停止，重新加载等操作 (started , stopped , restarted , reloaded)。 6.4.6.1、Example : 重新加载 systemd [root@localhost ~]# ansible webservers -i /etc/ansible/hosts -m systemd -a "daemon_reload=yes" 192.168.200.134 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "name": null, "status": {} } 6.4.6.2、Example : 启动 nginx [root@localhost ~]# ansible webservers -i /etc/ansible/hosts -m systemd -a "name=nginx state=started" 6.4.6.3、Example : 关闭 nginx [root@localhost ~]# ansible webservers -i /etc/ansible/hosts -m systemd -a "name=nginx state=stopped" 6.4.7、group 模块 对被管理节点的组进行管理，常用参数如下： name：组名称，必须的。 system：是否为系统组，yes | no。 6.4.7.1、Example : 创建普通组 db_admin [root@localhost ~]# ansible all -i /etc/ansible/hosts -m group -a "name=db_admin" 192.168.200.133 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "gid": 1001, "name": "db_admin", "state": "present", "system": false } 6.4.8、user 模块 用于对被管理节点上的用户进行管理，常用参数如下 : name：必须的参数，指定用户名。 password：设置用户的密码，这里接受的是一个加密的值，因为会直接存到 shadow , 默认不设置密码。 update_password：加入设置的密码不同于原密码，则会更新密码，在 1.3 版本中被加入。 home：指定用户的家目录。 shell：设置用户的 shell。 comment：用户的描述信息。 create_home：在创建用户时，是否创建其家目录，默认创建，加入不创建，设置为 no , 在 2.5 版本之前使用 createhome 参数。 group：设置用户的主组。 groups：将用户加入到多个其他组中，多个用逗号隔开，默认会把用户从其他已经加入的组中删除。 append：值为 yes | no , 和 groups 配合使用，值为 yes 时，不会把用户从其他已经加入的组中删除。 system：值为 yes 时，会创建一个系统账户。 expires：设置用户的过期时间，值为时间戳，会转为天数后，放在 shadow 的第 8 个字段里。 generate_ssh_key：设置为 yes 时，会为用户生成密钥，这不会覆盖原来的密钥。 ssh_key_type：指定用户的密钥类型，默认 rsa , 具体的类型取决于被管理节点。 state：删除或添加用户，yes 为添加，absent 为删除，默认值为 yes。 remove 当与 state=absent 一起使用时，删除一个用户及关联的目录，比如家目录，邮箱目录，可选的值为 yes/no。 先生成加密密码： [root@localhost ~]# pass=$(echo “LML123456” | openssl passwd -l -stdin) [root@localhost ~]# echo $pass 111MQBJpWBh$krH/eQgBQcMpyDMKxVpS.0 6.4.8.1、Example : 创建账号，设置密码 [root@localhost ~]# ansible all -i /etc/ansible/hosts -m user -a "name=foo password=${pass}" 6.4.8.2、Example : 创建账号，设置密码，改密钥类型 [root@localhost ~]# ansible all -i /etc/ansible/hosts -m user -a "name=Dragon password=${pass} ssh_key_type=ecdsa" 6.4.8.3 Example : 创建账号，设置密码，有效期，加组 创建 Cai 用户，并设置其有效期到 2024_4_15 日，加入到 db_admin 组中。 [root@localhost ~]# ansible all -i /etc/ansible/hosts -m user -a "name=Cai password=${pass} group=db_admin append=yes" 6.4.9、file 模块 file 模块主要用于远程主机上的文件操作，常用参数： group：定义文件 / 目录的属组。 mode：定义文件 / 目录的而权限。 owner：定义文件 / 目录属组。 path：必选项，操作文件 / 目录 的路径。 recurse：递归的设置文件的属性，只对目录有效。 src：要被链接 (软/硬) 的源文件的路径，值用于 state=link 的情况。 dest：被链接到的路径，只应用于 state=link 的情况。 state：对文件执行什么操作。 directory：如果目录不存在则创建目录。 file：文件不存在则不不会被创建，存在则返回文件的信息，常用于检查文件是否存在。 link：创建软连接。 hard：创建硬链接。 touch：如果文件不存在，则会创建一个新的文件，如果文件或目录存在，则更新其最后修改时间。 absent：删除目录，文件或者取消链接。 6.4.9.1、Example : 文件操作 # 创建一个文件 [root@localhost ~]# ansible all -i /etc/ansible/hosts -m file -a "path=/tmp/foo.conf state=touch" # 改变文件所有者及权限 [root@localhost ~]# ansible all -i /etc/ansible/hosts -m file -a "path=/tmp/foo.conf owner=nobody group=nobody mode=0644" # 创建一个软连接 [root@localhost ~]# ansible all -i /etc/ansible/hosts -m file -a "src=/tmp/foo.conf dest=/tmp/link.conf state=link" # 创建一个目录 [root@localhost ~]# ansible all -i /etc/ansible/hosts -m file -a "path=/tmp/test_dir state=directory" # 取消一个链接 [root@localhost ~]# ansible all -i /etc/ansible/hosts -m file -a "path=/tmp/link.conf state=absent" # 删除一个文件 [root@localhost ~]# ansible all -i /etc/ansible/hosts -m file -a "path=/tmp/foo.conf state=absent" 6.4.10、cron 模块 管理远程节点的 CRON 服务，等同于 Linux 中的计划任务，常用参数如下。 注意：使用 Ansible 创建的计划任务，是不能使用本地 crontab -e 去编辑，否则 Ansible 无法再次操作此计划任务。 name：指定一个 cron job 的名字，一定要指定，便于日后删除。 minute：指定分钟，可以设置成 (0-59 , * , /2 等) 格式，默认是 * , 也就是每分钟。 hour：指定小时，可以设置达成 (0-23 , * , */2 等) 格式，默认是 * , 也就是每小时。 day：指定天，可以设置成 (1-31 , * , */2 等) 格式，默认是 * , 也就是每天。 month：指定月份，可以设置成 (1-12 , * , */2 等) 格式，默认是 * , 也就是每周。 weekday：指定星期，可以设置成 (0-6 for Sunday-Saturday , * 等) 格式，默认是 * , 也就是每天。 job：要执行的内容，通常可以写个脚本，或者一段内容。 state：指定这个 job 的状态，可以是新增 (present) , 或者是删除 (absent) , 默认为 (present)。 6.4.10.1、Example 1 : 创建一个 cron job 任务 [root@manager ~]# ansible all -i /etc/ansible/hosts -m cron -a "name=newJob minute='0' job='ls -alh > /dev/null'" 验证 [root@host1 ~]# crontab -l #Ansible: newJob 0 * * * * ls -alh > /dev/null 6.4.10.2、Example 2 : 删除一个 cron job 任务 [root@manager ~]# ansible all -i /etc/ansible/hosts -m cron -a "name=newJob state=absent" 6.4.11、debug 模块 6.4.11.1、Example 1 : 打印变量 debug 模块主要用于调试时使用，通常的作用是将一个变量的值打印出来，常用参数如下： var：直接打印一个指定的变量值。 msg：打印一段可以格式化的字符串。 # 直接打印一个变量 (-e 是传入变量) [root@manager ~]# ansible all -i /etc/ansible/hosts -m debug -a "var=role" -e "role=web" # 打印带字符串的 变量 [root@manager ~]# ansible all -i /etc/ansible/hosts -m debug -a "msg='role is {{role}}'" -e "role=web" 6.4.12、template 模块 template 模块使用了 jinjia2 格式作文文件模板，可以进行文档内变量的替换。 它的每次使用都会被 ansible 标记为 “changed” 状态，文件以 .j2 结尾，常用参数如下： src：指定 Ansible 控制端的文件路径。 dest：指定 Ansible 被控制端的文件路径。 owner：指定文件的属主。 group：指定文件的属组。 mode：指定文件的权限。 backup：创建一个包含时间错信息的备份文件，这样如果以某种方式损坏了原始文件，就可以将其复原，yes/no。 6.4.12.1、Example 1 : 传递文件 (带变量) # 1. 创建一个 hello_world.j2 文件 [root@manager ~]# cat hello_world.j2 Hello {{var}} ! # 2. 执行命令，并且设置变量 var 的值为 world [root@manager ~]# ansible all -i /etc/ansible/hosts -m template -a "src=hello_world.j2 dest=/tmp/hello_world.world" -e "var=world" # 3. 在被控主机上验证 Hello world ! 6.4.13、lineinfile 模块 在被管理节点上，使用正则匹配的方式对目标文件的一行内容修改删除等操作。 如果是一个文件中把所有匹配到的多行进行统一处理，参考 replace 模块。 如果相对一个文件进行一次性 添加 / 更新 / 删除等多行内容操作，参考 blockinfile 模块。 常用参数如下： path：目标文件路径，必须的。 state：可选值 present 替换 (默认 | absent 删除。 regexp：在文件的每一行中查找的正则表达式，对于 state=present , 进找到的最后一行将被替代。 line：要在文件中插入/替换的行，需要 state=present。 create：文件不存在时，是否要创建文件并添加内容，yes/no。 6.4.13.1、Example 1 : 删除被控节点文件里的某一条内容 [root@manager ~]# ansible all -i /etc/ansible/hosts -m lineinfile -a "path=/etc/sudoers regexp='^% wheel' state=absent" 6.4.13.2、Example 1 : 关闭远程主机的 selinux [root@manager ~]# ansible all -i /etc/ansible/hosts -m lineinfile -a "path=/etc/selinux/config regexp='^SELINUX=' line='SELINUX=disabled' state=present" 七、Ansible-Playbook Ad-Hoc 的问题：AD-HOC 每次只能在被管理节点上执行简单的命令。 而日常工作中，我们往往面临的是一系列复杂的操作，例如我们可能需要安装软件，更新配置，重启服务等等一系列操作的组合，此时 Ad-Hoc 有些力不从心，使用 PLAYBOOK 可以帮助我们解决这个问题。 7.1、什么是 PalyBook Playbook 通常被大家翻译成剧本。 可以认为它是 Ansible 自定义的一门语言 (可以将 Playbook 比作 Linux 中的 shell) , 而 Ansible 中的 Module 可以比作为 Linux 中的各种命令。 7.2、YAML 学习 安装 pip 对 yaml 文件格式进行检查。 yum install python2-pip 7.2.1、YAML 特点 # YAML 文件以 # 为注释 # YAML 文件以 .yml 或 .yaml 结尾 # YAML 文件以 --- 开始，以... 结束，但是开始和结束标志都是可选的 7.2.2、基本语法 大小写敏感。 使用缩进表示层级关系，一般规范 2 个空格。 缩进时使用 tab 键，还是空格 一定要达到统一，建议使用空格。 相同层级的元素必须左侧对齐。 YAML 支持的数据结构有三种： 字符串 列表 字典 7.2.2.5、校验 YAML 语句 将 YAML 文件，通过 Python 的 YAML 模块进行验证： # 安装 python2-pip [root@manager ~]# yum install python2-pip # 安装 pyyaml [root@manager ~]# pip install pyyaml # cat test.yaml --- - red - green - blue ... # 对 YAML 格式文件进行检验 [root@manager ~]# python -c 'import yaml,sys; print yaml.load (sys.stdin)' < test.yaml ['red', 'green', 'blue'] 7.3、定义一个 Playbook 一个 Playbook 是由一个或多个 Play 构成，那么一个含有多个 Play 的 Playbook 结构上应该是如下的样子： --- - key1: value1 key2: value2 key3: value3 ... 一个含有多个 Play 的 Playbook 结构山应该是如下的样子： --- # 一个含有 3 个 Play 的伪 PlayBook 构成 - key1: value1 key2: value2 key3: value3 - key4: value1 key5: value2 key6: value3 - key1: value1 key2: value2 key3: value3 ... 7.3.1、Play 的属性 Play 中的每一个 key , 比如 key1 , key2 等，这些 key 在 PlayBook 中被定义为 Play 的属性。 这些属性具有特殊意义，我们不能随意的自定义 Play 的属性，常用属性如下： name：每个 play 的名字，用于任务执行后的回显 (一定要写)。 hosts：每个 play 涉及的被管理服务器，通 ad hoc 中的 pattern。 tasks：每个 play 中具体要完成的任务，以列表的形式表达。 become：如果需要提权，则加上 become 相关属性。 become_user：若提权的话，提权到哪个用户上。 remote_user：指定连接用户，若不指定，则默认使用当前执行 ansible Playbook 的用户。 等等 7.3.2、一个完整的剧本 最常规写法： --- - name: the first play example hosts: all remote_user: root tasks: - name: install nginx packet yum: name=nginx state=present - name: copy nginx.conf to remote server copy: src=nginx.conf dest=/etc/nginx/nginx.conf - name: start nginx service service: name=nginx enabled=true state=started ... tasks 属性中任务的多种写法： # 以启动 nginx 服务，并增加开机启动为例 # 一行的形式 service: name=nginx enabled=true state-started # 多行的形式 service: name=nginx enabled=true state=started # 多行字典的形式 service: name: nginx enabled: true state: started 7.3.3、具有多个 Play 的 Playbook --- - name: manage web servers hosts: webservers remote_user: root tasks: - name: install nginx packet yum: name=nginx state=present - name: copy nginx.conf to remote server copy: src=nginx.conf dest=/etc/nginx/nginx.conf - name: start nginx server service: name=nginx enabled=true state=started - name: manager db servers hosts: dbservers tasks: - name: update database config copy: src=my.cnf dest=/etc/my.cnf ... 7.4、校验一个 PlayBook 下面校验的方法，只能校验 PlayBook 是否正确，而不能校验 YAML 文件是否语法正确。 之前 YAML 校验的方法： [root@manager ~]# python -c 'import yaml,sys; print yaml.load (sys.stdin)' < test.yaml PlayBook 校验： [root@manager ~]# ansible-playbook myplaybook.yml --syntax-check playbook: myplaybook.yml 7.5、运行一个 PlayBook [root@manager ~]# ansible-playbook myplaybook.yml 7.6、如何单步跟从调试 PlayBook ansible-playbook myplaybook.yml --step 7.7、如何测试运行 PlayBook // 会执行完整个 PlayBook , 但是所有 Task 中的行为都不会在远程服务器上执行，所有执行都是模拟行为 # ansible-playbook myplaybook.yml -C //-C 为大写字母 C 八、Ansible 变量 8.1、Ansible 变量介绍 变量由 字母 数字 下划线 组成。 但 只能以字母开头，保留关键字不能作为变量名称。 8.2、变量类型 根据变量的作用范围，大体的将变量分为： 全局变量 剧本变量 资产变量 但这只是一个比较除粗糙的划分，不能囊括 Ansible 中的所有变量，下面将分别从这三种变量入手，去介绍变量的使用。 8.2.1、全局变量 全局变量 是 我们使用 ansible 或者使用 ansible-playbook 时，手动通过 -e 参数传递给 Ansible 的变量。 通过 ansible 或 ansible-playbook 的 help 帮助，可以获取具体格式使用方式。 普通的 key-value 模式： [root@manager ~]# ansible webservers -i /etc/ansible/hosts -m debug -a "msg='name is {{key}}'" -e "key='LiuMenglong'" 192.168.200.133 | SUCCESS => { "msg": "name is LiuMenglong" } 传递一个 YAML/JSON 的形式 (他们的最终形式必须是字典)： # 指定时必须加 @ [root@manager ~]# cat a.json {"name": "LiuML", "age": "16"} [root@manager ~]# ansible webservers -i /etc/ansible/hosts -m debug -a "msg='name is {{name}} , age is {{age}}'" -e @a.json [WARNING]: Found variable using reserved name: name 192.168.200.133 | SUCCESS => { "msg": "name is LiuML , age is 16" } [root@manager ~]# cat b.yaml --- name: lisi age: 33 ... [root@manager ~]# ansible webservers -i /etc/ansible/hosts -m debug -a "msg='name is {{name}} , age is {{age}}'" -e @b.yaml [WARNING]: Found variable using reserved name: name 192.168.200.133 | SUCCESS => { "msg": "name is lisi , age is 33" } 8.2.2、剧本变量 在 Playbook 中使用的变量叫做剧本变量，他的定义由多种方式，我们使用两种，文件内定义即引用文件。 8.2.2.1、通过 PLAY 属性 vars 定义 --- - name: test play vars hosts: all vars: user: lisi home: /home/lisi ... 8.2.2.2、通过 PLAY 属性 vars_file 定义 --- - name: test play vars hosts: all vars_files: - vars/users.yaml ... cat vars/users/yaml --- user: lilei home: /home/lilei ... 8.2.2.3、如何在 Playbook 中使用这些变量 在 PlayBook 中使用变量时，使用 {{ 变量名 }} 来使用变量，在使用变量是，大部分情况外侧要加双引号即 “{{ 变量 }}”。 Example1: --- - name: Test Vars using in playbook hosts: all vars: user: lisi home: /home/lisi tasks: - name: create the users {{user}} user: name={{user}} home={{home}} ... [root@manager ~]# ansible-playbook 123456.yaml -C [root@manager ~]# ansible-playbook 123456.yaml 注意事项：在下面的例子 (字典) 中，{{ 变量 }} 外一定要加双引号，否则会 yaml 解析错误 Example2 --- - name: Test Vars using in playbook hosts: all vars: user: lisi home: /home/lisi tasks: - name: create the users {{user}} user: name: "{{user}}" home: "{{home}}" ... 8.2.3、资产变量 资产变量是和资产紧密相关的一种变量，资产变量分为 主机变量 和 主机组变量，分别针对单个主机和一组主机。 8.2.3.1、主机变量 # cat hostsandhostvars [webservers] 192.168.200.133 user=lisi age=18 192.168.200.134 验证： [root@localhost ansible]# ansible webservers -i /etc/ansible/hostsandhostvars -m debug -a "var=user" 192.168.200.133 | SUCCESS => { "user": "lisi" } 192.168.200.134 | SUCCESS => { "user": "VARIABLE IS NOT DEFINED!" } 8.2.3.2、主机组变量 主机变量优先于主机组变量。 # cat hostsandhostvars [webservers] 192.168.200.133 user=lisi age=18 192.168.200.134 [webservers:vars] user=tom 验证： [root@localhost ansible]# ansible webservers -i /etc/ansible/hostsandhostvars -m debug -a "var=user" 192.168.200.133 | SUCCESS => { "user": "lisi" } 192.168.200.134 | SUCCESS => { "user": "tom" } 8.2.3.3、变量的继承 变量是可以继承的： # cat host_v3 [dbservers] 192.168.200.133 [webservers] 192.168.200.134 [allserver] [allserver:children] webservers dbservers [allserver:vars] user=lml 验证： [root@localhost ansible]# ansible webservers -i /etc/ansible/host_v3 -m debug -a "var=user" 192.168.200.134 | SUCCESS => { "user": "lml" } 参考： Ansible 超详细教程 w3cschoo Ansible Ansible 中文权威指南
一、下载 Python 安装包 官方下载地址：https://www.python.org/downloads/ Windows 用户：安装时一定要勾选 Add Python to PATH（否则后面会报错“python 不是命令”）。 务必勾选： Add Python 3.x to PATH Install launcher for all users（推荐） 验证安装： python --version pip--version 二、安装插件 在IDEA plugins 中搜索 Python. 三、更换 pip 默认源 3.1、使用命令行临时更换 运行以下命令来临时更换源： pip install -i https://pypi.tuna.tsinghua.edu.cn/simple some-package 3.2、配置永久更换 打开用户目录下的pip配置文件（如果文件不存在，则新建一个）。文件路径通常为： Windows: %APPDATA%\pip\pip.ini 例如： C:\Users\YourUsername\AppData\Roaming\pip\pip.ini Linux/macOS: ~/.pip/pip.conf 在文件中添加或修改以下内容来设置默认源： [global] index-url = https://pypi.tuna.tsinghua.edu.cn/simple 同样，可以将其替换为其他镜像地址。 保存文件并关闭。下次使用pip时，它将自动使用你设置的镜像源。 常用的国内镜像源： 阿里云 http://mirrors.aliyun.com/pypi/simple/ 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/ 豆瓣(备用) http://pypi.douban.com/simple/ 清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/ 华中理工大学 http://pypi.hustunique.com/ 3.3、查看 Python 的包管理工具 pip 默认源 使用命令行： pip config list 如果使用的是 pip 版本 10.0.0 或更高版本，可以使用： pip config list --only-sources 这将列出所有配置的源，包括默认源。
一、按键布局 二、相机基础设置 2.1、相机过热关机 2.2、触摸跟踪对焦 2.3、拍摄提示音 2.4、ISO Auto 最大值 夜晚拍摄噪点多但是比较亮。 2.5、快门、光圈、ISO 光圈优先：决定你的背景虚化效果。F 值越小，背景越虚化。 夜晚的时候更大的光圈噪点也会更小，画面也会更纯净。 快门优先：影响你的运动模糊。 快门调整到帧率的两倍，会有一种电影感的模糊效果。 2.6、选择合适的对焦方式 对焦模式：单次AF，对焦区域：广域。大部分时候机器可以自动对焦。 对焦模式： 自动对焦 / 手动对焦 对焦区域： 相机往画面的哪一区域对焦。 2.7、4K or 1080P 2.8、记录设置 选择帧数 & 码率。P 帧数，M 码率。码率越大，体积越大，画质越好。帧数越大，需要更多的光线，画面也就越流畅。 2.9、设置防抖 2.10、使用延时与慢动作 延迟拍摄： 如果想拍摄 120 帧的慢动作： 将相机的P制转换成N制。 但是N制在灯光下容易出现频闪。可以切换成P制，或者把快门调整为1/50或者1/100，可以一定程度上改善。 2.11、如何提升拍摄效率 1）设置自定义按键 2）切换拍摄方案 设置好拍摄的配置，拍摄设置存储： 3）调出配置
一、VSCode 插件 shellman：提供智能提示和自动补全功能。 shellcheck：提供语法检查的功能。 shell-format：提供代码格式化功能，快捷键：Alt+Shift+f。 Code Runner：提供代码运行功能。 Linux 上脚本首行要声明 bash 解释器，Windows 上也一样。不过，路径要更改为安装 Git 的路径，例如: E:\SOFTWARE\Git\bin/bash。 #!E:\SOFTWARE\Git\bin\bash # basic for command for test in Alabama Alaska Arizona do echo The next state is $test done 二、VSCode 实现 Shell 脚本调试 2.1、Windows 配置 SSH 2.1.1、通过「设置」安装 1、使用 Windows + I 快捷键打开「设置」，依次选择「系统」>「可选功能」。 2、点击「查看功能」，在搜索框中输入 OpenSSH 进行筛选。 3、根据需要勾选： OpenSSH 客户端：可以使用 ssh 命令连接到其他支持 SSH 的设备。 OpenSSH 服务器：允许其他设备通过 SSH 连接到你的电脑。 4、选择好后点击「下一步」，然后点击「安装」开始安装过程。 2.1.2、使用 PowerShell 安装 1、使用 Windows + R 快捷键打开「运行」对话框，输入 powershell，然后按 Ctrl + Shift + Enter 以管理员权限打开 PowerShell 窗口。 2、执行以下命令查看 OpenSSH 安装状态： 3、根据需要安装 OpenSSH 客户端和服务器组件： # 安装 OpenSSH 客户端 Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0 # 安装 OpenSSH 服务器 Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 2.1.3、在 Windows 中配置 OpenSSH 服务器 1、当你在 Windows 上安装了 OpenSSH 服务器之后，需要进行一些配置才能接受连接： 2、使用 Windows + R 快捷键打开「运行」对话框，输入 powershell，然后按 Ctrl + Shift + Enter 以管理员权限打开 PowerShell。 Set-Service -Name sshd -StartupType 'Automatic' 3、设置 SSHD 服务自动启动： Start-Service sshd 4、检查 SSH 服务器是否在侦听 22 端口： netstat -an | findstr /i ":22" 5、确保 Windows Defender 防火墙允许 TCP 22 端口的入站连接： Get-NetFirewallRule -Name *OpenSSH-Server* | select Name, DisplayName, Description, Enabled 如规则丢失或被禁用，可以创建新规则： New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 6、可选）如果要修改配置，如设置用户访问权限，可以编辑 sshd_config 配置文件： Start-Process Notepad C:\Programdata\ssh\sshd_config 7、根据需要修改配置文件，保存后关闭记事本。 8、完成更改后，重启 SSHD 服务应用配置： Restart-Service sshd 按照这些步骤，你的 Windows 就能通过 SSH 协议接受连接了。 2.2、使用 VSCode 远程连接 linux 服务 安装 VSCode 插件：Remote - SSH & Bash Debug。 输入：ssh root@192.168.10.102 进行连接。 Remote - SSH 连接后生成 .config： Host 192.168.10.102 HostName 192.168.10.102 User root Bash Debug 配置 launch.json： { // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "type": "bashdb", "request": "launch", "name": "Bash-Debug (type in script name)", "cwd": "${workspaceFolder}", "program": "${command:AskForScriptName}", "args": [] }, { "type": "bashdb", "request": "launch", "name": "Bash-Debug (select script from list of sh files)", "cwd": "${workspaceFolder}", "program": "${command:SelectScriptName}", "args": [] }, { "type": "bashdb", "request": "launch", "name": "Bash-Debug (hardcoded script name)", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/path/to/script.sh", "args": [] }, { "type": "bashdb", "request": "launch", "name": "Bash-Debug (simplest configuration)", "program": "${file}" } ] } 参考： 【OpenSSH】Windows 上的 OpenSSH：安装、配置和使用指南 在 Windows 下用 VScode 构造 shell 脚本的 IDE 使用 vscode 实现 shell 脚本调试
一、Ventoy Ventoy 是免费开源制作的工具，体积只有十几 M，纯净免安装，制作速度超快，支持 UEFI 启动和 Legacy 启动。U 盘可以同时存放多个系统镜像文件。 下载地址：https://github.com/ventoy/Ventoy/releases 二、重装系统 解压 ventoy-1.1.05-windows.zip 执行 Ventoy2Disk.exe。 注意：安装 Ventoy，U 盘会被格式化，请拿一个没有用过或者先把 U 盘中的数据拷贝出来。 制作 U 盘启动盘。 系统镜像下载：MSDN我告诉你 Windows 10 1909 64位 安装版 电脑启动快捷键：
一、PHP Cursor 配置 1、安装 PHP 扩展 PHP Intelephense PHP Debug PHP DocBlocker PHP Extension Pack PHP Server 2、配置 PHP 路径 { "window.commandCenter": 1, "java.configuration.maven.userSettings": "F:\\Maven\\apache-maven-3.5.2\\conf\\settings.xml", "maven.excludedFolders": [ "**/.*", "**/node_modules", "**/target", "**/bin", "**/archetype-resources" ], "pythonIndent.keepHangingBracketOnLine": true, "pythonIndent.trimLinesWithOnlyWhitespace": true, "pythonIndent.useTabOnHangingIndent": true, "git.ignoreMissingGitWarning": true, "php.validate.executablePath": "F:\\Development\\PHP\\php-7.4.29-Win32-vc15-x64\\php.exe" } 3、配置 PHP 调试 在项目根目录创建 .vscode/launch.json 文件： { "version": "0.2.0", "configurations": [ { "name": "Listen for Xdebug", "type": "php", "request": "launch", "port": 9003, "pathMappings": { "/var/www/html": "${workspaceFolder}" } } ] } 4、配置 PHP 代码格式化 在设置中配置 PHP 格式化工具 推荐使用 PHP-CS-Fixer 或 Prettier 5、配置 PHP 代码检查 在设置中启用 PHP 代码检查 可以配置 PHP_CodeSniffer 或 PHPStan 6、配置 PHP 自动完成 确保 PHP Intelephense 扩展已启用 在设置中配置自动完成选项 7、配置 PHP 文档生成 安装 PHP DocBlocker 扩展 配置文档注释模板 8、配置 PHP 测试 安装 PHPUnit 扩展 配置测试运行器 9、配置 PHP 项目结构 创建标准的 PHP 项目结构： project/ ├── src/ │ └── YourNamespace/ ├── tests/ ├── vendor/ ├── composer.json └── .gitignore 10、配置 Composer 安装 Composer 在项目根目录创建 composer.json： { "name": "your-vendor/your-project", "description": "Your project description", "type": "project", "require": { "php": ">=7.4" }, "autoload": { "psr-4": { "YourNamespace\\": "src/" } } } 11、配置 PHP 错误报告 在 php.ini 中设置： error_reporting = E_ALL display_errors = On display_startup_errors = On log_errors = On error_log = "C:\php\logs\php_error.log" 12、配置 PHP 性能优化 在 php.ini 中设置： opcache.enable=1 opcache.memory_consumption=128 opcache.interned_strings_buffer=8 opcache.max_accelerated_files=4000 opcache.revalidate_freq=60 opcache.fast_shutdown=1 13、配置 PHP 安全设置 在 php.ini 中设置： expose_php = Off session.cookie_httponly = 1 session.cookie_secure = 1 14、配置 PHP 开发工具 安装 Xdebug 用于调试 配置 Xdebug 设置： [xdebug] zend_extension=xdebug xdebug.mode=debug xdebug.start_with_request=yes xdebug.client_port=9003 15、配置 PHP 代码质量工具 安装 PHP_CodeSniffer 配置编码标准。
一、下载 & 安装 下载 PHP： https://windows.php.net/download/ 下载 Apache 服务器 https://www.apachelounge.com/download/ 解压后： 只用到 Apache24 文件夹，将它拷贝到你的自定义目录，并修改配置。 如：D:\Apache24，用文本编辑器打开 Apache24\conf\httpd.conf 配置文件。 二、运行 方法一：运行 Apache24\bin\httpd.exe，会弹出一个窗口，关闭窗口则关闭服务。 方法二：使用 cmd 命令运行 Apache24\bin\httpd.exe（一定要是 cmd） 方法三：将 Apache 服务安装到本机，运行 Apache24\bin\ApacheMonitor.exe 控制打开 / 关闭服务。 使用 cmd 命令在 Apache24\bin 目录下执行：httpd.exe -k install。 运行 Apache24\bin\ApacheMonitor.exe。 双击任务栏右下角的图标，在弹出的窗口点击 Start/Stop 控制打开 / 关闭服务 将项目放置到 Apache24\htdocs 目录下，在浏览器输入 localhost / 项目名 / 访问，如：http://localhost/web-mobile/。
一、Prometheus 相关概念 1.1、内部存储机制 Prometheus 有着非常高效的时间序列数据存储方法，每个采样数据仅仅占用 3.5byte 左右空间，上百万条时间序列，30 秒间隔，保留 60 天，大概花了 200 多 G（引用官方 PPT）。 Prometheus 内部主要分为三大块： Retrieval 是负责定时去暴露的目标页面上去抓取采样指标数据。 Storage 是负责将采样数据写磁盘。 PromQL 是 Prometheus 提供的查询语言模块。 1.2、数据模型 Prometheus 存储的所有数据都是时间序列数据（Time Serie Data，简称时序数据）。时序数据是具有时间戳的数据流，该数据流属于某个度量指标（Metric）和该度量指标下的多个标签（Label）。 每个 Metric name 代表了一类的指标，他们可以携带不同的 Labels，每个 Metric name + Label 组合成代表了一条时间序列的数据。 在 Prometheus 的世界里面，所有的数值都是 64bit 的。每条时间序列里面记录的其实就是 64bit timestamp (时间戳) + 64bit value (采样值)。 Metric name（指标名称）：该名字应该具有语义，一般用于表示 metric 的功能，例如：http_requests_total, 表示 http 请求的总数。其中，metric 名字由 ASCII 字符，数字，下划线，以及冒号组成，且必须满足正则表达式 [a-zA-Z_:][a-zA-Z0-9_:]*。 Lables（标签）：使同一个时间序列有了不同维度的识别。例如 http_requests_total {method=“Get”} 表示所有 http 请求中的 Get 请求。当 method=“post” 时，则为新的一个 metric。标签中的键由 ASCII 字符，数字，以及下划线组成，且必须满足正则表达式 [a-zA-Z_:][a-zA-Z0-9_:]*。 timestamp (时间戳)：数据点的时间，表示数据记录的时间。 Sample Value（采样值）：实际的时间序列，每个序列包括一个 float64 的值和一个毫秒级的时间戳。 例如图上的数据： http_requests_total {status="200",method="GET"} http_requests_total {status="404",method="GET"} 根据上面的分析，时间序列的存储似乎可以设计成 key-value 存储的方式（基于 BigTable）。 进一步拆分，可以像下面这样子： 上图的第二条样式就是现在 Prometheus 内部的表现形式了，__name__ 是特定的 label 标签，代表了 metric name。 再回顾一下 Prometheus 的整体流程： 上面提到了 K-V 存储，当然是使用了 LevelDB 的引擎，它的特点是顺序读写性能非常高，这是非常符合时间序列的存储的。 1.3、Metric 类型 Prometheus 定义了 4 种不同的指标类型 (metric type)：Counter（计数器）、Gauge（仪表盘）、Histogram（直方图）、Summary（摘要）。 1.3.1、Counter（计数器） 一种累加的 metric，典型的应用如：请求的个数，结束的任务数， 出现的错误数等等。 【例如】查询 http_requests_total {method=“get”, job=“Prometheus”, handler=“query”} 返回 8，10 秒后，再次查询，则返回 14。 1.3.2、Gauge（仪表盘） 数据是一个瞬时值，如果当前内存用量，它随着时间变化忽高忽低。 【例如】go_goroutines {instance=“172.17.0.2”, job=“Prometheus”} 返回值 147，10 秒后返回 124。 1.3.3、Histogram（直方图） Histogram 取样观测的结果（一般是请求持续时间或响应大小）并在一个可配置的分布区间（bucket）内计算这些结果。其也提供所有观测结果的总和。 Histogram 有一个基本 metric 名称 ，在一次抓取中展现多个时间序列： 累加的 counter，代表观测区间：_bucket {le=“”} 所有观测值的总数：_sum 观测到的事件数量：_count 例如 Prometheus server 中 prometheus_local_storage_series_chunks_persisted, 表示 Prometheus 中每个时序需要存储的 chunks 数量，我们可以用它计算待持久化的数据的分位数。 1.3.4、Summary（摘要） 和 histogram 相似，summary 取样观测的结果（一般是请求持续时间或响应大小）。但是它还提供观测的次数和所有值的总和，它通过一个滑动的时间窗口计算可配置的分位数。 Summary 有一个基本的 metric 名称 ，在一次抓取中展现多个时间序列： 观测事件的流式 φ- 分位数（0 ≤ φ ≤ 1）：{quantile=“φ”} 所有观测值的总和：_sum 观测的事件数量：_count 例如 Prometheus server 中 prometheus_target_interval_length_seconds。 1.4、Histogram 和 Summary 的对比 以下是类型为 histogram 和 summary 的样本输出示例： # A histogram, which has a pretty complex representation in the text format: # HELP http_request_duration_seconds A histogram of the request duration. # TYPE http_request_duration_seconds histogram http_request_duration_seconds_bucket {le="0.05"} 24054 http_request_duration_seconds_bucket {le="0.1"} 33444 http_request_duration_seconds_bucket {le="0.2"} 100392 http_request_duration_seconds_bucket {le="+Inf"} 144320 http_request_duration_seconds_sum 53423 http_request_duration_seconds_count 144320 # Finally a summary, which has a complex representation, too: # HELP rpc_duration_seconds A summary of the RPC duration in seconds. # TYPE rpc_duration_seconds summary rpc_duration_seconds {quantile="0.01"} 3102 rpc_duration_seconds {quantile="0.05"} 3272 rpc_duration_seconds {quantile="0.5"} 4773 rpc_duration_seconds_sum 1.7560473e+07 rpc_duration_seconds_count 2693 1.5、任务（JOBS）与实例（INSTANCES） 用 Prometheus 术语来说，可以抓取的端点称为 instance，通常对应于单个进程。 具有相同目的的 instances 的集合（例如，出于可伸缩性或可靠性而复制的过程）称为 job。 例如，一个具有四个复制实例的 API 服务器作业: job: api-server instance 1: 1.2.3.4:5670 instance 2: 1.2.3.4:5671 instance 3: 5.6.7.8:5670 instance 4: 5.6.7.8:5671 instance: 一个单独 scrape 的目标， 一般对应于一个进程。: jobs: 一组同种类型的 instances（主要用于保证可扩展性和可靠性） 1.6、Node exporter Node exporter 主要用于暴露 metrics 给 Prometheus，其中 metrics 包括：cpu 的负载，内存的使用情况，网络等。 1.7、Pushgateway Pushgateway 是 Prometheus 生态中一个重要工具，使用它的原因主要是： Prometheus 采用 pull 模式，可能由于不在一个子网或者防火墙原因，导致 Prometheus 无法直接拉取各个 target 数据。 在监控业务数据的时候，需要将不同数据汇总，由 Prometheus 统一收集。 由于以上原因，不得不使用 pushgateway，但在使用之前，有必要了解一下它的一些弊端： 将多个节点数据汇总到 pushgateway, 如果 pushgateway 挂了，受影响比多个 target 大。 Prometheus 拉取状态 up 只针对 pushgateway, 无法做到对每个节点有效。 Pushgateway 可以持久化推送给它的所有监控数据。因此，即使你的监控已经下线，prometheus 还会拉取到旧的监控数据，需要手动清理 pushgateway 不要的数据。 二、Exporter 介绍 Exporter 是 prometheus 监控中重要的组成部分，负责数据指标的采集。广义上讲所有可以向 Prometheus 提供监控样本数据的程序都可以被称为一个 Exporter。而 Exporter 的一个实例称为 target。官方给出的插件有 blackbox_exporter、node_exporter、mysqld_exporter、snmp_exporter 等，第三方的插件有 redis_exporter，cadvisor 等。 官方和一些社区提供好多 exproter, 我们可以直接拿过来采集我们的数据。 官方的 exporter 地址：https://prometheus.io/docs/instrumenting/exporters/ 2.1、常见的 Exporter 简介 1、blackbox_exporter GitHub 地址：https://github.com/prometheus/blackbox_exporter bloackbox exporter 是 prometheus 社区提供的黑盒监控解决方案，运行用户通过 HTTP、HTTPS、DNS、TCP 以及 ICMP 的方式对网络进行探测。这里通过 blackbox 对我们的站点信息进行采集。 2、node_exporter GitHub 地址：https://github.com/prometheus/node_exporter node_exporter 主要用来采集机器的性能指标数据，包括 cpu，内存，磁盘，io 等基本信息。 3、mysqld_exporter GitHub 地址：https://github.com/prometheus/mysqld_exporter mysql_exporter 是用来收集 MysQL 或者 Mariadb 数据库相关指标的，mysql_exporter 需要连接到数据库并有相关权限。 4、snmp_exporter GitHub 地址：https://github.com/prometheus/snmp_exporter SNMP Exporter 从 SNMP 服务中采集信息提供给 Promethers 监控系统使用。 2.2、Exporter 的来源 从 Exporter 的来源上来讲，主要分为两类： 1、社区提供 Prometheus 社区提供了丰富的 Exporter 实现，涵盖了从基础设施，中间件以及网络等各个方面的监控功能。这些 Exporter 可以实现大部分通用的监控需求。下表列举一些社区中常用的 Exporter： 2、用户自定义 除了直接使用社区提供的 Exporter 程序以外，用户还可以基于 Prometheus 提供的 Client Library 创建自己的 Exporter 程序，目前 Promthues 社区官方提供了对以下编程语言的支持：Go、Java/Scala、Python、Ruby。同时还有第三方实现的如：Bash、C++、Common Lisp、Erlang,、Haskeel、Lua、Node.js、PHP、Rust 等。 2.3、Exporter 的运行方式 从 Exporter 的运行方式上来讲，又可以分为： 1、独立运行 由于操作系统本身并不直接支持 Prometheus，同时用户也无法通过直接从操作系统层面上提供对 Prometheus 的支持。因此，用户只能通过独立运行一个程序的方式，通过操作系统提供的相关接口，将系统的运行状态数据转换为可供 Prometheus 读取的监控数据。 除了 Node Exporter 以外，比如 MySQL Exporter、Redis Exporter 等都是通过这种方式实现的。 这些 Exporter 程序扮演了一个中间代理人的角色（数据转换）。 2、集成到应用中（推荐） 为了能够更好的监控系统的内部运行状态，有些开源项目如 Kubernetes，ETCD 等直接在代码中使用了 Prometheus 的 Client Library，提供了对 Prometheus 的直接支持。这种方式打破的监控的界限，让应用程序可以直接将内部的运行状态暴露给 Prometheus，适合于一些需要更多自定义监控指标需求的项目。 2.4、Exporter 规范 所有的 Exporter 程序都需要按照 Prometheus 的规范，返回监控的样本数据。以 Node Exporter 为例，当访问 /metrics 地址时会返回以下内容： # 取前面 10 行 $ curl -s -k --header "Authorization: Bearer $TOKEN" https://192.168.0.113:6443/metrics|head -10 # HELP aggregator_openapi_v2_regeneration_count [ALPHA] Counter of OpenAPI v2 spec regeneration count broken down by causing APIService name and reason. # TYPE aggregator_openapi_v2_regeneration_count counter aggregator_openapi_v2_regeneration_count {apiservice="*",reason="startup"} 0 aggregator_openapi_v2_regeneration_count {apiservice="k8s_internal_local_delegation_chain_0000000002",reason="update"} 0 aggregator_openapi_v2_regeneration_count {apiservice="v1beta1.metrics.k8s.io",reason="add"} 0 aggregator_openapi_v2_regeneration_count {apiservice="v1beta1.metrics.k8s.io",reason="update"} 0 # HELP aggregator_openapi_v2_regeneration_duration [ALPHA] Gauge of OpenAPI v2 spec regeneration duration in seconds. # TYPE aggregator_openapi_v2_regeneration_duration gauge aggregator_openapi_v2_regeneration_duration {reason="add"} 0.929158077 aggregator_openapi_v2_regeneration_duration {reason="startup"} 0.509336209 Exporter 返回的样本数据，主要由三个部分组成：样本的一般注释信息（HELP），样本的类型注释信息（TYPE）和样本。 Prometheus 会对 Exporter 响应的内容逐行解析： 如果当前行以# HELP 开始，Prometheus 将会按照以下规则对内容进行解析，得到当前的指标名称以及相应的说明信息： # HELP <metrics_name> <doc_string> 如果当前行以# TYPE 开始，Prometheus 会按照以下规则对内容进行解析，得到当前的指标名称以及指标类型: # TYPE <metrics_name> <metrics_type> TYPE 注释行必须出现在指标的第一个样本之前。如果没有明确的指标类型需要返回为 untyped。 除了#开头的所有行都会被视为是监控样本数据。 每一行样本需要满足以下格式规范: metric_name [ “{” label_name “=” "label_value" { “,” label_name “=” "label_value" } [ “,” ] “}” ] value [ timestamp ]