快速运行一个你自己的「一言」程序

前言

动漫也好、小说也好、网络也好,不论在哪里,我们总会看到有那么一两个句子能穿透你的心。我们把这些句子汇聚起来,形成一言网络,以传递更多的感动。如果可以,我们希望我们没有停止服务的那一天。
简单来说,一言指的就是一句话,可以是动漫中的台词,也可以是网络上的各种小段子。 或是感动,或是开心,有或是单纯的回忆。来到这里,留下你所喜欢的那一句句话,与大家分享,这就是一言存在的目的。

——选自「一言」简介

1. 为什么要自己搭建?

「一言」其实提供了在线的 api 地址访问,因为「一言」是一个免费的服务,因此必然是对访问频率存在一定的限制,同时也有可能存在一定的网络延迟(考虑地域/网络环境等影响因素)。

「一言」官网:https://hitokoto.cn/

在线 API 地址:https://v1.hitokoto.cn/

API 文档:https://developer.hitokoto.cn/

2. 快速运行

本着快速运行的目的,Docker 自然会成为我们的首选工具,好在「一言」提供了官方的 Docker 镜像,简直就是懒人神器~

首先我们创建一个文件夹存放程序启动时相关的文件

1
2
mkdir -p hitokoto
cd hitokoto

接着我们创建「一言」的配置文件 config.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
name: 'demo' # 服务名称,例如:hitokoto
url: 'hitokoto_api:8000' # 服务地址,例如:https://v1.hitokoto.cn
api_name: 'demo_api_name' # 服务表示,例如:cd-01-demo
server: # 配置 HTTP 服务的信息
host: hitokoto_api # 监听的地址,因为我们采用 docker-compose 启动,因此设置为 service 名称即可
port: '8000' # 监听的端口
compress_body: true # 是否使用 GZIP 压缩
redis: # 配置 Redis
host: hitokoto_db # Redis 主机名,因为我们采用 docker-compose 启动,因此设置为 service 名称即可
port: 6379 # Redis 端口
password: '' # Redis 密码
database: 0 # Redis 数据库
sentences_ab_switcher: # 本节是服务 AB 异步更新的配置,如果您不知道这个是什么意思,请保持默认
a: 1 # a 状态对应的 redis 数据库
b: 2 # b 状态对应的 redis 数据库
remote_sentences_url: https://cdn.jsdelivr.net/gh/hitokoto-osc/sentences-bundle@latest/ # 语句库地址,通常默认即可。如果您想使用您自己打包部署的语句库,您可以修改此项

然后再创建 docker-compose.yml 编排文件

1
2
3
4
5
6
7
8
9
10
11
12
13
version: "3.8"

services:
hitokoto_db:
image: redis:6.0.8
hitokoto_api:
image: hitokoto/api
ports:
- 8000:8000
depends_on:
- hitokoto_db
volumes:
- ./config.yml:/usr/src/app/data/config.yml:ro

最后运行一下 docker-compose up ,待得运行成功之后,我们在终端测试一下接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ curl localhost:8000 | json_pp
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 316 100 316 0 0 11285 0 --:--:-- --:--:-- --:--:-- 11285
{
"creator_uid" : 5655,
"commit_from" : "web",
"creator" : "Muzi.言寺",
"hitokoto" : "曾盛开过一朵,曾不会败落,曾在他眼中流淌过浩瀚的银河。",
"uuid" : "d6e59b5a-6a12-4d14-ac64-fc0977de6853",
"created_at" : "1585293655",
"reviewer" : 4756,
"from" : "不痛",
"from_who" : "南语",
"type" : "h",
"length" : 27,
"id" : 5358
}

此时一个内网的「一言」程序就已经搭建成功了~

3. 快速使用

如何在 html 文件快速集成,这里贴个官方文档给出的代码,同时自己做了点改造~

创建 index.html 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=100, initial-scale=1.0" />
<title>一言</title>
</head>
<body>
<p
id="hitokoto"
style="
text-align: center;
border: 2px dashed black;
padding: 10%;
font-weight: 600;
"
>
:D 获取中...
</p>
</body>
<script>
fetch("http://localhost/api")
.then((response) => response.json())
.then((data) => {
const hitokoto = document.getElementById("hitokoto");
let from;
switch (data.type) {
case "a":
from = `《${data.from}》//动画`;
break;
case "b":
from = `《${data.from}》//漫画`;
break;
case "g":
from = `《${data.from}》//其他`;
break;
case "h":
from = `《${data.from}》//影视`;
break;
case "i":
from = `《${data.from}》//诗词`;
break;
case "k":
from = `《${data.from}》//哲学`;
break;
case "d":
from = `《${data.from}》//文学`;
break;
case "e":
from = `「${data.from}」//原创`;
break;
case "c":
from = `「${data.from}」//游戏`;
break;
case "f":
from = `「${data.from}」//来自网络`;
break;
case "j":
from = `「${data.from}」//网易云`;
break;
case "l":
from = `「${data.from}」//抖机灵`;
break;
default:
from = `「${data.from}」//其他`;
break;
}
hitokoto.innerText = `${data.hitokoto} —— ${from}`;
})
.catch(console.error);
</script>
</html>

我们使用 nginx 部署这个HTML 文件,同时反向代理「一言」的 API 接口,此时需要创建 nginx 的配置文件 default.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
server {
listen 80;
listen [::]:80;
server_name localhost;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
}

location /api {
proxy_pass http://hitokoto_api:8000/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_buffering off;
sendfile off;
proxy_max_temp_file_size 0;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_temp_file_write_size 64k;
proxy_http_version 1.1;
proxy_request_buffering off;
}

}

同时将 docker-compose.yml 文件修改一下,去掉 api 暴露的8000端口,同时增加nginx的编排配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
version: "3.8"

services:
hitokoto_db:
image: redis:6.0.8
hitokoto_api:
image: hitokoto/api
depends_on:
- hitokoto_db
volumes:
- ./config.yml:/usr/src/app/data/config.yml:ro
nginx:
image: nginx:1.18.0
ports:
- 80:80
depends_on:
- hitokoto_api
volumes:
- ./default.conf:/etc/nginx/conf.d/default.conf:ro
- ./index.html:/usr/share/nginx/html/index.html

再次执行 docker-compose up ,待运行成功之后,打开浏览器,输入 localhost 即可查看到页面,同时因为去掉了8000 端口的暴露,之前的http://localhost:8000的接口地址就变更为了 http://localhost/api了,是不是很方便呢~

image-20201103004506705

代码示例

https://github.com/xkcoding/practice_demo/tree/master/quick-run-hitokoto

-------------本文结束  感谢您的阅读-------------
o(╯□╰)o我只要一毛钱的鼓励~~