使用 glab 提交 Merge Request

glab 是一款使用 Go 语言实现的和 GitLab 实例交互的命令行工具。

之前是在 GitHub 上开发,但在 2022 年 11 月 22 之后,被 GitLab 官方采用,变成了官方支持的 cli 工具。

Installation

macOS & Linux 使用 Homebrew:

brew install glab

config

配置文件的地址在本地 ~/.config/glab-cli/

❯ cat .config/glab-cli/config.yml
# What protocol to use when performing git operations. Supported values: ssh, https
git_protocol: https
# What editor glab should run when creating issues, merge requests, etc.  This is a global config that cannot be overridden by hostname.
editor:
# What browser glab should run when opening links. This is a global config that cannot be overridden by hostname.
browser:
# Set your desired markdown renderer style. Available options are [dark, light, notty] or set a custom style. Refer to https://github.com/charmbracelet/glamour#styles
glamour_style: dark
# Allow glab to automatically check for updates and notify you when there are new updates
check_update: false
# Whether or not to display hyperlink escapes when listing things like issues or MRs
display_hyperlinks: false
# configuration specific for gitlab instances
hosts:
    gitlab.com:
        # What protocol to use to access the api endpoint. Supported values: http, https
        api_protocol: https
        # Configure host for api endpoint, defaults to the host itself
        api_host: gitlab.com
        # Your GitLab access token. Get an access token at https://gitlab.com/-/profile/personal_access_tokens
        token:
# Default GitLab hostname to use
    gitlab_host:
      token: glpxxx
      apt_host: gitlab_host
      git_protocol: https
      api_protocol: https
      user: gitlab_username
host: gitlab.com

附加填充里面的 token 等信息即可。

环境变量

GITLAB_URL=
# or GITLAB_HOST=
GITLAB_TOKEN=

zsh completion

glab completion -s zsh > /path/to/zsh/completion

可以通过 echo $FPATH 来查看本机 Zsh 的 completion 文件路径。

merge requests

创建 Merge Request:

glab mr create -a username -t "fix something"
glab mr create --autofill --labels bugfix
glab mr create --squash-before-merge --remove-source-branch -a username -t "feat: message"

合并

glab mr merge 123
glab mr note -m "needs to do before it can be merged" branch-foo

同意:

glab mr approve {id | branch} [flags]

glab mr approve 234
glab mr approve 234 456
glab mr approve branch-1
glab mr approve branch-1 branch-2

reference

[[2019-06-20-gitlab-cli-merge-request]]


2022-07-19 gitlab , git , cli , gitlab-cli , golang

Netdata outbound_packets_dropped_ratio 告警

一直使用 Netdata 来作为 VPS 的监控,配合 Netdata Cloud 来作为监控面板体验一直都不错。不过最近有一台机器经常发送邮件告警:

outbound_packets_dropped_ratio

看这个告警一头雾水,虽然每个词都懂,但就是不知道表示的什么含义。所以搜罗各种资料学习一下。

什么是 outbound packets dropped ratio

详细的解释 Netdata 也给了出来:

Details: ratio of outbound dropped packets for the network interface venet0 over the last 10 minutes

过去 10 分钟内网卡 venet0 出站的流量丢包率。

那具体什么是 dropped packets 呢?在 Linux 下有很多原因会出现丢包,有可能是网络不稳提,或者网络拥堵,或者应用无法处理负载。

Linux 下显示网络接口的 dropped packet

❯ sudo netstat -i
Kernel Interface table
Iface      MTU    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
br-c834d  1500  7024713      0      0 0       5439423      0      0      0 BMU
br-f28aa  1500   446015      0      0 0       7656772      0      0      0 BMRU
br-f50ea  1500  5779300      0      0 0       6093954      0      0      0 BMRU
docker0   1500        0      0      0 0             0      0      0      0 BMU
lo       65536 38808638      0      0 0      38808638      0      0      0 LRU
venet0    1500 78213871      0      0 0      114697804      0  25737      0 BOPRU
venet0:0  1500      - no statistics available -                        BOPRU
vethd37c  1500   151555      0      0 0        209478      0      0      0 BMRU
vethe8b7  1500     8254      0      0 0        134561      0      0      0 BMRU

可以看到图中 venet0 这块网卡在 TX-DRP 上确实是有一定的丢包。

显示网卡的统计信息:

netstat -s
# 显示 tcp
netstat -s -t
# 显示 udp
netstat -s -u

netstat -s 的结果

Ip:
    Forwarding: 1          //开启转发
    31 total packets received    //总收包数
    0 forwarded            //转发包数
    0 incoming packets discarded  //接收丢包数
    25 incoming packets delivered  //接收的数据包数
    15 requests sent out      //发出的数据包数
Icmp:
    0 ICMP messages received    //收到的ICMP包数
    0 input ICMP message failed    //收到ICMP失败数
    ICMP input histogram:
    0 ICMP messages sent      //ICMP发送数
    0 ICMP messages failed      //ICMP失败数
    ICMP output histogram:
