Raycast AI 使用体验

在之前的文章中就提到过 Raycast,前不久看到 [[Raycast]] 快速跟进了 OpenAI,现在推出了 Raycast AI,我没有想到的是,Raycast 的使用场景可以如此完美地和 AI 结合在一起。

Raycast 代替了如下我过去常常做的事情:

  • 再不需要打开网页,或者 ChatGPT 客户端再输入问题
  • 再不需要打开 Papago(或者 DeepL 等客户端)翻译段落(短句和单词基本靠 Chrome 插件和 [[GoldenDict]])
  • 再不需要打开 OpenAI Translator 对文本进行润色
  • 直接在 Obsidian 中让 Raycast AI 进行语法检查,改写,并一键替换原文
  • 代替 [[Cursor.so]] 编辑器的自然语言编程,Raycast AI 可以用来解释代码,生成代码并直接插入编辑器

直接提问

sna8

翻译

选中文本,然后 Cmd+Space,translate 即可。 ss9n

润色文本

直接使用 Improve Writing,并将润色过的文本直接粘贴回 Obsidian。 sYjl

总结

如果在网上看到一段非常长的文章,可以直接选中,然后让 Raycast 总结。 sA2g

Create AI Command 创建自己的命令行

可以看到的是上面的所有的操作,大部分都是 Raycast AI 默认自己定义的,但是 Raycast AI 更强大的一点在于它可以自己创建 AI Command(prompt),也就是说可以利用 OpenAI 的上下文对话的能力,将一些固定的模式写道 Raycast 中,然后下次使用的时候就可以直接输入几个字母触发了。也可以利用 Raycast 自己的快捷键来一键呼出。

一些使用小 Tip

Raycast 本身已经非常强大了,但是有一些贴心的功能他没有展示出来,需要用户自己去发现,下面就是一些使用的小 Tip。

  • 如果不满意 Raycast AI 的结果,可以直接按 Cmd+R 重新生成。
  • 生成内容之后可以使用 Cmd+k 来对结果进行更多的操作,比如复制,比如粘贴回选中的地方
  • Raycast AI 可以设置快捷键,比如可以将常用的 Ask AI,translate 等等设置一个单独的快捷键

alternative

如果还没有排到 Raycast AI,还可以试试 macOS 上的 MacGPT

折扣码

Raycast AI 将会进入 Raycast Pro 的套餐,每个月 8 美元,目前可以使用 RAYFRIENDS10 来获取 10% 的折扣。

raycast ai pro


2023-04-09 raycast , launcher , macos , openai , ai , chatgpt

向量数据库及实现整理

什么是向量数据库

在介绍什么是向量数据库之前先来了解一下数据库的种类。

s7qD

图上从左往右依次是 Key-Value 数据库([[Redis]],[[HBase]]),文档数据库([[MongoDB]],[[Cosmos DB]]),[[图数据库]]([[图数据库 Neo4j]],[[图数据库 Nebula Graph]]),向量数据库。

向量数据库就是用来存储,检索,分析向量的数据库。

向量数据库是一种专门用于存储和查询向量数据的数据库,其中向量数据指的是由数字组成的向量。向量数据库通常使用高效的相似度搜索算法,例如余弦相似度或欧几里得距离,来快速查询与目标向量最相似的向量。向量数据库在机器学习、计算机视觉、自然语言处理等领域中得到广泛应用。

The vectors are usually generated by applying some kind of transformation or embedding function to the raw data, such as text, images, audio, video, and others.

为什么需要有向量数据库

解决两个问题:

  • 高效的相似性检索 (similarity search)
    • 相似文本检索
    • 从图片检索图片,人脸匹配(支付),车牌号匹配,图片检测等
  • 高效的数据组织和分析能力
    • 人脸撞库,分析案发现场的人物图片

在机器学习领域,通常使用一组数值来表示一个物体的不同特征。比如我们去搜索图片的时候,数据库中存储和对比的并不是图片,而是去搜索算法提取的图片特征。

向量数据库的特点

向量数据库具有以下特点:

  • 提供标准的 SQL 访问接口
  • 高效的相似度搜索:向量数据库使用高效的相似度搜索算法,例如余弦相似度或欧几里得距离,来快速查询与目标向量最相似的向量。
  • 支持高维向量:向量数据库可以存储和查询高维向量,例如在图像识别和自然语言处理中经常使用的特征向量。
  • 高性能:向量数据库通常使用高性能的数据结构和算法,例如哈希表和树结构,以实现快速的查询和插入操作。
  • 可扩展性:向量数据库可以通过添加更多的节点或服务器来实现横向扩展,以支持大规模的向量数据集。
  • 支持多种数据类型:向量数据库通常支持多种数据类型,例如浮点数、整数和布尔值,以满足不同应用场景的需求。

和传统数据库的区别

  • 数据规模上超过关系型数据库,分布式,扩展性
  • 查询方式不同,计算密集型
    • 传统数据库点查范围查
    • 向量数据库是近似查
    • 搜索推荐
  • 低延时高并发

向量数据库有哪些

目前比较流行的向量数据库包括:

  • [[Milvus]]:一个开源的向量数据库,是全世界第一款向量数据库,也是目前最领先的云原生向量数据库,支持自托管,支持高维向量的存储和查询,提供了多种相似度搜索算法和多种客户端语言接口。构建在开源的  FaissHNSWAnnoy 之上
    • zilliz 是一个 SaaS 版本的 Milvus 平台,提供在线托管的 Milvus 服务。
  • [[Weaviate]] 开源,一个完全托管的向量数据库
  • [[Vespa]] 开源,可自托管,提供托管服务
  • [[Vald]]
  • [[Redis]] Redis 也提供了向量距离的相关内容
  • [[Qdrant]] 开源,Rust
  • [[Faiss]]:一个由 Facebook 开发的向量数据库,支持高效的相似度搜索和聚类操作,提供了多种索引结构和查询算法。
    • sqlite-vss 基于 Faiss 做了一个 SQLite Vector Similarity Search
  • [[Pinecone]] 闭源,完全托管的向量数据库
  • Annoy:一个开源的向量数据库,支持高维向量的存储和查询,使用随机化近似算法实现快速的相似度搜索。
  • Hnswlib:一个开源的向量数据库,支持高维向量的存储和查询,使用基于图的相似度搜索算法实现高效的查询。
  • NMSLIB:一个开源的向量数据库,支持多种相似度搜索算法和索引结构,可以用于高维向量和非向量数据的存储和查询。
  • Vearch
  • TensorDB
  • Om-iBASE,基于智能算法提取需存储内容的特征,转变成具有大小定义、特征描述、空间位置的多维数值进行向量化存储的数据库,使内容不仅可被存储,同时可被智能检索与分析。使用向量数据库可有效实现音频、视频、图片、文件等非结构化数据向量化存储,并通过向量检索、向量聚类、向量降维等技术,实现数据精准分析、精准检索。
  • Proxima
  • VQLite 是一个基于 Google ScaNN 包装的轻量简单的向量数据库,Go 语言编写。
  • pgvector 是为 [[PostgreSQL]] 数据库编写的一个向量近似度查询支持。
  • [[SPTAG]] 是微软开源的一个近似向量搜索的库
  • [[Elasticsearch]] 和 OpenSearch 的 GSI APU

