Preview
Skip to content
CodingDiary
返回

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

编辑页面
导读

「一言」官方 API 有频率限制?自己搭一个内网版!Docker Compose 一键部署:Redis + hitokoto/api 镜像,5 分钟搞定。附 Nginx 反向代理配置 + 前端 HTML 集成示例,完整 docker-compose.yml 直接拿来用。动漫台词、网络金句,属于你的私有一言服务~

前言

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

——选自「一言」简介

1. 为什么要自己搭建?

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

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

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

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

2. 快速运行

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

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

mkdir -p hitokoto
cd hitokoto

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

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 编排文件

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 ,待得运行成功之后,我们在终端测试一下接口

$ 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 文件

<!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

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的编排配置:

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


编辑页面
分享到:

上一篇
2020.Q4&年度总结
下一篇
如何在 Spring 环境下优雅的实现策略模式