Akawa

ETY001的博客

家里的服务器重做了系统后,bitshares节点我也计划重新换一种部署模式。

由于家里的网络是动态公网IP,联通会不定时把客户端踢下线,让其重新拨号,
这就导致 IP 会不定时变动。尽管做了 DDNS 脚本,每分钟去监测变动并修改,
但是架不住 DNS 的生效时间和脚本出现意外不可用。

所以新的部署方案,我使用 frp 来让我家里的服务器主动去把本地端口映射到
远程公网服务器上(目前是阿里云香港轻量服务器)。这样就能解决 IP 变动
带来的潜在不稳定因素了。

另外一个好处就是,这样相当于是在节点前加了一层,保证了自己真实 IP 不暴露。
即使有 DDoS 过来,也是前面的阿里云的节点挂掉。

除了部署方案调整了以外,节点的 URL 地址也发生了变动。

鉴于之前 liuye.tech 这个域名是注册给公司用的,现在公司已经注销了,
所以这个域名就不再继续使用了。

新注册了 61bts.com 专门用来放 BTS 相关的东西。

新的 API 地址是:

wss://api.61bts.com

之前不知道怎么想的,在一台物理机上通过 docker 来搭建两个 Node 的 Elasticsearch 集群。

由于 ES 默认分片要有一个备份,所以导致我的硬盘用量很大,关键是在同一台物理机上搞两个 Node 没有什么意义。

所以今天我又换回了单 Node 模式。

新的 Dockerfile 我放在了我的库里,https://github.com/ety001/dockerfile/tree/master/bts-es
那个 docker-compose.yml.single 就是了。

切换回单节点后,集群的健康状态里就会显示各个索引都是 yellow。原因就是刚才说的,ES 默认会
保持一个备份分片,而单节点后,没法分发备份分片到其他节点,所以就会报不健康。

我们可以通过执行下面的命令,来让分片默认0备份

1
2
3
4
5
6
7
8
$ curl -u elastic:123456 -XPUT "http://127.0.0.1:9200/_template/default_template" -H 'Content-Type: application/json' -d'
{
"index_patterns": ["*"],
"settings": {
"number_of_replicas": 0
}
}
'

通过设置默认模板,再创建的新的分片就不再需要有备份了。

PS:我搭建的国内 Bitshares ES 节点也上线了,目前还在数据同步中

1
2
3
https://es.61bts.com
用户名: bts
密码: btsbts

昨天新买的四条服务器内存到了,于是早上去安装一下。

很不幸的是,关机安装完内存条后,系统起不来。第一反应是内存没有插好。
拔下所有新装的内存,先试试能不能开机,结果不能。

系统一直卡在一个光标闪烁的状态。

由于一直就很想重做这个服务器的系统,当时装的时候,忘记做LVM了,
所以这次故障也懒得修了,直接开始重做系统。

花了2个小时,把基础系统做完,重启了几遍看看有没有什么问题,一切正常。

看到内存插满主板达到256G顶值后,心里美滋滋,心想这下可以大开杀戒了。

结果下午回到家,没安装几个服务,主机就挂了。

由于我的服务器电源连接在米家的电源开关上,所以我进行了远程重新断电上电操作。
通过米家可以看到机器自动启动成功了,但是一直连不上,怕是系统又进不去了。

折腾了半天没有成功后,不得不再回去看看是什么情况。

重新接上显示器后,发现跟早上的情况一个样,目测应该是硬盘有问题。打开 BIOS 看了下,果然

一共三块硬盘,只识别出来了两块,最关键的那块带这 grub 引导的硬盘没有识别出来。

考虑到新系统上了 LVM ,我这块没有识别出来的硬盘(金士顿)和另外一块东芝的做成了一个逻辑组,
所以在考虑能不能把金士顿这块从逻辑组里踢出去。

但是我重启引导进U盘里的系统后,发现并没有金士顿那个硬盘

有点慌!既然系统间歇性能启动起来,那看来硬盘坏的不严重。
估计重启几次,肯定会有一次能挂上。在重启了三四次后,终于检测出来了。

好,既然监测出来了,让我先理顺一下目前的情况。

1.当前是金士顿(/dev/sdb1)和东芝(/dev/sdc1)做了一个逻辑组 /dev/vssd

2.然后在 /dev/vssd 这个逻辑组上划分了两个逻辑卷 /dev/vssd/vboot/dev/vssd/vmain

3.系统有两个分区,/ 挂在 /dev/vssd/vmain 上,/boot 挂在 /dev/vssd/vboot 上。
尝试了挂载 //boot ,发现 / 挂载成功,/boot 挂载失败,提示磁盘有错误。
系统目前不超过 7G 大。