相关的开源项目:

  • pigsty 监控/数据库开箱即用 HA/PITR/IaC 一应俱全。Pigsty 可以让用户以接近硬件的成本运行企业级数据库服务。2.0.2 发布之后可以使用 pgvector 来存储向量。
  • vearch Vearch 是一个分布式的向量搜索系统。

ChatGPT Embedding 后的内容相似度查询是用 Cosine 算法

托管的向量数据库 Fully managed vector database

  • [[zilliz]] 托管的 Milvus 数据库
  • metal.io
  • drant 注册赠送 1 GB 存储空间
  • [[supabase]] 开启 pgvector 扩展

相关工具

  • docarray 是 Linux 基金会下的一个专门为多模态数据设计的 Python 工具包,一套数据结构就解决了表示、处理、传输和存储,存储这块儿提供了一套统一的向量数据库 API,包括 Redis、Milvus、Qdrant、Weaviate、ES 等等。

可学习的代码:

向量数据库的几个发展方向

  • 过去的向量数据库是面向实时性要求高,数据规模小,可用性高的场景,但是随着图像,视频,无人驾驶,NLP 的发展,数据量已经从千万级别增长到百亿级别
  • 单机想分布式云原生发展
  • 不同的索引实现方式,Faiss 为代表的 IVF 统一到了 HNSW/NGT 为代表的图流派。图索引尽管性能相对差,内存消耗高,但是性能好,召回率高。Google 也发布了 ScaNN 技术
  • 规范的查询语言,向量数据库还没有统一的查询接口,大多数是定制的 SDK 或 RESTful 接口
  • 向量数据库和传统数据库融合

向量数据库的实现原理

  • 存储
  • 查询
    • 相似度计算
    • 欧式距离 L2

欧式距离 Euclidean distance L2

欧氏距离是计算两个点之间最短直线距离的方法。

$d(x,y) = d(y,x) = \sqrt{\sum_{i=1}^{n}(x_i-y_i)^2}$

其中 $x=(x_1, x_2, …, a_n)$ 和 $y=(y_1, y_2, …, y_n)$ 是 N 维欧式空间中的点。

内积 Inner product (IP)

两个向量内积距离计算公式

$\mathbf{a} \cdot \mathbf{b} = \sum_{i=1}^{n} a_i b_i$

其中,$n$ 是向量的维数,$a_i$ 和 $b_i$ 分别是向量 $\mathbf{a}$ 和 $\mathbf{b}$ 在第 $i$ 个维度上的分量。

内积更适合计算向量的方向而不是大小。如果要使用点积计算向量相似度,必需对向量作归一化处理,处理后点积与余弦相似度等价。

二维

向量数据库的实际应用

  • 相似文本检索
  • 图片搜图片
  • 搜索音频内容
  • 搜索视频内容

一段代码演示向量数据库的用途

[[chatdoc]] 项目

  • [[LlamaIndex]]
  • [[LangChain]]

reference


2023-04-07 vector-database , vector , chatgpt , openai , database

LangChain 是什么

LangChain 是一个围绕大型语言模型 ([[LLM]])的应用开发框架,或者说是工具集,使用 Python 编写。LangChain 是由 Robust Intelligence 前的机器学习工程师 Chase Harrison 在 10 月底开源的工具库。众多 AI Hackathon 决赛项目使用 LangChain,它的 Github Star 迅速突破万,成为 LLM 应用开发者在选择中间件时最先想到的名字。

LangChain 能做什么?

  • 个人助理,记住用户的行为数据并提供建议
  • 聊天机器人,语言模型天然擅长生成文本
  • 生成式问答
  • 文档回答,针对特定的问题回答
  • 文本摘要,从文本中提取信息
  • 代码理解,理解代码的意图
  • 文本总结,从较长的文本中总结信息

模块

LangChain 主要提供如下的模块来支持快速开发:

  • Models 支持各种模型及集成
    • LLMs,LLM 通用接口,LLM 相关常用工具
  • Prompt,Prompts 管理,提示优化,提示序列化
  • Document Loaders,文档加载的标准接口,与各种格式的文档及数据源集成
  • Chains,包含一系列的调用,可能是一个 Prompt 模板,一个语言模型,一个输出解析器,一起工作处理用户的输入,生成响应,并处理输出
  • Agents,Agent 作为代理人去向 LLM 发出请求,采取形同,检查结果,直到工作完成。
  • Memory,是在 Chains 和 Agent 调用之间的持久化状态
  • Indexes 将自己的文本做索引

用不到 50 行代码实现一个文档对话机器人

我们都知道 [[ChatGPT]] 训练的数据只更新到 2021 年,因此它不知道最新在互联网上产生的内容。而且 ChatGPT 的另一个缺点就是当他不知道的时候就会开始一本正经的胡说。但是利用 LangChain 可以用不到 50 行的代码然后结合 ChatGPT 的 API 实现一个和既存文本的对话机器人。

假设所有 2022 年更新的内容都存在于 2022.txt 着一个文本中,那么通过如下的代码,就可以让 ChatGPT 来支持回答 2022 年的问题。

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import os

import jieba as jb
from langchain.chains import ConversationalRetrievalChain
from langchain.chat_models import ChatOpenAI
from langchain.document_loaders import DirectoryLoader
from langchain.embeddings import OpenAIEmbeddings
from langchain.text_splitter import TokenTextSplitter
from langchain.vectorstores import Chroma


def init():
    files = ['2022.txt']
    for file in files:
        with open(f"./data/{file}", 'r', encoding='utf-8') as f:
            data = f.read()

        cut_data = " ".join([w for w in list(jb.cut(data))])
        cut_file = f"./data/cut/cut_{file}"
        with open(cut_file, 'w') as f:
            f.write(cut_data)


