工程代码挑战网站 CodeWars 使用体验

CodeWars 是一个面向工程的代码挑战网站。不同于 [[LeetCode]] 侧重于考察算法,CodeWars 更注重与工程代码,提供了基础的单元测试,以及不同语言的实现。

相较于 LeetCode CodeWars 上面的问题相对比较直接,有些甚至可以用来学习一些编程语言的特性。和 LeetCode 一样带有讨论版,可以通过讨论版来学习。

codewars

适合的场景

  • 学习新一门新语言,通过完成题目来熟悉基础的语法
  • 想通过解题来了解语言的特性,比如 Java 中 stream

CodeWars 中也包含一些基础的算法,随着 Rank 越来越高也会有比较难的题目。

不同的模式

在注册进入 CodeWars 之后,会让用户选择不同的模式。

  • Fundamentals
  • Rank Up
  • Practice and Repeat
  • Beta
  • Random

基础,升级,练习,Beta,随机。可以根据自己的需求选择。

总结

如果看完上面的介绍你觉得 CodeWars 不错的话,可以点击 这里 来注册。如果你觉得又可以分享的解题思路,也可以点个 关注 一起来讨论。


2022-07-12 codewars , leetcode , coding , programming

利率史 读书笔记

怎么知道的这一本书

在看上一本 [[金融的本质]] 时突然对利率的变动比较好奇,所以就发现这一本《利率史》,一本关于利率变化历史的书籍。

在 [[金融的本质]] 一书中可以看到美联储可以通过影响隔夜拆借利率进而来影响整体市场的利率,从而通过利率来调控宏观经济。为什么利率对整个经济有如此巨大的影响?美联储加息成为了 2022 年全球经济的关键字。而国内房地产市场萧条,央行为什么通过调整房贷利率进而进一步影响房地产市场?这些问题都是我想通过这一本书想要了解的。

关于作者

本书的作者是[[悉尼 霍默]],债券经纪人,职业早期创办了自己的债券公司,开了固定收益分析的先河。霍默率先应用了相对价值分析、收益曲线以及金融世界与经济的关系等分析工具。他是使用金融市场资金流动分析的第一人,远远早于美联储正式采用这种分析手段。1961 年来到所罗门兄弟公司,后组建并管理第一个严格局限于固定收益的研究部门。霍默首次提出将债券和其利息剥离,分别销售。

作者于 1983 年去世,本书的第四版由理查德·西勒修订,在第三版的基础上新增了 1990 年到 2005 年的世界。

几句话总结书的内容

就如书名所述,这是一本关于利率历史的书。作者通过对古代(史前史,美索不达米亚,希腊,罗马),中世纪,文艺复兴,以及近现代近 4000 年的经济史来叙述全世界各个地区的利率变化,进而去观察地区经济,以及民族兴盛和衰亡的历史。

古代

公元前 1800 年,汉漠拉比法典就已经出现了对债务人和债权人相关的法律。 公元 600 年,希腊的索伦法典也对个人债务做出了规定,取消了利率的限制,豁免了过度的债务,以及取消个人劳役偿债。

公元前 450 年,罗马的《十二铜表法》也对信贷有所规定,贷款的利息被限制在每年不超过 8.333%,高于法定上限的利息将被处以 4 倍的赔偿。允许个人劳役偿债,但是得保证奴隶的健康。

公元 800 年《查理曼法典》,禁止一切贷款。

宗教改革之后,现代欧洲对收取利息合法化,利率成为了经济学家、金融家和政治家讨论的焦点,是放任自由还是国家控制。最终英国走了索伦的路子,废除了对利率的所有法律限制,而美国各州则在自己的高利贷法中确定了固定的利率上限,继承了汉谟拉比和古罗马的法律传统。

最高利率,伯林的 10000% ,最低纽约的 0.01% 。

20 世纪的美国 1900~1945

20 世纪前 90 年,多事之秋,四大政治事件

  • 1914~1918 第一次世界大战
  • 1933~1938 新政
  • 1939~1945 第二次世界大战
  • 1974~1989 冷战

三大经济事件:

  • 1914~1917 美联储的创建
  • 1929~1939 经济大萧条
  • 1965 年开始的大幅度通货膨胀

这些事件对美国经济和利率产生了巨大影响。

利率是各国政府最直接影响的价格之一,历史的最终裁决会将近几十年利率幅震荡的一部分原因与政治因素联系在一起。

1917 年开始美联储采用欧洲已经使用很久的方式来影响利率,从而根本上改变了美国货币市场结构。通过集中银行储备金、设立最后贷款人机制,该立法终结了短期利率的无规律上涨(过去,只要出现急需贷款额超过资金供应量,就会出现短期暴涨)。短期利率仍然随着信贷供求关系的变化而起伏,但是有了封顶保底。建立美联储主要是希望通过短期商业借贷来提供一种灵活货币以服务于贸易。然而第一次世界大战不久就爆发,巨额的政府新债改变了货币市场,提升了美联储的政治责任。在接下来的几十年中,政府债务取代了银行和美联储银行投资组合中的商业票据的地位。新政、大萧条和第二次世界大战强化了这种趋势。并且利用低利率来促进就业,已经成为了一种政治目标。1921 年以前,美国的利率通常平均远远高于长期债券收益率,而在 1921 年之后,短期利率通常平均低于长期债券的收益率。

20 世纪的美国 1946~1990

通胀在 1974 年达到两位数,OPEC 组织在 1973 年末实施石油价格急剧上涨措施,通胀蔓延到自由世界大部分地区。1974,1975 年的衰退降低里通胀率,但是 1979~1981 年通胀再次席卷而来,再次回到两位数,1979 年又一次石油价格飙升,物价飞涨,1980 年代的衰退对通胀几乎没有影响。利率上升到了美国历史上的最高水平,导致了 1981,1982 年的严重衰退,之后,通胀率在 80 年代后几年减弱到 3~5%。利率和收益率也随之下滑。

从 1946 年到 1981 年,美国经历了历史上最长的一个债券熊市,持续 35 年。

20 世纪美国利率

四件政治大事(一战、罗斯福新政、二战以及 1989 年前的冷战)和三大经济事件(建立美联储、经济大萧条以及 1965 年开始的大幅通胀)对于美国经济及美国利率产生了尤其重大的影响

日本

1970 年以后的 20 年里,日本发展成为世界金融大国,从 20 世纪 50 年代开始到 70 年代,政府确定了几个重点发展对象,包括炼油、化工、工业机械和电子电器。高速发展阶段,日本采用豁免利息税的储蓄账户来鼓励个人大量存款。然而,日本的金融市场远不如西欧和北美发达,利率相对比较高;金融业比较分散,而不是集中的形式,利率受到管制,与其他国家的金融交易也受到控制。

70 年代中期,日本发生金融改革,浮动汇率,1973 年第一次石油危机,造成了管制型旧金融系统的紧张,经济已经发展到了规模巨大、在国际上非常重要的成都,无法在严格管制、封闭的金融系统下继续。日本在 1975 年放松了金融系统的大部分管制。日本货币市场和债券市场得以发展,伴随日本股市的发展,越来越向国外开放。尤其是 1975 年政府通过发行债券进行了大规模的融资以弥补财政赤字。

