用openresty给hexo造了个随机图片接口

2,322次阅读
4 条评论

共计 8432 个字符,预计需要花费 22 分钟才能阅读完成。

用openresty给hexo造了个随机图片接口

最近博主在使用hexo+butterfly主题迁移和调整本站点,主要还是追求静态的性能。。。

butterfly主题设置封面

前几天用hexo迁移wordpress文章后,用hexo打开发现都没有文章封面,不像这里默认用文章得第一张图做文章封面

设置默认封面

看了下butterfly得文档,可以通过如下方式设置默认封面:

cover:
  # display the cover or not (是否顯示文章封面)
  index_enable: true
  aside_enable: true
  archives_enable: true
  # the position of cover in home page (封面顯示的位置)
  # left/right/both
  position: both
  # When cover is not set, the default cover is displayed (當沒有設置cover時,默認的封面顯示)
  default_cover:
    # - https://i.loli.net/2020/05/01/gkihqEjXxJ5UZ1C.jpg

这种方式是在文章没有设置封面时才使用该默认配置,如果这么设置得话,就所有得文章封面都一样了,哎,索然无味。不过仔细看了下default_cover用得列表,那就说明可以用多个图,测试了下增加了几个图链,文章封面就会不一样,但是图还是这些,它应该是随机从列表里渲染的,重复渲染几率高~

单独设置封面

看来保险的方式还是单独设置封面,就是繁琐而已,看了下hexo文档说明,单独设置则要在每个文章上配置cover参数:

---
title: 轻松时刻
tags: []
id: '187'
categories:
  - - uncategorized
abbrlink: 12414
date: 2018-11-26 02:14:49
cover: https://i.loli.net/2020/05/01/gkihqEjXxJ5UZ1C.jpg
---
略。。。。。

评估了下目前导出的文章都用sed+awk方式插入cover,新文章则自行编写时带上,似乎可行

#调试命令,输出文件名和第一张匹配的图图
[root@blog _posts]# for i in `ls *.md`;do echo $i ;  awk -F '[()]' '/http(s+):\/\/.*.(jpg|png|jpeg)/ {print $2}' $i | head -1; echo;done
ansible中的block.md
https://www.xadocker.cn/wp-content/uploads/2022/05/cfcd624c810f351d970f760a59fa68a0.jpeg

ansible中的并发和异步.md
https://www.xadocker.cn/wp-content/uploads/2022/05/cfcd624c810f351d970f760a59fa68a0.jpeg

ansible发布jar包.md
https://www.xadocker.cn/wp-content/uploads/2022/05/cfcd624c810f351d970f760a59fa68a0.jpeg

ansible批量修改密码.md
https://www.xadocker.cn/wp-content/uploads/2022/05/cfcd624c810f351d970f760a59fa68a0.jpeg

写成脚本如下,不一定通用,博主这里是拿到文章第一张图片设置封面,可能没有,自行新增处理存在或不存在的逻辑哈

[root@blog _posts]# cat insert-cover.sh
#!/bin/bash

for file_name in `ls *.md`
do
    echo ${file_name}
    cover_text=`awk -F '[()]' '/http(s+):\/\/.*.(jpg|png|jpeg)/ {print "cover: "$2}' ${file_name} | head -1`
    echo ${cover_text}
    echo
    sed "3i ${cover_text}" -i ${file_name}
done

# 删除cover配置
[root@blog _posts]# sed  '/cover: http.*/d' -i *.md

动态图片接口

开放的动态接口

根据上面操作基本结束封面配置,但是后面用typro写文章时博主又不懒得配链接,审美上看腻了,总是配置那几个关键技术的图图,食之乏味弃之可惜,于是开始整了个动态封面接口,网上挺多的

樱花:https://www.dmoe.cc/random.php
晓晴博客:https://acg.toubiec.cn/random.php
Unsplash Source | API Documentation:详情请看官网介绍
夏沫博客:https://cdn.seovx.com/?mom=302
https://cdn.seovx.com/d/?mom=302
https://cdn.seovx.com/ha/?mom=302
二次元随机图:https://api.blogbig.cn/random/api.php
搏天api:https://api.btstu.cn/sjbz/api.php
姬长信API For Docker:
----每日bing:https://api.isoyu.com/bing_images.php
----美女图片壁纸:https://api.isoyu.com/mm_images.php
----网红专栏壁纸:https://api.isoyu.com/beibei_images.php
----动态IP签名图片:https://api.isoyu.com/ip_images.php?signature=早安
----ARU(阿鲁)表情包:https://api.isoyu.com/ARU_GIF_S.php
樱道:https://api.r10086.com/动漫综合1.php (网站中有更多api接口)
小歪API:https://api.ixiaowai.cn/api/api.php(二次元动漫)
https://api.ixiaowai.cn/mcapi/mcapi.php(mc酱动漫)
https://api.ixiaowai.cn/gqapi/gqapi.php(高清壁纸)
保罗|API:https://api.paugram.com/wallpaper/
墨天逸:https://api.mtyqx.cn/tapi/random.php
EEE.DOG:https://api.yimian.xyz/img
动漫星空:https://api.dongmanxingkong.com/suijitupian/acg/1080p/index.php
岁月小筑:#https调用https://img.xjh.me/random_img.php
#http调用http://img.xjh.me/random_img.php
东方Project:https://img.paulzzh.tech/touhou/random