Tcp:
    0 active connection openings  //主动连接数
    0 passive connection openings  //被动连接数
    11 failed connection attempts  //失败连接尝试数
    0 connection resets received  //接收的连接重置数
    0 connections established    //建立连接数
    25 segments received      //已接收报文数
    21 segments sent out      //已发送报文数
    4 segments retransmitted    //重传报文数
    0 bad segments received      //错误报文数
    0 resets sent          //发出的连接重置数
Udp:
    0 packets received
    ...
TcpExt:
    11 resets received for embryonic SYN_RECV sockets  //半连接重置数
    0 packet headers predicted
    TCPTimeouts: 7    //超时数
    TCPSynRetrans: 4  //SYN重传数

或者可以使用 ip 命令:

❯ ip -s link show venet0
2: venet0: <BROADCAST,POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default 
    link/void 
    RX: bytes  packets  errors  dropped overrun mcast   
    30619319736 78217051 0       0       0       0       
    TX: bytes  packets  errors  dropped carrier collsns 
    32292008558 114701118 0       25738   0       0       

Why does linux drop packets?

为了找出 Linux 服务器为什么 drop packets 可以借助 dropwatch。这个工具可以用来诊断 Linux networking stack 的问题,主要是查看协议栈丢包问题。

dropwatch

安装必要的工具:

sudo apt-get install libpcap-dev libnl-3-dev libnl-genl-3-dev binutils-dev libreadline6-dev autoconf libtool pkg-config build-essential

安装完之后执行 libtoolize,这会拷贝,连接必要的脚本,包括 ltmain.sh

然后手动编译:

git clone https://github.com/nhorman/dropwatch
cd dropwatch
./autogen.sh
./configure
make
make install

如何修改告警策略

因为我是用 docker 安装,所以需要进入 netdata 容器:

docker exec -it netdata /bin/sh

然后执行:

/etc/netdata/edit-config health.d/net.conf

其中的第 107 行即可。

reference


2022-07-13 netdata , monitor , vps , network

工程代码挑战网站 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

Eu.org 免费域名申请

eu.org 是欧盟组织下面的域名,EU 代表欧盟,Paul Mockapetris 在 1996 年的 9-10 月份创建了这个域名的 DNS 服务器。现在对个人和组织是免费注册的。

“EU.org, free domain names since 1996”。

eu.org 是 Google 认可的顶级域名。

优点:

  1. 历史悠久;
  2. 支持 NS 记录,意味着支持所有域名记录;
  3. 稳定,可长期使用;
  4. 没有任何限制

缺点:

eu.org 在国内使用 http 会被被强行重置,配合 HTTPS 才可正常访问。

注册账号

申请页面 https://nic.eu.org/arf/ 注册账号,验证邮箱。

申请域名

点击 New Domain 申请域名。

  • 输入想要注册的域名,包括后缀
  • 填写地址
  • 需要提前添加 DNS 服务器,需要把准备申请的域名添加

在申请域名的时候需要提前填写 DNS 信息,但是 Cloudflare 不能提前添加未注册的域名,所以不能用 Cloudflare。

这里可以使用:

  • https://dns.he.net/
  • dns.com
  • dnspod

Hurricane Electric Hosted DNS(HE) NS Records:

  • ns1.he.net
  • ns2.he.net
  • ns3.he.net
  • ns4.he.net
  • ns5.he.net

DNSPOD 的 NS Record 一般都是 XXX.dnspod.com

之后 EU.org 会开始验证 NS 记录。如果没有问题最后的日志会是 done

---- Servers and domain names check

Getting IP for PHIL.NS.CLOUDFLARE.COM: 108.162.193.137 172.64.33.137 173.245.59.137
Getting IP for PHIL.NS.CLOUDFLARE.COM: 2803:f800:50::6ca2:c189 2606:4700:58::adf5:3b89 2a06:98c1:50::ac40:2189
Getting IP for VERA.NS.CLOUDFLARE.COM: 172.64.32.147 108.162.192.147 173.245.58.147
Getting IP for VERA.NS.CLOUDFLARE.COM: 2803:f800:50::6ca2:c093 2a06:98c1:50::ac40:2093 2606:4700:50::adf5:3a93


No error, storing for validation...
Saved as request 202303xxxxxxxx-arf-3xxxx

Done

这个过程的时间不确定,可能会是 1 天,也可能好几个星期,最后注册邮箱中会收到 EU.org 发过来的邮件,标题一般是 request [20210906172103-arf-xxxx] (domain test.EU.ORG) accepted,这表示域名注册成功了。

中途遇到的问题

Eu.org 在验证 NS 的过程中可能会出现如下错误:

SOA from NS1.HE.NET at 216.218.130.2: Error: Answer not authoritative (148.835 ms)

这个时候注意在前面选项 Name Servers 中选择 server names 单选项。

将 eu.org 域名添加到 Cloudflare

当 eu.org 域名申请完毕,可以将域名添加到 Cloudflare 管理。