90 年代开始,日本的金融自由完善了许多,日本已经不再是一个高利率的国家。而事实上 80 年代,日本就成为了利率最低的国家之一。

启发或想法

利率是什么

在谈论所有其他的概念之前,我们先来回答一个问题,什么是利率?

利率的英文叫做 interest rate, 是利息率的简称。在 Longman 词典中的解释是:

the percentage amount charged by a bank etc when you borrow money, or paid to you by a bank when you keep money in an account there

新闻中常常提到美联储加息或降息,很多人都会误认为美联储可以直接决定利率,而事实是美联储只能通过控制货币供给量来决定短期利率。但是影响经济最重要的是实际利率或者称为通胀调整利率(市场利率减去通胀率)。实际利率才是对资本决策最有实质性影响的。美联储影响长期实际利率的能力是间接的。实际利率受到经济因素影响,包括经济前景这些是不受美联储控制的。

作者试图通过漫漫历史长河的利率变化来给读者展示国家和文明的兴衰,作者认为在一个自由市场条件下,长期利率的趋势可以帮助分析这个国家的经济和政治状况。

利率如何影响经济

几乎在所有的教科书或百科上面都会提到,几乎所有的国家都会将利率作为调节宏观经济的重要工具,当经济过热,通胀上升的时候就提高利率,收紧信贷。当通胀得到控制,便把利率适当的调低。

缺点

就如作者所说,本书的目的并不是为了探讨利率波动对于社会和经济方面带来的后果,而只是要搜寻、记录并分析多个国家数世纪中通行利率。

在我个人看来本书的一大优点同样也是其最大的缺点,就是数据太翔实,大面积的原始数据,以至于欠缺了作者更深入的思考和总结。并且这些数据大大影响了阅读体验,不过如果是作为一本参考书来说,倒是非常不错的资料。

谁应该看这本书

  • 这本书更像是一本工具参考书,作者用大量翔实的数据介绍了各个时期各个地区的利率,非常适合页内人士按需查阅
  • 想了解利率对经济产生影响的人
  • 专业投资债券的人

印象深刻的 Quotes


2022-07-10 reading , reading-2022 , interest-rate , rate-history

Elasticsearch 导入数据

Elasticsearch 既然作为一个全文检索引擎,那么自然需要将数据导入,让 Elasticsearch 去索引。

Elasticsearch(后简写为 ES) 的基本单元是文档,使用 JSON 来描述。

有很多方法可以把数据导入到 ES:

  • RESTful 接口
  • Bulk API 批量导入
  • elasticsearch-dump
  • Logstash 将收集的数据导入

Prerequisite

导入数据前要了解的知识。

  • Cluster,集群,通常由多个节点组成 ES 集群
  • Index,通常称为索引,文档的属性
  • Document,文档,JSON 格式定义的数据
  • Shard,分片,索引会水平分片
  • Replicas,ES 允许用户创建索引和分片的 Replicas

RESTful 接口导入

如果数据文件比较简单,只有单层 JSON 结构,并且小于 1MB,可以使用 POST 请求直接将数据提交到 ES。

假设有数据 accounts.json

{"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"}

然后可以使用如下命令导入:

curl -u admin:my_elastic_pass -H 'Content-Type: application/json' -XPOST 'http://localhost:9200/accounts/_doc/_bulk?pretty' --data-binary @accounts.json

返回:

