Python (Ansbile)脚本高效批量管理服务器和安全
1、简介
在现代 IT 基础设施中,管理大量服务器是一项复杂而繁琐的任务。特别是在检查服务器的存活状态以及 SSH 登录等任务上,手动操作非常耗时且容易出错。本文将介绍如何使用 Python 脚本实现对多台服务器的批量检查和管理,包括检查服务器是否在线,以及通过密码或 SSH 密钥登录服务器。
2、背景
在我们测试机房环境,为了方便管理和使用。需要统一 账号,登录方式,以及堡垒机安全验证。在之前架构基础上,我们需要梳理整合现有所有测试机器。
需要批量管理和监控多台服务器。例如,检查服务器是否存活、是否可以通过 SSH 登录等。手动执行这些任务效率低且容易出错。通过编写自动化脚本,可以大大提高工作效率和准确性。
3、环境介绍
1、依赖库
- paramiko:用于 SSH 登录。
- tqdm:用于显示进度条。
- concurrent.futures:用于多线程处理。
可以通过以下命令安装这些库:
pip install paramiko tqdm
2、文件结构
hosts
:包含服务器 IP 地址的文件,每行一个 IP 地址。ssh_key
:SSH 私钥文件路径。script.py
:主脚本文件。
4、Python实现步骤
方便统计使用,归档文件 后期整理维护
第一步:读取 IP 地址
首先,我们需要读取 hosts
文件中的 IP 地址。每行一个 IP 地址。
# 读取 IP 地址
with open('hosts', 'r') as file:ip_addresses = [line.strip() for line in file.readlines()]
第二步:检查 IP 是否存活
我们使用 ping 命令检查每个 IP 是否存活。通过 subprocess 模块执行 ping 命令,并检查返回码来判断 IP 是否存活。
import subprocessdef is_alive(ip):try: #这里注意判断# For Unix/Linux/Macresult = subprocess.run(['ping', '-c', '1', ip], stdout=subprocess.PIPE, stderr=subprocess.PIPE)except FileNotFoundError:# For Windowsresult = subprocess.run(['ping', '-n', '1', ip], stdout=subprocess.PIPE, stderr=subprocess.PIPE)return result.returncode == 0
第三步:尝试 SSH 登录
我们使用 paramiko
库尝试通过密码和 SSH 密钥登录服务器。为了处理 RSA
格式的密钥,我们使用 paramiko.RSAKey.from_private_key_file
函数。
import paramiko
from paramiko import SSHClient, AutoAddPolicy, RSAKeydef ssh_login_with_password(ip, username, password):try:client = SSHClient()client.set_missing_host_key_policy(AutoAddPolicy())client.connect(ip, username=username, password=password, timeout=5)client.close()return Trueexcept Exception as e:return Falsedef ssh_login_with_key(ip, username, key_path):try:client = SSHClient()client.set_missing_host_key_policy(AutoAddPolicy())key = RSAKey.from_private_key_file(key_path)client.connect(ip, username=username, pkey=key, timeout=5)client.close()return Trueexcept Exception as e:return False
第四步:并行处理 IP 地址
为了提高效率,我们使用 concurrent.futures.ThreadPoolExecutor
实现多线程处理。每个线程会检查一个 IP 的存活状态,并尝试通过密码和 SSH 密钥登录。
from concurrent.futures import ThreadPoolExecutor, as_completed
from tqdm import tqdmdef check_ip(ip):if not is_alive(ip):return ('non_alive', ip)else:if ssh_login_with_password(ip, USERNAME, PASSWORD):return ('ssh_password_success', ip)elif ssh_login_with_key(ip, USERNAME, KEY_PATH):return ('ssh_key_success', ip)else:return ('ssh_failures', ip)with ThreadPoolExecutor(max_workers=10) as executor:futures = {executor.submit(check_ip, ip): ip for ip in ip_addresses}for future in tqdm(as_completed(futures), total=len(ip_addresses), desc="Checking IPs"):result, ip = future.result()if result == 'non_alive':non_alive_ips.append(ip)elif result == 'ssh_password_success':ssh_password_success.append(ip)elif result == 'ssh_key_success':ssh_key_success.append(ip)elif result == 'ssh_failures':ssh_failures.append(ip)
第五步:生成结果文件
最后,我们将检查结果写入一个文件中,按照指定的格式记录每个 IP 的状态。
# 写入结果到文件
with open('output.txt', 'w') as output_file:output_file.write("[no_alive]\n")output_file.write("\n".join(non_alive_ips) + "\n")output_file.write("[password]\n")output_file.write("\n".join(ssh_password_success) + "\n")output_file.write("[key]\n")output_file.write("\n".join(ssh_key_success) + "\n")output_file.write("[fail]\n")output_file.write("\n".join(ssh_failures) + "\n")print("Results have been written to output.txt")
完整的代码
# -*- coding: utf-8 -*-
# @Time : 2024-06-27 11:46
# @Author : 南宫乘风
# @Email : 1794748404@qq.com
# @File : kvm.py
# @Software: PyCharm
import os
import subprocess
from paramiko import SSHClient, AutoAddPolicy
from tqdm import tqdm
from concurrent.futures import ThreadPoolExecutor, as_completed# 读取 IP 地址
with open('hosts', 'r') as file:ip_addresses = [line.strip() for line in file.readlines()]# 初始化列表
non_alive_ips = []
ssh_password_success = []
ssh_key_success = []
ssh_failures = []# 检查 IP 存活状态
def is_alive(ip):# For Windowsresult = subprocess.run(['ping', '-n', '1', ip], stdout=subprocess.PIPE, stderr=subprocess.PIPE)return result.returncode == 0# 尝试使用密码进行 SSH 登录
def ssh_login_with_password(ip, username, password):try:client = SSHClient()client.set_missing_host_key_policy(AutoAddPolicy())client.connect(ip, username=username, password=password, timeout=5)client.close()return Trueexcept Exception as e:return False# 尝试使用 SSH 密钥进行登录
def ssh_login_with_key(ip, username, key_path):try:client = SSHClient()client.set_missing_host_key_policy(AutoAddPolicy())client.connect(ip, username=username, key_filename=key_path, timeout=5)client.close()return Trueexcept Exception as e:return False# 用户名和密码/密钥路径配置
USERNAME = 'root'
PASSWORD = 'xxxx.88'
KEY_PATH = r'E:\Code\Gitlab_Code\aliyun\kvm_centos\ssh_key'def check_ip(ip):if not is_alive(ip):return 'non_alive', ipelse:if ssh_login_with_password(ip, USERNAME, PASSWORD):return 'ssh_password_success', ipelif ssh_login_with_key(ip, USERNAME, KEY_PATH):return 'ssh_key_success', ipelse:return 'ssh_failures', ip# 检查每个 IP 地址
# 使用多线程检查 IP 地址
# 使用ThreadPoolExecutor来并发执行任务,最大工作线程数为10
with ThreadPoolExecutor(max_workers=10) as executor:# 提交检查每个IP地址的任务,并将任务对象与IP地址映射关系存储在字典futures中futures = {executor.submit(check_ip, ip): ip for ip in ip_addresses}# 遍历所有完成的任务,使用tqdm显示进度条for future in tqdm(as_completed(futures), total=len(ip_addresses), desc="Checking IPs"):# 获取任务执行结果和对应的IP地址result, ip = future.result()# 根据检查结果,将IP地址添加到相应的列表中if result == 'non_alive':non_alive_ips.append(ip)elif result == 'ssh_password_success':ssh_password_success.append(ip)elif result == 'ssh_key_success':ssh_key_success.append(ip)elif result == 'ssh_failures':ssh_failures.append(ip)# 输出结果
print("Non-alive IPs:", non_alive_ips)
print("SSH login with password successful:", ssh_password_success)
print("SSH login with key successful:", ssh_key_success)
print("Alive but SSH login failed:", ssh_failures)# 写入结果到文件
with open('output.txt', 'w') as output_file:output_file.write("[no_alive]\n")output_file.write("\n".join(non_alive_ips) + "\n")output_file.write("[password]\n")output_file.write("\n".join(ssh_password_success) + "\n")output_file.write("[key]\n")output_file.write("\n".join(ssh_key_success) + "\n")output_file.write("[fail]\n")output_file.write("\n".join(ssh_failures) + "\n")print("Results have been written to output.txt")
5、Ansbile实现步骤
1、上面生成的文件作为hosts使用
[fail]
192.168.84.37
192.168.84.38
192.168.99.160
192.168.99.176
192.168.99.254
192.168.102.200
192.168.102.248
192.168.102.249
192.168.102.250
192.168.102.251
#可以定义环境变量,方便登录使用
[fail:vars]
ansible_user=root
ansible_password="xxxxxx.88"
ansible_ssh_private_key_file=/opt/ansible/ssh_key
2、给密码登录的添加公钥
ansible password -i ./all_host -m authorized_key -a "user={{ ansible_user }} state=present key='{{ lookup('file', '~/.ssh/id_rsa.pub') }}'" -u root --ask-pass
作用:这条命令会提示用户输入 SSH 密码,并将运行 Ansible 以 root 用户身份连接到 all_host 文件中列出的所有主机。然后,它会将当前用户的公钥添加到这些主机上指定用户的 authorized_keys 文件中,以实现无密码 SSH 登录。
-
ansible password -i ./all_host
:ansible
:Ansible 命令的入口点。password
:这里应该是指 Ansible 的 inventory 文件中定义的模块名称-i ./all_host
:指定 Ansible inventory 文件的位置,这里是./all_host
。
-
-m authorized_key
:-m authorized_key
:指定要使用的 Ansible 模块,这里是authorized_key
模块,用于管理~/.ssh/authorized_keys
文件。
-
-a "user={{ ansible_user }} state=present key='{{ lookup('file', '~/.ssh/id_rsa.pub') }}'"
:-
-a
:为指定的模块传递参数。 -
"user={{ ansible_user }} state=present key='{{ lookup('file', '~/.ssh/id_rsa.pub') }}'"
user={{ ansible_user }}
:指定要在目标主机上操作的用户,这里使用了变量{{ ansible_user }}
,这个变量通常在 Ansible 的配置文件或命令行中定义。state=present
:确保公钥存在,如果不存在就添加。key='{{ lookup('file', '~/.ssh/id_rsa.pub') }}'
:从本地文件~/.ssh/id_rsa.pub
中读取公钥,并将其添加到目标主机的authorized_keys
文件中。
-
-
-u root
:-u root
:以 root 用户身份连接到目标主机。
-
--ask-pass
:--ask-pass
:提示输入 SSH 密码。这在目标主机还没有配置无密码 SSH 登录时很有用。
6、自动化配置安全
hosts.allow
和 hosts.deny
文件是 TCP Wrappers 的一部分,用于在 Unix 和 Linux 系统上控制对服务的访问。TCP Wrappers 提供了一种通过 IP 地址、主机名或域名限制或允许访问服务的机制。
hosts.allow
和 hosts.deny
文件的作用
hosts.allow
:定义允许哪些主机访问哪些服务。hosts.deny
:定义拒绝哪些主机访问哪些服务。
这两个文件通常位于 /etc
目录下。
格式
这两个文件的每一行包含一条访问控制规则,格式如下:
php复制代码<服务列表> : <客户端列表> [: <选项>]
- 服务列表:要控制的服务名称,可以是单个服务名,也可以是多个服务名,以逗号分隔。
- 客户端列表:允许或拒绝访问的客户端,可以是 IP 地址、主机名或域名,也可以是多个客户端,以逗号分隔。
- 选项(可选):可以包含日志记录或执行命令等额外操作。
使用示例
假设你有一台服务器,想控制对 SSH 服务的访问。
hosts.allow
允许特定 IP 地址访问 SSH 服务:
sshd : 192.168.1.100
允许特定子网访问 SSH 服务:
sshd : 192.168.1.0/24
允许特定主机名访问 SSH 服务:
sshd : trustedhost.example.com
hosts.deny
拒绝所有其他主机访问 SSH 服务:
sshd : ALL
使用场景
- 安全控制:通过限制对某些关键服务(如 SSH、FTP、SMTP 等)的访问,可以增强系统的安全性。
- 访问管理:在多用户环境中,可以根据需求灵活控制哪些用户或主机能够访问特定服务。
- 日志记录:结合日志选项,可以记录访问尝试,以便审计和监控。
示例需求
-
在
/etc/hosts.deny
中写入sshd:ALL
,拒绝所有主机的 SSH 访问。 -
在
/etc/hosts.allow
中允许特定 IP 地址段和单个 IP 地址的 SSH 访问:sshd:192.168.0.0/16:allow
sshd:192.168.102.20:allow
-
如果文件有变动,则重启
sshd
服务。
Ansible 剧本
编写一个 Ansible 剧本来自动执行上述操作。以下是完整的 Ansible 剧本代码:configure_ssh_hosts.yml
---
- name: 配置 hosts.allow 和 hosts.denyhosts: testbecome: yes # 使用sudo权限vars:hosts_deny_content: "sshd:ALL"hosts_allow_content: |sshd:192.168.0.0/16:allowsshd:192.168.102.20:allowtasks:- name: 更新 hosts.deny 文件lineinfile:path: /etc/hosts.denyline: "{{ hosts_deny_content }}"create: yesregister: hosts_deny_result- name: 更新 hosts.allow 文件copy:content: "{{ hosts_allow_content }}"dest: /etc/hosts.allowregister: hosts_allow_result- name: 如果配置发生变化则重启 sshd 服务systemd:name: sshdstate: restartedwhen: hosts_deny_result.changed or hosts_allow_result.changed- name: 确保 sshd 服务已启用并正在运行systemd:name: sshdstate: startedenabled: yes
使用方式
定义剧本名称和目标主机:
[root@ansible-yunwei ansible]# cat hosts
[test]
192.168.102.20
192.168.102.30
[root@ansible-yunwei ansible]# ansible-playbook -i ./hosts configure_ssh_hosts.yml PLAY [配置 hosts.allow 和 hosts.deny] *******************************************************************************************************************************TASK [Gathering Facts] *******************************************************************************************************************************************
ok: [192.168.102.30]
ok: [192.168.102.20]TASK [更新 hosts.deny 文件] ******************************************************************************************************************************************
ok: [192.168.102.30]
ok: [192.168.102.20]TASK [更新 hosts.allow 文件] *****************************************************************************************************************************************
ok: [192.168.102.30]
ok: [192.168.102.20]TASK [如果配置发生变化则重启 sshd 服务] ***************************************************************************************************************************************
skipping: [192.168.102.20]
skipping: [192.168.102.30]TASK [确保 sshd 服务已启用并正在运行] ****************************************************************************************************************************************
ok: [192.168.102.30]
ok: [192.168.102.20]PLAY RECAP *******************************************************************************************************************************************************
192.168.102.20 : ok=4 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
192.168.102.30 : ok=4 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
注意事项
hosts.allow
文件中的规则优先于hosts.deny
中的规则。如果一个主机被hosts.allow
允许,则不会被hosts.deny
拒绝。- 确保规则的顺序和逻辑正确,以免意外拒绝合法访问或允许非法访问。
- 这些文件适用于支持 TCP Wrappers 的服务,不适用于所有服务。
通过合理配置 hosts.allow
和 hosts.deny
文件,可以有效控制服务访问,提高系统的安全性。
相关文章:

