首页
下载
关于
Search
1
制作qcow2格式镜像
9 阅读
2
n2n内网穿透保姆教学
8 阅读
3
Linux小分享(一)
7 阅读
4
Go实现加班通知你老婆的脚本
6 阅读
5
Python实现分布式键值存储系统
5 阅读
日常记录
网络安全
Python
运维
Go
登录
Search
标签搜索
Python
算法
Go
定时任务
AiiCi
累计撰写
9
篇文章
累计收到
1
条评论
今日撰写
0
篇文章
首页
导航栏
日常记录
网络安全
Python
运维
Go
页面
下载
关于
用户登录
登录
搜索到
9
篇与
AiiCi
的结果
2024-05-14
Linux小分享(一)
每日三个小分享一、配置主机禁PING#在 /etc/sysctl.conf 中添加 net.ipv4.icmp_echo_ignore_all=1 #0表示允许,1表示禁止 sysctl -p #生效配置二、shell脚本无法运行#现象出现提示无法运行,存在字符问题 :set ff? #出现fileformat=dos :set fileformat=unix #即可解决三、脏数据回写Linux系统内存中会存在脏数据,一般系统默认脏数据30秒后会回写磁盘,可根据需求进行修改,单位:毫秒。#cat /etc/sysctl.conf vm.dirty_expire_centisecs=6000 sysctl -p
2024年05月14日
7 阅读
1 评论
0 点赞
2024-05-12
Python实现分布式键值存储系统
一、简介 在当今互联网时代,分布式系统已经成为构建高可用性、可扩展性和容错性的关键技术之一。然而,构建一个稳定、可靠的分布式系统并不容易,其中最大的挑战之一是如何实现一致性复制和故障容错。为了解决这个问题,出现了许多分布式共识算法,如Paxos和Raft等。 Raft算法是一种相对容易理解和实现的分布式一致性算法,它通过选举机制和日志复制来保证系统中各个节点之间的一致性。Raft算法的出现极大地简化了分布式系统的设计和实现,因此被广泛应用于各种分布式系统中,如分布式存储系统、分布式数据库、分布式日志系统等。二、算法原理Leader选举:在Raft算法中,节点通过选举产生一个领导者(Leader)。在正常情况下,每个节点都处于三种可能的状态之一:Leader、Follower和Candidate。初始状态下,所有节点都是Follower。当一个Follower节点在一段时间内没有收到Leader节点的心跳消息时,它会变成Candidate并开始一轮新的选举。节点会向其他节点发送投票请求,并根据收到的投票决定是否成为新的Leader。日志复制:一旦选出Leader,它就负责处理客户端的请求,并将操作作为日志条目复制到其他节点。Leader节点会周期性地向其他节点发送心跳消息,以保持其领导地位。其他节点在接收到Leader的日志条目后,会将其追加到自己的日志中,并向Leader发送确认消息。一旦Leader收到大多数节点的确认消息,就会提交该日志条目,并将其应用到状态机中。一致性保证:Raft算法保证了日志的一致性和强一致性。只有在大多数节点(超过半数)都提交了相同的日志条目时,才能保证日志的一致性。如果Leader节点失效或者网络分区,系统会重新选举新的Leader,以保证系统的可用性和一致性。安全性保障:Raft算法通过适当的消息通信和状态转换保证了系统的安全性。节点在选举过程中会根据自己的状态和收到的消息进行状态转换,从而避免出现多个Leader或者数据不一致的情况。容错性:Raft算法具有良好的容错性,能够应对节点失效、网络分区等异常情况。一旦Leader节点失效,其他节点会在一定时间内重新选举新的Leader;如果网络分区发生,Raft算法会保证只有大多数节点中的一部分成为新的Leader,从而避免数据不一致的情况。Raft算法通过Leader选举和日志复制机制保证了分布式系统的一致性和可用性,具有较好的容错性和安全性。你的代码实现了Raft算法的关键部分,包括节点状态转换、Leader选举、日志复制等,从而实现了一个简单的分布式键值存储系统。三、算法实现from flask_executor import Executor import threading import time import random import logging import requests from flask import Flask, request, render_template_string logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s', level=logging.INFO) MAX_RETRIES = 3 ELECTION_TIMEOUT_MIN = 1 # 最小选举超时时间(秒) ELECTION_TIMEOUT_MAX = 2 # 最大选举超时时间(秒) class RaftNode: def __init__(self, node_id, peers): self.node_id = node_id self.peers = peers self.current_term = 0 self.voted_for = None self.state = 'follower' self.last_heartbeat = None # 初始化为None,等待启动后再更新 self.timeout = random.uniform(ELECTION_TIMEOUT_MIN, ELECTION_TIMEOUT_MAX) self.failed_election_attempts = 0 self.max_failed_attempts = 3 self.lock = threading.Lock() # 添加锁对象 self.retry_timeout = 1 # 初始重试超时时间为1秒 self.max_retry_timeout = 10 # 最大重试超时时间为10秒 self.session = requests.Session() # 使用Session对象管理连接 self.vote_count = {candidate: 0 for candidate in peers} # 初始化每个候选人的选票数为0 def start(self): self.last_heartbeat = time.time() # 初始化 last_heartbeat threading.Thread(target=self.run).start() def run(self): while True: if time.time() - self.last_heartbeat > self.timeout: with self.lock: if self.state in ['follower', 'candidate']: logging.info("开始选举...") self.start_election() elif self.state == 'leader': logging.info("有leader产生了!") self.send_heartbeat() time.sleep(0.1) def start_election(self): # with self.lock: if self.state == 'follower' or self.state == 'candidate': self.state = 'candidate' self.current_term += 1 self.voted_for = self.node_id # 自己先投自己一票 self.last_heartbeat = time.time() self.failed_election_attempts = 0 votes = 1 responses = [] for peer in self.peers: response = self.request_vote(peer) responses.append(response) if response and response['term'] == self.current_term and response['vote_granted']: votes += 1 if votes > len(self.peers) / 2: self.state = 'leader' logging.info(f"Node {self.node_id} becomes leader for term {self.current_term}") break else: if response and response['term'] > self.current_term: self.current_term = response['term'] self.state = 'follower' break else: max_term = max(response['term'] for response in responses if response) if max_term > self.current_term: self.current_term = max_term self.state = 'follower' return if self.state != 'leader': self.failed_election_attempts += 1 if self.failed_election_attempts >= self.max_failed_attempts: logging.error("Exceeded maximum failed election attempts. Retrying election with backoff.") self.retry_election_with_backoff() # 使用指数退避策略重试选举 # 输出当前的选票情况 logging.info("当前选票情况:") for candidate, votes in self.vote_count.items(): logging.info(f"候选人 {candidate} 获得 {votes} 票") def replicate_data(self, data): for peer in self.peers: try: response = self.session.post(peer + '/replicate_data', json=data) if response.status_code != 200: logging.error(f"Error replicating data to {peer}: {response.status_code}") except requests.RequestException as e: logging.error(f"Error replicating data to {peer}: {e}") def retry_election_with_backoff(self): # with self.lock: retry_count = 0 while retry_count < MAX_RETRIES: time.sleep(self.retry_timeout) self.retry_timeout *= 2 self.start_election() retry_count += 1 def request_vote(self, peer): # with self.lock: if self.state == 'candidate': try: response = self.session.post(peer + '/vote_request', data={'term': self.current_term, 'candidate_id': self.node_id}) return response.json() except requests.RequestException as e: logging.error(f"Error sending vote request to {peer}: {e}") return None # 网络请求出错时返回None return None def handle_vote_request(self): # 处理来自其他节点的投票请求 data = request.form term = int(data['term']) candidate_id = data['candidate_id'] # with self.lock: if term > self.current_term: self.state = 'follower' self.current_term = term self.voted_for = candidate_id return {'term': self.current_term, 'vote_granted': True} elif term == self.current_term and (not self.voted_for or self.voted_for == candidate_id): self.voted_for = candidate_id return {'term': self.current_term, 'vote_granted': True} else: return {'term': self.current_term, 'vote_granted': False} def handle_heartbeat(self): data = request.get_json() term = data.get('term') if term > self.current_term: self.current_term = term self.state = 'follower' self.voted_for = None return {'success': True} def send_heartbeat(self): logging.info(f"Leader {self.node_id} sending heartbeat for term {self.current_term}") self.last_heartbeat = time.time() for peer in self.peers: retries = 0 while retries < MAX_RETRIES: try: response = self.session.post(peer + '/heartbeat', data={'term': self.current_term}) if response.status_code == 200: logging.info(f"Heartbeat sent successfully to {peer}") break else: logging.error(f"Error sending heartbeat to {peer}: {response.status_code}") retries += 1 time.sleep(1) # 等待一段时间后重试发送心跳 except requests.RequestException as e: logging.error(f"Error sending heartbeat to {peer}: {e}") retries += 1 time.sleep(1) # 等待一段时间后重试发送心跳 class KeyValueStoreNode(RaftNode): def __init__(self, node_id, peers): super().__init__(node_id, peers) self.shared_data = {} # 存储共享数据 self.app = Flask(__name__) self.executor = Executor(self.app) self.app.config['EXECUTOR'] = self.executor # 设置路由规则 self.app.add_url_rule('/kv', 'handle_request', self.handle_request, methods=['GET', 'POST', 'DELETE']) self.app.add_url_rule('/vote_request', 'handle_vote_request', self.handle_vote_request, methods=['POST']) self.app.add_url_rule('/replicate_data', 'replicate_data', self.replicate_data_handler, methods=['POST']) self.app.add_url_rule('/heartbeat', 'handle_heartbeat', self.handle_heartbeat, methods=['POST']) self.app.add_url_rule('/', 'index', self.index) def index(self): return render_template_string(''' <h1>节点信息</h1> <p>当前节点: {{ node_id }}</p> <p>已存储的键值对: {{ shared_data }}</p> <p>当前状态: {{ state }}</p> ''', node_id=self.node_id, shared_data=self.shared_data, state=self.state) def handle_request(self): action = request.args.get('action') key = request.args.get('key') value = request.args.get('value') if self.state == 'leader': if action == 'get': return self.get(key) elif action == 'set': self.set(key, value) return "OK" elif action == 'delete': self.delete(key) return "OK" else: return "ERROR: Invalid action" else: leader_url = f"{self.peers[0]}/kv" try: response = self.session.request(method=request.method, url=leader_url, params=request.args) return response.text except requests.RequestException as e: return f"ERROR: {e}" def get(self, key): return str(self.shared_data.get(key, "Key not found")) def set(self, key, value): self.shared_data[key] = value # 当节点是领导者时,将数据复制到其他节点 if self.state == 'leader': self.replicate_data({'key': key, 'value': value}) def delete(self, key): if key in self.shared_data: del self.shared_data[key] # 当节点是领导者时,将删除操作复制到其他节点 if self.state == 'leader': self.replicate_data({'key': key, 'value': None}) def replicate_data_handler(self): data = request.json key = data.get('key') value = data.get('value') if value is not None: self.shared_data[key] = value else: if key in self.shared_data: del self.shared_data[key] return "OK" def start(self): super().start() threading.Thread(target=self.app.run, kwargs={'host': '0.0.0.0', 'port': int(self.node_id.split(":")[-1])}).start() if __name__ == "__main__": node1 = KeyValueStoreNode("http://127.0.0.1:5001", ["http://127.0.0.1:5002", "http://127.0.0.1:5003"]) node2 = KeyValueStoreNode("http://127.0.0.1:5002", ["http://127.0.0.1:5001", "http://127.0.0.1:5003"]) node3 = KeyValueStoreNode("http://127.0.0.1:5003", ["http://127.0.0.1:5001", "http://127.0.0.1:5002"]) node1.start() node2.start() node3.start() while True: time.sleep(1)四、总结 选择使用Python实现Raft算法的分布式键值存储系统项目的原因在于,一方面通过实现一个基于Raft算法的分布式系统可以深入理解分布式一致性算法的原理和实现细节,提升对分布式系统的理解和掌握程度;另一方面,实践是学习的最佳方式,通过动手实现一个分布式系统可以将理论知识转化为实际能力,提升解决实际问题的能力。此外,分布式系统涉及到诸多复杂的技术挑战,如一致性算法、节点管理、故障处理等,通过挑战这些技术问题可以提升解决问题的能力和技术水平。
2024年05月12日
5 阅读
0 评论
0 点赞
2024-05-09
开源防病毒引擎ClamAV
一、概述 ClamAV 是一个开源的防病毒引擎,用于检测恶意软件、病毒、间谍软件等恶意文件。它被设计用于扫描文件、邮件等,以检测潜在的威胁。ClamAV 最初是为 UNIX 系统设计的,但后来也被移植到了其他平台上,如:Linux/Unix、MAC OS X、Windows、OpenVMS。 ClamAV 通过使用病毒定义数据库来检测文件中的恶意代码。它可以与其他软件集成,如电子邮件服务器、文件服务器等,以提供实时的病毒扫描和检测服务。由于它是开源的,因此可以自由使用和修改,而且由于其广泛的支持和社区,病毒数据库通常能够及时更新以应对新的威胁。二、部署安装系统环境:centos7.9安装编译环境 yum install -y gcc gcc-c++ autoconf pcre pcre-devel make automakezlib zlib-devel openssl openssl-devel 下载源码包curl -O http://www.clamav.net/downloads/production/clamav-1.3.1.tar.gz 或 wget http://www.clamav.net/downloads/production/clamav-1.3.1.tar.gz添加用户和组groupadd clamav useradd -g clamav -s /bin/false -c "Clam AntiVirus" clamav编译安装tar xvzf clamav-1.3.1.tar.gz cd clamav-1.3.1 ./configure --prefix=/opt/clamav --disable-clamav make && make install创建相关目录mkdir /opt/clamav/logs # (日志存放目录) mkdir /opt/clamav/updata # (clanav 病毒库目录)在/var/log目录下添加两个logs文件:clamd.log和freshclam.log,将所有者改为新加的clamav用户,并设置相应的文件读写权限修改配置文件#vi etc/clamd.conf # Example 注释掉这一行. 第8 行 LogFile /opt/clamav/logs/clamd.log #删掉前面的注释目录改为logs下面 第14行 PidFile /opt/clamav/updata/clamd.pid #删掉前面的注释路径改一下 第57行 DatabaseDirectory /opt/clamav/updata #同上 第65行 #vi etc/freshclam.conf #Example 注释掉这一行 DatabaseDirectory /opt/clamav/updata UpdateLogFile /opt/clamav/logs/freshclam.log PidFile /opt/clamav/updata/freshclam.pid文件授权chown clamav:clamav /opt/clamav/logs/freshclam.log chown clamav:clamav /opt/clamav/logs/clamd.log chown clamav:clamav /opt/clamav/updata三、使用#升级库 opt/clamav/bin/freshclam # (升级病毒库) 保证你的LINUX可以正常上网哦. #查杀 /opt/clamav/bin/clamscan # 查杀当前目录下的文件 /opt/clamav/bin/clamscan -r # 查杀当前目录的所有文件及目录 /opt/clamav/bin/clamscan dir # 查杀dir目录 /opt/clamav/bin/clamscan -r dir # 查杀目录dir下的所有文件及目录 #帮助 /opt/clamav/bin/clamscan --help
2024年05月09日
5 阅读
0 评论
0 点赞
2024-05-01
Dependency check配置本地数据库mysql
一、简介 Dependency Check 是一款开源的静态分析工具,主要用于检测项目中的依赖库是否存在已知的安全漏洞。它是由 OWASP(Open Web Application Security Project)开发和维护的,旨在帮助开发者在构建软件时提前识别和修复安全隐患。以下是 Dependency Check 的一些关键特性和功能:二、核心功能安全漏洞检测: Dependency Check 通过扫描项目的依赖库和插件,检测其中是否包含已知的安全漏洞。它会检查常见的依赖管理系统(如 Maven、Gradle、NPM、Yarn、Composer 等)所引用的库版本,并与已知漏洞数据库进行比对。漏洞数据库: 工具主要依赖于 National Vulnerability Database (NVD) 和其他来源(如 NPM Advisory、OSS Index 等)来获取漏洞信息。这些数据库包含了大量的已知安全漏洞及其详细信息。生成报告: Dependency Check 在扫描完成后生成详细的报告,报告中列出了所有发现的漏洞,风险等级,受影响的组件及其版本,以及解决这些漏洞的建议和链接。多语言支持: 支持多种编程语言和包管理工具,包括 Java、.NET、Node.js、Python、Ruby、PHP 等,这使得它在不同技术栈的项目中都能使用。集成与自动化: 可以与 CI/CD 管道集成,自动化依赖库的安全检查。例如,可以通过 Jenkins、GitHub Actions 等工具在构建过程中自动运行 Dependency Check,确保每次构建都不会引入新的漏洞。三、使用方式命令行工具: Dependency Check 提供了一个命令行工具,可以直接在开发环境或 CI 环境中运行。用户可以通过命令行参数指定要扫描的项目路径和其他配置选项。插件形式: 支持作为插件集成到构建工具中,例如 Maven、Gradle、SBT、Ant 等,使得在构建过程中自动进行安全检查。REST API: 提供了 REST API,允许用户通过网络请求方式进行扫描和获取报告,适用于需要自定义集成的场景。优点提前发现漏洞:在开发和构建过程中提前发现并修复依赖库中的安全问题,减少生产环境中漏洞带来的风险。全面的报告:详细的报告帮助开发者快速理解和解决问题。自动化和集成:与各种 CI/CD 工具的良好集成,使安全检查流程自动化,减少手动操作的时间和错误。例子运行 Dependency Check 扫描 Maven 项目:dependency-check --project myProject --scan /path/to/project --format HTML --out report.html在 Maven 项目中使用 Dependency Check 插件:<build> <plugins> <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> <version>6.0.3</version> <executions> <execution> <goals> <goal>check</goal> </goals> </execution> </executions> </plugin> </plugins> </build>通过这些功能,Dependency Check 帮助开发团队提升项目的安全性,减少因第三方依赖库漏洞导致的安全事件风险。四、配置本地数据库目前支持的数据库包括:h2、mysql、oracle、sql server、postgresQL。这里我们以mysql作为实例讲解!初始化数据库,执行链接中的脚本即可https://github.com/jeremylong/DependencyCheck/blob/main/core/src/main/resources/data/initialize_mysql.sql很重要!需要将mysql的驱动放到 dependency-checklib 目录下,使用下面的脚本即可,它会先进行导入数据库然后再进行检测。第一次使用去掉-n参数,如果加了-n不会同步数据库#!/bin/bash ######################################### # Author: AiiCi # # Time: 2024-05 # # description: 依赖单扫描 # ######################################### DIR="/root/dependency-check/bin" #可执行文件目录 TAGGET="/home/backupJenkins/workspace" #扫描目录 OUTPUT="/root/out_dependency-check" #输出目录 if [ -z $1 ];then echo -e "\e[31mUSE: $0 ProjectName\e[0m" exit 1 fi ls $TAGGET/$1/target/ >/dev/null 2>&1 if [ $? -ne 0 ];then echo -e "\e[31m$TAGGET/$1/target/ directory not found\e[0m" exit 1 fi cd $DIR ./dependency-check.sh --project $1 --disableRetireJS --disableNodeJS -s $TAGGET/$1/target/ --dbDriverName com.mysql.cj.jdbc.Driver --connectionString jdbc:mysql://10.169.140.235:3306/dependencycheck --dbUser dcuser --propertyfile /root/dependency-check/pwd.properties -n -o $OUTPUT/$1 -l info.log cd - >/dev/nulldbDriverName:表示数据库的dirver名称connectionString:表示连接数据库的字符串,执行初始化脚本后创建的数据库叫dependencycheckdbUser:是用户名,初始化的用户名叫 dcuserpropertyfile:这个参数是表示dcuser 的密码,需要在properties文件中存储,形式是:data.password=DC-Pass1337! 这个密码是执行初始化脚本后的默认密码-n 表示不同步数据库如果需要批量执行可以选择下列脚本:#!/bin/bash ######################################### # Author: AiiCi # # Time: 2024-05 # # description: 依赖全扫描 # ######################################### DIR="/root/dependency-check/bin" #可执行文件路径 TAGGET="/home/backupJenkins/workspace" #扫描路径 OUTPUT="/root/out_dependency-check" #输出路径 PROJECTS=($(ls $TAGGET|grep -v "tmp")) #项目列表去掉了tmp缓存目录 cd $DIR for project in "${PROJECTS[@]}"; do echo -e "\e[32m当前执行项目 $project\e[0m" ./dependency-check.sh --project $project --disableRetireJS --disableNodeJS -s $TAGGET/$project/target/ --dbDriverName com.mysql.cj.jdbc.Driver --connectionString jdbc:mysql://10.169.140.235:3306/dependencycheck --dbUser dcuser --propertyfile /root/dependency-check/pwd.properties -n -o $OUTPUT/$project done cd - >/dev/null
2024年05月01日
4 阅读
0 评论
0 点赞
1
2