首页
实用链接
图床推荐
友链
关于
Search
1
彻底卸载Cloudflare Tunnel(解决 cloudflared service uninstall 报错问题)
483 阅读
2
从零开始注册Hugging Face账号到部署网页应用
102 阅读
3
Debian 11.2 搭建 Typecho 个人博客教程
90 阅读
4
紫电猫8.8元随身WIFI刷Debian系统教程
88 阅读
5
Linux配置frps与frpc的四种隧道并设置开机启动
87 阅读
默认分类
教程
随笔
软件开发
笔记
登录
/
注册
Search
标签搜索
Datawhale
AI+X
Fun-Transformer
#Datewhale组队学习
隧道
Debian
Transformer
教程
随身wifi
frp
frpc
frps
内网穿透
Linux
toml
我的世界
Minecraft
MySQL
单片机
OLED
Simuoss
累计撰写
20
篇文章
累计收到
12
条评论
首页
栏目
默认分类
教程
随笔
软件开发
笔记
页面
实用链接
图床推荐
友链
关于
搜索到
8
篇与
的结果
2025-09-21
[2025年5月最新] 如何为WSL配置代理 & 如何为Docker配置代理
配置本机WSL代理正常安装好WSL编辑C:\Users\<UserName>.wslconfig,写入以下内容:[wsl2] networkingMode=mirrored localhostForwarding=true autoProxy=true dnsTunneling=true编辑.bashrc,在末尾添加下列隧道配置export http_proxy="http://localhost:10809" export https_proxy="http://localhost:10809"应用更改source ~/.bashrc配置Docker代理正常安装Docker配置 Docker 守护进程 (Docker Daemon) 代理sudo mkdir -p /etc/systemd/system/docker.service.d sudo vi /etc/systemd/system/docker.service.d/http-proxy.conf写入以下内容[Service] Environment="HTTP_PROXY=http://localhost:10809/" Environment="HTTPS_PROXY=http://localhost:10809/"重启Docker服务sudo systemctl daemon-reload sudo systemctl restart docker大功告成!
2025年09月21日
6 阅读
0 评论
0 点赞
2025-09-21
Typecho博客从本地部署到Docker部署(1.2.1->1.3.0)迁移成功,Congratulations!
前言24年8月,因为Wifi棒子断电重启后无法自动回连Wifi,博客站就迁移到了一块847工控板上。一开始一切运行正常,但到了25年初,工控板经常异常死机,死机时用手摸一下还会自动重启,怀疑是板子电气性能不佳,遂计划把博客站迁移到其他设备上。但是开始迁移时却被一些问题卡住了,届时正值找工作比较忙,于是就先作罢,博客站就此荒废了几个月的时间。这个周末和盒子里的847工控板大眼瞪小眼看了许久,决定把它收拾了,就有了本篇。预先准备我的博客数据库使用SQLite,所以至少应该保留类似66ba4f5eec6c5.db这样的数据库文件。文件的路径通常在typecho\usr下。如果你想保留之前的主题,还需要保留整个typecho\usr\themes文件夹运行博客的新机器上需要先装好docker,为了方便今后的数据迁移,我们使用docker部署使用Docker部署时,建议直接使用docker compose,方便后续维护。compose文件如下:services: typecho: image: joyqi/typecho:nightly-php7.4-apache container_name: typecho-server restart: always environment: - TYPECHO_SITE_URL=https://xxx.xxx ports: - 8634:80 volumes: - ./typecho:/app对比文档里的写法,我们去掉了头部过时的版本声明,修改了宿主机端口,并挂载出了整个/app(也就是Typecho应用程序根目录)。挂载出整个/app的好处有以下两点:如果你的域名使用https,就需要编辑config.inc.php;如果你想迁移主题包,还需要编辑typecho\usr\themes文件夹,那索性就都挂载出来。开始迁移将以上docker compose文件保存到你想放置Typecho的目录,文件名为docker-compose.yaml,然后同级运行命令:docker compose up -d # 如果你不是root,使用sudo docker compose up -d这时docker会从云端仓库把Typecho镜像拉下来,静待一段时间,直到命令行窗口显示:笔者近期家里没有合适的设备,就选择了Windows上使用Docker Desktop部署,之后买了新设备再迁移。在Linux上的回显也大同小异。此时,同目录的typecho文件夹下就是容器内部挂载出的/app目录了。进入typecho\usr,把之前的.db文件(通常类似66ba4f5eec6c5.db)复制过来,然后进入127.0.0.1:8634进行博客初始化。初始界面直接点击我准备好了,开始下一步即可。随后你会看到下面界面,这里按照之前博客的配置选,比如我之前是SQLite,就选SQLite。pdo驱动和原生驱动都可以正常运行,选哪个都行。数据库前缀一般没有人会改,如果你记不清了,可以上类似sqlite-viewer的网站查看,比如我这个db文件夹就是以typecho为前缀的:最下面的数据库文件路径,我们已经把原先的数据库文件放在了正确的地方,所以只要把这里的.db文件的名字改成我们之前名字就好。配置完成点确认开始安装,此时Typecho会提示安装程序检查到原有数据表已经存在,证明我们配对了。选择使用原有数据即可。不出意外的话,会出现如下界面。如果你也到了这里,恭喜你迁移基本成功!可以进入博客界面看看数据都在不在常见问题明明密码正确,但就是登录不进管理界面,点击登录总是被重新定向到登录页,原地tp问题解析:如果站点是通过HTTPS访问的(比如https://blog.simuoss.cn),但Typecho内部没有正确配置为使用安全连接,会导致登录后Session或Cookie处理异常,从而被重定向回登录页。解决方案:在Typecho根目录下的 config.inc.php 文件中,添加以下代码并保存:define('__TYPECHO_SECURE__', true);这行代码告诉Typecho当前环境是安全的(HTTPS),应该生成安全的Cookie。保存后,运行以下指令重启Typecho:docker compose restart # 如果你不是root,使用sudo docker compose restart此时重新登录,就能进管理后台了。进入后台后显示:[升级程序] 检测到新版本!但点升级后报500 SERVER ERROR或DATABASE QUERY ERROR此时先使用以下指令重启:docker compose restart # 如果你不是root,使用sudo docker compose restart如果还是报错,再看下面的解决方案。问题解析:在Docker容器中,Web服务器进程是以特定用户(通常是 www-data)身份运行的,但这个用户不一定有数据库的写入权限,所以升级修改数据库结构时就会失败。解决方案:使用下方命令进入typecho容器内部,并授予www-data用户所有权:docker exec -it typecho-server bash # 进入容器内部命令行。如果你不是root,使用sudo docker exec -it typecho-server bash chown -R www-data /app/usr/ # 将整个目录的所有者设置成`www-data`然后退出容器并重启服务:exit # 退出容器 docker compose restart # 如果你不是root,使用sudo docker compose restart重启后再点击完成升级按钮,即可安全升级到最新版本。如果不重启,直接点升级按钮,还是会报500 SERVER ERROR。这时候不用担心,重启后就可以正常进入管理后台了。如果你在进行这些操作之前已经点过完成升级按钮了,就需要在执行完上述流程之后,先删掉已经损坏的.db文件,重新复制来原先的.db文件,然后使用docker compose restart重启服务,重新进行升级流程。如何迁移主题?前文提到,只要把之前的typecho\usr\themes文件夹复制过来即可。复制来后重启服务,主题就回来了。docker compose restart # 如果你不是root,使用sudo docker compose restart参考链接:Typecho 登录返回 302 的解决方法致谢:阿里Qwen:Debug时帮我提供了很多思路
2025年09月21日
11 阅读
0 评论
0 点赞
2025-01-15
【2025.1 Datawhale AI+X 共学活动】Fun-Transformer —— Task1:引言 (Seq2Seq、Encoder-Decoder、Attention机制)
Datewhale组队学习为什么我们需要 Seq2Seq ?历史背景首先我们要知道,在Seq2Seq出现之前,我们是如何处理输入输出数据的在 Seq2Seq 框架提出之前,深度神经网络在图像分类等问题上取得了非常好的效果。在其擅长解决的问题中,输入和输出通常都可以表示为固定长度的向量,如果长度稍有变化,会使用填充(Padding)等操作,其目的是将序列数据转换成固定长度的格式,以便于输入到需要固定长度输入的神经网络中。比如,我们有两个序列是输入数据:[1, 1, 4]和[1, 9, 1, 9]但模型只能处理长度为6的序列那就需要先对两个序列做填充:[1, 1, 4] -> [1, 1, 4, 0, 0, 0][1, 9, 1, 9] -> [1, 9, 1, 9, 0, 0]才能正确地输入模型如果要类比的话,这种填充操作有些类似以下概念:离心机配平后才能开机(除非你喜欢艺术)PC历史上出现过一种RDRAM内存,必须一次插满偶数个内存槽。如果你只买了一条内存条,还需要再买一条“空内存条”补到主板上,以防止信号反射。(空内存条也不便宜)一把手枪弹匣有10发子弹容量,但规定必须装满才能发射,而你只有3发子弹。所以你找来了7发塑料假子弹先塞进去,再放3发真子弹,这样就能开枪了。填充操作的缺陷这种填充操作当然不是没有代价的。比如第一个序列[1, 1, 4],我明明想处理的是[1, 1, 4],为什么非要输入[1, 1, 4, 0, 0, 0]不可?这样一来,如果我本来就想输入[1, 1, 4, 0, 0, 0],那岂不是这两个完全不同的序列,在模型看起来却完全一致吗?为了解决这个问题,我们还需要引入一个掩码的概念。比如对于[1, 1, 4]:原始序列:[1, 1, 4]填充序列:[1, 1, 4, 0, 0, 0]掩码序列:[1, 1, 1, 0, 0, 0](把原始序列的内容标记为1,后续填充的位置标记为0)这样就解决了[1, 1, 4]和[1, 1, 4, 0, 0, 0]的趋同问题,因为此时他们有不一样的掩码。类比到我们前文手枪的例子:要如何区分枪里到底是10颗真子弹,还是3颗真7颗假呢?我们可以提前告诉枪手,第1、2、3颗是真的,打完就可以停手了。这个“哪些子弹是真子弹”的信息,就是掩码这样的操作逻辑一定程度上合理,但明显可以更合理——为什么一定要填充呢?所以,Seq2Seq模型应运而生。Seq2Seq 的巧妙设计前面提到的填充操作之所以会存在,是因为模型的输入和输出表示为固定长度的向量,我们为了让数据正确进到模型,就需要对输入数据做填充和掩码的预处理。而Seq2Seq模型,即“序列到序列”,提供了一种直接输入任意长度序列,并输出期望序列的方式。模型直接能够读取一个长度可变的向量,无需进行预处理。这是如何实现的呢?其实非常简单:既然传统模型只能接受固定长度向量,那我们只需要在模型中加一步将任意长度的向量都转化为一个固定长度(维度)的向量,再拿这个定长向量去进行后续操作,不就好了吗?甜菜!Seq2Seq 的缺点虽然Seq2Seq的处理方式很巧妙,但是不可否认的是,它也有一些问题没有解决。首先,Seq2Seq模型的本质,还是最终生成了一个固定长度的向量。那这个向量能表达的意思的复杂程度,就严重受限于向量的长度(或者说维度)。如何理解这个问题?比如你和朋友有个约定,用一种特殊的交流方式传递信息。你们都买了一套12色水彩笔,规定不同的颜色搭配有着不同的意思。不过,受限于只有12色,所以你们只能表达出一些简单的意思,比如今天老地方见,或者下课之后一起去打球。你们对这种交流方式极其满意。班里的两个富哥发现了你们的游戏,并决定模仿。他们一人买了一桶128色水彩笔!复杂的颜色可以让他们表达出2024年12月31日,我们开车一起去xx景点跨年,晚上不通宵到6点谁也不许走这种复杂的语义。而你和朋友看着自己的12色水彩,欲哭无泪。另一个问题,Seq2Seq模型具有良好的模块化特性,能够与卷积神经网络(CNNs)、循环神经网络(RNNs)等神经网络架构无缝集成。这本来是好事。但是,由于循环神经网络(RNN)的固有特性,Seq2Seq模型在处理长序列时存在短期记忆限制,难以有效捕获和传递长期依赖性。其实这口锅应该让RNN来背为什么会出现这种问题呢?假设你在阅读一本侦探小说,开头提到了一些重要的信息:“罪犯的外套上有一个红色的线头。”但是在 300 页后,侦探揭开真相时需要用到这个线索。如果你忘了“红色线头”这个细节,可能就无法理解故事的结局。在机器学习中,这个“开头的信息”对应的是序列的早期数据,“故事结局的推理”对应的是模型对后续步骤的预测。如果模型忘了早期的重要信息,预测结果就可能出现错误。而 RNN 是一个时间步接一个时间步地处理序列数据,每次都将当前输入和之前的记忆(隐藏状态)结合起来,然后输出一个新的隐藏状态。这样会出现以下几点问题:信息传递过程的逐步稀释:早期的信息在隐藏状态中一层层传递,像是一瓶颜料滴入流水,逐渐被稀释。如果序列太长,早期信息可能会被完全“冲淡”。梯度消失问题:模型通过反向传播优化参数时,早期时间步的梯度(学习信号)会因为连乘关系而指数级减小,导致模型难以学会捕捉这些早期时间步的信息。隐藏状态容量有限:RNN 的隐藏状态是一个固定大小的向量,比如 256 维,但长序列的信息可能需要更大的容量才能完整存储,这就导致了一种“信息拥挤”的现象。最后,Seq2Seq模型还存在一个暴露偏差(Exposure Bias)问题。在Seq2Seq模型的训练过程中,经常采用“teacher forcing”策略,即在每个时间步提供真实的输出作为解码器的输入。然而,这种训练模式与模型在推理时的自回归生成模式存在不一致性,导致模型在测试时可能无法很好地适应其自身的错误输出。如何理解这句话呢?这需要借助一个理解来比喻Seq2Seq模型的训练过程:训练阶段(Teacher Forcing)就像你在学习开车时,有一位教练坐在副驾驶,一直告诉你前方的道路情况(真实的目标输出),比如“前方是直路”“前方有个右转弯”,你只需要按教练的指令操作方向盘,几乎不会出错。推理阶段(自回归生成)当你独自开车时,突然被蒙上了眼睛(没有真实的目标输出),只能靠自己上一秒的操作和记忆来判断接下来的路该怎么走。如果前一秒稍微偏了方向,后续可能就越走越偏,甚至撞车。Encoder-Decoder模型是什么与Seq2Seq模型的关系Seq2Seq模型,指的是一种“序列到序列”的处理思路。而Encoder-Decoder模型,是实现这种思路的具体方式。如果将Seq2Seq比作“健康的生活需要多吃水果”,那Encoder-Decoder就是:星期水果种类每日摄入量周一苹果 + 猕猴桃200克 + 150克周二香蕉 + 蓝莓150克 + 100克周三橙子 + 草莓200克 + 150克周四葡萄 + 梨150克 + 200克周五芒果 + 火龙果200克 + 150克周六桃子 + 柚子150克 + 200克周日哈密瓜 + 樱桃200克 + 150克编码器Encoder在做什么简单来说,Encoder是一个RNN,里面包含很多堆叠起来的循环单元(如 LSTM 或 GRU)。当我们输入一个序列,比如 “今天吃什么好” ,输入的句子会先被分解为一个序列:输入序列:[今天, 吃, 什么, 好]在实际模型中,每个词会被转换为对应的词向量(embedding),比如:今天 → 向量 [0.5, 0.1, 0.3, ...]吃 → 向量 [0.8, 0.2, 0.4, ...]什么 → 向量 [0.3, 0.7, 0.9, ...]好 → 向量 [0.6, 0.4, 0.2, ...]这些向量是输入到编码器的内容。假设编码器是一个 两层 LSTM,它会一层一层地处理输入。每个时间步的处理过程如下:时间步 1:处理“今天”输入词向量:[今天]初始隐藏状态:随机初始化为 [0, 0, 0, ...]输出隐藏状态:h1 = [0.6, 0.2, 0.1, ...]解释:编码器初步理解了“今天”的信息,并把它存储在隐藏状态 h1 中。时间步 2:处理“吃”输入词向量:[吃]隐藏状态:h1(包含“今天”的信息)输出隐藏状态:h2 = [0.7, 0.3, 0.4, ...]解释:编码器在隐藏状态中同时记录了“今天”和“吃”的信息。时间步 3:处理“什么”输入词向量:[什么]隐藏状态:h2(包含“今天”和“吃”的信息)输出隐藏状态:h3 = [0.8, 0.5, 0.6, ...]解释:编码器进一步整合了“今天、吃、什么”的上下文信息。时间步 4:处理“好”输入词向量:[好]隐藏状态:h3(包含“今天、吃、什么”的信息)输出隐藏状态:h4 = [0.9, 0.7, 0.8, ...]解释:最终隐藏状态 h4 汇总了整个句子的上下文信息。h4,就是 “今天吃什么好” 这句话的 意思,专业一些叫 语义。解码器Decoder又做了什么假设我们在这里是想实现一个中英互译,输入是中文 “今天吃什么好” ,输出是英文翻译。解码器接收上下文向量 h4(编码器输出)并开始生成目标序列 “What should I eat today?”。解码器的生成过程是逐步进行的,每个时间步生成一个单词。这里使用 RNN(如 LSTM 或 GRU)来逐步生成目标序列。在解码器开始生成序列之前,它的参数(权重和偏置)已经被初始化(也就是预先训练好了)。权重(Weights):连接不同神经网络层的参数,它们决定了层与层之间信息的传递方式。决定了解码器如何将输入(上下文向量、前一步的输出)映射到当前的输出。偏置(Biases):在神经网络层中加入的固定值,用于调节激活函数的输出。帮助解码器对模型的输出进行调整,使其能够灵活地生成更符合目标语言规律的翻译。随后,解码器开始基于h4这个语义来生成目标序列(翻译后的英文)时间步 1:生成第一个单词 "What"解码器接收到上下文向量 h4(包含了整个中文句子的理解)作为输入。解码器根据当前输入(h4)和其隐藏状态 h0(由h4初始化来的)预测第一个单词。输出:What(解码器预测的第一个单词)。类比:翻译官开始翻译时,首先从大意(上下文向量)出发,决定翻译的第一个单词。时间步 2:生成第二个单词 "should"解码器将上一步生成的单词 What 作为当前时间步的输入。结合上下文向量 h4 和前一步的隐藏状态,解码器生成第二个单词。输出:should(解码器预测的第二个单词)。类比:翻译官根据翻译的第一个单词(What)和对整句话的理解(h4),生成第二个单词。时间步 3:生成第三个单词 "I"解码器将上一步生成的单词 should 作为当前时间步的输入。根据上下文向量 h4 和前一步的隐藏状态,解码器生成第三个单词。输出:I(解码器预测的第三个单词)。类比:翻译官继续根据上下文和前一步的翻译来生成下一个单词。时间步 4:生成第四个单词 "eat"解码器输入前一个单词 I。结合上下文向量 h4 和前一步的隐藏状态,解码器生成第四个单词。输出:eat(解码器预测的第四个单词)。类比:翻译官根据已翻译的单词 What should I 以及对中文句子的理解(h4)生成下一个单词。时间步 5:生成第五个单词 "today?"解码器输入前一个单词 eat。结合上下文向量 h4 和前一步的隐藏状态,解码器生成第五个单词。输出:today?(解码器预测的第五个单词)。类比:翻译官最终将最后的单词“今天”翻译成英文,并加上疑问符号“?”。Encoder-Decoder 的应用我们前文提到,Encoder-Decoder是Seq2Seq的具体实现。所以,只要是能转化为序列的数据,都可以作为其应用场景。视频、音频、图像、文字,任何可以被编码成序列数据的实体都能够被Encoder-Decoder结构处理。机器翻译、对话机器人、诗词生成、代码补全、文章摘要(文本 – 文本)语音识别(音频 – 文本)图像描述生成(图片 – 文本)图片转视频(图片 - 视频)给视频配音(视频 - 音频)有太多可以想到的应用场景了!Encoder-Decoder 的缺陷其实也就是上面提过的,Seq2Seq模型的最经典的缺点:固定长度的向量,无法表达出复杂的信息。就像12色的水彩笔无法表达2024年12月31日,我们开车一起去xx景点跨年,晚上不通宵到6点谁也不许走一样。这样的操作逻辑一定程度上合理,但明显可以更合理——为什么一定要固定长度呢?这就是Attention机制带来的翻天覆地的大变革了。Attention机制Attention 解决定长向量问题的方法Attention:Seq2Seq,定长的能力是有极限的,我从短暂的人生当中学到一件事,越是固定维度,就越会发现定长向量的能力是有极限的,除非超越定长。Seq2Seq:你到底想说什么。Attention:所以我不做定长辣!Seq2Seq!Attention 模型的特点是 Encoder 不再将整个输入序列编码为固定长度的“向量C” ,而是编码成一个向量(Context vector)的序列(“C1”、“C2”、“C3”)。也就是,原先是将输入数据编码成单个变量(固定长度的向量C),而现在将输入数据编码成一整个数组!数组里面存着任意数量的定长向量,但是数组长度是可变的!这样,在产生每一个输出的时候,都能够做到充分利用输入序列携带的信息。Attention 的核心工作Attention Is All You Need Ура!!!!在传统的 Seq2Seq 模型中,编码器会将整个输入序列压缩成一个单一的 上下文向量,这个向量包含了输入序列的全部信息。解码器使用这个上下文向量生成目标序列。然而,上下文向量在编码长序列时存在信息丢失的问题,因为它只能携带一个固定长度的摘要,随着输入长度的增加,信息会逐渐被压缩,导致模型难以捕获远距离的依赖关系。Attention 机制的引入解决了这一问题,它允许解码器在生成每个目标单词时,都能够动态地关注输入序列的不同部分,而不是依赖于一个单一的上下文向量。在 Seq2Seq 中加入 Attention 后,模型的工作原理发生了变化:编码器的输出编码器在每个时间步都会生成一个隐藏状态(h1, h2, h3,...),这些隐藏状态反映了输入序列中每个位置的信息。解码器的 Attention 权重解码器生成每个目标单词时,首先会为输入序列的每个位置计算一个 注意力权重(Attention weight)。这个权重决定了当前解码器生成单词时,应该多大程度地关注输入序列中的哪个部分。权重计算:解码器的当前状态与编码器每个时间步的隐藏状态进行比较,计算它们之间的相似度。这个相似度即为 Attention 权重,表示当前目标单词与输入序列各个部分的关联程度。加权求和生成上下文向量解码器根据计算得到的 Attention 权重,对编码器的所有隐藏状态进行加权求和,得到一个新的 上下文向量。这个上下文向量是动态的,依赖于目标序列当前生成的单词,因此它包含了关于输入序列的更丰富、更具体的信息。生成目标单词解码器将这个新的上下文向量与当前的隐藏状态结合,生成目标序列中的下一个单词。这很像人类看图片的逻辑,当我们看下面这张熊猫图片的时候,我们将注意力集中在了图片的焦点上(熊猫)。在图片上,我们的视线聚焦在熊猫及其攀爬的树干,熊猫和树干在这个区域内非常清晰,在此之外的区域则相对模糊,表示其他景物(例如熊猫背后的山林)没有被“注意力”所关注。这样的图像就能够直观地展示注意力机制是如何在众多信息中挑选出关键部分进行重点处理的。 如上面所说的,我们的视觉系统就是一种 Attention机制,将有限的注意力集中在重点信息上,从而节省资源,快速获得最有效的信息。Attention 的3大优点之所以要引入 Attention 机制,主要是3个原因:参数少:模型复杂度跟 CNN、RNN 相比,复杂度更小,参数也更少。所以对算力的要求也就更小。速度快:Attention 解决了 RNN 不能并行计算的问题。Attention机制每一步计算不依赖于上一步的计算结果,因此可以和CNN一样并行处理。效果好:在 Attention 机制引入之前,有一个问题大家一直很苦恼:长距离的信息会被弱化,就好像记忆能力弱的人,记不住过去的事情是一样的。欢迎各位大佬在评论区交流&批评指正!Datewhale组队学习参考链接Datawhale AI+X 共学活动 Fun-Transformer —— Task1:引言Attention Is All You Need
2025年01月15日
13 阅读
0 评论
1 点赞
2024-08-17
彻底卸载Cloudflare Tunnel(解决 cloudflared service uninstall 报错问题)
问题引入Cloudflare 是一家国际知名的互联网基础设施服务的公司。对国内用户来说,很多人用 Cloudflare 的免费服务来给网页带上 https (比如本站),又或者是用 Cloudflare Tunnel(Cloudflare Argo Tunnel) 来穿透本地网页到公网。但是,由于众所周知的原因,国内访问 Cloudflare 服务通常不是很通畅,而在配置 Cloudflare Tunnel 时也偶尔会因为各种原因失败,需要重新安装。这时,cloudflared 会提示如下:这是由于 cloudflared 没有完全清理安装文件导致的。如何解决在执行卸载指令之后,执行指令清除 cloudflared 的所有配置文件:sudo cloudflared service uninstall sudo rm /etc/systemd/system/cloudflared*这时再重新执行安装指令即可。切换到HTTP2连接有时候在隧道创建成功后,Cloudflare 后台会显示隧道状态是 degraded (退化状态),这可能是由于新版的Cloudflare隧道“强制”使用QUIC进行连接,而国内的网络接入服务商对UDP协议支持很不好造成的。可以通过以下方式设置默认使用HTTP2连接。编辑配置文件:sudo vi /etc/systemd/system/cloudflared.service在 ExecStart 一行的启动指令里添加如下参数:--protocol http2此时启动指令应该是类似 ExecStart=/usr/bin/cloudflared --no-autoupdate --protocol http2 tunnel run --token <your_token> 的形式。重新启动服务sudo systemctl daemon-reload sudo systemctl restart cloudflared #由于网络环境原因可能启动不成功,多执行几次本句参考链接:遇事不决,量子力学!搞定Cloudflare Tunnels无法建立隧道的问题【便笺】配置Cloudflare隧道默认使用HTTP2Cloudflare Tunnel 中文文档Cloudflared service not removed after uninstall
2024年08月17日
483 阅读
0 评论
2 点赞
2024-08-11
Linux配置frps与frpc的四种隧道并设置开机启动
前言对于个人爱好者而言,国内的绝大多数家庭宽带都没有公网IP,即使能要到动态公网IP,也需要配置DDNS服务,比较麻烦。但是购买云服务器,又面临着算力较低,开销较大的问题。所以,在家中配置一台高性能服务器,并购买一台低配置大带宽的云服务器做端口转发,甚至是全端口转发,是一件性价比较高的实现方式。在开设穿透上,我们这里使用 FRP。frp 采用 C/S 模式,将服务端部署在具有公网 IP 的机器上,客户端部署在内网或防火墙内的机器上,通过访问暴露在服务器上的端口,反向代理到处于内网的服务。 在此基础上,frp 支持 TCP, UDP, HTTP, HTTPS 等多种协议,提供了加密、压缩,身份认证,代理限速,负载均衡等众多能力。此外,还可以通过 xtcp 实现 P2P 通信。下载预编译包这一步对于服务端和用户端都一样,没有区别,因为预编译包里面同时包含frps和frpc选择合适的平台与系统打开 FRP的Github Releases界面。一般推荐直接下载最新版(截止本文撰写是0.59.0版本)。可以看到,图中有很多版本的Release包,都是frp_版本_系统_平台的命名格式。通常来讲,云服务商提供的服务器,直接选择frp_0.59.0_linux_amd64.tar.gz即可。系统自然不必说,常见的ubuntu、centos、debian等等都属于Linux。平台的对应关系:|平台|意义||:-:|:-:||arm|32位的arm芯片,通常用在机顶盒、手机等等设备,目前比较少见||arm64|64位的arm芯片,通常用在机顶盒、高端路由器,手机等等设备,比如高通骁龙、联发科天玑等等||amd64|【最常见】64位的x86架构芯片,Intel和AMD在2003年以后的芯片都选这个||arm_hf|带有硬件浮点单元的32位arm芯片||mips|32位的mips芯片,通常用在一些路由器、医疗和工控设备里||mips64|64位的mips芯片,通常用在一些路由器、医疗和工控设备里|下载预编译包到本地并解压可以直接在远端服务器上使用curl下载(以frp_0.59.0_linux_amd64.tar.gz为例):curl -L https://github.com/fatedier/frp/releases/download/v0.59.0/frp_0.59.0_linux_amd64.tar.gz如果你选择了别的版本,可以直接改动后面的文件名。如果远程服务器下载缓慢,也可以在本地下载好后,使用(s)ftp协议或其他方式上传至远程服务器。这里推荐使用自带ftp协议的ssh终端,如 MobaXterm下载好后,解压文件:tar -xzvf frp_0.59.0_linux_amd64.tar.gz-x:表示解压。 -z:表示文件是 gzip 格式的(.gz)。 -v:表示显示解压的文件列表(可选)。 -f:指定文件名。在服务端搭建frps服务修改配置文件进入frp文件目录:cd frp_0.59.0_linux_amd64用vim文本编辑器修改 frps.toml 配置文件vi frps.toml注意,对于初学者来说,vim编辑器可能比较难以使用,使用方式可以参照这篇文章:vim使用教程图文教程(零基础超详细)。如果还是觉得难以使用,推荐Windows用户下载MobaXterm,并在连接到服务器后,用右侧的sftp文件界面来修改toml文件内容。清除原先内容,复制以下内容到文件并保存:bindPort = 7000 # frp服务的端口。最基础的服务有这一行就够了,后面的都可以不要。需要注意如果你有防火墙,防火墙也需放开该端口 # 服务面板可查看frp服务状态信息,无论开启还是关闭都不影响服务正常使用。想要关闭就把后面四行用#号注释掉 webServer.addr = "0.0.0.0" # 后台管理地址,默认是127.0.0.1,如果是公网访问则改成0.0.0.0 webServer.port = 7500 # 后台管理端口 webServer.user = "admin" # (可选)后台登录用户名 webServer.password = "admin" # (可选)后台登录密码 # 身份认证。如果不配置这一项,那么任何想连接至你的服务器的frpc请求都会被同意。不过不开启这个配置起来简单一些。 #transport.tls.force = true # 服务端将只接受 TLS链接 #auth.method = 'token' # 客户端访问验证方式 #auth.token = "54321" # 客户端访问验证密码,frpc要与frps一致 # 自定义的监听的端口,所有对服务器该端口访问将被转发到本地内网,做了反向代理可不处理防火墙放行 #vhostHTTPPort = 8000 #vhostHTTPSPort = 45443保存退出。这时,输入./frps -c ./frps.toml即可运行服务,如果正常运行,就先按ctrl+c关闭程序,因为我们后面要配置后台运行和开机启动。设置开机启动在这里,我们使用 systemd 来将frps注册为系统服务。systemd 是一个用于 Linux 操作系统的系统和服务管理器。它是大多数现代 Linux 发行版中用于启动和管理系统服务的主要工具。systemd 负责管理系统启动、服务运行、系统资源分配以及进程和日志管理等。在多数主流的 Linux 发行版中,systemd 已经成为默认的系统管理工具。使用以下指令创建frps.service服务文件并编辑:sudo vim /etc/systemd/system/frps.service这里会提示你输入密码,因为此目录有root等级权限。如果没有提示输入密码,证明你用了root用户直接操作日常人物,这是不好的。如果你想用我前面提到的sftp工具直接修改,那你需要在Session里面重新开一个具有root权限的stfp会话,因为左边自带的stfp没有root权限,不能直接修改这个路径的文件。所以尽量还是学一下 vim 吧:vim使用教程图文教程(零基础超详细)。如果还是觉得难以使用,推荐Windows用户下载MobaXterm写入内容,注意修改frp文件路径:[Unit] # 服务名称,可自定义 Description = frp server After = network.target syslog.target Wants = network.target [Service] Type = simple # 启动命令,改为实际存放frps的路径 ExecStart = /path/to/frps -c /path/to/frps.toml # 自动重启设置 Restart = always # 适用于重启策略的额外设置 RestartSec = 5s [Install] WantedBy = multi-user.target注意修改你的frps路径。如果你想修改自动重启配置,可参照下面的细则调整配置文件(一般没有必要,可以直接跳过):Restart: - no:默认值,不会自动重启服务。 - always:无论服务的退出状态如何(正常退出或崩溃),systemd 都会自动重启服务。 - on-failure:只有在服务因非零退出状态或超时而失败时,systemd 才会重启服务。 - on-abnormal:只有在服务异常退出(如段错误、崩溃等)时,systemd 才会重启服务。 - on-success:仅当服务正常退出(退出码为0)时,systemd 才会重启服务。 - on-abnormal:只有在服务异常退出(如段错误、崩溃等)时,systemd 才会重启服务。 RestartSec:定义在服务重启之前等待的时间。这里设置为 5 秒。保存文件。随后,依次执行以下命令(如有启动失败,评论区联系):启动frpsudo systemctl start frps停止frpsudo systemctl stop frps重启frpsudo systemctl restart frps查看frp状态sudo systemctl status frps设置为开机自启sudo systemctl enable frps恭喜你,你已经完成了服务端的搭建工作,随后该服务会在系统开机时自启,无惧重启了。在用户端搭建frps服务修改配置文件进入frp文件目录:cd cd frp_0.59.0_linux_amd64用vim文本编辑器修改 frpc.toml 配置文件vi frpc.toml注意,对于初学者来说,vim编辑器可能比较难以使用,使用方式可以参照这篇文章:vim使用教程图文教程(零基础超详细)。如果还是觉得难以使用,推荐Windows用户下载MobaXterm,并在连接到服务器后,用右侧的sftp文件界面来修改toml文件内容。清除原先内容,复制以下内容到文件,理解你的每一项配置并按需修改和删除:transport.tls.enable = true # 从 v0.50.0版本开始,transport.tls.enable的默认值为 true serverAddr = "47.76.92.71" # 服务端ip,改成你的 serverPort = 7000 # 服务端端口,和之前配置frps.toml时候一致 #auth.method = 'token' # 客户端访问验证方式,如果你前面开启了访问验证,这里需要和之前配置frps.toml时候一致 #auth.token = '54321' # 客户端访问验证密码,如果你前面开启了访问验证,这里需要和之前配置frps.toml时候一致 # TCP隧道配置方式(如MySQL、Minecraft等等服务) [[proxies]] name = "thisclient.mc" # 客户端服务名,建议写成“xxx.xxx”的形式好分辨 type = "tcp" # 通讯方式 localIP = "127.0.0.1" # 客户端的ip(本机就写127.0.0.1,局域网下其他主机也可以写其它局域网IP) localPort = 25565 # 客户端服务端口(比如MC的默认端口是25565,MySQL是3306) remotePort = 13306 # 映射到服务端端口(服务器需放行。注意有些服务可能要求端口一致,但大部分不需要) # UDP隧道配置方式(如语音服务、MC基岩版) [[proxies]] name = "mc-bedrock" type = "udp" # 注意这里变了 localIP = "127.0.0.1" localPort = 19132 # MCBE的默认端口 remotePort = 39132 # 走TCP通道的HTTP流量,穿透网站用,但这种方式需要在网站后面加端口号 [[proxies]] name = "test-http" type = "tcp" localIP = "127.0.0.1" # 需要暴露的服务的IP localPort = 80 # 将本地80端口的服务暴露在公网的6060端口 remotePort = 6060 # 暴露服务的公网入口 # SSH隧道,远程连接用 [[proxies]] name = "ssh" type = "tcp" localIP = "127.0.0.1" localPort = 22 # ssh隧道默认端口是22 remotePort = 6000 #customDomains = ["xxx.xxx.xxx.xxx"] #如果想用域名访问,就在这里改 # HTTP隧道代理方式,穿透网站用,远程端口可以不是80并且不需要在访问时加端口号 [[proxies]] name = "web" type = "http" localPort = 80 #customDomains = ["域名"] # HTTPS隧道代理方式,需要注意配置证书 [[proxies]] name = "web-80" type = "https" localPort = 45443 #customDomains = ["cloud.your-service.com"]保存退出。这时,输入./frpc -c ./frpc.toml即可运行服务,如果正常运行,就先按ctrl+c关闭程序,因为我们后面要配置后台运行和开机启动。设置开机启动客户端设置开机启动方法与服务端一致,唯一不同的是创建的文件名和配置文件的frpc路径不同。所以相同的内容读者可以自行跳过在这里,我们使用 systemd 来将frpc注册为系统服务。systemd 是一个用于 Linux 操作系统的系统和服务管理器。它是大多数现代 Linux 发行版中用于启动和管理系统服务的主要工具。systemd 负责管理系统启动、服务运行、系统资源分配以及进程和日志管理等。在多数主流的 Linux 发行版中,systemd 已经成为默认的系统管理工具。使用以下指令创建frpc.service服务文件并编辑:sudo vim /etc/systemd/system/frpc.service这里会提示你输入密码,因为此目录有root等级权限。如果没有提示输入密码,证明你用了root用户直接操作日常人物,这是不好的。如果你想用我前面提到的sftp工具直接修改,那你需要在Session里面重新开一个具有root权限的stfp会话,因为左边自带的stfp没有root权限,不能直接修改这个路径的文件。所以尽量还是学一下 vim 吧:vim使用教程图文教程(零基础超详细)。如果还是觉得难以使用,推荐Windows用户下载MobaXterm写入内容,注意修改frp文件路径:[Unit] # 服务名称,可自定义 Description = frp client After = network.target syslog.target Wants = network.target [Service] Type = simple # 启动命令,改为实际存放frpc的路径 ExecStart = /path/to/frpc -c /path/to/frpc.toml # 自动重启设置 Restart = always # 适用于重启策略的额外设置 RestartSec = 5s [Install] WantedBy = multi-user.target注意修改你的frpc路径。如果你想修改自动重启配置,可参照下面的细则调整配置文件(一般没有必要,可以直接跳过):Restart: - no:默认值,不会自动重启服务。 - always:无论服务的退出状态如何(正常退出或崩溃),systemd 都会自动重启服务。 - on-failure:只有在服务因非零退出状态或超时而失败时,systemd 才会重启服务。 - on-abnormal:只有在服务异常退出(如段错误、崩溃等)时,systemd 才会重启服务。 - on-success:仅当服务正常退出(退出码为0)时,systemd 才会重启服务。 - on-abnormal:只有在服务异常退出(如段错误、崩溃等)时,systemd 才会重启服务。 RestartSec:定义在服务重启之前等待的时间。这里设置为 5 秒。保存文件。随后,依次执行以下命令(如有启动失败,评论区联系):启动frpsudo systemctl start frpc停止frpsudo systemctl stop frpc重启frpsudo systemctl restart frpc查看frp状态sudo systemctl status frpc设置为开机自启sudo systemctl enable frpc恭喜你,你已经完成了客户端的搭建工作,随后该服务会在系统开机时自启,无惧重启了。至此,我们就完成了所有服务的搭建。如果对过程有什么问题,或者出现了报错,请在下方评论留言联系。
2024年08月11日
87 阅读
0 评论
4 点赞
1
2