情况理顺完,我们的思路也就有了。

  1. /dev/vssd/vmain 缩小到 /dev/sdc1 的大小以内,
  2. /dev/vssd 中把 /dev/vssd/vboot 删除,
  3. /dev/sdb1 这个 pv/dev/vssd 逻辑组中删除,这个时候,逻辑组里就没有金士顿硬盘了,
  4. 在逻辑组 /dev/vssd 中再新建一个 /dev/vssd/vboot 逻辑卷,
  5. 重新调整 /dev/vssd/vmain 的大小,让其把剩余所有的空间占有,
  6. 重新挂在 /dev/vssd/vmain/dev/vssd/vboot,在 /dev/vssd/vboot 上安装内核,
  7. 重新生成 fstab
  8. 重新安装 Grub/dev/sdc 上,并生成新的 grub.cfg 存储到 /dev/vssd/vboot 上。

开始实施。

1.缩小 /dev/vssd/vmain,需要先监测才能缩小

1
w2fsck -f /dev/vssd/vmain

执行缩小,由于我的东芝是400多G,那么我只要缩小到400G内就好了,懒得计算,取了个整 300G

1
2
3
4
# 先缩小文件系统
resize2fs /dev/vssd/vmain 300G
# 再缩小逻辑卷
lvreduce -L 300G /dev/vssd/vmain

三步操作如下图

2.从 /dev/vssd 中把 /dev/vssd/vboot 删除,

1
lvremove /dev/vssd/vboot

3.从逻辑组中移除金士顿硬盘

1
vgreduce vssd /dev/sdb1

操作完可以看到逻辑组(VG)里只有一个 PV 了,并且 VG 的容量跟东芝的硬盘一样大了

4.新建 /dev/vssd/vboot

1
lvcreate -L 200M vssd -n vboot

5.扩容 /dev/vssd/vmain

1
2
# 注意这里参数是小写L
lvextend -l +100%FREE /dev/vssd/vmain

6.格式化 /dev/vssd/vboot 后,重新挂载

1
2
mkfs.ext2 /dev/vssd/vboot
mount /dev/vssd/vboot /mnt/boot

重新安装内核

1
pacstrap /mnt linux linux-firmware

7.生成新的 fstab