Python (Ansbile)脚本高效批量管理服务器和安全
1、简介 在现代 IT 基础设施中,管理大量服务器是一项复杂而繁琐的任务。特别是在检查服务器的存活状态以及 SSH 登录等任务上,手动操作非常耗时且容易出错。本文将介绍如何使用 Python 脚本实现对多台服务器的批量检查和管理,包括检查服务器…...

《数字图像处理与机器视觉》案例三 (基于数字图像处理的物料堆积角快速测量)
一、前言 物料堆积角是反映物料特性的重要参数,传统的测量方法将物料自然堆积,测量物料形成的圆锥表面与水平面的夹角即可,该方法检测效率低。随着数字成像设备的推广和应用,应用数字图像处理可以更准确更迅速地进行堆积角测量。 …...
Postman接口测试工具的原理及应用详解(四)
本系列文章简介: 在当今软件开发的世界中,接口测试作为保证软件质量的重要一环,其重要性不言而喻。随着前后端分离开发模式的普及,接口测试已成为连接前后端开发的桥梁,确保前后端之间的数据交互准确无误。在这样的背景…...

扛鼎中国AI搜索,天工凭什么?
人类的创作不会没有瓶颈,但AI的热度可不会消停。 大模型之战依旧精彩,OpenAI选择在Google前一天举行发布会,两家AI企业之间的拉扯赚足了热度。 反观国内,百模大战激发了大家对于科技变革的热切期盼,而如今行业已逐渐…...