def load():
    loader = DirectoryLoader('./data/cut', glob='**/*.txt')
    docs = loader.load()
    text_splitter = TokenTextSplitter(chunk_size=1000, chunk_overlap=0)
    docs_texts = text_splitter.split_documents(docs)
    api_key = os.environ.get('OPENAI_API_KEY')
    embeddings = OpenAIEmbeddings(openai_api_key=api_key)
    vectordb = Chroma.from_documents(docs_texts, embeddings, persist_directory='./data/cut/')
    vectordb.persist()
    openai_ojb = ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo")
    chain = ConversationalRetrievalChain.from_llm(openai_ojb, vectordb.as_retriever())
    return chain

chain = load()

def get_ans(question):
    chat_history = []
    result = chain({
        'chat_history': chat_history,
        'question': question,
    })
    return result['answer']

if __name__ == '__main__':
    s = input('please input:')
    while s != 'exit':
        ans = get_ans(s)
        print(ans)
        s = input('please input:')

reference


2023-04-05 langchain , llm , ai , artificial-intelligence , chatgpt , gpt-3 , gpt-4 , openai , embedding , vector-database

介绍一下新推出的 EV Hosting 网络共享托管服务

因为自己之前买过一些 VPS,但是一直空闲很多,所以想着是否能够充分利用起来。最近正好看到可以免费使用 [[Clientexec]] 管理 Web Hosting 账单,所以隆重介绍一下刚刚推出的新服务 EV Hosting,目前上线了两个功能,共享网站托管服务和自定义域名邮箱服务。

新加坡 共享网站托管服务

共享网站托管服务(Shared Web Hosting) 是一种网站托管服务,是将多个网站存储在同一台服务器上,并共享服务器上的 CPU、内存和带宽。这种类型的托管服务通常是最便宜和最受欢迎的选择,特别适合个人和小型企业。

如果你是一个不懂技术的个人但想在网络上有一片属于自己的空间,或者你想以最低的成本开展在线商城,欢迎来订购使用。

本站提供的托管服务,服务器位于新加坡,CPU 是 AMD Ryzen 9 3900X 12-Core Processor,服务器共 128 GB 内存。

ev hosting sg

一键安装超过 400 种应用

目前该服务托管于新加坡的服务器,使用 [[DirectAdmin]] 面板,装有 [[Softaculous]],可以一键安装包括 [[WordPress]],[[Joomla]],[[NextCloud]],[[Tiny Tiny RSS]],[[miniflux]],[[FreshRSS]],[[phpmyadmin]] 等等超过 450 种的应用程序1,不少的应用我之前也是介绍过的,并且还一直在用,比如 [[NextCloud]] 这个文件同步工具,[[miniflux]] 这个 在线的 RSS 阅读器。Softaculout 非常强大,很多功能和特性有待你去发现。

DirectAdmin 后台也有一个在线的文件管理器,可以直接基于网页对网站内容进行管理。

nrWr

自定义域名邮箱

另外订购所有的套餐都可以在后台配置自定义邮箱,每一个邮箱每个小时可以发送至多 200 封邮件。请不要滥用发件发送恶意、垃圾邮件。

也可以使用后台提供的 Roundcube 网络邮箱界面来管理自己的邮件。

MySQL 数据库

购买套餐之后可以在后台创建响应的 MySQL 数据库供应用程序保存数据使用。所有的数据库内容及网站内容都会定期通过备份来保证安全。

附加功能

可以通过附加功能,来设置 Node.js,PHP,Python 等应用程序。

neId

为了庆祝上线,在订购所有年付套餐的时候输入 EVHOSTING 则可以享受 5 折的优惠(优惠截止 4 月末)。最低可以以 8 元购买一年 Bronze 套餐(限量 10 个,如果看到界面显示优惠券代码无效则表示优惠码用完或已经过期)。

加利福尼亚 网络优化 共享空间

加利福尼亚的共享空间是大陆网络优化空间,到大陆的网络延迟非常文档。

ev hosting us

自定义域名邮箱服务

如果你只需要发送邮件的服务,那么也可以订购这个自定义域名邮箱的服务,订购服务之后需要我手工启用,后台使用的是 Mailcow,我再添加了域名之后会给你的邮箱发送相应管理后台的信息。

所有在线购买的产品都可以通过在线提交工单的方式获得支持,并且后续会陆陆续续更新更多相关的使用技巧,欢迎关注。另外服务刚刚上线,如果有任何使用的问题,反馈并且到的验证的都可以免费获取一年的 Bronze 套餐。


2023-04-04 hosting , email , mailcow , clientexec , online-business , vps

记录一下 Clientexec 中配置 SMTP 时的一些问题

本文记录一下在配置 Clientexec 中的 SMTP 发送邮件的时候遇到的一些错误。添加了 [[mailcow]] 的 SMTP 配置,但是测试发送邮件总是报如下的错误。

验证 SMTP 配置

SMTP Error: The following recipients failed: email-test@clientexec.com: : Sender address rejected: not owned by user admin@mailcow.email

这就非常奇怪, 为了验证我的 SMTP 配置是没有问题的,我还直接写了一段 Python 发送邮件的程序,邮件是可以正常的发送出去的。所以我把怀疑点移动到了 Clientexec 面板。开始怀疑是不是 [[Clientexec]] 在 SMTP 配置的地方有什么 BUG。

Python

import smtplib  
from email.mime.text import MIMEText  
from email.mime.multipart import MIMEMultipart  
  
  
def send_email(sender_email, recipient_email, subject, body, smtp_server,  
smtp_port, username, password):  
    # Create a message object  
    message = MIMEMultipart()  
    message['From'] = sender_email  
    message['To'] = recipient_email  
    message['Subject'] = subject  
      
    # Add the body of the message as a MIMEText object  
    message.attach(MIMEText(body, 'plain'))  
      
    # Connect to the SMTP server and send the message  
    with smtplib.SMTP(smtp_server, smtp_port) as server:  
    server.starttls()  
    server.login(username, password)  
    server.sendmail(sender_email, recipient_email, message.as_string())  
  
  
sender_email = ''  
recipient_email = ''  
subject = 'Test Email'  
body = 'This is a test email sent from Python!'  
smtp_server = ''  
smtp_port = 587  
username = ''  
password = ''  
  
