两个礼拜前买过一个月 A400 互联 的 VPS,但是因为其提供商不是非常靠谱,所以尽管在使用,但还只是用作流量转发,并没有把重要的数据放在上面。这两天在 LowEndTalk 上正好看到 HostHatch 扩展新加坡业务,发布新机器 2核4G 1T流量的机器只需要 35$ 一年,而且两年付还可以得到两倍的内存,空间和流量,所以就立即下了一单。
2 CPU cores (50% dedicated, burstable up to 200%)
4 GB RAM
20 GB NVMe SSD
1 TB bandwidth
$35 per year
Pay for two years - get doubled RAM, storage, and bandwidth
中间还发生了一点小小问题,因为付款的 Paypal 很久没有使用,付款之后 HostHatch 没有处理,开了 Ticket 之后回复说因为 Paypal on-hold 了这笔订单需要等待 24 小时,等 Paypal 处理之后 HostHatch 才会开始处理。所以等待的期间我又用信用卡下了一单,然后过了一天,我突然发现账号下面有两台机器。不过也好,两台机器做个主备。
bench 的结果:
----------------------------------------------------------------------
CPU Model : Intel(R) Xeon(R) CPU E5-2690 v2 @ 3.00GHz
CPU Cores : 2
CPU Frequency : 3000.000 MHz
CPU Cache : 16384 KB
Total Disk : 39.0 GB (18.0 GB Used)
Total Mem : 7976 MB (2120 MB Used)
Total Swap : 1023 MB (5 MB Used)
System uptime : 24 days, 17 hour 59 min
Load average : 0.21, 0.12, 0.10
OS : Ubuntu 18.04.5 LTS
Arch : x86_64 (64 Bit)
Kernel : 4.15.0-20-generic
TCP CC : cubic
Virtualization : Dedicated
Organization : AS63473 HostHatch, LLC
Location : Singapore / SG
Region : Singapore
----------------------------------------------------------------------
I/O Speed(1st run) : 495 MB/s
I/O Speed(2nd run) : 731 MB/s
I/O Speed(3rd run) : 715 MB/s
Average I/O speed : 647.0 MB/s
----------------------------------------------------------------------
Node Name Upload Speed Download Speed Latency
Speedtest.net 3295.69 Mbps 2583.03 Mbps 0.65 ms
Shanghai CU 219.87 Mbps 629.33 Mbps 214.01 ms
Guangzhou CT 18.45 Mbps 113.17 Mbps 229.08 ms
Guangzhou CU 424.10 Mbps 587.32 Mbps 203.09 ms
Hongkong CN 2560.67 Mbps 1094.98 Mbps 33.92 ms
Tokyo JP 294.63 Mbps 614.84 Mbps 74.30 ms
----------------------------------------------------------------------
YABS 的结果:
# ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #
# Yet-Another-Bench-Script #
# v2021-06-05 #
# https://github.com/masonr/yet-another-bench-script #
# ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #
Wed Aug 25 00:46:05 BST 2021
Basic System Information:
---------------------------------
Processor : Intel(R) Xeon(R) CPU E5-2690 v2 @ 3.00GHz
CPU cores : 2 @ 2999.998 MHz
AES-NI : ✔ Enabled
VM-x/AMD-V : ❌ Disabled
RAM : 3.9 GiB
Swap : 1024.0 MiB
Disk : 18.7 GiB
fio Disk Speed Tests (Mixed R/W 50/50):
---------------------------------
Block Size | 4k (IOPS) | 64k (IOPS)
------ | --- ---- | ---- ----
Read | 237.97 MB/s (59.4k) | 1.78 GB/s (27.9k)
Write | 238.59 MB/s (59.6k) | 1.79 GB/s (28.0k)
Total | 476.57 MB/s (119.1k) | 3.58 GB/s (55.9k)
| |
Block Size | 512k (IOPS) | 1m (IOPS)
------ | --- ---- | ---- ----
Read | 2.85 GB/s (5.5k) | 2.87 GB/s (2.8k)
Write | 3.00 GB/s (5.8k) | 3.07 GB/s (2.9k)
Total | 5.85 GB/s (11.4k) | 5.94 GB/s (5.8k)
iperf3 Network Speed Tests (IPv4):
---------------------------------
Provider | Location (Link) | Send Speed | Recv Speed
| | |
Clouvider | London, UK (10G) | 1.11 Gbits/sec | 412 Mbits/sec
Online.net | Paris, FR (10G) | 1.37 Gbits/sec | 993 Mbits/sec
WorldStream | The Netherlands (10G) | 788 Mbits/sec | 638 Mbits/sec
Biznet | Jakarta, Indonesia (1G) | 3.41 Gbits/sec | 2.55 Gbits/sec
Clouvider | NYC, NY, US (10G) | 628 Mbits/sec | 562 Mbits/sec
Velocity Online | Tallahassee, FL, US (10G) | 476 Mbits/sec | 238 Mbits/sec
Clouvider | Los Angeles, CA, US (10G) | 930 Mbits/sec | 908 Mbits/sec
Iveloz Telecom | Sao Paulo, BR (2G) | busy | 348 Mbits/sec
Geekbench 5 Benchmark Test:
---------------------------------
Test | Value
|
Single Core | 593
Multi Core | 1191
Full Test | https://browser.geekbench.com/v5/cpu/9485985
因为看 LET 上对 HostHatch 的评价还好,并且这是一家长期做生意的提供商,所以我就陆陆续续把其他平台上的 MySQL 数据迁移过来了,并且正好两台机器配置了一下Master Master Replication。
和之前在 A400 的机器一样,用 Docker 来管理各个服务。基本上也是同步一下数据,更改一下配置就可以起来。
❯ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5c9f15d2f6fd cflask_simple_worker "/bin/sh -c 'celery …" 4 days ago Up 6 hours cflask_simple_worker_1
b9d05a0aab65 cflask-production "/bin/bash shell_scr…" 4 days ago Up 6 hours 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp cflask_flask-prod_1
fe5babd77ff8 technosoft2000/calibre-web "/bin/bash -c /init/…" 2 weeks ago Up 2 days 8083/tcp calibre-web
27bb97742691 funkwhale/all-in-one:1.1.4 "/init" 2 weeks ago Up 2 days 80/tcp funkwhale
9f167b8f1a27 umputun/remark42:latest "/init.sh /srv/remar…" 2 weeks ago Up 2 days (healthy) 8080/tcp remark42
966776d9c62c luminoleon/epicgames-claimer "python3 -u main.py …" 2 weeks ago Up 2 days epic
11f2ab0251a3 gogs/gogs:0.12.3 "/app/gogs/docker/st…" 4 weeks ago Up 2 days 3000/tcp, 0.0.0.0:10022->22/tcp, :::10022->22/tcp gogs
2490f033f39d wordpress:latest "docker-entrypoint.s…" 4 weeks ago Up 2 days 80/tcp wordpress_blog
8f11b6177487 kmb32123/youtube-dl-server:latest "python -u ./youtube…" 4 weeks ago Up 2 days 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp youtube-dl-server_youtube-dl-server_1
ed9cc80eac6a ghcr.io/naiba/nezha-dashboard "/dashboard/app" 4 weeks ago Up 2 days 80/tcp, 0.0.0.0:5555->5555/tcp, :::5555->5555/tcp nezha_dashboard_1
6654066f6c09 wallabag/wallabag "/entrypoint.sh wall…" 4 weeks ago Up 2 days (healthy) 80/tcp wallabag
406190504fd3 phpmyadmin/phpmyadmin "/docker-entrypoint.…" 4 weeks ago Up 2 days 80/tcp phpmyadmin_phpmyadmin_1
8c902e165528 chevereto:latest "docker-php-entrypoi…" 7 weeks ago Up 2 days 80/tcp chevereto
fcca09be33e6 redis:4-alpine "docker-entrypoint.s…" 7 weeks ago Up 2 days 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp redis
b7c7844143ed fengkx/postgres:13-alpine "docker-entrypoint.s…" 2 months ago Up 2 days (healthy) 0.0.0.0:5432->5432/tcp, :::5432->5432/tcp postgres
129bede6f06c linuxserver/bookstack "/init" 2 months ago Up 2 days 80/tcp, 443/tcp bookstack
6901eecc15c8 diygod/rsshub "dumb-init -- npm ru…" 2 months ago Up 2 days 1200/tcp rsshub_rsshub_1
9229265c93de yourls "docker-entrypoint.s…" 2 months ago Up 2 days 80/tcp yourls
4f935d65a3fc hurlenko/filebrowser "/filebrowser --root…" 2 months ago Up 2 days 8080/tcp filebrowser
8ab377d558e3 wordpress:latest "docker-entrypoint.s…" 2 months ago Up 2 days 80/tcp wordpress
4fa2aad47f10 miniflux/miniflux:latest "/usr/bin/miniflux" 3 months ago Up 2 days 8080/tcp miniflux
47b8ad4f0d41 netdata/netdata "/usr/sbin/run.sh" 3 months ago Up 2 days (healthy) 0.0.0.0:19999->19999/tcp, :::19999->19999/tcp netdata
87f802cee469 f6f2296798e9 "docker-entrypoint.s…" 3 months ago Up 2 days 6379/tcp rsshub_redis_1
37898721ec5b browserless/chrome:1.43-chrome-stable "./start.sh" 3 months ago Up 2 days 3000/tcp rsshub_browserless_1
79e7d9774b63 b4bz/homer "/bin/sh /entrypoint…" 3 months ago Up 2 days 8080/tcp homer
f505c56e7a24 jrcs/letsencrypt-nginx-proxy-companion "/bin/bash /app/entr…" 3 months ago Up 2 days letsencrypt-nginx
97486b8aa958 jwilder/nginx-proxy "/app/docker-entrypo…" 3 months ago Up 2 days 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp nginx-proxy
可以看到即使跑了这么多应用,内存连一半都没有用完。CPU 也不过刚刚 1/4,性能还是挺满意的。
日常可以注册一下 HostHatch,通常会在论坛或者邮件中通知有优惠。
今天回到家突然发现刚买的一台 VPS 根目录空间 100% 被占用了,使用 du 一层层查看占用最后发现是 /var/lib/docker/containers
下有一个 json 日志文件占用了 20G 大小。
简单的查了一下发现 Docker 容器的日志都会被记录在宿主机的 /var/lib/docker/containers/
路径下。而我有一个容器因为不停地输出日志,没多久就占了很大空间。
在默认情况下 Docker 容器的日志会输出到一个 json-file 文件中,容器输出到 stdout
和 stderr
的内容加上时间戳会被记录到宿主机。
这些日志文件在宿主机的 /var/lib/docker/containers/
文件夹下,以这样的形式命名:
/var/lib/docker/containers/<container id>/<container id>-json.log
修改 Docker 配置 vi /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {"max-size": "10m", "max-file": "3"}
}
注意修改之后需要重启 Docker 使之生效 sudo systemctl restart docker
。
或者针对个别容器设置,在 docker-compose.yml 中:
注意需要版本2及以上
version: '2'
services:
app:
container_name: app
image: node
restart: always
logging:
driver: "json-file"
options:
max-file: "5" // number of files or file count
max-size: "10m" // file size
或者命令行:
docker run --log-opt max-size=10m --log-opt max-file=5 my-app:latest
应用自己去管理自己的日志,比如使用 Logging Framework,在 Java 中通常使用 log4j 将日志打印到一个远端的中心化地方,这样就可以绕过 Docker 和操作系统。这种方式给予了开发者更多的控制权。
为了保存日志数据,你可以配置一个持久化的存储或将日志转发到一个远程日志的系统,比如 Elastic Stack 或 Sematext Cloud,但是基于应用的日志框架存在的问题便是如果部署了多个容器,那么你需要一个方式来告诉日志系统,哪些日志属于哪个容器。
你可以在容器内部创建一个目录,然后将该目录挂载到宿主机上,那么一些长期或共享使用的数据可以长久的存储。你可以复制,备份,或者从其他容器访问这些数据。也可以在多个容器之间共享这些 volume。
但是使用 Data Volume 存在的问题是,很难将这些容器迁移到其他宿主机而不丢失数据。
在 Docker 下,另外一个记录日志的方式是使用 logging drivers。不像 Data Volumes, Docker logging driver 会从容器的 stdout 和 stderr 输出中直接读取数据。默认的配置会将这些日志记录到宿主机的一个文件中,但是改变 logging driver 可以允许你将事件转发给 syslog, gelf, journald 或其他 endpoints。
因为容器不再需要读写日志文件,可以提升一定的性能。但是也有一些弊端,Docker log 命令只能在 json-file
log driver 下使用;log diver 有一些功能限制,日志文件只能被传输而不能被解析;当 TCP 服务不可达时,容器会 shut down。
另一个解决方案是通过一个专用的、独立的日志容器来记录和手机日志,这非常适用于微服务架构。这个优势在于这完全不依赖与宿主机。相反,专用的日志容器可以允许你在 Docker 的环境中管理日志文件。他会自动从其他容器收集日志,监控,分析,并且将他们转存到一个中心存储上。
这种方式使得我们可以轻易地将容器在不同的宿主机中移动,并且可以非常轻松的扩展日志基础设施,只需要增加日志容器即可。
和专用的日志容器类似,使用日志容器,但是不同点在于,每一个应用容器都有专用的日志容器,允许你对每一个应用的日志进行自定义。第一个容器会将日志文件打印到 volume,然后日志文件会日志容器打上标签,然后再被传送到日志管理系统。
使用 sidecar 的一个主要的优势是,你可以为每一个 log 增加额外自定义的标签,可以更好地确定其来源。
同样也有一些劣势,设置或扩容可能会变得非常复杂和困难,并且需要更多的资源。你需要确保应用容器和 sidecar 容器是一起进行工作的,否则可能会造成数据丢失。
Logging driver 是 Docker 用来才运行的容器和服务中收集数据的机制,这使得数据更容易进行分析。当一个新的容器被创建,Docker 会自动使用 json-file log driver 作为默认。同时,你可以使用 logging driver plugins 来和其他日志工具进行交互。
下面是一个通过自定义 logging driver 来和 syslog 交互的例子:
docker run -–log-driver syslog –-log-opt syslog-address=udp://syslog-server:514 alpine echo hello world
有两个选项:
上面提过,默认的 logging driver 是 JSON 文件,其他选项有 logagent, syslog, fluentd, journald, splunk 等等。你可以通过修改 Docker configuration 文件 来进行配置:
# /etc/docker/daemon.json
{
"log-driver": "journald"
}
然后再执行:
systemctl restart docker
使之生效。
或者,你可以通过命令来为每一个容器单独设置
docker run --log-driver syslog --log-opt syslog-address=udp://syslog-server:514 alpine echo hello word
选项解释:
Vagrant 是一个使用 Ruby 编写,基于纯文本文件自动化创建和配置虚拟机的工具。
基于 VirtualBox 和 [[VMware]] ,通过 Vagrant 去控制虚拟机。
Vagrant 是 hashicorp 公司的产品。该公司有大量的开源项目。
Vagrant 提供了 vagrant 命令,通过 Vagrantfile
文件声明虚拟机配置。
按照官网的介绍安装。
brew cask install virtualbox
brew cask virtualbox-extension-pack
brew cask install vagrant
下载一个虚拟机:
vagrant box add ubuntu/trusty64
初始化一个 Ubuntu 镜像:
vagrant init ubuntu/trusty64
在初始化之后可以在当前目录下找到 Vagrantfile
:
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
end
ubuntu/trusty64 是在 Vagrant 官网搜索到的虚拟机的镜像。
启动虚拟机:
vagrant up
❯ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'ubuntu/trusty64' could not be found. Attempting to find and install...
default: Box Provider: virtualbox
default: Box Version: >= 0
==> default: Loading metadata for box 'ubuntu/trusty64'
default: URL: https://vagrantcloud.com/ubuntu/trusty64
==> default: Adding box 'ubuntu/trusty64' (v20190514.0.0) for provider: virtualbox
default: Downloading: https://vagrantcloud.com/ubuntu/boxes/trusty64/versions/20190514.0.0/providers/virtualbox.box
Download redirected to host: cloud-images.ubuntu.com
==> default: Successfully added box 'ubuntu/trusty64' (v20190514.0.0) for 'virtualbox'!
==> default: Importing base box 'ubuntu/trusty64'...
==> default: Matching MAC address for NAT networking...
==> default: Checking if box 'ubuntu/trusty64' version '20190514.0.0' is up to date...
==> default: Setting the name of the VM: vagrant_default_1630040745169_54425
==> default: Clearing any previously set forwarded ports...
Vagrant is currently configured to create VirtualBox synced folders with
the `SharedFoldersEnableSymlinksCreate` option enabled. If the Vagrant
guest is not trusted, you may want to disable this option. For more
information on this option, please refer to the VirtualBox manual:
https://www.virtualbox.org/manual/ch04.html#sharedfolders
This option can be disabled globally with an environment variable:
VAGRANT_DISABLE_VBOXSYMLINKCREATE=1
or on a per folder basis within the Vagrantfile:
config.vm.synced_folder '/host/path', '/guest/path', SharedFoldersEnableSymlinksCreate: false
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
default: Adapter 1: nat
==> default: Forwarding ports...
default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
default: SSH address: 127.0.0.1:2222
default: SSH username: vagrant
default: SSH auth method: private key
default:
default: Vagrant insecure key detected. Vagrant will automatically replace
default: this with a newly generated keypair for better security.
default:
default: Inserting generated public key within guest...
default: Removing insecure key from the guest if it's present...
default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
default: The guest additions on this VM do not match the installed version of
default: VirtualBox! In most cases this is fine, but in rare cases it can
default: prevent things such as shared folders from working properly. If you see
default: shared folder errors, please make sure the guest additions within the
default: virtual machine match the version of VirtualBox you have installed on
default: your host and reload your VM.
default:
default: Guest Additions Version: 4.3.40
default: VirtualBox Version: 6.1
==> default: Mounting shared folders...
default: /vagrant => /home/einverne/Git/vagrant
修改 Vagrant 可以自定义虚拟机网络,内存和 CPU 等等。
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
machine_box = "ubuntu/trusty64"
config.vm.define "local-env-1" do |machine|
machine.vm.box = machine_box
machine.vm.hostname = "local-env-1"
machine.vm.network "private_network", ip: "192.168.33.11"
machine.vm.provider "virtualbox" do |node|
node.name = "local-env-1"
node.memory = 2048
node.cpus = 2
end
end
config.vm.define "local-env-2" do |machine|
machine.vm.box = machine_box
machine.vm.hostname = "local-env-2"
machine.vm.network "private_network", ip: "192.168.33.12"
machine.vm.network "forwarded_port", guest: 26379, host: 26380
machine.vm.provider "virtualbox" do |node|
node.name = "local-env-2"
node.memory = 2048
node.cpus = 2
end
end
end
启动之后可以通过 vagrant ssh $name
登录虚拟机。
在虚拟机启动后 /vagrant
目录会挂载宿主机的同级目录。文件是同步的,这样就可以通过该目录来共享文件。
在 Vagrantfile 中可以如下语法:
config.vm.provision :shell, path: "bootstrap.sh"
会执行 bootstrap.sh
脚本。
Vagrant Box 相对于 Vagrant,就像是 Docker Image 对应于 Docker。
可以使用:
vagrant box add name
来添加 Box。
升级 Box
vagrant box update --box name
删除 Box
vagrant box remove name
常用命令有:
和 Docker 类似,Vagrant 也有几种不同的网络配置:
端口映射,将宿主机端口映射到虚拟机端口,宿主机 8080 端口映射到虚拟机 80 端口:
config.vm.network "forwarded_port", guest: 80, host: 8080
私有网络(host-only),只有宿主机能访问虚拟机,多个虚拟机在同一个网段,相互可以访问:
config.vm.network "private_network", ip: "192.168.21.4"
公有网络(bridge),虚拟机和宿主机相当于局域网中独立的主机,设置静态IP:
config.vm.network "public_network", ip: "192.168.1.120"
如果使用 public_network 而不配置 IP,那么会 DHCP 自动获取 IP 地址。
设置共享目录,Vagrant 使用 rsync 来同步文件:
config.vm.synced_folder "/directory/of/host_machine", "/directory/of/guest_machine"
虚拟机实例启动之后,通过工具自动设置,支持 Shell,Puppet,Chef,Ansible 等等:
config.vm.provision "shell", run: "always", inline: <<-SHELL
sudo yum install -y net-tools
SHELL
run: “always”表示每次vagrant up的时候,都执行Provision。
引用外部脚本:
config.vm.provision "shell", path: "script.sh
并非每次vagrant up的时候,都会执行Provision。只有在下面3种情况下Provision才会执行:
使用 Ansible
config.vm.provision "ansible" do |ansible|
ansible.playbook = "playbook.yml"
end
使用虚拟机内部的 Ansible:
Vagrant.configure("2") do |config|
# Run Ansible from the Vagrant VM
config.vm.provision "ansible_local" do |ansible|
ansible.playbook = "playbook.yml"
end
end
vagrant package --output hadoop_master.box hadoop_master
hadoop_master是虚拟机实例名称,hadoop_master.box是box名。
在创建box的时候,如果虚拟机实例正在运行,vagrant会先halt,然后再export。
将box添加到本地仓库:
vagrant box add hadoop_master hadoop_master.box
查看本地仓库的box列表:
$ vagrant box list
centos7 (virtualbox, 0)
hadoop_master (virtualbox, 0)
创建并且切换到用于测试的项目目录:
mkdir ~/test_vagrant && cd ~/test_vagrant
创建Vagrantfile,并使用刚才新创建的hadoop_master.box作为box:
vagrant init -m hadoop_master
创建,并启动虚拟机:
vagrant up
登陆到虚拟机:
vagrant ssh
可以看到和创建box之前的虚拟机是一模一样的
昨天心血来潮,看到推送的主机优惠信息中有一条半价的优惠,A400互联(带AFF),查了一下是一家成立不久的国人主机服务提供商,顿时就失去了兴趣,不过后来看到其配置又有点心动。
洛杉矶 [[CN2 线路]]的 VPS:
都是 KVM 架构的。
随后我又找到两个测试的 IP:
最后让我订购的原因就是网络,虽然我对网络要求没有那么高,但是我之前的服务器要不就是在美国网络延迟超过 200ms,要不就是内存空间比较小,稍微吃一点资源的应用就没有办法用上。所以综上我就买了一个洛杉矶的 2核4G 配置,网络带宽 30M 我个人也差不多够用了。
因为是国人商家,还是对其抱有一点敬畏,所以重要的数据都不在上面保存,我计划就是用来作为数据中转,以及因为其网络比较满足我的需求,可能用来做一下 frp 端口映射。
另外有一些自动化的服务,比如 Syncthing 文件同步, RSS 抓取(Miniflux),自动化任务(Huginn)等等。
同时定时备份一下相关数据,因为 Syncthing 本身就是多节点的,挂掉一个也不会有影响,我只不过用它来提升同步速度;另外 RSS 阅读器我只需要定期备份一下订阅源即可(如果想保留数据的话,把 PostgreSQL 数据库数据也备份一下即可;Huginn 我只需要备份我的 Task 即可,在新的机器上 Docker 其服务导入即可。
使用 teddysun 的 benchmark 简单的测试一下:
执行:
wget -qO- bench.sh | bash
结果:
----------------------------------------------------------------------
CPU Model : Intel(R) Xeon(R) CPU E5-2630L v2 @ 2.40GHz
CPU Cores : 2
CPU Frequency : 2399.998 MHz
CPU Cache : 16384 KB
Total Disk : 109.4 GB (2.9 GB Used)
Total Mem : 3936 MB (146 MB Used)
Total Swap : 0 MB (0 MB Used)
System uptime : 0 days, 0 hour 3 min
Load average : 0.18, 0.35, 0.17
OS : Ubuntu 20.04.1 LTS
Arch : x86_64 (64 Bit)
Kernel : 5.4.0-42-generic
TCP CC : cubic
Virtualization : KVM
Organization : AS35251 Ziyin Lin trading as Netlab
Location : Los Angeles / US
Region : California
----------------------------------------------------------------------
I/O Speed(1st run) : 252 MB/s
I/O Speed(2nd run) : 248 MB/s
I/O Speed(3rd run) : 243 MB/s
Average I/O speed : 247.7 MB/s
----------------------------------------------------------------------
Node Name Upload Speed Download Speed Latency
Speedtest.net 28.63 Mbps 27.18 Mbps 134.59 ms
Shanghai CT 13.73 Mbps 27.99 Mbps 125.49 ms
Shanghai CU 17.36 Mbps 28.36 Mbps 150.00 ms
Guangzhou CT 28.58 Mbps 1.33 Mbps 157.69 ms
Guangzhou CU 28.62 Mbps 19.46 Mbps 162.23 ms
Shenzhen CU 28.61 Mbps 25.36 Mbps 159.82 ms
Hongkong CN 27.79 Mbps 28.43 Mbps 253.90 ms
Singapore SG 28.59 Mbps 23.48 Mbps 198.68 ms
Tokyo JP 28.88 Mbps 15.75 Mbps 121.03 ms
----------------------------------------------------------------------
IO 性能一般,好一点的机器通常能到 700 MB/s,甚至超过 1GB/s,网络带宽除了一次广州的下载有点奇怪,还行,可以多跑几次看一下,没有虚标。
所有的应用都使用 Docker 安装
如果看到这里,你也想购买可以在下单的时候使用优惠码 0811,会立即使用半价。
在执行下的 docker-compose
之前需要先创建 nginx-proxy
名字的网络。可以参考这里
docker network create nginx-proxy
[[miniflux]] 是一款用 Go 写的开源 RSS 阅读器,比较轻量,但是功能都有。
version: '3'
services:
miniflux:
container_name: miniflux
image: miniflux/miniflux:latest
restart: always
depends_on:
db:
condition: service_healthy
environment:
- DATABASE_URL=postgres://YOUR_USERNAME:YOUR_PASSWORD@db/miniflux?sslmode=disable
- RUN_MIGRATIONS=1
- CREATE_ADMIN=1
- ADMIN_USERNAME=MINIFLUX_USERNAME
- ADMIN_PASSWORD=MINIFLUX_PASSWORD
- VIRTUAL_HOST=YOUR_DOMAIN
- VIRTUAL_PORT=8080
- LETSENCRYPT_HOST=YOUR_DOMAIN
- LETSENCRYPT_EMAIL=YOUR_EMAIL
db:
image: postgres:latest
container_name: postgres
restart: always
environment:
- POSTGRES_USER=YOUR_USERNAME
- POSTGRES_PASSWORD=YOUR_PASSWORD
volumes:
- miniflux-db:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready", "-U", "miniflux"]
interval: 10s
start_period: 30s
volumes:
miniflux-db:
networks:
default:
external:
name: nginx-proxy
说明:
a400 在我过去使用的两个月里面发生了近5次的服务中断问题,幸亏好我把大部分的服务已经迁移到了 HostHatch 后买的 VPS 上了。所幸网络延迟略好,拿来做个代理,做一些不需要 99.99% 在线的应用吧。
VPS 性能测试的几个方面:
在运行这类测试脚本之前,最好先将脚本下载下来之后打开看一眼,以防止安装执行一些不可信的文件。
相较于其他 benchmark 的优势在于可以测试全球不同地区的网络延迟情况。
sudo curl -sL -k https://ipasn.com/bench.sh | sudo bash
来自:LET
teddysun 提供的综合脚本,检测 CPU,内存,负载,磁盘 IO,带宽:
wget -qO- bench.sh | bash
curl -Lso- bench.sh | bash
UnixBench 测试,UnixBench 跑分不一定代表真实性能,但可以提供一定参考。
wget --no-check-certificate https://github.com/teddysun/across/raw/master/unixbench.sh
chmod +x unixbench.sh
./unixbench.sh
curl -sL yabs.sh | bash
默认情况下脚本会测试:
可以通过如下参数来禁用一些检测。
格式:
curl -sL yabs.sh | bash -s -- -flags
将其中的 flags
替换:
-f/-d
禁用 fio 磁盘-i
禁用 iperf 网络带宽检测-g
禁用 Geekbench比如只想检测磁盘读写,可以使用如下的命令:
curl -sL yabs.sh | bash -s -- -i -g
(curl -s wget.racing/nench.sh | bash; curl -s wget.racing/nench.sh | bash) 2>&1 | tee nench.log
全国各地测速节点的一键测速脚本 Superspeed.sh
使用:
bash <(curl -Lso- https://git.io/superspeed)
SuperBench.sh
是在 bench.sh 上的增强,增加了服务器类型检测,OpenVZ, KVM ,独立服务器通电时间检测等。
该脚本需要 root 运行:
wget -qO- https://raw.githubusercontent.com/oooldking/script/master/superbench.sh | bash
#或者
curl -Lso- https://raw.githubusercontent.com/oooldking/script/master/superbench.sh | bash
wget -qO- git.io/superbench.sh | bash
curl -Lso- git.io/superbench.sh | bash
curl -LsO git.io/bench.sh; chmod +x bench.sh && ./bench.sh -a share
LemonBench,是一款针对 Linux 服务器设计的服务器性能测试工具。通过综合测试,可以快速评估服务器的综合性能,为使用者提供服务器硬件配置信息。
curl -LsO bench.monster/speedtest.sh; bash speedtest.sh -asia
可以通过手工执行命令的方式查看 CPU 信息:
cat /proc/cpuinfo
同理可以查看内存:
cat /proc/meminfo
以及硬盘:
fdisk -l
df -lh
The speed of read and write of your hard drive.
dd if=/dev/zero of=test bs=64k count=4k oflag=dsync
dd if=/dev/zero of=test bs=8k count=256k conv=fdatasync
个人比较常用的是 speedtest-cli
pip install speedtest-cli
speedtest-cli
测试服务器到国内的速度,oooldking:
wget -qO- https://raw.githubusercontent.com/oooldking/script/master/superspeed.sh | bash
网络连通性
wget https://raw.githubusercontent.com/helloxz/mping/master/mping.sh && bash mping.sh
测试带宽
wget https://raw.github.com/sivel/speedtest-cli/master/speedtest.py
python speedtest.py --share
全球各地 ping 测试网站:
或者
http://www.ipip.net/ping.php
wget https://raw.githubusercontent.com/helloxz/mping/master/mping.sh
bash mping.sh
脚本:
wget -qO- https://raw.githubusercontent.com/zq/shell/master/autoBestTrace.sh | bash
一键检测VPS回程国内三网路由,root1:
curl https://raw.githubusercontent.com/zhucaidan/mtr_trace/main/mtr_trace.sh|bash
支持的线路为:电信CN2 GT,电信CN2 GIA,联通169,电信163,联通9929,联通4837,移动CMI
BestTrace 工具。
wget https://cdn.ipip.net/17mon/besttrace4linux.zip
unzip besttrace*
chmod +x besttrace
./besttrace -q1 202.106.196.115
http://ping.chinaz.com/
https://www.17ce.com/
http://www.webkaka.com/
http://ce.cloud.360.cn/
安装检查工具:
sudo apt install -y smartmontools
使用 df -h
查看硬盘设备,然后执行:
smartctl -A /dev/sda | grep "Power_On_Hours"
后面的数字即为硬盘的通电时间小时数。如果通电时间比较长,就要做好备份工作了。
一键脚本:
wget -q https://github.com/Aniverse/A/raw/i/a && bash a
# cpu
cat /proc/cpuinfo
lscpu
dd if=/dev/zero of=test bs=64k count=16k conv=fdatasync
dd if=/dev/zero of=test bs=64k count=4k oflag=dsync
# speed
wget http://cachefly.cachefly.net/100mb.test
GitHub 地址:https://github.com/lmc999/RegionRestrictionCheck
执行命令:
bash <(curl -L -s https://raw.githubusercontent.com/lmc999/RegionRestrictionCheck/main/check.sh)
Mailu 是一个开源的邮件服务器,可以使用 Docker 部署安装,后台界面使用 Python & Flask 开发。
建议在开始自建之前先阅读:
了解常用的 [[SPF]],[[DKIM]],[[DMARC]] 记录的作用。
系统环境要求:
telnet smtp.gmail.com 25
来测试,返回 220 表示可以。
本文在 Ubuntu 20.04 LTS 上进行。
可以使用如下命令测试 25 端口是否开放:
telnet smtp.gmail.com 25
如果返回超时需要向主机提供商申请开通 25 端口。
确保如下的端口可用:
netstat -tulpn | grep -E -w '25|80|110|143|443|465|587|993|995'
以 example.com
为例:
sudo hostnamectl set-hostname mx.example.com
重启之后使用如下命令检查:
hostname
# 应该显示 mx
hostname -f
# 应该显示 mx.example.com
假设 VPS 的域名是 1.1.1.1
,以 example.com
为例:
mx.example.com
到 1.1.1.1v=spf1 mx ~all
_dmarc.example.com
TXT 记录,值为 v=DMARC1;p=none;pct100;rua=mailto: admin@example.com;ruf=mailto: admin@example.com
记得修改其中的 admin@example.com
为自己的域名。
这一步需要在 VPS 提供商后台进行设置,有一些服务器商不支持用户自行修改,那么需要用户 open ticket 来咨询,并设置 IP 到域名的解析记录。
设置完成之后可以通过 dig -x IP
来查看是否生效。
可以参考 Docker 官网安装。
sudo apt-get update
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common -y
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
sudo apt-get install docker-ce docker-ce-cli containerd.io -y
systemctl start docker
systemctl enable docker
安装 Docker Compose
curl -fsSL https://get.docker.com | bash -s docker
curl -L "https://github.com/docker/compose/releases/download/1.26.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
Mailu 官方提供了一个自动配置生成网页
可以选择两种 Webmail
将配置下载之后查看配置,然后使用 Docker Compose 安装
docker-compose up -d
安装成功后:
等待服务启动之后,登录后台,然后进行一定初始化配置。然后在界面中添加域名。
在后台添加域名:
登录后台之后,点击 Mail Domains,然后在列表也点击最前面的按钮,进入域名详情之后点击右上角的 Regenerate Keys
生成 [[DKIM]] 和 [[DMARC]] 记录。
然后按照界面显示的内容,将 DNS 记录更新到域名的 DNS 中,等待一段时间生效即可。
添加域名后在后台找到 DKIM,将其值拷贝出来,到 Cloudflare,或者任何 DNS 服务提供商添加 DKIM
在域名界面添加用户邮箱,这个用户邮箱之后就可以通过 [[webmail]] 来登录,发信或者收信。
最后可以使用 https://www.mail-tester.com/ 来发信测试。
最近正好买了两台配置一样的 VPS,整理学习一下 MySQL 的双主同步配置。
假设有两台服务器,分别安装了 MariaDB。
Install MariaDB on Ubuntu 18.04
sudo apt update
sudo apt install mariadb-server
sudo mysql_secure_installation
两台机器的IP分别是:
修改 MySQL 配置 vi /etc/mysql/mariadb.conf.d/50-server.cnf
:
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
binlog_do_db = demo
# bind-address = 127.0.0.1
bind-address
允许 MySQL 与外部通信,如果清楚自己需要从外网连接,可以设置 0.0.0.0
,不过要清楚如果允许 MySQL 从外部访问,可能带来数据安全问题然后需要重启 MySQL:
sudo /etc/init.d/mysql restart
然后使用 sudo mysql -u root -p
登录,创建登录用户:
CREATE USER 'your_name'@'%' IDENTIFIED BY 'password';
grant all on *.* to 'your_name'@'%';
grant all privileges on *.* to 'your_name'@'%' with grant option;
这样可以在其他机器上通过 your_name 来访问 MySQL,而不是用 root。
创建同步数据的账户,并授予复制权限:
create user 'slave_user'@'%' identified by 'password';
grant replication slave on *.* to 'demouser'@'%';
flush privileges;
最后执行:
show master status;
显示:
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000002 | 741 | demo | |
+------------------+----------+--------------+------------------+
记住该信息,接下来在另外一台机器中需要使用。
同样,安装,修改配置,重启,然后登录。
不过需要注意的是在第二台机器中,需要将服务 ID 改成 2:
server-id = 2
然后执行:
stop slave;
CHANGE MASTER TO MASTER_HOST = '10.10.10.1', MASTER_USER = 'slave_user', MASTER_PASSWORD = 'password', MASTER_LOG_FILE = 'mysql-bin.000002', MASTER_LOG_POS = 741;
start slave;
然后在第二台机器,创建 slave_user
账号。
执行:
show master status;
MariaDB [(none)]> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000002 | 866 | demo | |
+------------------+----------+--------------+------------------+
同理,回到 10.10.10.1 第一台机器。
执行:
stop slave;
CHANGE MASTER TO MASTER_HOST = '10.10.10.2', MASTER_USER = 'slave_user', MASTER_PASSWORD = 'password', MASTER_LOG_FILE = 'mysql-bin.000002', MASTER_LOG_POS = 866;
start slave;
因为上面的配置是同步了 demo 数据库,所以可以在 demo 数据库中创建表,然后分别在两台机器中查看。
use demo;
create table dummy(`id` varchar(10));
然后分别在两台机器中查看:
show tables;
然后删除表 drop table dummy
。
可以通过如下命令查看 slave 状态:
show slave status\G;
Slave_IO_Running 及Slave_SQL_Running 进程必须正常运行,即 Yes 状态,否则说明同步失败 若失败查看 MySQL 错误日志中具体报错详情来进行问题定位。
# 主数据库端ID号
server_id = 1
# 开启 binlog
log-bin = /var/log/mysql/mysql-bin.log
# 需要复制的数据库名,如果复制多个数据库,重复设置这个选项即可
binlog-do-db = demo
# 将从服务器从主服务器收到的更新记入到从服务器自己的二进制日志文件中
log-slave-updates
# 控制binlog的写入频率。每执行多少次事务写入一次(这个参数性能消耗很大,但可减小MySQL崩溃造成的损失)
sync_binlog = 1
# 这个参数一般用在主主同步中,用来错开自增值, 防止键值冲突
auto_increment_offset = 1
# 这个参数一般用在主主同步中,用来错开自增值, 防止键值冲突
auto_increment_increment = 1
# 二进制日志自动删除的天数,默认值为0,表示“没有自动删除”,启动时和二进制日志循环时可能删除
expire_logs_days = 7
# 将函数复制到slave
log_bin_trust_function_creators = 1
binlog-ignore-db
是 master 侧的设置,告诉 Master 不要记录列出的 DB 修改。
replicate-ignore-db
是一个 slave 侧的设置,告诉 Slave 忽略列出的 DB。
binlog-do-db=DATABASE_NAME1
binlog-do-db=DATABASE_NAME2
或者像这样忽略系统的,然后同步所有的
binlog_ignore_db = mysql
binlog_ignore_db = information_schema
binlog_ignore_db = performance_schema
MySQL 会产生很多 mysql-bin.[index]
这样的 log 在系统中。不建议直接删除,可以使用 MySQL 内建的机制定期清理。
SET GLOBAL expire_logs_days = 3;
然后编辑配置 vi /etc/mysql/my.cnf
:
[mysqld]
expire_logs_days=3
gdu 是一个使用 Go 编写的,非常漂亮的磁盘空间占用分析工具。
直接运行 gdu 可以展示一个非常直观的磁盘空间占用。
gdu 为 SSD 做了优化,但在机械硬盘上也能很好的工作。
Linux:
curl -L https://github.com/dundee/gdu/releases/latest/download/gdu_linux_amd64.tgz | tar xz
chmod +x gdu_linux_amd64
sudo mv gdu_linux_amd64 /usr/bin/gdu
macOS:
brew install -f gdu
brew link --overwrite gdu # if you have coreutils installed as well
Android Termux 安装:
wget https://github.com/dundee/gdu/releases/lastest/download/gdu_linux_arm64.tgz
tar xzvf gdu_linux_arm64.tgz
chmod +x gdu_linux_arm64
更多的安装方式可以参考 repo
gdu # analyze current dir
gdu -a # show apparent size instead of disk usage
gdu <some_dir_to_analyze> # analyze given dir
gdu -d # show all mounted disks
gdu -l ./gdu.log <some_dir> # write errors to log file
gdu -i /sys,/proc / # ignore some paths
gdu -I '.*[abc]+' # ignore paths by regular pattern
gdu -c / # use only white/gray/black colors
gdu -n / # only print stats, do not start interactive mode
gdu -np / # do not show progress, useful when using its output in a script
gdu / > file # write stats to file, do not start interactive mode
gdu -o- / | gzip -c >report.json.gz # write all info to JSON file for later analysis
zcat report.json.gz | gdu -f- # read analysis from file
因为 macOS 下的 Rime 输入法(鼠须管) 不是经常更新二进制,所以要体验性特性总是要手工进行编译安装。
之前的想要 Rime 实现按下 Esc 切换为英文时,看到 commit history 有提交的时候就尝试手工编译安装了一下。一直都在笔记里面,现在整理一下发出来。
首先从 App Store 中安装 Xcode 12.2 及以上版本。
如果只有 Xcode 10 只能编译 x86_64
的版本。
从官网 下载安装。
或者从Homebrew 安装:
brew install cmake
或者从 MacPorts 安装:
port install cmake
获取 Squirrel 的源码:
git clone --recursive https://github.com/rime/squirrel.git
cd squirrel
通过如下方式获取 Rime 的插件(这一步如果不需要可以跳过,不过建议安装特定的插件以提高使用舒适度):
bash librime/install-plugins.sh rime/librime-sample # ...
bash librime/install-plugins.sh hchunhui/librime-lua
bash librime/install-plugins.sh lotem/librime-octagram
添加两个插件 librime-lua,librime-octagram
You have the option to skip the following two sections - building Boost and librime, by downloading the latest librime binary from GitHub releases.
可以直接执行如下命令从 GitHub release 页面下载编译好的 Boost 和 librime,跳过下面两个步骤:
bash ./travis-install.sh
准备工作做好之后,就可以开始编译 Squirrel
选择下面两种方式中的一个安装 Boost 库。
Option: 下载源码编译安装:.
export BUILD_UNIVERSAL=1
make -C librime xcode/thirdparty/boost
export BOOST_ROOT="$(pwd)/librime/thirdparty/src/boost_1_75_0"
Let’s set BUILD_UNIVERSAL
to tell make
that we are building Boost as
universal macOS binaries. Skip this if building only for the native architecture.
After Boost source code is downloaded and a few compiled libraries are built,
be sure to set shell variable BOOST_ROOT
to its top level directory as above.
You may also set BOOST_ROOT
to an existing Boost source tree before this step.
Option: 从 Homebrew 从安装:
brew install boost
Note: with this option, the built Squirrel.app is not portable because it links to locally installed libraries from Homebrew.
Learn more about the implications of this at https://github.com/rime/librime/blob/master/README-mac.md#install-boost-c-libraries
Option: 从 MacPorts 安装:
port install boost -no_static
Again, set BUILD_UNIVERSAL
to tell make
that we are building librime as
universal macOS binaries. Skip this if building only for the native architecture.
Build librime, dependent third-party libraries and data files:
export BUILD_UNIVERSAL=1
make deps
当所有的依赖都安装准备好之后, 开始编译 Squirrel.app
:
make
To build only for the native architecture, pass variable ARCHS
to make
:
# for Mac computers with Apple Silicon
make ARCHS='arm64'
# for Intel-based Mac
make ARCHS='x86_64'
编译后之后就可以安装到系统上:
# Squirrel as a Universal app
make install
# for Intel-based Mac only
make ARCHS='x86_64' install
之后就可以享受完美的 Rime 输入法体验了。
在 make ARCHS='x86_64'
的时候遇到错误:
CompileXIB /Users/einverne/Git/squirrel/zh-Hans.lproj/MainMenu.xib (in target 'Squirrel' from project 'Squirrel')
cd /Users/einverne/Git/squirrel
export XCODE_DEVELOPER_USR_PATH\=/Applications/Xcode.app/Contents/Developer/usr/bin/..
/Applications/Xcode.app/Contents/Developer/usr/bin/ibtool --errors --warnings --notices --module Squirrel --output-partial-info-plist /Users/einverne/Git/squirrel/build/Squirrel.build/Release/Squirrel.build/zh-Hans.lproj/MainMenu-PartialInfo.plist --auto-activate-custom-fonts --target-device mac --minimum-deployment-target 10.9 --output-format human-readable-text --compile /Users/einverne/Git/squirrel/build/Release/Squirrel.app/Contents/Resources/zh-Hans.lproj/MainMenu.nib /Users/einverne/Git/squirrel/zh-Hans.lproj/MainMenu.xib
Command CompileXIB failed with a nonzero exit code
** BUILD FAILED **
The following build commands failed:
CompileXIB /Users/einverne/Git/squirrel/Base.lproj/MainMenu.xib (in target 'Squirrel' from project 'Squirrel')
CompileXIB /Users/einverne/Git/squirrel/zh-Hant.lproj/MainMenu.xib (in target 'Squirrel' from project 'Squirrel')
CompileXIB /Users/einverne/Git/squirrel/zh-Hans.lproj/MainMenu.xib (in target 'Squirrel' from project 'Squirrel')
(3 failures)
make: *** [release] Error 65
$ sudo rm -rf /Library/Developer/CommandLineTools
)$ xcode-select --install
).ld: warning: directory not found for option '-L/usr/local/lib/Release'
ld: warning: directory not found for option '-L/Users/einverne/Git/squirrel/librime/thirdparty/lib/Release'
ld: library not found for -licudata
clang: error: linker command failed with exit code 1 (use -v to see invocation)
librime 是 Rime,包括各个系统上的桌面版,Squirrel(鼠须管) 等等依赖的核心库。
首先要安装 Xcode 和命令行工具,以及必要的编译工具:
brew install cmake git
获取代码:
git clone --recursive https://github.com/rime/librime.git
or download from GitHub, then get code for third party dependencies separately.
安装 Boost 库,Boost 库是一个 C++ 的第三方库,Rime 大量地依赖了这个库。
选择一 (推荐): 下载源码,手工编译:
cd librime
make xcode/thirdparty/boost
The make script will download Boost source tarball, extract it to
librime/thirdparty/src/boost_<version>
and create needed static libraries
for building macOS uinversal binary.
Set shell variable BOOST_ROOT
to the path to boost_<version>
directory prior
to building librime.
export BOOST_ROOT="$(pwd)/thirdparty/src/boost_1_75_0"
选择 2: 从 Homebrew 安装 Boost 库:
brew install boost
如果你只想编译,并且安装到自己的 macOS 上,这是一个节省时间的选择。通过 Homebrew 中的 Boost 编译安装的 librime 可能不能在其他机器上完美的工作。
Built with Homebrewed version of Boost, the librime
binary will not be
portable to machines without certain Homebrew formulae installed.
选择 3: Install an older version of Boost libraries from Homebrew.
Starting from version 1.68, boost::locale
library from Homebrew depends on
icu4c
, which is not provided by macOS.
Make target xcode/release-with-icu
tells cmake to link to ICU libraries
installed locally with Homebrew. This is only required if building with the
librime-charcode
plugin.
To make a portable build with this plugin, install an earlier version of
boost
that wasn’t dependent on icu4c
:
brew install boost@1.60
brew link --force boost@1.60
Required third-party libraries other than Boost are included as git submodules:
# cd librime
# if you haven't checked out the submodules with git clone --recursive ..., do:
# git submodule update --init
make xcode/thirdparty
This builds libraries located at thirdparty/src/*
, and installs the build
artifacts to thirdparty/include
, thirdparty/lib
and thirdparty/bin
.
You can also build an individual library, eg. opencc
, with:
make xcode/thirdparty/opencc
make xcode
This creates build/lib/Release/librime*.dylib
and command line tools
build/bin/Release/rime_*
.
Or, create a debug build:
make xcode/debug
make xcode/test
Or, test the debug build:
make xcode/test-debug
(
cd debug/bin;
echo "congmingdeRime{space}shurufa" | Debug/rime_api_console
)
Use it as REPL, quit with Control+d:
(cd debug/bin; ./Debug/rime_api_console)