由于 /dev/vssd/vboot 是新创建的,所以原来分区的 UUID 也就不存在了,因此需要更新 fstab
否则启动的时候会找不到分区。(通过截图可以看到原来的 UUID

1
genfstab -U /mnt > /mnt/etc/fstab

8.重新安装 Grub ,生成新的 grub.cfg

1
2
3
4
5
6
# 进入chroot
arch-chroot /mnt
# 安装 grub 到 /dev/sdc
grub-install --target=i386-pc /dev/sdc
# 生成新的 grub.cfg
grub-mkconfig -o /boot/grub/grub.cfg

9.所有操作结束后,退出 chroot,卸载所有已挂载分区,重启。

完美启动!!!!

天天盯盘实在是有点吃不消了,有些工作还是需要用机器来完成。
由于已经习惯了靠 Docker 部署,所以先把基础工作做好,把火币
的 python sdk 环境封装个 Docker 基础包。

Dockerfile

1
2
3
4
5
6
7
8
9
10
11
FROM alpine:3.9
WORKDIR /app
ARG TAG=1.0.5
RUN apk --no-cache add git python3 && \
git clone https://github.com/HuobiRDCenter/huobi_Python.git && \
cd huobi_Python && \
git checkout ${TAG} && \
python3 setup.py install && \
cd .. && \
rm -rf huobi_Python
CMD ["pwd"]

编译的时候,可以通过 ARG 来控制你要使用的版本。

1
docker build --build-arg TAG=1.0.5 -t ety001/huobi-lib:1.0.5 .

测试一下

在当前目录创建个测试文件 a.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from huobi import SubscriptionClient
from huobi.model import *
from huobi.exception.huobiapiexception import HuobiApiException
from huobi import RequestClient

request_client = RequestClient()

# Get the timestamp from Huobi server and print on console
timestamp = request_client.get_exchange_timestamp
print(timestamp)

# Get the latest btcusdt‘s candlestick data and print the highest price on console
candlestick_list = request_client.get_latest_candlestick("btcusdt", CandlestickInterval.DAY1, 20)
for item in candlestick_list:
print(item.high)

启动一个临时容器,测试一下我们的 SDK 是否安装正确

1
docker run -it --rm -v $(pwd):/app ety001/huobi-lib:1.0.5 python3 /app/a.py

如果环境正确,则会正常输出数据。

OVER!接下来就要去研究下火币的各个 API 了。

今天完成了我第一个 Flutter App —— 网络剪切板
当我满怀激动的编译出 Release 版本后,发现程序并不能联网。

经过搜索发现,原来要想联网需要自己手动去 AndroidManifest.xml 里添加下面的权限

1
<uses-permission android:name="android.permission.INTERNET"/>

我觉得 Flutter 的这种方式,让人觉得很恶心,这些工作不应该是 Flutter 自身的工具集
来完成的事情吗?为什么需要用户再去手动配置权限?不可思议。

由于最近需要在模拟器里搞事情,Genymotion 是个很好用的模拟器,
然而初始状态下,并不好用,需要安装很多必备软件。
这篇会简述下大致的步骤。

1. 安装 Genymotion

具体安装过程请去 Genymotion 的官网查看。
安装好以后,安装 Google Nexus 5X 8.0-API26 这个版本。

2. 安装 OpenGapps

安装 OpenGapps 的目的是为了使用 Google Play Store 来安装浏览器。
在 Genymotion 的 3.0.3 版本中,已经自带了 OpenGapps 的安装途径,
就在模拟器的控制栏上,如图所示

点击后,按照提示即可完成安装,重启后,就可以登录 Google Play Store 来安装个浏览器了。

3. 安装 Genymotion ARM Translation

由于 Genymotion 的模拟器是 x86 架构编译的 Android 系统,有一些 App 是不支持 X86 的,
所以我们需要安装一个翻译器。

访问 https://github.com/m9rco/Genymotion_ARM_Translation 这里,
找到 Android 8.0 版本的下载包,下载后直接把 zip 包拖拽进模拟器里,
按照提示信息安装即可,完成后重启模拟器。

4. 安装 XPosed 框架

访问 https://forum.xda-developers.com/showthread.php?t=3034811
在这个页面,下载 XposedInstaller_*.apk

然后访问 https://dl-xda.xposed.info/framework/
依次打开 sdk26 / x86 目录,下载最新的 zip 包。下载完成后,拖拽入模拟器安装。

安装完重启模拟器,再拖入 XposedInstaller_*.apk 进行安装,完成后,重启模拟器。

这样一些基础软件就都完成了安装,再使用起来就方便了很多。

具体的比赛贴子:https://bitsharestalk.org/index.php?topic=29665.0

使用我之前开发的机器人参赛非常简单。这里是之前发布机器人时的贴子:https://akawa.ink/2019/05/22/bts-trade-bots.html

本教程是在Linux下运行。

首先,需要有Docker环境,具体Docker安装方法请参考Docker官方网站。

然后,创建一个环境变量文件,用于配置你的机器人,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 节点地址
API_URL=wss://bts.open.icowallet.net/ws
# 账号名
ACCOUNT=
# 账号active私钥
PRIV_KEY=
# 钱包密码
PASSWD=123456
# 做市市场 Quote:Base
MARKET=GDEX.BTC:BTS
# 买单价格比率
BUY_RATE=0.01
# 卖单价格比率
SELL_RATE=0.01
# 花费base的数量
BUY_AMOUNT=100
# 得到base的数量
SELL_AMOUNT=100
# base货币最大持有量
BASE_MAX=2000
# quote货币最大持有量
QUOTE_MAX=2000

假设该文件名为 bts_bts

启动机器人的命令如下:

1
2
3
4
5
docker run -itd \
--name bot1 \
--restart always \
--env-file btc_bts \
ety001/btsbots-cli:latest

启动之后,可以用 docker logs -f --tail 100 bot1 来查看机器人的运行状态。

如果想要停止并删除机器人,执行 docker stop bot1 && docker rm bot1 即可。

继上篇文章《重写了我的bitshares-elasticsearch的docker-compose》之后,经过一天的调试,我又增加了 Kibana 的配置到 docker-compose.yml 文件中。

使用方法很简单,首先停止所有容器

1
docker-compose down

然后备份下你之前的密码,再更新代码仓库到最新。

之后,修改 kibana.yml 文件中的 elasticsearch.password 为你的 elastic 密码。

如果你想要直接暴露 Kibana 的管理端口,可以修改 docker-compose.yml 文件,

1
2
3
4
5
6
7
8
9
10
kibana:
container_name: kibana
image: docker.elastic.co/kibana/kibana:7.4.0
volumes:
- ./kibana.yml:/usr/share/kibana/config/kibana.yml
networks:
esnet:
ipv4_address: 172.22.0.5
#ports: # 去掉这里的注释即可直接暴露端口
# - 5601:5601 # 去掉这里的注释即可直接暴露端口

最后,启动所有容器即可,

1
docker-compose up -d

目前,我已经在我的节点上配置了开放用户,

URL: https://bts-es.liuye.tech/
Username: bts
Password: btsbts

OlGLOj5UsS2Ms4mf4wfRQMZWWQwmD2Uoeu6lIuaj.png

之前在《用 docker compose 搭建 bitshares elastic search》中已经介绍了如何使用docker-composer搭建 Bitshares Elastic Search 服务

最近有些时间,就对之前的部署进行了优化,并且升级了 elastic search 的版本和 Bitshares 的版本。

仓库地址(Repository) => https://github.com/ety001/dockerfile/tree/master/bts-es

Manual in English => https://github.com/ety001/dockerfile/blob/master/bts-es/README.md

如何部署

1. 克隆代码库

1
2
$ git clone https://github.com/ety001/dockerfile.git
$ cd dockerfile/bts-es

2. 修改 docker-composer.yaml 中的部分参数

  • ES_JAVA_OPTS=-Xms3g -Xmx3g 这里可以调整 es 的内存占用
  • ELASTIC_PASSWORD 这是你的es密码. 请同时修改 --elasticsearch-basic-auth 的值
  • #ports: - 9200:9200, 如果你想直接让http服务可以被访问,可以取消这个地方的注释

3. 生成证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ docker run \
-it --rm \
-v $(pwd)/ssl:/usr/share/elasticsearch/config/certs \
docker.elastic.co/elasticsearch/elasticsearch:7.4.0 \
/bin/bash

-- 进入临时容器 --

# elasticsearch-certutil ca
ENTER ENTER (两次回车)

# elasticsearch-certutil cert --ca elastic-stack-ca.p12
ENTER ENTER ENTER (三次回车)

# mv *.p12 config/certs/
# chown 1000:1000 config/certs/*.p12

# exit

4. 增加 vm.max_map_count 配置

1
$ sudo sysctl -w vm.max_map_count=262144

如果想要永久修改这个配置值,在 /etc/sysctl.conf 中增加 vm.max_map_count 设置。
配置好需要重启,执行 sysctl vm.max_map_count 检查是否配置成功。

5. 启动

1
$ docker-compose up -d

其他常用命令

1. 检查运行日志

1
$ docker-compose logs -f --tail 100

2. 停止所有容器

1
$ docker-compose down

3. 检查es是否成功运行

1
$ curl -u elastic:123456 -X GET 'http://172.22.0.2:9200/_cat/health'

123456 是你在 docker-compose.yml 中配置的密码.

4. 把 es01 加入到 nginx 的容器网络中

如果你同时使用 docker 来部署 nginx,你可以把 es01 容器加入到 nginx 容器
所在的网络里,这样可以方便 nginx 做反向代理到 eshttp 服务并加上证书。

假设你的 nginx 容器所在网络名为 lnmp

1
docker network connect --ip 172.20.0.3 lnmp es01

任何问题?

如果有任何问题,欢迎提 issue。

My bitshares account: ety001
My witness account: liuye

最近 GBAC 计划参与 Bitshares 的见证人竞选,而我负责见证人服务节点等一系列服务的搭建。

一个见证人,最好是配备2台节点服务器(主备),1台测试节点服务器,1个API节点服务器,1个喂价程序。

其中像API和测试节点为了省成本,可以跟备机一块。最让我头疼的就是喂价程序了。

找了两个老的开源的喂价程序,折腾了一整天,总是各种各样的报错,最后@abit 提供了一个 https://github.com/Zapata/bitshares-pricefeed ,最终终于打包成可用的 docker 镜像了。

目前已经提交 PR 给原库了,不过还没有合并。目前想要使用的话,可以先用我的库,

1
2
3
4
git clone https://github.com/ety001/bitshares-pricefeed.git
cd bitshares-pricefeed
git checkout develop
docker build -t bitshares-pricefeed .

打包好以后,镜像大约在250MB左右,比原作者的1G多的镜像小了很多。

使用前,先生成默认配置文件

1
docker run -it --rm -v /path/to:/app bitshares-pricefeed:latest bitshares-pricefeed create

执行后,在 /path/to 目录下会有一个 config.yml 的配置文件,里面的注释解释的比较清楚,自己看一下就好。

然后执行下面的命令即可启动喂价程序

1
docker run -v /path/to/config.yml:/config/config.yml bitshares-pricefeed:latest bitshares-pricefeed --configfile /config/config.yml --node wss://ws.gdex.top update --active-key=XXXXXXX

其中 active-key 就是你的见证人账号的 active 权限的私钥

简单来说,就是简单的两步,创建配置文件,启动喂价程序。

不得不说,现在我对于docker的依赖越来越严重了。。。

0%