if __name__ == '__main__':  
    send_email(sender_email, recipient_email, subject, body, smtp_server,  
    smtp_port, username, password)

验证 Clientexec 后台 SMTP 设置

为了验证 Clientexec 后台的 SMTP 设置是可以正常工作的,我看到官方的文档上提供了 Gmail SMTP 设置的说明,所以我直接用之前的 Gmail 的 SMTP 设置,在 Clientexec 后台配置了一下。测试是可以正常发送邮件的。唉,难道还是我的 SMTP 配置不正确。

为了验证不是 Clientexec 只优化了 Gmail 的发送邮件,我又把域名添加到 [[MXRoute]] 生成了一个 SMTP 的用户名和密码。然后在 Clientexec 后台添加了配置,测试,发现竟然也发送成功了。那么到此时我只能怀疑是不是 Mailcow 在发信的时候有一些限制。

开启 Clientexec 调试日志

编辑 config.php

    // ***  LOG_LEVELS (each level adds additional information) ***
    // 0: No logging
    // 1: Security attacks attempts, errors and important messages (recommended level)
    // 2: Reserved for debugging
    // 3: + Warnings and EventLogs, VIEW/ACTION and Request URIs and URI redirections and POST/COOKIE values
    // 4. + plugin events, curl requests, some function calls with their parameters, etc.
    //          (use this when sending logs to support)
    // 5: + include suppressed actions
    // 6: + Action responses (ajax,serialized,XML (as array)
    // 7: + SQL queries
    define('LOG_LEVEL', 6);

    // To activate text file logging, replace the 'false' with the file full path. Do not use relative paths.
    // Use absolute paths(e.g. /home/yourinstallationpath/ce.log, instead of ce.log)
    // The log may show passwords, so please use a file outside the web root, but writable by the web server user.
    define('LOG_TEXTFILE', 'ce.log');

然后将日志等级调整到 6,将日志写到文件中方便查看。

然后在页面操作的时候查看日志 less ce.log

于是我又将 Mailcow 的 SMTP 配置添加到后台,进行测试。同时观察日志。

(4) 04/05/23 07:35:42 - Starting to send Test Email with subject "Clientexec Test Email"...
(5) 04/05/23 07:35:43 - CLIENT -> SERVER: EHLO client.einverne.info

(5) 04/05/23 07:35:43 - CLIENT -> SERVER: STARTTLS

(5) 04/05/23 07:35:44 - CLIENT -> SERVER: EHLO client.einverne.info

(5) 04/05/23 07:35:44 - CLIENT -> SERVER: AUTH LOGIN

(5) 04/05/23 07:35:44 - CLIENT -> SERVER: [credentials hidden]
(5) 04/05/23 07:35:44 - CLIENT -> SERVER: [credentials hidden]
(5) 04/05/23 07:35:45 - CLIENT -> SERVER: MAIL FROM:<admin@client.einverne.info>

(5) 04/05/23 07:35:45 - CLIENT -> SERVER: RCPT TO:<email-test@clientexec.com>

(5) 04/05/23 07:35:45 - SMTP ERROR: RCPT TO command failed: 553 5.7.1 <admin@client.einverne.info>: Sender address rejected: not owned by user admin@mailcow.mail

(5) 04/05/23 07:35:45 - CLIENT -> SERVER: QUIT

(5) 04/05/23 07:35:45 - SMTP Error: The following recipients failed: email-test@clientexec.com: <admin@client.einverne.info>: Sender address rejected: not owned by user admin@mailcow.mail

发现了 SMTP Error。

验证 Mailcow

因为排除了 Clientexec 后台配置的问题,于是我使用 Mailcow 加上 Sender address rejected 关键字进行搜索,这才发现 Mailcow 相关的问题出现过很多次, 原来是 Mailcow 默认开启了 Sender Addresses Verification,必须要手动关闭这个验证 才能代替发送邮件。

从错误日志中就能发现原来 Clientexec 在测试发送邮件的时候是使用的 admin@clientexec-domain.com 来发送邮件的。而我的 SMTP 配置的发件邮箱是 no-reply@domain.com 这样的,Mailcow 默认情况下是不允许用户以别人的身份发送邮件的(当然这也是能理解的,我不理解的是 Clientexec 后台明明是有 Override From 这样的选项的,却在测试邮件的功能里用其他邮箱来测试),所以才会报错。

解决问题的方法

本来只是想简单的总结一下解决问题的过程,但这个解决问题的思维过程正好可以提炼成一个思考问题的方式。而以上解决问题的思考方式就是非常简单的排除法。

  • 首先是验证 SMTP 配置是否有问题,用 Python 写了一段发信程序
  • 然后是验证 Clientexec 后台 SMTP 配置是否有 BUG,通过尝试其他的 SMTP 配置,发现没有问题
  • 那是不是 SMTP 提供服务的 Mailcow 有问题,通过日志和错误信息查询到原因

2023-04-04 clientexec , web-hosting-billing , mailcow , smtp , email , python

《我们为什么要睡觉》读书笔记

怎么知道的这一本书

最早听说这一本《我们为什么要睡觉》,还是在有一年 Bill Gates 的年度读书单中看到的,后来又在关注的博主的推荐图书中第二次看到,并且这个博主给了一个非常不错的评价,再到最近就是和一个朋友聊天的时候提到睡眠的问题,朋友常常不能在深夜快速的入睡,平时又起得不规律,所以我又想起了这一本很久都没有看的书。

关于作者

“Why We Sleep” 的作者是 Matthew Walker,他是加州大学伯克利分校的神经科学和心理学教授,也是 Sleep and Neuroimaging 实验室的主任。他的研究集中在睡眠、梦境和意识的神经科学机制上。Walker 自己也上过 TED,也会到各地演讲,在 YouTube 上能找到他很多资料。他自己也有一档播客,讲述的内容就是有关于睡眠的。

几句话总结书的内容