首先需要在 eu.org 管理后台中修改域名的 nameservers 修改成 Cloudflare 的 NS 地址。

通常是:

  • phil.ns.cloudflare.com
  • vera.ns.cloudflare.com

这两个地址可以在 Cloudflare 后台添加域名之后获得。

在 Cloudflare 添加新申请的域名,如果添加的时候提示:

eu.org is not a registered domain

或者提示这个域名没有注册,就等待一下 EU.org 刷新 WHOIS,然后等待一会儿再尝试添加。


2022-07-11 eu-org , domain , free-domain

利率史 读书笔记

怎么知道的这一本书

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

在 [[金融的本质]] 一书中可以看到美联储可以通过影响隔夜拆借利率进而来影响整体市场的利率,从而通过利率来调控宏观经济。为什么利率对整个经济有如此巨大的影响?美联储加息成为了 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 服务器控制面板 HestiaCP 使用

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

HestiaCP 提供了一个简单干净的网页界面,给网站维护人员提供了更加简单的方式维护网页服务器。HestiaCP 提供了很多功能,包括

  • 管理部署网站(Nginx, Apache,PHP)
  • SSL 证书及 SNI Wildcard support
  • 数据库(MySQL,PostgreSQL)
  • FTP([[ProFTPd]], [[vsftpd]])
  • DNS zones(Bind)DNS 服务器
  • 邮件服务器([[Dovecot]], [[exim4]])支持 [[SPF]]、[[DKIM]] 等
  • 垃圾邮件扫描([[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 还是非常不错的。

后台演示:

hestia control panel

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'

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

安装完成之后会在日志中看到后台登录的链接,以及默认的用户名(admin)和密码。脚本执行完成后可能会需要一次重启来完成安装。

访问 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 账号

Nginx 模板设置

可以在 /usr/local/hestia/data/templates/web/nginx/ 目录下查看到默认的 Nginx 配置模板。其中的默认模板:

  • default.tpl
  • default.stpl

可以将默认的模板拷贝到新的文件修改:

cp original.tpl new.tpl
cp original.stpl new.stpl
cp original.sh new.sh

模板中支持的变量可以参考官网

Tips

修改面板的端口

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

v-change-sys-port 2083

重置 admin 密码

更改 admin 用户密码

v-change-user-password admin yourpass

或者更改其他任何用户的密码。

更改 hostname

v-change-sys-hostname your.hostname

强制主机 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]]
  • [[Control Panel]]

reference


2022-07-05 linux , control-panel , hestia , web-server , mail-server , dns , aapanel , php , nginx , open-source , mail-server , pop2 , imap , mariadb , vsftpd , iptables

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

电子书

本站提供服务

最近文章

  • Dinox 又一款 AI 语音实时转录工具 前两天介绍过 [[Voicenotes]],也是一款 AI 转录文字的笔记软件,之前在调查 Voicenotes 的时候就留意到了 Dinox,因为是在小红书留意到的,所以猜测应该是国内的某位独立开发者的作品,整个应用使用起来也比较舒服,但相较于 Voicenotes,Dinox 更偏向于一个手机端的笔记软件,因为他整体的设计中没有将语音作为首选,用户也可以添加文字的笔记,反而在 Voicenotes 中,语音作为了所有笔记的首选,当然 Voicenotes 也可以自己编辑笔记,但是语音是它的核心。
  • 音流:一款支持 Navidrom 兼容 Subsonic 的跨平台音乐播放器 之前一篇文章介绍了Navidrome,搭建了一个自己在线音乐流媒体库,把我本地通过 [[Syncthing]] 同步的 80 G 音乐导入了。自己也尝试了 Navidrome 官网列出的 Subsonic 兼容客户端 [[substreamer]],以及 macOS 上面的 [[Sonixd]],体验都还不错。但是在了解的过程中又发现了一款中文名叫做「音流」(英文 Stream Music)的应用,初步体验了一下感觉还不错,所以分享出来。
  • 泰国 DTV 数字游民签证 泰国一直是 [[Digital Nomad]] 数字游民青睐的选择地,尤其是清迈以其优美的自然环境、低廉的生活成本和友好的社区氛围而闻名。许多数字游民选择在泰国清迈定居,可以在清迈租用廉价的公寓或民宿,享受美食和文化,并与其他数字游民分享经验和资源。
  • VoceChat 一款可以自托管的在线聊天室 VoceChat 是一款使用 Rust(后端),React(前端),Flutter(移动端)开发的,开源,支持独立部署的在线聊天服务。VoceChat 非常轻量,后端服务只有 15MB 的大小,打包的 Docker 镜像文件也只有 61 MB,VoceChat 可部署在任何的服务器上。
  • 结合了 Google 和 AI 的对话搜索引擎:Perplexity AI 在日本,因为 SoftBank 和 Perplexity AI 开展了合作 ,所以最近大量的使用 Perplexity ,这一篇文章就总结一下 Perplexity 的优势和使用技巧。