{
  "_index" : "accounts",
  "_id" : "_bulk",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

可以通过如下命令来查看所有索引的情况:

curl "localhost:9200/_cat/indices?v"

然后访问 Kibana,在后台就可以查询导入的内容:

kibana

Bulk

这里使用官方的样例数据:

wget https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip
unzip accounts.zip
curl -XPOST 'localhost:9200/bank/account/_bulk?pretty' --data-binary @accounts.json

需要注意的是如果使用 Bulk 批量导入,那么格式需要按照:

action_and_meta_data\n
optional_source\n
action_and_meta_data\n
optional_source\n
....
action_and_meta_data\n
optional_source\n

或者可以在 Kibana 后台,点击侧边栏 Dev Tools,然后在编辑框中输入:

POST bank/_bulk
{"index":{"_id":"1"}}
{"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"}
{"index":{"_id":"6"}}
{"account_number":6,"balance":5686,"firstname":"Hattie","lastname":"Bond","age":36,"gender":"M","address":"671 Bristol Street","employer":"Netagy","email":"hattiebond@netagy.com","city":"Dante","state":"TN"}
省略...

最后点击执行。

kibana devtool bulk import

执行成功后,可以运行 curl localhost:9200/bank/_search,如果返回值中 value 是导入的条数就表示成功了。

elasticsearch-dump

Logstash

Logstash 是开源的服务器端数据处理管道,能够同时从多个来源采集数据、转换数据,然后将数据发送到 Elasticsearch 中。Logstash 的官方文档请参见:https://www.elastic.co/guide/en/logstash/current/getting-started-with-logstash.html

reference

  • <https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html

2022-07-08 elasticsearch , kibana , import-data , csv

使用 Docker 安装最新 8.x Elasticsearch 和 Kibana

[[Elasticsearch]] 是基于 [[Lucene]] 开源的全文搜索引擎。提供 RESTful 接口,可以实现精确快速的实时检索。

[[Kibana]] 是一个基于 Web 的可视化前端。还有一个 [[elasticsearch-head]] 也是一个 Elasticsearch 的前端,不过这里因为 Kibana 使用场景更加广泛,就选择 Kibana。

Installation

创建 network:

docker network create elastic

这里仅演示单节点的 Elasticsearch 搭建过程,如果要搭建集群模式,可以自行参考官网。

version: "3.0"

services:
  elasticsearch:
    container_name: es
    image: elasticsearch:8.3.2
    environment:
      - xpack.security.enabled=false
      - "discovery.type=single-node"
      - "ELASTIC_PASSWORD=${ELASTIC_PASSWORD}"
    networks:
      - elastic
    ports:
      - 9200:9200
  kibana:
    container_name: kibana
    image: kibana:8.3.2
    environment:
      - ELASTICSEARCH_HOSTS=http://es:9200
    networks:
      - elastic
    depends_on:
      - elasticsearch
    ports:
      - 5601:5601

networks:
  elastic:
    driver: bridge

Docker compose 会启动两个容器,一个容器运行 Elasticsearch,使用端口 9200,一个容器运行 Kibana 使用端口 5601.

两个镜像最新的版本可以分别在这里查看:

使用如下的命令检查 Elasticsearch 的状态:

❯ curl http://localhost:9200
{
  "name" : "d9f0b969f13c",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "VRWzzZpISPugOCQadlC88A",
  "version" : {
    "number" : "8.3.2",
    "build_type" : "docker",
    "build_hash" : "8b0b1f23fbebecc3c88e4464319dea8989f374fd",
    "build_date" : "2022-07-06T15:15:15.901688194Z",
    "build_snapshot" : false,
    "lucene_version" : "9.2.0",
    "minimum_wire_compatibility_version" : "7.17.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "You Know, for Search"
}

当启动 Elasticsearch 之后会产生一些证书,这些证书用来安全的在 Kibana 中访问 Elasticsearch。

  • http_ca.crt:CA 证书,用来签名 HTTP 请求
  • http.p12:Keystore that contains the key and certificate for the HTTP layer for this node.
  • transport.p12:Keystore that contains the key and certificate for the transport layer for all the nodes in your cluster.

http.p12transport.p12 是密码保护的 PKSC#12 keystore。

可以使用如下命令获取 http.p12 密码:

bin/elasticsearch-keystore show xpack.security.http.ssl.keystore.secure_password

可以使用如下命令获取 transport.p12 密码:

bin/elasticsearch-keystore show xpack.security.transport.ssl.keystore.secure_password

等待容器启动之后可以直接访问 Kibana http://localhost:5601/

reference


2022-07-07 docker , elasticsearch , kibana

FFmpeg 使用指南之 concat demuxer 串联多个文件

FFmpeg 可以使用 -i 参数来输入一个或多个文件,但有些时候会有一些将多个文件串联成一个文件的需求。比如将多个视频合并成一个视频文件,将多个音频文件合并和一个长音频文件。这个时候就需要使用到 FFmpeg 的 concat demuxer

concat demuxer 是 FFmpeg 1.1 引入的。主要可以用来合并多个媒体文件。

串联多个相同编码的文件

FFmpeg 有两种方式可以串联相同的文件:

  • the concat “demuxer”
  • the concat “protocol”

demuxer 更加灵活,需要相同的编码,容器格式可以不一样。而 protocol 则需要容器的格式也一致。

Concat demuxer

demuxer 通过从一个固定格式的文件中读取文件列表,然后 FFmpeg 可以对这些文件一同处理。

创建文件 mylist.txt,包含所有想要串联的文件:

# this is a comment
file '/path/to/file1.wav'
file '/path/to/file2.wav'
file '/path/to/file3.wav'

注意,这里的 # 是注释语句。文件中的文件路径可以是绝对的或相对的路径,然后就可以使用 FFmpeg 对这多个文件 stream-copy 或者 re-encode(重新编码) :

ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.wav

如果路径是相对的,这里的 -safe 0 可以省略。

如果有多个文件要添加到 mylist.txt 文件中,可以使用 Bash 脚本批量生成:

# with a bash for loop
for f in *.wav; do echo "file '$f'" >> mylist.txt; done
# or with printf
printf "file '%s'\n" *.wav > mylist.txt

Concat protocol

demuxer 在文件流级别工作,concat protocol 在文件级别工作。特定的文件(比如 MPEG-2 传输流,或者其他)可以串联起来。

下面的命令将三个 MPEG-2 TS 文件串联到一起,不重编码:

ffmpeg -i "concat:input1.ts|input2.ts|input3.ts" -c copy output.ts

串联不同编码的文件

某些情况下,多个文件可能使用不同的编码,那么上面的命令就都无法使用。

Concat filter

如果要让 concat filter 工作,输入的文件必须拥有相同的 frame dimensions (eg. 1920*1080 pixels) 并且要有相同的 framerate。

假设有三个文件需要串联起来,每一个文件都有一个视频流和一个音频流:

ffmpeg -i input1.mp4 -i input2.webm -i input3.mov \
-filter_complex "[0:v:0][0:a:0][1:v:0][1:a:0][2:v:0][2:a:0]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" output.mkv

来拆解一下命令,首先指定所有的输入文件,然后实例化一个 -filter_complex filtergraph

然后:

[0:v:0][0:a:0][1:v:0][1:a:0][2:v:0][2:a:0]

告诉 ffmpeg 使用输入文件中的哪一个流,然后发送给 concat filter。在这个例子中,第一个文件的视频流 0 [0: v:0] 和音频流 0 [0: a:0] ,第二个文件的视频流 0 [1: v:0] 和音频流 0 [1: a:0]

concat=n=3:v=1:a=1[outv][outa]

这个就是 concat fitler, n=3 告诉 filter 这里有三个输入分段,v=1 则表明每一个分段有一个视频流,a=1 表明每一个分段有一个音频流。filter 然后将这些分段连接产生两个输出流, [outv][outa] 两个输出流的名字。

注意的是两侧的双引号是必须的。

然后使用这些输出流,将他们 组合成输出文件

-map "[outv]" -map "[outa]" output.mkv

这行告诉 FFmpeg 使用 concat filter 的结果,而不是直接使用输入的 streams。

有一个叫做 mmcat 的 Bash script,可以在老版本的 FFmpeg 中实现 concat filter。

reference


2022-07-06 ffmpeg , linux , video , encoder , ffmpeg-concat

Linux 服务器控制面板 Hestia 使用

Hestia 是一个开源的 Linux 服务器控制面板,HestiaCP fork 自另一款流行的控制面板 VestaCP 。由于 VestaCP 开发和维护趋于停止,很多安全问题和漏洞没有及时修复,所以有人从 VestaCP 拉出新分支进行开发和维护。

HestiaCP 提供了一个简单干净的网页界面,给网站维护人员提供了更加简单的方式维护网页服务器。HestiaCP 提供了很多功能,包括管理部署网站(Nginx, Apache,PHP),数据库(MySQL,PostgreSQL), FTP([[ProFTPd]], [[vsftpd]]),DNS zones(Bind),邮件服务器([[Dovecot]], [[exim4]]),垃圾邮件扫描([[SpamAssassin Score]]),邮件病毒扫描([[ClamAV]])等等。

HestiaCP 还提供了基于命令行的管理工具,具体可以见 文档

另一个值得一说的功能就是,HestiaCP 提供了一键安装网站(Quick Install App)的功能,默认提供了一些非常受欢迎的网页应用,包括 [[WordPress]], [[Drupal]], [[Joomla]], [[Opencart]], [[PrestaShop]], [[Lavarvel]], [[Symfony]]。

在接触 Hestia 之前,有段时间直接使用 LNMP,或者使用 [[aapanel]],但后来发现 aaPanel 的 License 或许存在某些问题,并且在读了 Stallman著作 之后对自由软件的认识更深刻了一些,所以直接替换成 GPL 发布的 Hestia。作为 aaPanel 的开源代替品,发现 Hestia 还是非常不错的。

后台演示:

Features

  • Apache2, Nginx, PHP-FPM
  • 多 PHP 版本
  • 集群功能的 DNS 服务器
  • POP/IMAP/SMTP 邮件服务器,带反垃圾邮件,病毒扫描
  • 支持 MariaDB 和 PostgreSQL 数据库
  • 自带 [[fail2ban]] 和防火墙

Prerequisites

  • 一台运行 Debian 或 Ubuntu 的服务器或 VPS,推荐使用一个全新安装的系统,避免可能出现的任何问题
  • root 权限,或者使用 sudo

Installation

本文中演示在 Ubuntu 20.04 上安装 HestiaCP。整个过程可能会需要 15 分钟左右。

安装脚本:

wget https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh
bash hst-install.sh

可以通过 安装器 自己选择安装的组件。选择组件之后会产生一个命令:

wget https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh
sudo bash hst-install.sh --apache no --phpfpm yes --multiphp no --vsftpd yes --proftpd no --named yes --mysql yes --postgresql no --exim yes --dovecot yes --sieve no --clamav no --spamassassin no --iptables yes --fail2ban yes --quota no --api yes --interactive yes --with-debs no  --port '8083' --hostname 'your_hostname' --email 'i@youremail.com' --password 'your_password' --lang 'en'

你可以根据自己的需要自行选择需要的组件。可以在官网 文档 中查看默认会安装的组件。

安装完成之后会在日志中看到后台登录的链接,已经默认的用户名和密码。安装完成后可能会需要一次重启来完成安装。

访问 https://ip:8083 ,或者如果已经配置了域名 A 记录指向该 IP,也可以使用域名加端口来访问。

netplan 错误

安装过程中如果遇到:

[ * ] Installing dependencies...
!!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!                                             
WARNING: Your network configuration may not be set up correctly.
Details: The netplan configuration directory is empty.
You may have a network configuration file that was created using                                                systemd-networkd.

It is strongly recommended to migrate to netplan, which is now the
default network configuration system in newer releases of Ubuntu.

While you can leave your configuration as-is, please note that you
will not be able to use additional IPs properly.

If you wish to continue and force the installation,
run this script with -f option:
Example: bash hst-install-ubuntu.sh --force

!!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
Error: Unable to detect netplan configuration.

是因为 Ubuntu 没有使用 netplan,或者 VPS 主机提供的镜像没有使用 netplan,但是 /etc/netplan 文件夹存在,这就导致 HestiaCP 安装脚本执行过程中判断错误。

解决方案:查看 /etc/netplan 文件夹,如果配置文件夹是空的,那么可以直接删除该文件夹,如果确定自己已经使用了 netplan 作为网络配置,那么检查一下网络配置。

Usage

申请 Let’s Encrypt SSL 证书

在完成安装访问后台的时候,浏览器会报 Your connection is not private 的错误,这是因为 SSL 证书缺失了。

可以使用 v-add-letsencrypt-host 命令来圣晴证书。

不过我在执行的过程中发生一些问题,报错:

Error: Let's Encrypt validation status 400 (xxx.einverne.info). Details: Unable to update challenge :: authorization must be pending
Error: Let's Encrypt SSL creation failed

查看发现因为在机器上安装了 Docker,所以虚拟了一个网络端口,在后台 Web 查看域名的时候,看到其中关联的 IP 地址是一个本地的地址 172.17.0.1,把这个地址修改成 VPS 的真实 IP 地址。然后重新执行命令即可。

如果出现其他的错误,也可以到如下的目录中查看日志:

/var/log/hestia/LE-user-domain-timestamp

Create a new user

虽然以 admin 登录可以在后台做任何事情,但是还是推荐创建一个新用户,以新用户的身份来操作。

添加域名

创建完用户之后以该用户登录,然后在 Web 中,选择添加域名。

添加的过程中有如下配置:

  • Domain:需要添加的域名
  • IP Address: IP 地址,如果服务器有多个 IP 这里也会显示出来
  • Create DNS zone: 如果想要 HestiaCP 来管理 [[DNS zone]] 可以配置
  • Enable mail for this domain: 如果要使用该域名来发送邮件可以配置该选项

在高级选项中:

  • Aliases: 默认你需要配置 www.yourdomain.com 指向你的域名
  • Proxy Support: HestiaCP 默认使用 Nginx 来代理静态文件
  • Web Statistics: 是否开启数据记录,默认未开启,但是 HestiaCP 自带了强大的 AWStats,可以到其 官网 查看
  • Custom document root: 默认是 /home/your_user/web/your_website/public_html/
  • Enable SSL for this domain: 开启 SSL
  • Additional FTP Accounts: 是否创建 FTP 账号

Tips

修改面板的端口

默认情况下 HestiaCP 使用 8083 端口,当然在安装的时候也可以指定,但是如果安装完成之后想要调整端口,可以使用如下的命令:

v-change-sys-port 2083

强制主机 SSL

强制主机名使用 SSL

v-add-letsencrypt-host
v-add-web-domain-ssl-hsts 'admin' 'hcp.domain.com'
v.add-web-domain-ssl-force 'admin' 'hcp.domain.com'

删除不需要的主机方案

rm -fr /usr/local/hestia/install/rhel
rm -fr /usr/local/hestia/install/ubuntu
rm -fr /usr/local/hestia/install/debian/7
rm -fr /usr/local/hestia/install/debian/8
rm -fr /usr/local/hestia/install/debian/9

开放端口

touch /etc/iptables.up.rules
v-add-firewall-rule ACCEPT 0.0.0.0/0 22 TCP SSH
v-add-firewall-rule ACCEPT 0.0.0.0/0 5566 TCP HestiaCP

使用命令行工具

source /etc/profile
PATH=$PATH:/usr/local/hestia/bin && export PATH

修改控制面板的 IP

可以使用命令行:

v-update-sys-ip 1.2.3.4
v-rebuild-web-domains admin
v-rebuild-mail-domains admin

HestiaCP vs VestaCP

HestiaCP 是 VestaCP fork,VestaCP 开发和维护趋于停止,存在许多漏洞和安全性问题。VestaCP 是第一个 Nginx 的 GUI 控制面板。在 VestaCP 之前有很多 CLI-only 的管理工具。

  • HestiaCP 支持 Debian 和 Ubuntu
  • HestiaCP 添加了 CardDAV/CalDAV/ActiveSync 支持。1
  • [[aapanel]]
  • [[CyberPanel]]
  • [[DirectAdmin]]

2022-07-05 linux , control-panel , hestia , web-server , mail-server , dns , aapanel

Elasticsearch 入门使用

[[Elasticsearch]] 是一款基于 [[Lucene]] 的开源的、分布式的搜索引擎。提供一个分布式、多租户的全文搜索引擎。提供 HTTP Web 界面和 JSON 格式接口。

Elasticsearch 由 Java 实现,是目前最流行的大数据存储、搜索和分析引擎。

GitHub:https://github.com/elastic/elasticsearch

大数据要解决三个问题:

  • 存储
    • 传统关系型数据库 MySQL,Oracle 遇到瓶颈,Google 提出 Map/Reduce 和 Google File System,Hadoop 作为开源实现在业界得到应用,但 Hadoop 存储无法实现数据实时检索和计算
  • 检索
    • [[Apache Hive]] 作为在 Hadoop 基础之上的数据仓库提供了查询分析的能力
  • 展现

但 Elasticsearch + Kibana 的组合可以快速解决如上提到的问题。

Elasticsearch 是面向文档的,存储整个文档或对象,内部使用 JSON 作为文档序列化格式。

installation

在使用 Linux 安装之前设置 vm.max_map_count 至少是 262144.

使之生效:

sudo sysctl -w vm.max_map_count=262144

让系统重启之后也生效,需要编辑 /etc/sysctl.conf 添加一行:

vm.max_map_count=262144

通过 docker-compose 安装。

也可以下载手动安装

我个人推荐在本地使用单节点安装启用

默认情况,Elasticsearch 通过 9200 端口对外提供 REST API。Kibana 的默认端口是 5601。

如果遇到如下问题,请查看是否设置了 vm.max_map_count

es03_1 ERROR: [1] bootstrap checks failed. You must address the points described in the following [1] lines before starting Elasticsearch.

Single node

单节点的 Elasticsearch 可以使用 Docker 在本地启用,参考这里

常用命令:

docker network create elastic
docker run --name es --net elastic -p 9200:9200 -p 9300:9300 -it docker.elastic.co/elasticsearch/elasticsearch:8.3.1
docker exec -it es /usr/share/elasticsearch/bin/elasticsearch-reset-password

概念

Node

Node,节点,Elasticsearch 运行实例,集群由多个节点组成。节点存储数据,并参与集群索引、搜索和分析。

Shard

Shard, 分片,数据中的一小部分,每一个分片是一个独立的 Lucene 实例,自身也是一个完整的搜索引擎。

索引会存储大量的数据,这些数据会超出单个节点的硬件限制,例如,占用 1TB 磁盘空间的 10 亿个文档的单个索引可能超出单个节点的磁盘容量,所以 Elasticsearch 提供了索引水平切分(Shard 分片)能力。

创建索引时只需要定义所需分片数量。每一个分片本身就是一个具有完全功能的独立「索引」,可以分布在集群中的任何节点上。

文档会被存储并被索引在分片中。但是当我们使用程序与其通信时,不会直接与分片通信,而是通过索引。

当集群扩容或缩小时,Elasticsearch 会自动在节点之间迁移分配分片。

分片分为:

  • 主分片 primary shard
  • 从分片 replica shard

从分片是主分片的副本,提供数据的冗余副本,在硬件故障时提供数据保护,同时服务于搜索和检索只读请求。

索引中主分片的数量在索引创建之后就固定了,但是从分片数量可以随时改变。

设置三个主分片和一组从分片

PUT /blogs
{
    "settings" : {
        "number_of_shards" : 3,
        "number_of_replicas" : 1
    }
}

分片很重要:

  • 分片可以水平拆分数据,实现大数据存储和分析
  • 跨分片进行分发和并行操作,提高性能和吞吐量

Index

Index, 索引。在 Elasticsearch 中,存储数据的行为叫做索引 Indexing,在索引数据值前,要决定数据存储在哪里。

单个集群中可以定义任意多索引。

一个 Elasticsearch 集群可以包含多个索引(数据库),可以包含很多类型(表),类型中可以包含很多文档(行),文档中包含很多字段(列)。

关系数据库  -> 数据库 -> 表 -> 行 -> 列 (column)
Elasticsearch -> 索引 -> 类型 -> 文档 -> 字段(field)

在 Elasticsearch 中索引有不同的含义。

作为名词

索引就是 Elasticsearch 提供的「数据库」。

作为动词

为文档创建索引,就是将文档存储到索引(数据库)中的过程,只有建立了索引才能被检索。

反向索引

在关系型数据库中为某一列添加索引,是在文件结构中使用 B-Tree 加速查询。在 Elasticsearch 和 Lucene 中使用 Inverted index (反向索引)的结构来实现相同的功能。

通常文档中的每一个字段都被创建了索引(有一个反向索引)

创建索引

假如要创建员工名单:

PUT /corp/employee/1
{
"first_name" : "John",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
  • 为每一个员工文档创建索引
  • 文档被标记为 employee 类型
  • 这个类型会存放在 corp 索引中

Document

Document 文档,可被索引的基本信息单元。文档以 JSON 表示。单个索引理论上可以存储任意多的文档。

副本

副本在分片或节点发生故障时提供高可用。

分片和对应的副本不可在同一个节点上

副本机制,可以提高搜索性能和水平扩展吞吐量,因为可以在所有副本上并行搜索。

默认情况下,Elasticsearch 中的每个索引都分配一个主分片和一个副本。集群至少需要有两个节点,索引将有一个主分片和一个完整副本。

Query DSL 搜索

Elasticsearch 提供了灵活的查询语言,可以完成更加复杂的搜索任务。

使用 JSON 作为主体:

GET /megacorp/employee/_search
{
    "query" : {
        "match" : {
            "last_name" : "Smith"
        }
    }
}

Aggregation

Elasticsearch 有一项功能叫做 Aggregation,类似于 GROUP BY,但是更强大。结合查询语句可以实现非常多的聚合操作。

分布式

Elasticsearch 可以被扩展到上百成千台服务器来处理 PB 级别的数据。Elasticsearch 是分布式的。用户在使用的过程中不需要考虑到分片,集群等等,这些都是 Elasticsearch 自动完成的:

  • 将文档分区到不同的容器,分片中
  • 跨节点平衡集群中节点间的索引和搜索负载
  • 自动复制数据提供冗余副本,防止硬件错误造成数据丢失
  • 自动在节点之间路由
  • 无缝扩展或恢复集群

集群健康状态查询:

GET /_cluster/health
{
"cluster_name": "elasticsearch",
"status": "green", <1>
"timed_out": false,
"number_of_nodes": 1,
"number_of_data_nodes": 1,
"active_primary_shards": 0,
"active_shards": 0,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 0
}

其中 status 有三个状态:

  • green 主分片和从分片都可以用
  • yellow 主分片可用,但存在从分片不可用
  • red 存在不可用的主分片

使用

集群健康状况:

GET /_cat/health?v

列出节点信息:

GET /_cat/nodes?v

列出集群中索引信息:

GET /_cat/indices?v

创建索引:

PUT /customer?pretty
GET /_cat/indices?v

2022-07-04 elasticsearch , elastic , lucene , search , java

编码 读书笔记

怎么知道的这一本书

之前在 Twitter 上看到一则帖子,有人求推荐书,如果要向一位学金融的朋友推荐一本计算机入门书籍,你会选择哪一本?在答复里面,我看到了有人推荐这一本《编码:隐匿在计算机软硬件背后的语言》。所以我把这一本书作为 [[20220627 21 天挑战计划]] 中要阅读的一本书。当时我没有想到的是,在豆瓣标记的时候我意外发现我早已经在 2018 年标记读过,但当时没有做笔记,也没有整理标记,4 年过去,就像没有读过一样。这更加坚定了我之后读书一定要整理书摘,用自己的语言撰写一下读书笔记的决心。

几句话总结书的内容

编码是一本由实体世界中信息传递,进而一步步带领读者进入计算机编码的通俗读物。作者会使用通俗易懂的语言,循序渐进地引领读者理解计算机是如何工作的。

什么是编码?

作者在本书的开头引用了《美国传统英语词典》对编码(code)的解释:

  • 3.1 a system of signals used to represent letters or numbers in transmitting messages
  • 3.2 a system of symbols, letters, or words given certain arbitrary meanings, used for transmitting messages requiring secrecy or brevity
    1. a system of symbols and rules used to represent instructions to a computer

这其中可以看到两层含义,一种是表达在信息传输过程中用来表述字母或数字的信号,可以是直接的信号,也可以是加密的,或简练的信息;另外一层含义是由字符和规则组成的系统用来向计算机传达指令。

同样在《牛津高阶英汉词典》中的解释更为直接:

    1. a system of computer programming instructions

也就是,计算机编程指令系统。

而在本书中,编码特指的是在机器和人之间传递信息的方式。我们所编写的代码,需要让计算机可以理解执行。

莫尔斯编码

我们都知道一个国际求救信号 SOS,但为什么是 SOS 呢,是什么的缩写吗?是比较好读吗?其实都不是,而原因是因为在莫尔斯编码中,S 是三个点,而 O 是三个划(-),SOS 是一个比较容易记忆的编码序列,并且不容易和其他序列搞混。于是这个编码就作为国际通用的求救信号留了下来。

莫尔斯编码通过对字母进行点和划的编码以实现信息的传递,但这个效率无疑是比较低的,如果在手动操作的情况下,每分钟也只能传递各位数字的单词,而通过口头交流可以达到每分钟 100 个单词左右的速度。

布莱叶盲文

布莱叶盲文通过凸起的点编码文字,使得盲人可以阅读。布莱叶盲文通过三行两列的六个凸起的点编码信息,布莱叶盲文也是一种二进制编码方式,每一个凸起的点可以表示两种状态,通过不同的组合,六位的编码可以表达出 2^6,也就是 64 种不同的编码。

除了 24 个字母,为了使用的简便,后续人们还引入了字母组合,常用单词,充分利用这 64 种不同的变化。

手电筒

作者在介绍了莫尔斯编码和布莱叶盲文之后用了整整一章的内容介绍了手电,以及基本的电路知识,也许你会感到奇怪为什么在这个时候介绍了这么多电流、电压、电阻、功率的知识。但电气化的开始才是之后计算机时代来临的前提。

欧姆定律:

I = E / R

电流(I)等于电压(电动势 E)除以电阻(R)。

瓦特:

P = E * I

瓦特等于电压(E)乘以电流(I)。

但作者真正要介绍的并不是这些物理知识,而是控制电灯的开关,这一个开关,又可以将一个最简单的电路(手电)变成一个二进制的编码,开和关分别是两个状态。

电报机和继电器 电报系统

电报系统的诞生正式开启了全球即时通信的时代,但是电报是怎么来的呢?想想一想如果将一个简单的控制电灯开关的电路系统分别放到你和朋友的家中,那你们就可以分别通过开关来控制对方家中的电灯,那么就可以信息的传递。电路系统使用的原理就是如此:在线路的一端通过一些措施,使得线路的另一端发生某种变化。

[[萨缪尔 莫尔斯]] 通过电磁现象在 1836 年通过专利局,成功发明电报机,但直到 1843 年,才说服国会为其创建公共基金。1844 年 5 月 24 日,华盛顿特区和马里兰州巴尔迪摩市电报线路架设完成,完成了人类历史上第一条信息的传递:「What hath God wrought!」

电报机的发明标志着现代通信的开始,人们第一次能够在视线或听力之外的距离开始实时交流,信息的传递速度比骏马还有快。

但是电报机最大的问题是长导线带来的电阻,电报线路使用高达 300 伏的电压使得有效距离可以超过 300 英里,但线路还是无法无限延长。

于是人们发明了中继系统,每隔 200 英里设定一个中继,接收信息,然后再转发出去。于是人们发明了继电器。通过电路的方式将信息转发出去。

阿拉伯数字 十进制

全球通用的数字系统通常被称为阿拉伯数字,起源于印度,被阿拉伯数学家带入欧洲。波斯数学家穆罕默德·伊本穆萨·奥瑞兹穆(根据这个人的名字衍生出英文单词 algorithm)在公元 825 年写了一本关于代数的书,使用了印度计数系统。

  • 阿拉伯数字系统和位置有关,一个数字的位置不同,表示计量不同
  • 没有专门用来表示数字 10 的符号
  • 比代表数字 10 的符号还有用得多嗯符号 0

这个 0,是数字和数学史上最重要的一个发明。0 的出现简化了乘法和除法。

十进制的代替

因为人类是有 10 个手指,所以适应了 10 进制,于是作者通过循序渐进的方式提问,如果是 4 指动物呢?于是进一步介绍了 8 进制,再如果是龙虾呢?两个大钳子,4 进制,再如果是海豚呢?两个鳍,2 进制。

当我们把数字系统减少到只有 0 和 1 的二进制系统时,我们无法找到比二进制系统更加简单的数字系统了。但是之前提到过的所有开关、电线、灯泡、继电器都可以用来表示二进制的 0 和 1。

二进制

1948 年,美国数学家约翰·威尔德·特克(John Wilder Turkey)意识到随着计算机的普及,二进制可能为发挥极大作用,所以发明了一个新的、更短的词语来替代不方便的 binary digital,选择了短小、简单、精巧的词 bit。

逻辑与开关

交换律:

A + B = B + A
A * B = B * A

结合律:

A + (B + C) = (A + B) + C
A*(B*C) = (A*B)*C

分配率:

A*(B+C) = A*B + A*C

传统代数是处理数字的,布尔的天才在于将代数从数的概念中抽离出来,更加抽象。在布尔代数中,操作数不是数字而是类(class),简单来说,一个类就是一个食物的群体(集合 Set)。

布尔代数中,符号 + 表示两个集合的并集,x 表示两个集合的交集。

但是布尔生活的那个时代,没有人把布尔代数用于电路。直到 20 世纪 30 年代的香农。

逻辑门

克洛德·艾尔伍德·香农在 1938 年,完成了《继电器和开关电路的符号分析》(A Symbolic Analysis of Relay and Switching Circuits)一篇著名的硕士论文,并在 10 年之后,发表《通信的数学原理》(The Mathematical Theory of Communication) 清晰尔严谨地阐述了,电子工程师可以运用布尔代数的所有工具去设计开关电路。如果简化了一个网络的布尔表达式,那么也可以简化相应的电路。

于是人们在简单的电路基础上抽象出了与门、或门、与非门、与或门等等。

字节与十六进制

8 比特表示一个字节(byte),8 比特在很多方面都比单独的比特更胜一筹。

全世界大部分书面语言(除了中日韩中使用的象形文字)的基本字符都少于 256 ,字节是一种理想的保存文本的手段。

当一个字节无法表示所有信息时,使用两个字节,也可以很好的表达。

从算盘到芯片

20 世纪 40 年代初期,真空管开始取代继电器,到 1945 年,真空管已经完全取代了继电器。

晶体管不再需要真空而是使用固体制造,体积比真空管更小,晶体管需要的电量更小,产生的热量更小,更持久耐用。

开发真空管的最初目的是为了放大电信号,但是同样可以应用于逻辑门的开关,作用和晶体管一样。

诺伊斯在 1957 年与其他 7 位科学家离开肖克利半导体创办仙童(Fairchild)半导体公司,并随后发明了集成电路。

1965 年摩尔(Moore)发现从 1959 年开始,同一块芯片上可以集成的晶体管数目每年番一倍。

到 20 世纪 70 年代,使用集成电路在一块电路板上制造一个完整的计算机处理器变得可能。

在比较微处理器时使用三个标准:

  • 多少位处理器,表示数据宽度,能够处理加减的比特位数
  • 最大时钟频率,单位 Hz,连接到微处理器并驱动运行的振荡器的最大频率,超过此时钟频率,微处理器将不能正常工作
  • 可寻址存储器的字节数

到 1972 年 4 月,英特尔发布 8008 芯片,一个时钟频率位 200KHz,可寻址空间为 16 KB 的 8 位微处理器。

启发或想法

虽然看到介绍已经大致了解了这绝不是一本晦涩难懂的书,但还是惊讶于作者可以将电路,布尔代数等等复杂的概念如此深入浅出地描述给作者,并且中间穿插非常多的物理学、数学发展历史,以及历史上这种对计算机硬件发展起决定性作用的部件,继电器,晶体管等等,让这一本书不但在了解计算机组成部分之外还了解到了大量有趣的历史决定时刻,让我感受到了那个天才,英雄辈出的时代精神。

在读书的过程中,不断地有各个时期学过的课程浮现在眼前,物理中的电磁学,到大学时期的,电路,代数,汇编等课程,在阅读的过程中非常享受所有知识融为一体的感觉。

曾经有一个问题总是困扰着我,[[人类为什么在近 200 年发展如此快]]?在这一本书中我更进一步的体会到了如下的几点:

  • 人类信息交换的速度变快了,这也就意味着[[波普尔]]所说的假设验证的速度变快了,在地球一端所提出的概念,可以在地球的另一端被验证。而这一过程恰恰是伴随着电路,电报,计算机,网络的发明而发生的
  • 社会的分工和合作,知识的交换创造了更高的价值,知识的自由分享产生了巨大的复利,[[布尔]]多年前的代数理论,[[冯诺伊曼]]构想的计算机结构,等等一系列思想的发展总是以超前的姿态引领着人类科技的发展

谁应该看这本书

  • 想要了解计算机是如何工作的人
  • 想要了解计算机发展历史的人

印象深刻的 Quotes

在作者对芯片的描述中,作者总结出三点去描述微处理器,时钟频率,可寻址字节数,以及位数,而这三者则是作者铺垫了非常多章节的内容,当我读到时顿时感受到了作者清晰的写作思路。


2022-07-03 reading , reading-2022 , code , computer , computer-language , encoding , computer-software , language

Plex Media Server 备份恢复和数据迁移

备份

备份是一定要做的事情,为了数据安全。

通常 Plex 中的媒体文件都会用 [[Syncthing]] 来做一份备份冗余,但是 Plex Media Server 生成的媒体文件,包括 viewstates, metadata, settings 等等就需要直接去备份 Plex Media Server 的内容了。

在 Debian/Fedora/CentOS/Ubuntu 中:

/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/

数据库地址

Plex 在本地使用 SQLite3 存储数据。

在 macOS 上:

~/Library/Application\ Support/Plex\ Media\ Server/Plug-in\ Support/Databases/com.plexapp.plugins.library.db

Windows 上:

"%LOCALAPPDATA%\Plex Media Server\Plug-in Support\Databases\com.plexapp.plugins.library.db"

在 Linux 上(包括 NAS):

$PLEX_HOME/Library/Application\ Support/Plex\ Media\ Server/Plug-in\ Support/Databases/com.plexapp.plugins.library.db

备份时不要对备份的数据进行任何修改,防止备份数据库出错。

如果修改了媒体文件的地址,需要更新数据库:

UPDATE `section_locations` 
   SET `root_path`=
       REPLACE(`root_path`, 
               '/Old_PATH/', 
               '/NEW_PATH/')
WHERE `root_path` like '%Old_PATH%';

如果确定需要修改数据库中的路径,那么确保所有表中的路径都要修改。

移动媒体文件到另外的位置

如果只是升级磁盘,文件的目录没有变化,那么只需要在迁移之前停掉 Plex Media Server,然后升级完成之后再启动即可。

如果更改了媒体文件的路径,那么就需要多出几步。

  • 首先停用 Emptying of Trash
    • 在管理后台禁用 Empty trash automatically after every scan
  • 停止 Plex Media Server
  • 将文件内容拷贝到新的位置
  • 启动 Plex Media Server
  • 启动 Plex Web App
  • 编辑 Libraries ,添加新的位置到库中,暂时保留之前的文件路径,需要对每一个移动的库都操作一遍
  • 更新库,在添加之后,执行一次 Scan Library Files,服务器会检查新位置的文件内容,然后和已经有的媒体文件做关联
  • 等待完成扫描之后移除老的文件路径。

reference


2022-07-02 plex , plex-media-server , backup , syncthing

使用 Owncast 搭建自己的在线视频串流直播间

Owncast 是一个开源,可自行架设的、去中心化的,单用户视频串流工具。Owncast 使用 Go 语言编写。支持简单的在线聊天,支持 HLS 和 S3 存储。

Owncast 可以很好的成为 Twitch,YouTube Live 等等在线直播平台的代替。用户可以完整地控制自己的内容以及服务器。

Prerequisite

  • Ubuntu 20.04
  • [[FFmpeg]] 4.2 以上版本,需带有 x264/var_stream_map

Docker 安装

Docker compose1 如下:

version: '3.3'

services:
  owncast:
    image: 'gabekangas/owncast:latest'
    restart: always
    volumes:
      - '${CONFIG_PATH}/data:/app/data'
    ports:
      - '8080:8080'
      - '1935:1935'

启动容器之后,进入 /admin 页面,默认的用户名和密码是,admin 和 abc123

手动安装

安装 FFmpeg

apt update
apt install ffmpeg

下载 owncast:

mkdir -p /opt/owncast && cd /opt/owncast
wget https://github.com/owncast/owncast/releases/download/v0.0.2/owncast-0.0.2-linux-64bit.zip
unzip owncast-0.0.2-linux-64bit.zip

修改配置文件:

vim config.yaml

修改自己的串流秘钥和信息,样例文件内容如下:

# See https://owncast.online/docs/configuration/ for more details

instanceDetails:
  name: EV   //名称
  title: EV Live Stream  //网站标题

  logo:
    small: /img/logo128.png
    large: /img/logo256.png

  tags:
    - music
    - software
    - streaming

  # https://owncast.online/docs/configuration/#external-links
  # for full list of supported social links.  All optional.
  socialHandles:
    - platform: github
      url: http://github.com/owncast/owncast
    - platform: mastodon
      url: http://mastodon.something/owncast

videoSettings:
  # Change this value and keep it secure.  Treat it like a password to your live stream.
  streamingKey: secret_key   //串流秘钥

启动 owncast

./owncast

启动后查看日志文件 transcoder.log 如果没有报错着运行成功,如报错无法正常串流播放

可以使用 screen 或者 [[tmux]] 等工具在使用后台运行 owncast:

screen -S live  //创建新的命令行
cd cd /opt/owncast  //进入目录
./owncast  //执行脚本

服务器需要开放端口 1935,8080 设置 OBS 串流

服务器 rtmp://127.0.0.1/live 串流秘钥 [secret]

播放地址 http://127.0.0.1:8080

成功运行之后,日志文件在 transcoder.log

自动安装

cd /your/own/path
curl -s https://owncast.online/install.sh | bash

执行成功之后会返回默认的端口和默认的 streaming key。

cd owncast
./owncast
# change port
./owncast -webserverport 8095

配置 Nginx 反向代理,如果熟悉 [[Nginx Proxy Manager]] 也可以直接使用这个反向代理。

添加配置文件 vi /etc/nginx/conf.d/owncast.conf:

server {
    listen 80;
    server_name     你的域名;

    location / {
        proxy_pass http://127.0.0.1:8080;    #8080改为Owncast对外开放的端口,默认为8080
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

测试:

nginx -t

使配置生效:

nginx -s reload
sudo systemctl start nginx
sudo systemctl enable nginx
# 获取证书
sudo certbot --nginx

配置 [[systemd]],修改文件 vi /etc/systemd/system/owncast.service:

[Unit]
Description=Owncast Service

[Service]
Type=simple
WorkingDirectory=/your/own/path/owncast  #注意替换位置
ExecStart=/your/own/path/owncast/owncast  #注意替换位置
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

生效:

systemctl daemon-reload
systemctl enable owncast
systemctl start owncast

设置 OBS

OBS 官网 安装OBS,在设置>服务中选择自定义(Custom),在管理员页面获取RTMP服务器链接和流密钥并填入OBS中,点击Start Streaming测试链接,开始推流。

FFmpeg

也可以直接从命令行使用 [[FFmpeg]] 来推流到 Owncast 服务器。

ffmpeg -re -i /path/to/video.mp4 -c copy -f flv rtmp://localhost:1935/live/secret_key
# or
ffmpeg -i "http://IP_OF_HDHR:5004/auto/vCH.N" -c:v libx264 -c:a aac -b:v 512K -maxrate 512K -bufsize 1M -f flv rtmps://OWNCAST_URL:PORT/live/STREAM_KEY
# or
ffmpeg -video_size 1280x720 -i $1 \
  -c:v libx264 -b:v 512k -maxrate 1984k -bufsize 3968k \
  -c:a aac -b:a 128k -ar 44100 \
  -f flv rtmp://live.einvrne.info/live/KEY

或者:

ffmpeg -f alsa -ac 2 -i hw:1,0 -thread_queue_size 64 \
  -f v4l2 -framerate 60 -video_size 1280x720 -input_format yuyv422 -i /dev/video2 \
  -c:v libx264 -preset veryfast -b:v 1984k -maxrate 1984k -bufsize 3968k \
  -vf "format=yuv420p" -g 60 -c:a aac -b:a 128k -ar 44100 \
  -f flv rtmp://<ip-of-your-server>/live/<your-streaming-key>

如果串流 MP4 遇到:

Codec mpeg4 is not supported in the official FLV specification,

解决方案:

ffmpeg -re -nostdin -i "$file" \
    -vcodec libx264 -preset:v ultrafast \
    -acodec aac \
    -f flv rtmp://<your-server>/app/STREAM_KEY

说明:

  • -vcodec codec 设置视频编码器,是 -codec:v 的别名
  • -acodec codec 设置音频解码器,是 -codec:a 的别名
  • -nostdin 表示禁止交互输入
  • -preset:v 表示使用 FFmpeg 默认的编码,按速度降序 ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow, placebo
  • -f fmt 强制指定输入或输出的文件格式

ffmpeg -re -i ~/INPUT_FILE -vcodec libx264 -profile:v main -preset:v medium -r 30 -g 60 -keyint_min 60 -sc_threshold 0 -b:v 2500k -maxrate 2500k -bufsize 2500k -filter:v scale=”trunc(oha/2)2:720” -sws_flags lanczos+accurate_rnd -acodec libfdk_aac -b:a 96k -ar 48000 -ac 2 -f flv rtmp://live.twitch.tv/app/STREAM_KEY

reference


2022-06-29 owncast , docker-compose , docker , livesteam

电子书

最近文章

  • 解决 Clash for Windows 节点测速 timeout 问题 [[Clash for Windows]] 使用过程中一直没有什么问题,但是昨天心血来潮把 Clash for Windows 从 0.18.8 升级到了最新版本(0.20.5) ,然后发现节点全部 timeout。但可以排除的是这些节点肯定是可以用的,因为在手机上是完全没有问题的。
  • Arc 浏览器初印象 很早之前就在 Twitter 上看到有人分享了 Arc 浏览器的使用体验,说是非常惊艳,我就稍微的浏览了一下官网,抱持怀疑的态度先注册了一下体验,一直好奇到了 2022 年能够在浏览器上做出什么样的创新,自 Chrome 横空出世以来,快,安全迅速抢占了浏览器市场。剩下的一点点份额被 Firefox,Safari,Edge,[[Vivaldi]] 等等占据,早两年的时候我也写过一篇标题略微耸动的文章 —- 我可能要抛弃用了很多年的 Chrome 改用 Vivaldi ,但事实是 3年多过去了,我日常用的还是 Chrome,虽然 Google 在浏览器插件,隐私等等问题上这两年来一直被诟病,但至少还没有彻底地激怒我这个用户。
  • 使用开源 Wakapi 代替 WakaTime 统计编码时间 之前折腾 GitHub Profile 的时候发现了 [[WakaTime]] 这样一款统计编码时间的工具,之后在读 waka-readme 项目的时候发现,还有两个完全开源的后端兼容版本,一个是 Golang 编写的 [[wakapi]] ,一个是 Huskell 编写的 hakatime 。
  • 使用 WakaTime 统计编码时间 [[WakaTime]] 是为程序员打造的编码统计 Dashboard,可以同来统计项目,编程语言,IDE,编码时间等等内容。 之前在折腾 GitHub Profile 的时候发现的,可以在 GitHub Profile 页面中动态的展示最近的编程状态。
  • 折腾一下 GitHub Profile 虽然很早就知道 GitHub 发布了 Profile 功能,可以使用 README 来丰富 Profile 页面。但是一直以来没啥动力,大多数时候都不会去到主页去访问。但现在有些时候逛 GitHub 的时候会点到 其他人 的主页去看,发现有一些主页虽然只有寥寥几句,但却可以清楚的知道「他/她」最近在贡献什么内容,擅长什么技能。虽然我在 GitHub 上还是观摹大佬居多,但也想着通过这个契机在整理 GitHub Profile 的时候加深一下对自己的认知。