人类的一生中有三分之一的时间都是在睡眠,但是却从来没有人解释为什么人类需要睡觉,如果不睡觉会发生什么。作者通过对睡眠的层层剖析,通过大量的实验去研究睡眠,来解释我们为什么要睡觉。

  • 睡眠是什么
    • 睡眠的几个特征
      • 处于睡眠中的生物体通常是平躺
      • 熟睡的生物体的肌肉张力降低
      • 睡觉的人不会表现出明显的交流或反应
      • 状态很容易逆转(惊醒),与昏迷、麻醉、冬眠和死亡区别开来
      • 睡眠在 24h 内遵循一种可靠的定时模式,昼夜交替
    • 外部意识的丧失,停止感知外部世界,但是耳朵仍然在听,鼻子可以闻到,舌头和皮肤也有感觉
    • 睡眠状态会丧失对时间的感知
    • 两种睡眠
      • 眼睛运动的睡眠
      • 眼睛不运动的睡眠
    • 睡眠的周期,两个阶段,交替出现
      • 非快速眼动睡眠
      • 快速眼动睡眠
    • 睡眠的不同模式
      • 单相睡眠,在晚上进行很长时间的睡眠
      • 双相睡眠,在晚上睡 7~8 小时,下午进行 30~60 分钟小睡
    • 人类一生中不同阶段睡眠不一样
      • 出生之前,几乎所有时间都处于一种类似睡眠的状态
        • 缺乏快速眼动睡眠与孤独症谱系障碍(ASD,自闭症)有关联
      • 童年的睡眠,婴幼儿显示多相睡眠,许多短的睡眠片段
      • 青春期,深度非快速眼动睡眠在青春期之前达到顶峰,然后开始减弱
        • 深度睡眠也许才是大脑成熟的驱动力
        • 理性在青少年中最后才会出现,因为它是接受睡眠成熟改造的最后一个大脑区域
      • 中年和老年的睡眠,睡眠出现问题,睡得越来越早
  • 睡眠的好处和睡眠不足的坏处,为什么需要睡眠
    • 可以让寿命更长吗?
    • 学习之后的睡眠具有加强记忆和避免遗忘的力量
    • 睡眠有助于帮助恢复神经
    • 熟睡的大脑通过清醒时大脑不会尝试的方法,将不同的知识集合起来,形成问题解决能力
    • 睡眠和阿兹海默,心血管疾病等等都有关系
  • 梦的科学解释
    • 瓦解了 [[弗洛伊德]] 关于梦是愿望的满足的非科学理论
    • 梦的意义和内容,[[亚里士多德]],在《自然诸短篇》,坚持基于自身经验的信念,相信梦起源于最近清醒时经历的事件
    • 弗洛伊德认为梦来自没有实现的无意识愿望,弗洛伊德的理论缺乏明确的预测,科学家无法设计出实验来检验他的理论中的任何论点
    • 梦的创造性和对梦的控制
      • 深度非快速眼动睡眠可以增强个体的记忆
      • 快速眼动睡眠提供了精湛的、补足性的好处,以抽象且新奇的方式,将记忆的元素相互混合 [[门捷列夫]] 发现元素周期表
  • 从安眠药到社会变革,通过具体的实验,对睡眠障碍进行解释
    • 梦游症
      • 有睡眠及其疾病引起的非意志行为具有非常现实的法律、个人和社会后果
    • 失眠症
      • 代谢率高,导致核心体温更高,而睡眠需要降低体内温度
      • 提高警觉水平的激素皮质醇,神经化学物质肾上腺素,去升上腺素升高,心率很高
      • 大脑活动模式改变
    • 嗜睡症
    • 致死性家族性失眠症
    • 睡眠剥夺 VS 食物剥夺

启发或想法

在知道这一本书之前,我甚至没有想过这个问题「我们为什么要睡觉」? 我个人的睡眠一直非常不错,从来就是到点身体就会告诉眼睛要闭起来了,到了网上 11 ,12 点左右就不自觉的没有精力做任何的事情,而每天早上到点(7 点到 8 点之前) 就会自然而言睁开眼睛。甚至过去的几年时间里面我连闹钟也不需要设置,我的生物钟比闹钟都准,更甚至有几次本来就定好要早起一会儿出门,当我醒来睁开眼睛的时候,过一分钟就是定好的闹钟。而我一旦早上起床之后就再也睡不着了,虽然我感觉挺好,但是有些假期或者周末想多睡一会儿的时候却也是睡不着。用这本书中的话来说就是人的身体已经觉得睡眠足够了,所以再睡也只是闭目养神而已。

与我而言,还有一个更加神奇的事情是我从来不做梦,或者说我从来不记得我做过梦。有朋友总是会对自己的梦境非常清楚,甚至能描述出梦境中发生的事情,像是上演了一部大片一样。但每一次我听到都感觉非常神奇,我自己没有任何的感受,书中第三部分解释了很多梦形成的原因,但我还是没有办法给我自己的经历一个很好的解释。

兼听则明 偏信则暗

在读完这本书之后,大概率会被书中「严谨」的科学实验所说服,但我在浏览相关介绍的时候,在 HackerNews 上也看到一篇反驳的文章

我把这篇反驳文章的几个子标题放在这里:

  • 不,较短的睡眠并不意味着较短的寿命
  • 对于抑郁症患者而言,睡个好觉并不总是有益的
  • 睡眠不足不会直接杀死你
  • 不,世界卫生组织从未宣布失眠是一种流行病
  • 不,发达国家中三分之二的成年人并未未能获得建议的睡眠量

作者在文章中也引用了一些实验数据来论证自己的观点,当然在这个地方,我是没有办法去判断他们谁对与谁错的。两方不同的观点都有各自详细的数据佐证。

但我想说的是,科学不就是在这样提出假设,修正理论中的错误,发布自己新的理论,再进行更进一步的研究批判,从而螺旋式的上升的嘛。这又不得不提到自由派哲学家[[洛克]],[[波普尔]]所说的 [[人类认识的可错性]],抱持开放的心态,不盲目相信任何一本书、任何一个人、任何一个观点。科学的精神就是开放和质疑。读书要抱着追求「普遍的共识」,在这个基础之上跟阅读更多新的理论,但永远不排除自己出错的可能性,这样才能进步。

谁应该看这本书

推荐所有睡眠不好的朋友阅读,了解一下睡眠是什么。虽然上问题到人类不一定需要 8 个小时的睡眠时间,但是休息好,能够有充分的睡眠对个人也是很好的。


2023-04-03 sleep , book , reading , reading-2023 , reading-2023q2

Clientexec 汉化

之前购买 RackNerd 的机器看到有赠送 [[Clientexec]] 的授权就顺手申请了一个。ClientExec 是一套为主机商开发的客户管理,支持,财务系统。借助 ClientExec 的强大能力可以快速构建一个共享空间,VPS,域名分售系统。