【Ant Design Vue的更新日志】
🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…...

Elasticsearch环境搭建|ES单机|ES单节点模式启动|ES集群搭建|ES集群环境搭建
文章目录 版本选择单机ES安装与配置创建非root用户导入安装包安装包解压配置JDK环境变量配置single-node配置JVM参数后台启动|启动日志查看启动成功,访问终端访问浏览器访问 Kibana安装修改配置后台启动|启动日志查看浏览器访问 ES三节点集群搭建停止es服务域名配置…...
System.currentTimeMillis() JAVA 转C#
JAVA中的System.currentTimeMillis() ,指获取当前时间与1970年1月1日00:00:00 GMT之间所差的毫秒数的方法。 这个方法返回的是一个long类型的值,表示从某个固定时间点(通常是UNIX纪元,即1970年1月1日00:00:00 GMT)到…...

人机交互新维度|硕博电子发布双编码器操作面板、无线操作面板等新品
6月15日,硕博电子召开了一场新品发布会,向业界展示了多项前沿技术成果,其中备受瞩目的当属SPM-KEYP-D08双编码器操作面板、SPM-KEYP-D16W无线操作面板、SPR-HT-XK12A无线手持发射端以及SPQ-WT-B01洒水车专用控制面板。这些创新产品的亮相&…...
简单shell
目录 预备知识 fork 进程等待 wait waitpid 环境变量 概念 分类 常见的环境变量及其用途 环境变量的查看与设置 exec系列 函数解释 命名理解 简单shell 预备知识 fork fork 是 Linux 和许多其他类 Unix 系统中的一个重要系统调用,它用于创建一个新的…...
Spring Boot + FreeMarker 实现动态Word文档导出
Spring Boot FreeMarker 实现动态Word文档导出 在现代企业应用中,文档自动化生成是一项提升工作效率的重要功能。Spring Boot与FreeMarker的组合,为开发者提供了一个强大的平台,可以轻松实现动态Word文档的导出。本文将指导你如何使用Sprin…...