试了几个,有些已荒废,有些适合收藏不适外露(●ˇ∀ˇ●),看来对于图片的质量和服务可用性还得自己出手了,质量嘛就去ins上淘一点,略。。。

因为考虑到博主不会php,也不考虑php,因为后面博主考虑关闭php~。目前博主能用的只有django,但是这玩意也好重,还是算了。基于目前服务器的负载,博主急需一个轻量的服务,突然间想起好久未使用的技能openresty,锈逗了~~~以下是初步想法

  1. 一个静态图片服务
  2. 将图片路径存入到redis 集合中
  3. nginx去redis中获取随机值,该值就是图片路径,通过子请求去获取图片
    • 图片存在则返回图片给用户
    • 图片不存在则返回404

我们来看下如何实现

静态服务

这东西最简单,配个root就行,但是博主得加点限制

  • 防盗链
  • 限制为内部调用,只能通过接口调用
server
    {
        listen 80;
        server_name randimg.xadocker.cn;
        location / {
            return 301 https://randimg.xadocker.cn$request_uri;
        }
        access_log  /home/wwwlogs/randimg.xadocker.cn.json.log json_logs;
    }

server
    {
        listen 443 ssl http2;
        server_name randimg.xadocker.cn;

        ssl_certificate /usr/local/nginx/ssl/randimg.xadocker.cn/randimg.xadocker.cn.pem;
        ssl_certificate_key /usr/local/nginx/ssl/randimg.xadocker.cn/randimg.xadocker.cn.key;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";
        ssl_session_cache builtin:1000 shared:SSL:10m;
        # openssl dhparam -out /usr/local/nginx/conf/ssl/dhparam.pem 2048
        ssl_dhparam /usr/local/nginx/conf/ssl/dhparam.pem;

    root  /home/wwwroot/randimg.xadocker.cn/;
    valid_referers blocked *.xadocker.cn *.baidu.com ~\.google\.;
    if ($invalid_referer) { return 403; }

    location ~ ^/getImages {
        # 暴露接口,只能通过这个接口访问
    }

    location ~ ^/internal/images/ {

        # 调试时可以将其注释直接访问站点root目录类文件
        internal;
    }

    location / { return 403; }
    access_log  /home/wwwlogs/randimg.xadocker.cn.json.log json_logs;
}

将图片名字存储到redis

静态服务目录结构