因为正好有授权在,所以就在 RackNerd 的机器上面安装了一下。安装的过程倒是比较简单,但就是这套系统实在太复杂,从绑定的插件到,支付系统,到后台语言都比较麻烦,所以这一篇文章简单地讲述一下我汉化 Clientexec 的过程,这里面也有很多的坑。

获取英文语言字符串

如果要在 Clientexec 中新增语言包,可以通过源代码 language 路径下的语言包进行修改。

在安装完成的 Clientexec 的目录下,拷贝原来的英文语言。

/language/core-en.po
/language/core-en.mo

简体中文的语言编码代号是 zh,所以需要拷贝得到:

core-zh.po
core-zh.mo

这个语言代号,可以从 /library/Zend/Locale/Data/Translation.php 文件中得到,在数组 $languageTranslation 中搜索 Chinese 就可以看到。

nBlg

得到了对应的原始英文内容之后,就可以开始着手翻译,有很多的方式可以进行翻译。

翻译 Po 文件

po 和 mo 文件

这里需要补充一下 po 和 mo 文件的相关前提知识。 PO 和 MO 文件是 GNU gettext 工具包中使用的翻译文件格式,用于本地化软件应用程序和网站。PO 文件是 Portable Object 的缩写,它是一个文本文件,包含原始字符串和它们的翻译。MO 文件是 Machine Object 的缩写,它是一个二进制文件,包含已翻译的字符串,可用于更快地加载和使用翻译。Clientexec 是 PHP 编写的,也是通过这种方式进行国际化,多语言。

通常,开发者在开发过程中在源代码中使用原始字符串,并使用 GNU gettext 提供的工具来提取这些字符串并创建 PO 文件。然后,翻译者可以使用 PO 文件中的原始字符串并提供它们的翻译。一旦翻译完成,MO 文件将由 GNU gettext 编译器从 PO 文件生成。在软件运行时,应用程序将使用 MO 文件中的翻译来显示正确的本地化字符串,这使得软件能够在不同的语言环境下运行。

翻译 PO 文件

有很多的方式可以去翻译 po 文件

  • 我最开始的时候是傻乎乎的使用 [[Poedit]] 桌面客户端手工进行翻译。直接打开 po 文件进行翻译
  • 然后想着效率太低了,想能不能用 [[Crowdin]] 这个共享协作的翻译平台进行翻译,创建项目,然后网站上也提供了很多翻译的选项,直接 cmd+Enter 倒也是能快速翻译,但是我觉得还是太慢了,翻译了半天才 2%
  • 然后我想到这不就是从一个语言到另一个语言的翻译么,能不能找找免费的翻译工具翻译,[[DeepL]] 免费提供一个月 50 万字的额度,但是注册失败了,然后我想到之前用 GoldenDict 的时候用 Python 调用 Google Translator 用了很久。现在只要写一个读取 po 文件,然后调用 Google Translator 的方法,翻译完成之后再写回文件即可

需要注意的是 PO 文件有一个头部的「注释」,在文件的开头,因为我把文件上传到了 Crowdin,然后再下载下来的,所以 Crowdin 修改了这些注释,最好的方式是保持和原来一致,否则 Clientexec 可能无法识别。

从 PO 文件生成 MO 文件

有如下的方法:

  • Poedit 软件内能直接从 PO 文件生成 MO 文件
  • 或者可以通过在线的工具 localise

nHkw

  • Choose source file 中选择需要转换的 PO 文件
  • 然后在 To 中选择 Gettext MO(binary)
  • 然后点击 Convert
  • 保存到本地 并命名为 core-zh.mo

MO 文件是 Clientexec 用来加载使用的二进制文件,其中包含了翻译文字。

上传到 Clientexec 并在后台设置

将现在得到的两个文件:

core-zh.po
core-zh.mo

上传到 Clientexec 的 language 文件夹下。这个地方要注意的是,如果这两个文件没有足够的权限,后台即使设置了也会没有效果。

chmod 755 core-zh.po core-zh.mo

最后在 Clientexec 后台设置 -> Localization 中,首先启用 Chinese,然后将站点设置成中文即可。最后的成果

reference


2023-04-01 clientexec , billing , webhosting , racknerd , language , python

在命令行下使用 GitHub Copilot CLI

GitHub Copilot CLI 是一个让 GitHub Copilot 来在命令行环境下使用自然语言提示命令行的工具。

如果要使用 GitHub Copilot CLI ,那么必需能够访问 GitHub Copilot,并且还需要通过 waitlist。另外需要注意的是 GitHub Copilot CLI 目前还是在试验中(technical preview),有一些 corner case 或者还有一些平台支持可能不完善,并且 CLI 补充的任何命令请在完全知晓是什么内容和作用的情况下再执行。

安装

使用 npm 全局安装:

npm install -g @githubnext/github-copilot-cli

然后将 github-copilot-cli 添加到 PATH,然后使用下面的命令授权

github-copilot-cli auth

然后按照命令行的提示在网页授权。一旦授权,token 会保存在用户设备本地,为后续的请求使用。这个命令正常只会在第一次使用的时候执行。

更新命令

npm install -g @githubnext/github-copilot-cli

设置 alias

正常情况下可以直接执行 github-copilot-cli 来使用,但是更建议使用 ??, git?, gh? 这样的方式。

可以在 Shell 的配置 .zshrc.bashrc 中添加

eval "$(github-copilot-cli alias -- "$0")"

使用

GitHub Copilot CLI 会将自然语言转变成 shell 命令,在安装之后可以通过如下三种方式使用:

  • ?? 将自然语言变成命令
  • git? 将自然语言变成 git 命令
  • gh? 将自然语言变成 GitHub CLI 命令

s8dN

GitHub Copilot CLI 的三种模式均以相同方式工作 —- 编写自然语言查询来声明您想要的内容,然后 GitHub Copilot CLI 将尝试构建一个命令或命令序列来执行它。

如果满意 Copilot 建议的命令,只需要求 GitHub Copilot CLI 运行它即可。

GitHub Copilot CLI 还会逐步解释建议命令的作用。 当学习新命令时尤其需要注意:shell 非常强大,您可能会无意中做出您不打算进行的破坏性的变化。在运行命令之前,一定要确保您理解建议命令的作用。像所有 AI 系统一样,GitHub Copilot CLI 不是完美的,可能会犯错误。

Shell 使用注意事项

因为直接使用 Shell ,而有一些关键的符号在 Shell 中有其自身的含义,所以有一些需要特别注意的内容。