3D生物打印的未来:多材料技术的突破
多材料生物打印技术是近年来发展迅速的一项技术,为组织工程和再生医学带来了新的机遇,可以帮助我们更好地理解人体组织的结构和功能,并开发新的治疗方法。 1. 组织构建 复杂性模拟:多材料生物打印技术能够构建具有层次结构和异质…...

充电宝口碑哪个好?好用充电宝品牌有哪些?好用充电宝推荐
充电宝作为我们日常生活和出行的重要伙伴,其品质和性能直接影响着我们的使用体验。今天,就来和大家探讨一下充电宝口碑哪个好,为大家盘点那些备受赞誉的好用充电宝品牌,并向您推荐几款值得入手的充电宝,外出时不再担心…...
Pytorch-----(6)
一 、问题 如何计算基于不同变量的操作如矩阵乘法。 二、具体实现 0.4版本以前,张量是包裹在变量之中的,后者有三个属性grad、volatile和 requires_grad属性。(grad 就是梯度属性,requires_grad属性就是 是否需要存储梯度&#x…...
leetcode hot100 第三题:最长连续序列(Java)
给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1: 输入:nums [100,4,200,1,3,2] 输出:4 解…...

利用Jaspar进行转录因子结合位点预测
前期我们介绍了如何进行ChIP-qPCR验证,里面提到了一个比较重要的因素——扩增范围的选择及引物的设计。相比双荧光素酶、酵母单杂-点对点验证等允许完整启动子验证的实验,ChIP-qPCR要求单次验证的范围尽量控制在150-200bp内。但一个基因的启动子一般有2-…...
Ubuntu添加系统字体
(2024.6.30) 系统字体保存路径在/usr/share/fonts下,如果此目录下缺少字体,则使用其他可视化api(如Python的pygame库)的默认配置时可能会出现乱码问题。 往Ubuntu中添加字体的方法 方法一:手…...
深度学习相关概念及术语总结2
目录 76.AUC77.DBSCAN聚类78.贝叶斯个性化排序79.BPRBandit算法 76.AUC AUC(Area Under the Curve)是一种常用的评价指标,用于衡量分类模型的性能。AUC值代表了模型在不同阈值下的真阳性率(True Positive Rate)和假阳…...

基于改进滑模、经典滑模、最优滑模控制的永磁同步电机调速系统MATLAB仿真
微❤关注“电气仔推送”获得资料(专享优惠) 模型简介 针对永磁同步电机调速系统的响应性能和抗干扰能力问题,本文做了四个仿真,分别为:永磁同步电机的PID控制调速系统、基于传统滑模控制的永磁同步电机的调速系统、最…...

windows环境下创建python虚拟环境
windows环境下创建python虚拟环境 使用virtualenv库创建虚拟环境,可使不同的项目处于不同的环境中 安装方法: pip install virtualenv -i https://pypi.tuna.tsinghua.edu.cn/simple pip install virtualenvwrapper-win -i https://pypi.tuna.tsinghua…...
Fragment切换没变化?解决办法在这里
大家好,今天跟大家分享下如何避免fragment切换失败。方法其实很简单,只要在onCreate方法中初始化一个默认的fragment即可。 //开始事务FragmentTransaction transaction getActivity().getSupportFragmentManager().beginTransaction();transaction.rep…...

【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...

使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...

Linux-进程间的通信
1、IPC: Inter Process Communication(进程间通信): 由于每个进程在操作系统中有独立的地址空间,它们不能像线程那样直接访问彼此的内存,所以必须通过某种方式进行通信。 常见的 IPC 方式包括&#…...
13.10 LangGraph多轮对话系统实战:Ollama私有部署+情感识别优化全解析
LangGraph多轮对话系统实战:Ollama私有部署+情感识别优化全解析 LanguageMentor 对话式训练系统架构与实现 关键词:多轮对话系统设计、场景化提示工程、情感识别优化、LangGraph 状态管理、Ollama 私有化部署 1. 对话训练系统技术架构 采用四层架构实现高扩展性的对话训练…...