# 当前图片服务目录结构
[root@xadocker randimg.xadocker.cn]# tree -L 4
.
`-- internal
    `-- images
        |-- akb48teamsh
        |   `-- 8429494170
        `-- weibocos
            `-- 45280393108

# 样例图片地址
[root@xadocker images]# pwd
/home/wwwroot/randimg.xadocker.cn/internal/images
[root@xadocker images]# ls akb48teamsh/8429494170/89352102_1063660667326708_8589188623952390983_n.jpg
akb48teamsh/8429494170/89352102_1063660667326708_8589188623952390983_n.jpg

# 博主这里将akb48teamsh/8429494170/89352102_1063660667326708_8589188623952390983_n.jpg这个做为value存储redis中得集合中

将图片相对路径存入redis集合中

使用find和xargs配合插入,但是xargs -n10 这个参数不生效,导致我redis-cli插入是一个一个插入

但是使用xargs -n10打印倒是能打10个一行,奇怪~~~~

[root@xadocker images]# find */ -type f | xargs -n10 -i{} redis-cli -a passwordxxxxx  sadd myimages  {}

查看redis键值

[root@xadocker images]# redis-cli
127.0.0.1:6379> auth passwordxxxxx
OK
127.0.0.1:6379> SRANDMEMBER myimages
"akb48teamsh/8429494170/301554207_1130519864512854_7745758296285175055_n.jpg"
127.0.0.1:6379> SRANDMEMBER myimages
"akb48teamsh/8429494170/272933045_146856814381529_1286943523991638639_n.jpg"
127.0.0.1:6379> SRANDMEMBER myimages
"akb48teamsh/8429494170/79644807_2932310016787538_275067540623034722_n.jpg"
127.0.0.1:6379> SRANDMEMBER myimages
"akb48teamsh/8429494170/191033593_483170126285325_8916111552677783580_n.jpg"

接下来就是通过lua去redis获取集合随机值了

lua调用redis

使用redis链接池减少链接得创建,此处用到lua-resty-redis模块和redis_iresty第三方提供模块可查看此篇文章:https://www.xadocker.cn/archives/1580.html

使用ngx.location.capture子请求进行内部location调用

[root@xadocker lua]# cat get_random_images.lua
local redis = require "comm.redis_iresty"
local opts = {
    host = "127.0.0.1",
    port = "6379",
    password = "passworddddd",
    db = 0,
    keepalive = 60000,
    pool_size = 32,
}

local red = redis:new(opts)

--- 获取随机图片路径
local pic_name, err = red:srandmember('myimages')
if nil == pic_name then
    ngx.log(ngx.INFO, "redis key myimages not found", pic_name, err)
    --- ngx.exit(ngx.HTTP_FORBIDDEN)
    ngx.header['Content-Type'] = 'text/html'
    ngx.exit(ngx.HTTP_NOT_FOUND)
    return

else
    ngx.log(ngx.INFO, "get images: ", pic_name)
    ngx.header['Content-Type'] = 'image/jpeg, image/png, image/gif'
    local res =  ngx.location.capture("/internal/images/" .. pic_name, { method = ngx.HTTP_GET, always_forward_body = true})
    if res.status == 404 then
        ngx.exit(ngx.HTTP_NOT_FOUND)
        return
    else
        ngx.say(res.body)
    end
end

此处有个坑,就是使用ngx.location.capture去调用http2的服务会报错

lua:30: http2 requests not supported yet

搜索了下,说可以是用lua-resty-http模块去处理

最后博主没有采用lua-resty-http,而是取消http2就可以了,注意nginx只要存在一个server配置了http2,那就会导致该server地址下的所有其他server都是http2,要关只能一起关

# listen上配置http2 
       listen 443 ssl http2;

# listen上关闭http2
       listen 443 ssl;

最后的nginx配置文件

[root@xadocker vhost]# cat randimg.xadocker.cn.conf
server
    {
        listen 80;
        server_name randimg.xadocker.cn;
        location / {
            return 301 https://randimg.xadocker.cn$request_uri;
        }
        access_log  /home/wwwlogs/randimg.xadocker.cn.json.log json_logs;
    }

server
    {
        listen 443 ssl;
        server_name randimg.xadocker.cn;

        ssl_certificate /usr/local/nginx/ssl/randimg.xadocker.cn/randimg.xadocker.cn.pem;
        ssl_certificate_key /usr/local/nginx/ssl/randimg.xadocker.cn/randimg.xadocker.cn.key;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";
        ssl_session_cache builtin:1000 shared:SSL:10m;
        # openssl dhparam -out /usr/local/nginx/conf/ssl/dhparam.pem 2048
        ssl_dhparam /usr/local/nginx/conf/ssl/dhparam.pem;

        root  /home/wwwroot/randimg.xadocker.cn/;
        valid_referers blocked *.xadocker.cn *.baidu.com ~\.google\.;
        if ($invalid_referer) { return 403; }

        location ~ ^/getImages {
            content_by_lua_file lua/get_random_images.lua;
        }

        location ~ ^/internal/images/ {
            internal;
        }

        location / { return 403; }
        access_log  /home/wwwlogs/randimg.xadocker.cn.json.log json_logs;
}

至此基本功能以实现,在hexo中就不用为挑选封面发愁了,直接每篇文章配置cover即可,注意需要保证每个接口地址不能一样,否则会导致获得得图片封面都是一样的,所以此处加了个 date +%s%N进去

for i in `ls *.md`;do sed -i  -r "2i cover: http://randimg.xadocker.cn/getImages?ts=`date +%s%N`" $i;done
用openresty给hexo造了个随机图片接口

目前先放出跑几天,目前多多少少还是有点问题得,后面得加点限制。。。

正文完
 1
xadocker
版权声明:本站原创文章,由 xadocker 2023-01-05发表,共计8432字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(4 条评论)
评论达人 LV.1
2023-01-07 12:59:13 回复

6

 Android  Chrome  中国广东省广州市电信
    Avatar photo
    xadocker 博主
    2023-01-07 16:54:22 回复

    @越 6+1

     Windows  Chrome  中国广东省广州市电信
小背包 评论达人 LV.1
2023-03-31 11:32:12 回复

大神,您好! get_random_images.lua 这个文件可以分享一下吗?

 Windows  Edge  中国福建省龙岩市电信
    Avatar photo
    xadocker 博主
    2023-04-01 14:02:18 回复

    @小背包 博文里已有提供了😂

     Windows  Chrome  中国广东省广州市电信