有一些符号可能在提交到 GitHub Copilot CLI 之前就被 Shell 处理了,所以避免使用如下的符号,或者使用 \ 转义,或者将符号放到单引号 '...' 中。

  • 查询中的单引号 ',双引号 ",或者问号,感叹号,通常会造成 shell 的语法错误,如果遇到这种情况,按 Ctrl-c,然后重新查询即可
  • 括号,包括 () [], {} 也可能造成语法错误
  • * 号,会匹配文件或文件夹,这会导致敏感的文件名出现在查询中
  • | 管道符,将被解释为 shell pip,并将查询解释为单独的命令。造成查询 Copilot 失败
  • 小心,避免在任何变量前使用 $ ,这会导致 Shell 将其扩展成一个变量值,并且可能无意之间将敏感的环境变量传给 GitHub Copilot 查询
  • Warp 是我去年介绍的一款使用 Rust 编写的终端,Warp 也提供了类似的通过 AI 支持的命令行补全,如果感兴趣也可以去体验一下。
  • 另外还有一些 Zsh 插件也可以借助 OpenAI Codex 的能力提供命令自动补全的能力,比如 Zsh Codex 但是该项目有一段时间没有更新了。

2023-03-31 github , github-copilot , cli , linux , shell , zsh , ai , artificial-intelligence

chatwoot 开源的客户支持工具:在网站上加上聊天对话框

Chatwoot 是一个 Ruby 编写的,开源的,可自建的即时消息的客户支持工具 [[Business Messaging Platform]],可以嵌入到网页,集成 Telegram,电子邮件,帮助企业提供在线的客户服务支持。chatwoot 开始于 2016 年。

在接触到 Chatwoot 之前,陆陆续续了解过 [[crisp.chat]],tawk.to。而我昨天稍微了解了一下这个行业之后就发现原来对企业的在线实时聊天的服务已经竞争非常充分了。只简单的了解了一下就发现超过 10 家公司在做类似的事情,并且还有非常多的公司以开源的方式在进行。

比如已经作为商业产品在运作的:

  • [[Intercom]]
  • [[tawk.to]]
  • [[crisp.chat]]
  • [[Drift]]
  • [[HelpCrunch]]
  • [[Zendesk]]
  • [[Help Scout]]
  • [[Freshdesk]]
  • [[chatfuel]]
  • [[airchat]]
  • [[PubNub]]
  • [[Kustomer]]

等等

以开源的方式在进行的有:

  • 文本介绍的重点 [[chatwoot]]
  • [[papercups]]
  • [[Chaskiq]]

这么多相类似的产品,大部分的商业产品所面向的客户都不太一样,有面向大客户的,比如 Intercom,Zendesk 等等,也有面向垂直电子商务的,也有面向创业公司的。

但总之上面的这些都不是本文的重点,下面就重点放在 Chatwoot 的使用上面。

Installation

Chatwoot 官方提供了很多种方式安装,还包括很多云服务提供商可以一键安装。但是我选择用 Docker(docker-compose) 安装。详情配置见这里

git clone git@github.com:einverne/dockerfile.git
cd dockerfile/chatwoot
cp env .env
# modify .env
docker compose run --rm rails bundle exec rails db:chatwoot_prepare
docker compose up -d

默认配置下 Chatwoot 是只监听本地的 localhost:3000 端口,所以还需要前台用 Nginx 做一下反向代理。

server {
  server_name <yourdomain.com>;

  # Point upstream to Chatwoot App Server
  set $upstream 127.0.0.1:3000;

  # Nginx strips out underscore in headers by default
  # Chatwoot relies on underscore in headers for API
  # Make sure that the config is set to on.
  underscores_in_headers on;
  location /.well-known {
    alias /var/www/ssl-proof/chatwoot/.well-known;
  }

  location / {
    proxy_pass_header Authorization;
    proxy_pass http://$upstream;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Ssl on; # Optional

    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    proxy_http_version 1.1;
    proxy_set_header Connection “”;
    proxy_buffering off;

    client_max_body_size 0;
    proxy_read_timeout 36000s;
    proxy_redirect off;
  }
  listen 80;
}

如何实时接受消息

因为我使用 HestiaCP 作为服务器面板,这里还遇到一个小坑,因为默认的 HestiaCP 模板文件stpl 配置最下方有一个 Nginx 配置1

    proxy_hide_header Upgrade;

也就是说默认情况下会隐藏请求头。这导致了我在安装完 chatwoot 之后,发送消息,管理后台以及前端小插件,iOS 客户端都不能实时收到新消息,必需整页刷新才能收到新消息,这导致我 Debug 了好久。虽然在之前安装 VS Code Server 在线版 的时候就遇到过一次,但还是掉进了这个坑里面。

Agent

通过 Chatwoot 的 Agent API 可以自行编写回答机器人。如果接入了 OpenAI,Rasa 等聊天机器人就可以快速的搭建一套智能客服了。

Super Admin

可以访问,<chatwoot-installation-url>/super_admin

升级 Chatwoot

因为使用 Docker Compose 安装 Chatwoot,所以升级非常简单。

docker-compose pull
docker-compose up -d

docker exec -it $(basename $(pwd))-rails-1 sh -c 'RAILS_ENV=production bundle exec rails db:chatwoot_prepare'

reference


2023-03-31 chatwoot , open-source , online-chat , customer-engagement , support , real-time-support

自建邮件服务器 Mailcow 配置通过 MXRoute 发送邮件

之前写过一篇文章是如何使用 Mailcow 自架邮件服务器,自那个时候开始以及使用自己架设的邮件服务器快一年左右的时间了,因为是自己使用,收件是没有什么问题,发件的话用 mail-tester.com 测试也能拿 10 分,但一直是没有作为主力发件服务器去使用的,主要还是怕会进入垃圾箱。但是最近看到 [[MXRoute]] 有春季打折,15 美元一年 25 GB 空间,就订购了一个想试试看。

有了这两个前提之后,我就像能不能让我的收件通过 Mailcow,邮件直接到我的服务器,然后发件的时候通过 MXRoute 发送,毕竟 MXRoute 的发件 IP 地址要比我自己的服务器 IP 地址要可信得多,送达率可能也比我自己的服务器要高。然后我简单地了解了一下发现 Mailcow 是自带 Relay (邮件中继服务) 功能的。

那这一篇文章就讲讲怎么在 Mailcow 中配置使用 MXRoute 来发送邮件。

初始 Mailcow 配置

在 Mailcow 中首先要完成正常的域名添加,然后再新增 Mailbox 邮箱。因为这个部分比较简单,直接在 Mailcow 后台操作,然后根据 Mailcow 后台的 DNS 配置,修改域名对应的 MX 记录,SPF 记录,DKIM 记录,DMARC 记录即可。

假如我想要配置一个博客评论的邮箱,比如 no-reply@blog.einverne.info,那么首先要在 Mailcow 后台添加 blog.einverne.info 的域名,然后配置如下的 DNS 记录。

ON6L

然后在 Mailbox 中添加 no-reply@blog.einverne.info 的邮箱。此时使用 Mailcow 的后台也是可以对此邮箱进行发件和收件的。但这个时候走的都是此服务器。

MXRoute 配置

首先完成MXRoute 的基础配置,当然这个地方需要注意的是必需要好好理解一下几个 DNS 记录的作用,不要完全照着 MXRoute 发过来的配置直接修改。

首先也需要在 MXRoute 后台添加域名 blog.einvenre.info,然后新增一个邮箱 no-reply@blog.einverne.info

Configure the account as a catchall for the domain. In cPanel, this is under Forwarders / Aliases → Add Domain Forwarder. Not sure where it is in DirectAdmin as I don’t have any DirectAdmin accounts to test with. The reason it needs to be a catchall is so it can be used to send mail from any address at the domain.

然后下面重要的部分配置就需要注意了。

  • 首先把域名的 MX 记录设置成自己的邮件服务器的地址,MX 记录指向自己的邮件服务器地址
  • 然后修改域名的 [[SPF]] 记录,同时授权自己的邮件服务器 IP 和 MXRoute 的 IP
  • 最后同时添加 Mailcow 的 DKIM 和 MXRoute 的 DKIM 记录

假如自己的 Mailcow 邮件服务器的 IP 地址是 198.52.100.1, IPv6 的地址是 2001:db8::1,那么配置可以像如下这样:

v=spf1 ip4:198.52.100.1 ip6:2001:db8::1 include:mxroute.com -all

如果不清楚 SPF 记录 是什么,可以参考之前的文章,解释了邮件是如何工作的。

或者,如果不想在 SPF 记录中直接使用 IP 地址,也可以使用 mx 来代替配置具体的 IP 地址,不过需要注意的是需要配置额外的 MX 记录(指向一个域名或 IP),如果配置的 MX 记录是域名,那么还需要注意配置 A 记录将域名解析到邮件服务器。如果配置 MX 域名,那么可能会产生一次额外的 DNS 查询,不过个人是推荐这么做的,因为邮件服务器的 IP 地址更换了,只需要修改域名的 A 记录值就可以了。

v=spf1 a mx include:mxroute.com ~all

最后为了让邮件送达率更高,还需要配置 [[DKIM]],在 DNS 记录中需要同时配置 Mailcow 和 MXRoute 的 DKIM 记录。

一般情况下 DKIM 记录 key 是

dkim._domainkey.example.com

值就是网站提供的类似:

v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC...

这里可以看到的是 DKIM 记录的 key,Mailcow 一般是

dkim._domainkey.example.com

而 MXRoute 一般是

x._domainkey.example.com

同时把这两个记录添加到 DNS 记录中。

完成上面的 DNS 配置之后就可以进入 Mailcow 后台配置了。

Mailcow 配置邮件中继

在 Mailcow 后台,点击 System -> Configuration (顶部菜单) → Routing 标签。

OPn3

然后找到页面中的 「Add sender-dependent transport」

O8KY

然后在这个地方添加 MXRoute Host,邮箱的用户名和密码。

添加完成之后,可以点击 「test」进行测试。输入自己邮箱的地址,然后保留 To Address 地址为默认的 null@hosted.mailcow.de 然后保证测试的结果中得到了 250 OK 。

O3Gp

然后在顶部菜单 E-Mail -> Configuration -> Domains,找到对应的域名,点击 Edit。

OJRN

在编辑界面中找到「Sender-dependent transports」,在下拉菜单中选择刚刚配置的 Relay 邮箱。

现在任何通过 Webmail 或者邮件客户端通过此域名发送的邮件都是通过 MXRoute 来发送的。

上面的功能演示的是在 Mailcow 中配置邮件中继,但是这个功能底层还是依赖的 Postfix 的标准功能 sender_dependent_relayhost_maps ,所以用户可以在其他程序比如 Mail-in-a-box 等等中进行相同的配置,或者用户也可以手动直接修改 Postfix 配置。

reference


2023-03-30 mxroute , mailcow , email-server , email-hosting , sendmail , postfix , mailu , email-template

电子书

最近文章

  • Omnivore 一款开源的稍后阅读服务 Omnivore 是一个开源的,稍后阅读应用,查看起官方的页面,支持非常多的客户端,包括了 iOS, macOS, Chrome,等等 Android 还在测试中。
  • 我买了一块 1TB 的便携移动硬盘 三星 T7 笔记本电脑用了 3 年多,各种媒体材料,尤其是音乐我喜欢放在本地,以及各种应用程序基本上已经把磁盘自带的空间占满了,这两天刚好看到日亚有促销活动,可能是看我之前搜索过 SanDisk E61,E81 ,所以推荐里面直接推送了一个三星的 T7,看了一下价格只要 10600 JPY,用 Keepa 对比了一下历史价格,以及京东上的价格,感觉还挺合适的,就下了单。
  • 对象存储服务提供商提供的免费存储容量 [[对象存储]] 的英文是 Object-based Storage System,是一种将数据以对象的形式存储在分布式系统中的服务,而不是传统的文件系统或者块存储。
  • 反查一个域名的所有子域名 前段时间看到一篇文章说因为 Nginx 的一个「特性」,在直接访问 IP ,并且没有配置默认证书的情况下 Nginx 就会返回一个 SSL 证书从而倒置域名的泄露,进而泄露了网站的源 IP,使得一些扫描网站,比如 [[censys]] 可以直接查询到域名背后的网站 IP,从而导致网站即使用了 CDN 也会遭受到攻击。在这个契机下,我又开始了衍生,因为在 censys,[[fofa]],[[Shodan]] 等等网站上你只需要输入一个域名就可以获得所有这个站点相关的信息,那么有没有办法可以在只知道一个网站域名的情况下知道所有的二级域名呢。
  • 使用 Dokku 构建属于你自己的 PaaS Dokku 是一个开源的 PaaS,用户可以非常轻松地构建自己的 PaaS 云平台。